summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS.md2
-rw-r--r--DONORS.md67
-rw-r--r--core/SCsub2
-rw-r--r--core/bind/core_bind.cpp3
-rw-r--r--core/color.cpp5
-rw-r--r--core/color.h2
-rw-r--r--core/error_macros.cpp10
-rw-r--r--core/error_macros.h27
-rw-r--r--core/image.cpp7
-rw-r--r--core/math/a_star.cpp88
-rw-r--r--core/math/a_star.h35
-rw-r--r--core/math/aabb.cpp5
-rw-r--r--core/math/aabb.h1
-rw-r--r--core/math/basis.cpp21
-rw-r--r--core/math/basis.h4
-rw-r--r--core/math/bsp_tree.cpp4
-rw-r--r--core/math/delaunay.h4
-rw-r--r--core/math/math_funcs.h2
-rw-r--r--core/math/plane.cpp7
-rw-r--r--core/math/plane.h6
-rw-r--r--core/math/quat.cpp5
-rw-r--r--core/math/quat.h1
-rw-r--r--core/math/quick_hull.cpp2
-rw-r--r--core/math/rect2.cpp5
-rw-r--r--core/math/rect2.h1
-rw-r--r--core/math/transform.cpp5
-rw-r--r--core/math/transform.h1
-rw-r--r--core/math/transform_2d.cpp6
-rw-r--r--core/math/transform_2d.h1
-rw-r--r--core/math/vector2.cpp4
-rw-r--r--core/math/vector2.h6
-rw-r--r--core/math/vector3.cpp5
-rw-r--r--core/math/vector3.h7
-rw-r--r--core/os/input_event.cpp40
-rw-r--r--core/os/input_event.h11
-rw-r--r--core/pool_vector.h7
-rw-r--r--core/project_settings.cpp2
-rw-r--r--core/script_language.cpp1
-rw-r--r--core/script_language.h27
-rw-r--r--core/ustring.cpp15
-rw-r--r--core/ustring.h1
-rw-r--r--core/variant_call.cpp102
-rw-r--r--doc/classes/AABB.xml8
-rw-r--r--doc/classes/AStar.xml28
-rw-r--r--doc/classes/AnimationNodeBlendSpace2D.xml2
-rw-r--r--doc/classes/Area2D.xml1
-rw-r--r--doc/classes/Array.xml2
-rw-r--r--doc/classes/BackBufferCopy.xml4
-rw-r--r--doc/classes/CanvasItem.xml1
-rw-r--r--doc/classes/Color.xml8
-rw-r--r--doc/classes/Control.xml15
-rw-r--r--doc/classes/EditorInspectorPlugin.xml4
-rw-r--r--doc/classes/HTTPRequest.xml32
-rw-r--r--doc/classes/Image.xml11
-rw-r--r--doc/classes/InputEvent.xml4
-rw-r--r--doc/classes/InputEventMouseMotion.xml8
-rw-r--r--doc/classes/OS.xml3
-rw-r--r--doc/classes/Plane.xml8
-rw-r--r--doc/classes/PoolByteArray.xml7
-rw-r--r--doc/classes/PoolColorArray.xml7
-rw-r--r--doc/classes/PoolIntArray.xml7
-rw-r--r--doc/classes/PoolRealArray.xml7
-rw-r--r--doc/classes/PoolStringArray.xml7
-rw-r--r--doc/classes/PoolVector2Array.xml7
-rw-r--r--doc/classes/PoolVector3Array.xml7
-rw-r--r--doc/classes/PopupMenu.xml2
-rw-r--r--doc/classes/ProjectSettings.xml12
-rw-r--r--doc/classes/Quat.xml8
-rw-r--r--doc/classes/RayCast.xml1
-rw-r--r--doc/classes/RayCast2D.xml1
-rw-r--r--doc/classes/Rect2.xml8
-rw-r--r--doc/classes/SoftBody.xml24
-rw-r--r--doc/classes/Spatial.xml1
-rw-r--r--doc/classes/String.xml2
-rw-r--r--doc/classes/TextEdit.xml24
-rw-r--r--doc/classes/Theme.xml2
-rw-r--r--doc/classes/TileMap.xml3
-rw-r--r--doc/classes/TouchScreenButton.xml2
-rw-r--r--doc/classes/Transform.xml8
-rw-r--r--doc/classes/Transform2D.xml8
-rw-r--r--doc/classes/Variant.xml33
-rw-r--r--doc/classes/Vector2.xml8
-rw-r--r--doc/classes/Vector3.xml8
-rw-r--r--doc/classes/VisualShaderNodeInput.xml6
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp6
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp20
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp55
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp9
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp6
-rw-r--r--drivers/unix/file_access_unix.cpp1
-rw-r--r--editor/animation_track_editor.cpp1
-rw-r--r--editor/array_property_edit.cpp8
-rw-r--r--editor/create_dialog.cpp21
-rw-r--r--editor/create_dialog.h1
-rw-r--r--editor/editor_about.cpp1
-rw-r--r--editor/editor_audio_buses.cpp3
-rw-r--r--editor/editor_data.cpp30
-rw-r--r--editor/editor_data.h3
-rw-r--r--editor/editor_file_system.cpp15
-rw-r--r--editor/editor_help.cpp19
-rw-r--r--editor/editor_node.cpp9
-rw-r--r--editor/editor_node.h2
-rw-r--r--editor/editor_properties.cpp17
-rw-r--r--editor/editor_properties_array_dict.cpp8
-rw-r--r--editor/editor_resource_preview.cpp21
-rw-r--r--editor/editor_spin_slider.cpp2
-rw-r--r--editor/editor_themes.cpp2
-rw-r--r--editor/filesystem_dock.cpp6
-rw-r--r--editor/groups_editor.cpp1
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp6
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp122
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h7
-rw-r--r--editor/plugins/mesh_instance_editor_plugin.cpp1
-rw-r--r--editor/plugins/script_text_editor.cpp21
-rw-r--r--editor/plugins/script_text_editor.h1
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp72
-rw-r--r--editor/plugins/spatial_editor_plugin.h12
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp4
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp1
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp5
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp67
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h2
-rw-r--r--editor/project_settings_editor.cpp39
-rw-r--r--editor/scene_tree_dock.cpp39
-rw-r--r--editor/script_editor_debugger.cpp79
-rw-r--r--editor/script_editor_debugger.h17
-rw-r--r--editor/settings_config_dialog.cpp10
-rw-r--r--main/main.cpp14
-rw-r--r--main/splash_editor.pngbin36310 -> 50789 bytes
-rw-r--r--main/tests/test_astar.cpp259
-rw-r--r--modules/assimp/SCsub3
-rw-r--r--modules/assimp/editor_scene_importer_assimp.cpp971
-rw-r--r--modules/assimp/editor_scene_importer_assimp.h50
-rw-r--r--modules/assimp/import_state.h53
-rw-r--r--modules/csg/csg.cpp10
-rw-r--r--modules/gdnative/gdnative/pool_arrays.cpp35
-rw-r--r--modules/gdnative/gdnative_api.json49
-rw-r--r--modules/gdnative/include/gdnative/pool_arrays.h14
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml3
-rw-r--r--modules/gdscript/gdscript.cpp5
-rw-r--r--modules/gdscript/gdscript_function.cpp4
-rw-r--r--modules/gdscript/gdscript_functions.cpp3
-rw-r--r--modules/gdscript/gdscript_parser.cpp3
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp1
-rw-r--r--modules/mono/glue/Managed/Files/AABB.cs5
-rw-r--r--modules/mono/glue/Managed/Files/Basis.cs5
-rw-r--r--modules/mono/glue/Managed/Files/Color.cs5
-rw-r--r--modules/mono/glue/Managed/Files/Mathf.cs69
-rw-r--r--modules/mono/glue/Managed/Files/MathfEx.cs3
-rw-r--r--modules/mono/glue/Managed/Files/Plane.cs7
-rw-r--r--modules/mono/glue/Managed/Files/Quat.cs5
-rw-r--r--modules/mono/glue/Managed/Files/Rect2.cs5
-rw-r--r--modules/mono/glue/Managed/Files/Transform.cs5
-rw-r--r--modules/mono/glue/Managed/Files/Transform2D.cs5
-rw-r--r--modules/mono/glue/Managed/Files/Vector2.cs5
-rw-r--r--modules/mono/glue/Managed/Files/Vector3.cs5
-rw-r--r--modules/visual_script/visual_script.cpp1
-rw-r--r--modules/visual_script/visual_script_editor.cpp10
-rw-r--r--platform/android/os_android.cpp34
-rw-r--r--platform/iphone/gl_view.mm13
-rw-r--r--platform/osx/os_osx.mm5
-rwxr-xr-x[-rw-r--r--]platform/windows/os_windows.cpp127
-rw-r--r--platform/windows/os_windows.h68
-rw-r--r--platform/x11/os_x11.cpp75
-rw-r--r--platform/x11/os_x11.h3
-rw-r--r--scene/2d/navigation_2d.cpp12
-rw-r--r--scene/2d/touch_screen_button.cpp8
-rw-r--r--scene/3d/physics_body.cpp4
-rw-r--r--scene/3d/soft_body.cpp7
-rw-r--r--scene/SCsub1
-rw-r--r--scene/animation/animation_blend_space_1d.cpp1
-rw-r--r--scene/animation/animation_blend_space_2d.cpp1
-rw-r--r--scene/debugger/SCsub5
-rw-r--r--scene/debugger/script_debugger_remote.cpp (renamed from core/script_debugger_remote.cpp)172
-rw-r--r--scene/debugger/script_debugger_remote.h (renamed from core/script_debugger_remote.h)12
-rw-r--r--scene/gui/dialogs.cpp10
-rw-r--r--scene/gui/dialogs.h5
-rw-r--r--scene/gui/item_list.cpp1
-rw-r--r--scene/gui/label.cpp13
-rw-r--r--scene/gui/slider.cpp8
-rw-r--r--scene/gui/text_edit.cpp14
-rw-r--r--scene/gui/text_edit.h7
-rw-r--r--scene/gui/tree.cpp3
-rw-r--r--scene/main/scene_tree.cpp70
-rw-r--r--scene/main/scene_tree.h23
-rw-r--r--scene/main/viewport.cpp126
-rw-r--r--scene/main/viewport.h36
-rw-r--r--scene/resources/animation.cpp12
-rw-r--r--scene/resources/material.cpp28
-rw-r--r--scene/resources/ray_shape.cpp10
-rw-r--r--scene/resources/visual_shader.cpp34
-rw-r--r--scene/resources/visual_shader.h1
-rw-r--r--scene/resources/visual_shader_nodes.cpp17
-rw-r--r--servers/audio/effects/eq.cpp4
-rw-r--r--servers/register_server_types.cpp2
-rw-r--r--servers/visual/shader_language.cpp1448
-rw-r--r--servers/visual/shader_language.h5
-rw-r--r--servers/visual/visual_server_viewport.cpp2
-rw-r--r--servers/visual_server.cpp11
-rw-r--r--thirdparty/README.md8
-rw-r--r--thirdparty/assimp/code/Common/BaseImporter.cpp17
-rw-r--r--thirdparty/assimp/code/Common/DefaultIOSystem.cpp161
-rw-r--r--thirdparty/assimp/code/Common/Exporter.cpp42
-rw-r--r--thirdparty/assimp/code/Common/ImporterRegistry.cpp6
-rw-r--r--thirdparty/assimp/code/Common/PostStepRegistry.cpp7
-rw-r--r--thirdparty/assimp/code/Common/SceneCombiner.cpp50
-rw-r--r--thirdparty/assimp/code/Common/Version.cpp14
-rw-r--r--thirdparty/assimp/code/Common/scene.cpp18
-rw-r--r--thirdparty/assimp/code/FBX/FBXCompileConfig.h8
-rw-r--r--thirdparty/assimp/code/FBX/FBXConverter.cpp345
-rw-r--r--thirdparty/assimp/code/FBX/FBXConverter.h94
-rw-r--r--thirdparty/assimp/code/FBX/FBXDocument.h39
-rw-r--r--thirdparty/assimp/code/FBX/FBXExportProperty.cpp6
-rw-r--r--thirdparty/assimp/code/FBX/FBXExporter.cpp122
-rw-r--r--thirdparty/assimp/code/FBX/FBXExporter.h2
-rw-r--r--thirdparty/assimp/code/FBX/FBXImporter.cpp217
-rw-r--r--thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp20
-rw-r--r--thirdparty/assimp/code/MMD/MMDCpp14.h83
-rw-r--r--thirdparty/assimp/code/MMD/MMDImporter.cpp372
-rw-r--r--thirdparty/assimp/code/MMD/MMDImporter.h96
-rw-r--r--thirdparty/assimp/code/MMD/MMDPmdParser.h597
-rw-r--r--thirdparty/assimp/code/MMD/MMDPmxParser.cpp608
-rw-r--r--thirdparty/assimp/code/MMD/MMDPmxParser.h782
-rw-r--r--thirdparty/assimp/code/MMD/MMDVmdParser.h376
-rw-r--r--thirdparty/assimp/code/Material/MaterialSystem.cpp19
-rw-r--r--thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp268
-rw-r--r--thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h112
-rw-r--r--thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp6
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp1
-rw-r--r--thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp25
-rw-r--r--thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp29
-rw-r--r--thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h7
-rw-r--r--thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp63
-rw-r--r--thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h8
-rw-r--r--thirdparty/assimp/code/revision.h23
-rw-r--r--thirdparty/assimp/include/assimp/.editorconfig8
-rw-r--r--thirdparty/assimp/include/assimp/BaseImporter.h20
-rw-r--r--thirdparty/assimp/include/assimp/Bitmap.h6
-rw-r--r--thirdparty/assimp/include/assimp/ByteSwapper.h5
-rw-r--r--thirdparty/assimp/include/assimp/CreateAnimMesh.h14
-rw-r--r--thirdparty/assimp/include/assimp/DefaultIOStream.h19
-rw-r--r--thirdparty/assimp/include/assimp/DefaultIOSystem.h5
-rw-r--r--thirdparty/assimp/include/assimp/Defines.h9
-rw-r--r--thirdparty/assimp/include/assimp/Exceptional.h23
-rw-r--r--thirdparty/assimp/include/assimp/Exporter.hpp4
-rw-r--r--thirdparty/assimp/include/assimp/GenericProperty.h7
-rw-r--r--thirdparty/assimp/include/assimp/Hash.h6
-rw-r--r--thirdparty/assimp/include/assimp/IOStream.hpp12
-rw-r--r--thirdparty/assimp/include/assimp/IOStreamBuffer.h43
-rw-r--r--thirdparty/assimp/include/assimp/IOSystem.hpp4
-rw-r--r--thirdparty/assimp/include/assimp/Importer.hpp4
-rw-r--r--thirdparty/assimp/include/assimp/LineSplitter.h36
-rw-r--r--thirdparty/assimp/include/assimp/LogAux.h5
-rw-r--r--thirdparty/assimp/include/assimp/Macros.h49
-rw-r--r--thirdparty/assimp/include/assimp/MathFunctions.h33
-rw-r--r--thirdparty/assimp/include/assimp/MemoryIOWrapper.h6
-rw-r--r--thirdparty/assimp/include/assimp/ParsingUtils.h9
-rw-r--r--thirdparty/assimp/include/assimp/Profiler.h14
-rw-r--r--thirdparty/assimp/include/assimp/ProgressHandler.hpp8
-rw-r--r--thirdparty/assimp/include/assimp/RemoveComments.h8
-rw-r--r--thirdparty/assimp/include/assimp/SGSpatialSort.h5
-rw-r--r--thirdparty/assimp/include/assimp/SceneCombiner.h11
-rw-r--r--thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h5
-rw-r--r--thirdparty/assimp/include/assimp/SmoothingGroups.h6
-rw-r--r--thirdparty/assimp/include/assimp/SmoothingGroups.inl7
-rw-r--r--thirdparty/assimp/include/assimp/SpatialSort.h5
-rw-r--r--thirdparty/assimp/include/assimp/StandardShapes.h7
-rw-r--r--thirdparty/assimp/include/assimp/StreamReader.h10
-rw-r--r--thirdparty/assimp/include/assimp/StreamWriter.h8
-rw-r--r--thirdparty/assimp/include/assimp/StringComparison.h7
-rw-r--r--thirdparty/assimp/include/assimp/StringUtils.h5
-rw-r--r--thirdparty/assimp/include/assimp/Subdivision.h5
-rw-r--r--thirdparty/assimp/include/assimp/TinyFormatter.h32
-rw-r--r--thirdparty/assimp/include/assimp/Vertex.h67
-rw-r--r--thirdparty/assimp/include/assimp/XMLTools.h5
-rw-r--r--thirdparty/assimp/include/assimp/aabb.h11
-rw-r--r--thirdparty/assimp/include/assimp/ai_assert.h4
-rw-r--r--thirdparty/assimp/include/assimp/anim.h4
-rw-r--r--thirdparty/assimp/include/assimp/camera.h6
-rw-r--r--thirdparty/assimp/include/assimp/cexport.h6
-rw-r--r--thirdparty/assimp/include/assimp/cfileio.h6
-rw-r--r--thirdparty/assimp/include/assimp/cimport.h6
-rw-r--r--thirdparty/assimp/include/assimp/color4.h13
-rw-r--r--thirdparty/assimp/include/assimp/color4.inl94
-rw-r--r--thirdparty/assimp/include/assimp/defs.h43
-rw-r--r--thirdparty/assimp/include/assimp/fast_atof.h6
-rw-r--r--thirdparty/assimp/include/assimp/importerdesc.h10
-rw-r--r--thirdparty/assimp/include/assimp/light.h6
-rw-r--r--thirdparty/assimp/include/assimp/material.h6
-rw-r--r--thirdparty/assimp/include/assimp/material.inl265
-rw-r--r--thirdparty/assimp/include/assimp/matrix3x3.h15
-rw-r--r--thirdparty/assimp/include/assimp/matrix3x3.inl70
-rw-r--r--thirdparty/assimp/include/assimp/matrix4x4.h18
-rw-r--r--thirdparty/assimp/include/assimp/matrix4x4.inl179
-rw-r--r--thirdparty/assimp/include/assimp/mesh.h40
-rw-r--r--thirdparty/assimp/include/assimp/metadata.h4
-rw-r--r--thirdparty/assimp/include/assimp/pbrmaterial.h7
-rw-r--r--thirdparty/assimp/include/assimp/postprocess.h21
-rw-r--r--thirdparty/assimp/include/assimp/qnan.h31
-rw-r--r--thirdparty/assimp/include/assimp/quaternion.h6
-rw-r--r--thirdparty/assimp/include/assimp/quaternion.inl6
-rw-r--r--thirdparty/assimp/include/assimp/scene.h42
-rw-r--r--thirdparty/assimp/include/assimp/texture.h13
-rw-r--r--thirdparty/assimp/include/assimp/types.h40
-rw-r--r--thirdparty/assimp/include/assimp/vector2.h4
-rw-r--r--thirdparty/assimp/include/assimp/vector2.inl6
-rw-r--r--thirdparty/assimp/include/assimp/vector3.h12
-rw-r--r--thirdparty/assimp/include/assimp/vector3.inl2
-rw-r--r--thirdparty/assimp/include/assimp/version.h2
-rw-r--r--thirdparty/libogg/bitwise.c5
-rw-r--r--thirdparty/libogg/crctable.h278
-rw-r--r--thirdparty/libogg/framing.c175
-rw-r--r--thirdparty/libogg/ogg/config_types.h1
-rw-r--r--thirdparty/libogg/ogg/ogg.h1
-rw-r--r--thirdparty/libogg/ogg/os_types.h20
-rw-r--r--thirdparty/zstd/common/bitstream.h4
-rw-r--r--thirdparty/zstd/common/compiler.h6
-rw-r--r--thirdparty/zstd/common/mem.h2
-rw-r--r--thirdparty/zstd/common/xxhash.c10
-rw-r--r--thirdparty/zstd/common/zstd_internal.h8
-rw-r--r--thirdparty/zstd/compress/zstd_compress.c603
-rw-r--r--thirdparty/zstd/compress/zstd_compress_internal.h84
-rw-r--r--thirdparty/zstd/compress/zstd_compress_literals.c149
-rw-r--r--thirdparty/zstd/compress/zstd_compress_literals.h29
-rw-r--r--thirdparty/zstd/compress/zstd_compress_sequences.c415
-rw-r--r--thirdparty/zstd/compress/zstd_compress_sequences.h47
-rw-r--r--thirdparty/zstd/compress/zstd_double_fast.c5
-rw-r--r--thirdparty/zstd/compress/zstd_fast.c18
-rw-r--r--thirdparty/zstd/compress/zstd_lazy.c56
-rw-r--r--thirdparty/zstd/compress/zstd_opt.c10
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress.c5
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress_block.c7
-rw-r--r--thirdparty/zstd/zstd.h18
-rw-r--r--version.py2
334 files changed, 7172 insertions, 6711 deletions
diff --git a/AUTHORS.md b/AUTHORS.md
index 4ae6db35d7..c5981306c4 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -55,6 +55,7 @@ name is available.
Dana Olson (adolson)
Daniel J. Ramirez (djrm)
Daniel Rakos (aqnuep)
+ David Sichma (DavidSichma)
Dharkael (lupoDharkael)
Dmitry Koteroff (Krakean)
DualMatrix
@@ -120,6 +121,7 @@ name is available.
Patrick (firefly2442)
Paul Batty (Paulb23)
Paul Joannon (paulloz)
+ Paul Trojahn (ptrojahn)
Pawel Kowal (pkowal1982)
Pedro J. Estébanez (RandomShaper)
Pieter-Jan Briers (PJB3005)
diff --git a/DONORS.md b/DONORS.md
index ffb7bf125e..3ab4b91f67 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -14,10 +14,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Enjin Coin <https://enjincoin.io>
Heroic Labs <https://heroiclabs.com>
+ Interblock <http://interblockgaming.com>
## Gold sponsors
Gamblify <https://www.gamblify.com>
+ Image Campus <https://www.imagecampus.edu.ar>
Moonwards <https://www.moonwards.com>
## Mini sponsors
@@ -27,8 +29,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Anandarup Mallik
Andrew Dunai
Brandon Lamb
- Christian Chipont
- Christian Uldall Pedersen
+ Christopher Montesano
Christoph Woinke
Darkhan Baimyrza
Denis Malyavin
@@ -42,6 +43,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Javary Co.
Jeffery Chiu
Jeppe Zapp
+ John Benard (Linuxydable)
Justin Arnold
Justo Delgado Baudí
Kyle Szklenski
@@ -52,7 +54,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Mike King
Nathan Warden
Neal Gompa (Conan Kudo)
- Patrick Aarstad
ScottMakesGames
Slobodan Milnovic
Stephan Lanfermann
@@ -64,7 +65,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Andrei
cheese65536
- Daniel Hartmann
Dave
David Gehrig
David Snopek
@@ -82,18 +82,17 @@ generous deed immortalized in the next stable release of Godot Engine.
Taylor Ritenour
Zaven Muradyan
+ _
Alexander Trey Saunders
Asher Glick
Austen McRae
Bernhard Werner
beVR
Brian van der Stel
- Cameron MacNair
Carlo Cabanilla
Daniel James
David Giardi
Default Name
- Edward E
Florian Breisch
Gamejunkey
Gero
@@ -103,6 +102,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Jon Woodward
Jose Fernando Alexandre
Karl Werf
+ Klavdij Voncina
Lex Steers
Luke
Maciej Pendolski
@@ -115,11 +115,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Scott Wadden
Sergey
Shawn Yu
+ The Architect
thechris
Tom Langwaldt
tukon
Unseen Domains
- wmww
Alex Khayrullin
Branwyn Tylwyth
@@ -129,19 +129,18 @@ generous deed immortalized in the next stable release of Godot Engine.
Conrad Curry
Craig Smith
Darrian Little
- Dean Harmon
Ivan Trombley
+ Jakub Dering
Joan Fons
Joshua Flores
Krzysztof Jankowski
Lord Bloodhound
- Lucas Ferreira Franca
Nathan Lundquist
- Nicklas Breum
Pascal Grüter
Petr Malac
Rami
Reneator
+ Rob
Robert Willes
Ronnie Ashlock
Thomas Bjarnelöf
@@ -156,6 +155,7 @@ generous deed immortalized in the next stable release of Godot Engine.
André Frélicot
andres eduardo lopez
Andrew Bowen
+ aoshiwik
Ben Botwin
Carlos de Sousa Marques
Chase Taranto
@@ -166,7 +166,6 @@ generous deed immortalized in the next stable release of Godot Engine.
D
Daniel Eichler
David White
- Eric
Eric Monson
Erik Hatfield
Eugenio Hugo Salgüero Jáñez
@@ -189,8 +188,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Juraj Móza
Kasper Jeppesen
kinfox
- Klaus The
- Klavdij Voncina
Maarten Elings
Marcelo Dornbusch Lopes
Markus Fehr
@@ -199,7 +196,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Marvin
Matt Eunson
Max Bulai
- Max R.R. Collada
MuffinManKen
Nick Nikitin
Oliver Dick
@@ -218,7 +214,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Scott Pilet
spilldata
Stoned Xander
+ TheLevelOfDetail .
Thomas Krampl
+ Thomas Kurz
Tobias Bocanegra
Urho
Zie Weaver
@@ -236,27 +234,25 @@ generous deed immortalized in the next stable release of Godot Engine.
Adam Smeltzer
Adisibio
Adrian Demetrescu
- Aggelos Arnaoutis
Agustinus Arya
Aidan O'Flannagain
+ Aki Mimoto
Albin Jonasson Svärdsby
Alder Stefano
Alessandro Senese
- Alexander Koppe
Alexandre
Alex Davies-Moore
Allen Schade
Andreas Evers
Andreas Krampitz
- Andreas Schüle
André Simões
Andrés Rodríguez
Andrew Thomas
Andrzej Skalski
+ Angelos Arnaoutis
Anthony Bongiovanni
Anthony Staunton
Anton Kurkin
- Antony K. Jones
AP Condomines
Arda Erol
Arseniy M
@@ -266,7 +262,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Avencherus
B A
Balázs Batári
- Beliar
Benedikt
Ben G
Ben Phelan
@@ -278,20 +273,21 @@ generous deed immortalized in the next stable release of Godot Engine.
Bryan Stevenson
Carl van der Geest
Carwyn Edwards
+ Casey M.
Chris Brown
Chris Chapin
Christian Baune
+ Christian Chipont
Christian Winter
Christoffer Sundbom
Christopher Schmitt
Clay Heaton
- Cobaltum
Collin Shooltz
Daniel Johnson
+ Daniel Kimblad
DanielMaximiano
Daniel Pontillo
Daniel Reed
- David Cravens
David May
David Rapisarda
David Woodard
@@ -308,14 +304,16 @@ generous deed immortalized in the next stable release of Godot Engine.
Ellen Marie Dash
Elmeri '- Duy Kevin Nguyen
Emanuel Kotzayan
+ Ennemoser Ernst
Eric Ellingson
Eric Martini
Eric Williams
+ Erkki Seppälä
EugeneTel
Evan Rose
Felix Kollmann
- fengjiongmax
Flaredown
+ Florian Richer
FuDiggity
G3Dev sàrl
Gadzhi Kharkharov
@@ -324,6 +322,7 @@ generous deed immortalized in the next stable release of Godot Engine.
George Marques
gmmath
Greg Olson
+ GREGORY C FEIN
Greg P
Greyson Richey
Guldoman
@@ -332,7 +331,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Hiroshi Naruo
Hunter Jones
Hylpher
- ialex32x
Iiari
IndustrialRobot
Isaac Morton
@@ -341,6 +339,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Jaime Ruiz-Borau Vizárraga
Jako Danar
James A F Manley
+ Jannik Gröger
Jax
Jed
Jeff Hungerford
@@ -353,7 +352,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Joel Fivat
Joel Setterberg
Johannes Wuensch
- John Selig
Jomei Jackson
Jonas Rudlang
Jonas Yamazaki
@@ -365,9 +363,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Jose Andrés Mejias Rojas
Jose C. Rubio
Joseph Catrambone
- Josh 'Cheeseness' Bush
Juanfran
- Juan Negrier
Judd
Julian Murgia
JungleRobba
@@ -378,7 +374,6 @@ generous deed immortalized in the next stable release of Godot Engine.
KC Chan
Keedong Park
Keith Bradner
- Kevin Kolcheck
Kevin McPhillips
kickmaniac
Kiyohiro Kawamura (kyorohiro)
@@ -400,12 +395,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Malik Ahmed
Malik Nejer
Marcus Richter
- Markus Lohaus
Markus Michael Egger
Martin Candela
Martin Holas
Martin Liška
Matthew Little
+ Matti Pohjanvirta
Maxime Blade
Maxwell
medecau
@@ -417,12 +412,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Michael Haney
Michael Labbe
Mikael Olsson
- Mikayla Hutchinson
+ Mikayla
Mike Birkhead
Mitchell J. Wagner
MoM
Nathan Fish
- Nathan W
Natrim
nee
Neil Blakey-Milner
@@ -440,20 +434,19 @@ generous deed immortalized in the next stable release of Godot Engine.
Olivier
Omar Delarosa
Oscar Norlander
- Pafka
Pan Ip
- Patrick Forringer
Patrick Nafarrete
Paul Gieske
Paul Mason
Paweł Kowal
+ Penguin
+ Petrus Prinsloo
Philip Cohoe
Pierre-Igor Berthet
Pitsanu Tongprasin
Point08
Poryg
Rafa Laguna
- Rafal Wyszomirski
rainerLinux
Raphael Leroux
Remi Rampin
@@ -462,6 +455,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Ricardo Alcantara
Richard Diss
Richard Ivánek
+ Richard Patching
Robert Farr (Larington)
Robert Hernandez
Rodrigo Loli
@@ -471,7 +465,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Ronan Jouchet
Ryan Groom
Ryan Hentz
- Saad Khoudmi
+ Sam.C
Sam Edson
Samuele Zolfanelli
Sanka.X
@@ -487,13 +481,11 @@ generous deed immortalized in the next stable release of Godot Engine.
SK
smbe19
Sootstone
- Stonepyre
Svenne Krap
- The Architect
+ tezuvholovdr
thomas
Thomas Bechtold
Thomas Kelly
- Thomas Kurz
tiansheng li
Tim Drumheller
Timothy B. MacDonald
@@ -504,7 +496,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Torsten Crass
Travis O'Brien
Trent Skinner
- Triptych
Troy Bonneau
Tryggve Sollid
Turgut Temucin
diff --git a/core/SCsub b/core/SCsub
index b12c6a9e27..755c5c65c6 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -120,6 +120,8 @@ if env['builtin_zstd']:
"compress/zstd_ldm.c",
"compress/zstd_opt.c",
"compress/zstdmt_compress.c",
+ "compress/zstd_compress_literals.c",
+ "compress/zstd_compress_sequences.c",
"decompress/huf_decompress.c",
"decompress/zstd_ddict.c",
"decompress/zstd_decompress_block.c",
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 1d451b2982..c539f912aa 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -3165,6 +3165,9 @@ Ref<JSONParseResult> _JSON::parse(const String &p_json) {
result->error = JSON::parse(p_json, result->result, result->error_string, result->error_line);
+ if (result->error != OK) {
+ ERR_PRINTS(vformat("Error parsing JSON at line %s: %s", result->error_line, result->error_string));
+ }
return result;
}
diff --git a/core/color.cpp b/core/color.cpp
index a54a3115cc..a6ad50b745 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -214,6 +214,11 @@ 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;
diff --git a/core/color.h b/core/color.h
index 8fb78d1ced..b34a82ef19 100644
--- a/core/color.h
+++ b/core/color.h
@@ -86,6 +86,8 @@ struct Color {
void operator/=(const Color &p_color);
void operator/=(const real_t &rvalue);
+ bool is_equal_approx(const Color &p_color) const;
+
void invert();
void contrast();
Color inverted() const;
diff --git a/core/error_macros.cpp b/core/error_macros.cpp
index 0e8e4a9bb4..eda6b9cbbb 100644
--- a/core/error_macros.cpp
+++ b/core/error_macros.cpp
@@ -31,6 +31,7 @@
#include "error_macros.h"
#include "core/io/logger.h"
+#include "core/ustring.h"
#include "os/os.h"
bool _err_error_exists = false;
@@ -42,6 +43,11 @@ void _err_set_last_error(const char *p_err) {
OS::get_singleton()->set_last_error(p_err);
}
+void _err_set_last_error(const String &p_err) {
+
+ _err_set_last_error(p_err.utf8().get_data());
+}
+
void _err_clear_last_error() {
OS::get_singleton()->clear_last_error();
@@ -99,6 +105,10 @@ 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 String &p_error, ErrorHandlerType p_type) {
+ _err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_type);
+}
+
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, bool fatal) {
String fstr(fatal ? "FATAL: " : "");
diff --git a/core/error_macros.h b/core/error_macros.h
index 65802de9d2..d4b69ff40d 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -55,8 +55,10 @@ enum ErrorHandlerType {
ERR_HANDLER_SHADER,
};
+class String;
typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
void _err_set_last_error(const char *p_err);
+void _err_set_last_error(const String &p_err);
void _err_clear_last_error();
struct ErrorHandlerList {
@@ -77,6 +79,7 @@ void add_error_handler(ErrorHandlerList *p_handler);
void remove_error_handler(ErrorHandlerList *p_handler);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
+void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, bool fatal = false);
#ifndef _STR
@@ -98,10 +101,10 @@ extern bool _err_error_exists;
_err_set_last_error(m_reason); \
_err_error_exists = true; \
}
-#define ERR_EXPLAIN(m_string) \
- { \
- _err_set_last_error(String(m_string).utf8().get_data()); \
- _err_error_exists = true; \
+#define ERR_EXPLAIN(m_string) \
+ { \
+ _err_set_last_error(m_string); \
+ _err_error_exists = true; \
}
#else
@@ -430,10 +433,10 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
-#define ERR_PRINTS(m_string) \
- { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, String(m_string).utf8().get_data()); \
- _err_error_exists = false; \
+#define ERR_PRINTS(m_string) \
+ { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
+ _err_error_exists = false; \
}
#define ERR_PRINT_ONCE(m_string) \
@@ -455,10 +458,10 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
-#define WARN_PRINTS(m_string) \
- { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, String(m_string).utf8().get_data(), ERR_HANDLER_WARNING); \
- _err_error_exists = false; \
+#define WARN_PRINTS(m_string) \
+ { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
+ _err_error_exists = false; \
}
#define WARN_PRINT_ONCE(m_string) \
diff --git a/core/image.cpp b/core/image.cpp
index 5e4e0c0d0c..74706535b3 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -1284,8 +1284,8 @@ static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint3
Component *dst_ptr = &p_dst[i * dst_w * CC];
uint32_t count = dst_w;
- while (count--) {
-
+ while (count) {
+ count--;
for (int j = 0; j < CC; j++) {
average_func(dst_ptr[j], rup_ptr[j], rup_ptr[j + right_step], rdown_ptr[j], rdown_ptr[j + right_step]);
}
@@ -1375,6 +1375,7 @@ void Image::shrink_x2() {
int ps = get_format_pixel_size(format);
new_img.resize((width / 2) * (height / 2) * ps);
ERR_FAIL_COND(new_img.size() == 0);
+ ERR_FAIL_COND(data.size() == 0);
{
PoolVector<uint8_t>::Write w = new_img.write();
@@ -2934,7 +2935,7 @@ void Image::srgb_to_linear() {
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 };
+ 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);
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index ae2b56e7b7..bfa8b90344 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -164,36 +164,59 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
}
Segment s(p_id, p_with_id);
- if (s.from == p_id) {
- s.from_point = a;
- s.to_point = b;
- } else {
- s.from_point = b;
- s.to_point = a;
+ if (bidirectional) s.direction = Segment::BIDIRECTIONAL;
+
+ Set<Segment>::Element *element = segments.find(s);
+ if (element != NULL) {
+ s.direction |= element->get().direction;
+ if (s.direction == Segment::BIDIRECTIONAL) {
+ // Both are neighbours of each other now
+ a->unlinked_neighbours.remove(b->id);
+ b->unlinked_neighbours.remove(a->id);
+ }
+ segments.erase(element);
}
segments.insert(s);
}
-void AStar::disconnect_points(int p_id, int p_with_id) {
-
- Segment s(p_id, p_with_id);
- ERR_FAIL_COND(!segments.has(s));
-
- segments.erase(s);
+void AStar::disconnect_points(int p_id, int p_with_id, bool bidirectional) {
Point *a;
bool a_exists = points.lookup(p_id, a);
- CRASH_COND(!a_exists);
+ ERR_FAIL_COND(!a_exists);
Point *b;
bool b_exists = points.lookup(p_with_id, b);
- CRASH_COND(!b_exists);
+ ERR_FAIL_COND(!b_exists);
+
+ Segment s(p_id, p_with_id);
+ int remove_direction = bidirectional ? (int)Segment::BIDIRECTIONAL : s.direction;
+
+ Set<Segment>::Element *element = segments.find(s);
+ if (element != NULL) {
+ // s is the new segment
+ // Erase the directions to be removed
+ s.direction = (element->get().direction & ~remove_direction);
+
+ a->neighbours.remove(b->id);
+ if (bidirectional) {
+ b->neighbours.remove(a->id);
+ if (element->get().direction != Segment::BIDIRECTIONAL) {
+ a->unlinked_neighbours.remove(b->id);
+ b->unlinked_neighbours.remove(a->id);
+ }
+ } else {
+ if (s.direction == Segment::NONE)
+ b->unlinked_neighbours.remove(a->id);
+ else
+ a->unlinked_neighbours.set(b->id, b);
+ }
- a->neighbours.remove(b->id);
- a->unlinked_neighbours.remove(b->id);
- b->neighbours.remove(a->id);
- b->unlinked_neighbours.remove(a->id);
+ segments.erase(element);
+ if (s.direction != Segment::NONE)
+ segments.insert(s);
+ }
}
bool AStar::has_point(int p_id) const {
@@ -227,10 +250,13 @@ PoolVector<int> AStar::get_point_connections(int p_id) {
return point_list;
}
-bool AStar::are_points_connected(int p_id, int p_with_id) const {
+bool AStar::are_points_connected(int p_id, int p_with_id, bool bidirectional) const {
Segment s(p_id, p_with_id);
- return segments.has(s);
+ const Set<Segment>::Element *element = segments.find(s);
+
+ return element != NULL &&
+ (bidirectional || (element->get().direction & s.direction) == s.direction);
}
void AStar::clear() {
@@ -284,13 +310,17 @@ Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const {
for (const Set<Segment>::Element *E = segments.front(); E; E = E->next()) {
- if (!(E->get().from_point->enabled && E->get().to_point->enabled)) {
+ Point *from_point = nullptr, *to_point = nullptr;
+ points.lookup(E->get().u, from_point);
+ points.lookup(E->get().v, to_point);
+
+ if (!(from_point->enabled && to_point->enabled)) {
continue;
}
Vector3 segment[2] = {
- E->get().from_point->pos,
- E->get().to_point->pos,
+ from_point->pos,
+ to_point->pos,
};
Vector3 p = Geometry::get_closest_point_to_segment(p_point, segment);
@@ -376,11 +406,11 @@ float AStar::_estimate_cost(int p_from_id, int p_to_id) {
Point *from_point;
bool from_exists = points.lookup(p_from_id, from_point);
- CRASH_COND(!from_exists);
+ ERR_FAIL_COND_V(!from_exists, 0);
Point *to_point;
bool to_exists = points.lookup(p_to_id, to_point);
- CRASH_COND(!to_exists);
+ ERR_FAIL_COND_V(!to_exists, 0);
return from_point->pos.distance_to(to_point->pos);
}
@@ -392,11 +422,11 @@ float AStar::_compute_cost(int p_from_id, int p_to_id) {
Point *from_point;
bool from_exists = points.lookup(p_from_id, from_point);
- CRASH_COND(!from_exists);
+ ERR_FAIL_COND_V(!from_exists, 0);
Point *to_point;
bool to_exists = points.lookup(p_to_id, to_point);
- CRASH_COND(!to_exists);
+ ERR_FAIL_COND_V(!to_exists, 0);
return from_point->pos.distance_to(to_point->pos);
}
@@ -532,8 +562,8 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar::is_point_disabled);
ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar::connect_points, DEFVAL(true));
- ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points);
- ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar::are_points_connected);
+ ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id", "bidirectional"), &AStar::disconnect_points, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id", "bidirectional"), &AStar::are_points_connected, DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_point_count"), &AStar::get_point_count);
ClassDB::bind_method(D_METHOD("get_point_capacity"), &AStar::get_point_capacity);
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 0a5d3e992c..8ff62e646b 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -81,24 +81,35 @@ class AStar : public Reference {
struct Segment {
union {
struct {
- int32_t from;
- int32_t to;
+ int32_t u;
+ int32_t v;
};
uint64_t key;
};
- Point *from_point;
- Point *to_point;
+ enum {
+ NONE = 0,
+ FORWARD = 1,
+ BACKWARD = 2,
+ BIDIRECTIONAL = FORWARD | BACKWARD
+ };
+ unsigned char direction;
bool operator<(const Segment &p_s) const { return key < p_s.key; }
- Segment() { key = 0; }
+ Segment() {
+ key = 0;
+ direction = NONE;
+ }
Segment(int p_from, int p_to) {
- if (p_from > p_to) {
- SWAP(p_from, p_to);
+ if (p_from < p_to) {
+ u = p_from;
+ v = p_to;
+ direction = FORWARD;
+ } else {
+ u = p_to;
+ v = p_from;
+ direction = BACKWARD;
}
-
- from = p_from;
- to = p_to;
}
};
@@ -133,8 +144,8 @@ public:
bool is_point_disabled(int p_id) const;
void connect_points(int p_id, int p_with_id, bool bidirectional = true);
- void disconnect_points(int p_id, int p_with_id);
- bool are_points_connected(int p_id, int p_with_id) const;
+ void disconnect_points(int p_id, int p_with_id, bool bidirectional = true);
+ bool are_points_connected(int p_id, int p_with_id, bool bidirectional = true) const;
int get_point_count() const;
int get_point_capacity() const;
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index a4eb1fe2a5..27da061274 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -69,6 +69,11 @@ void AABB::merge_with(const AABB &p_aabb) {
size = max - min;
}
+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;
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 52e5ed3626..c3ce33c6f4 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -64,6 +64,7 @@ public:
bool operator==(const AABB &p_rval) const;
bool operator!=(const AABB &p_rval) const;
+ bool is_equal_approx(const AABB &p_aabb) const;
_FORCE_INLINE_ bool intersects(const AABB &p_aabb) const; /// Both AABBs overlap
_FORCE_INLINE_ bool intersects_inclusive(const AABB &p_aabb) const; /// Both AABBs (or their faces) overlap
_FORCE_INLINE_ bool encloses(const AABB &p_aabb) const; /// p_aabb is completely inside this
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 0a491010e2..d77501c0f6 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -106,17 +106,17 @@ Basis Basis::orthonormalized() const {
}
bool Basis::is_orthogonal() const {
- Basis id;
+ Basis identity;
Basis m = (*this) * transposed();
- return is_equal_approx(id, m);
+ return m.is_equal_approx(identity);
}
bool Basis::is_diagonal() const {
return (
- Math::is_equal_approx(elements[0][1], 0) && Math::is_equal_approx(elements[0][2], 0) &&
- Math::is_equal_approx(elements[1][0], 0) && Math::is_equal_approx(elements[1][2], 0) &&
- Math::is_equal_approx(elements[2][0], 0) && Math::is_equal_approx(elements[2][1], 0));
+ Math::is_zero_approx(elements[0][1]) && Math::is_zero_approx(elements[0][2]) &&
+ Math::is_zero_approx(elements[1][0]) && Math::is_zero_approx(elements[1][2]) &&
+ Math::is_zero_approx(elements[2][0]) && Math::is_zero_approx(elements[2][1]));
}
bool Basis::is_rotation() const {
@@ -557,16 +557,9 @@ void Basis::set_euler_yxz(const Vector3 &p_euler) {
*this = ymat * xmat * zmat;
}
-bool Basis::is_equal_approx(const Basis &a, const Basis &b, real_t p_epsilon) const {
+bool Basis::is_equal_approx(const Basis &p_basis) const {
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- if (!Math::is_equal_approx(a.elements[i][j], b.elements[i][j], p_epsilon))
- return false;
- }
- }
-
- return true;
+ 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 {
diff --git a/core/math/basis.h b/core/math/basis.h
index 4be4ea4cd3..9b2e38b3d3 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -127,7 +127,9 @@ public:
return elements[0][2] * v[0] + elements[1][2] * v[1] + elements[2][2] * v[2];
}
- bool is_equal_approx(const Basis &a, const Basis &b, real_t p_epsilon = CMP_EPSILON) const;
+ bool is_equal_approx(const Basis &p_basis) const;
+ // TODO: Break compatibility in 4.0 by getting rid of this so that it's only an instance method. See also TODO in variant_call.cpp
+ bool is_equal_approx(const Basis &a, const Basis &b) const { return a.is_equal_approx(b); }
bool is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon = UNIT_EPSILON) const;
bool operator==(const Basis &p_matrix) const;
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
index cfa698282e..ece293d036 100644
--- a/core/math/bsp_tree.cpp
+++ b/core/math/bsp_tree.cpp
@@ -364,7 +364,7 @@ static int _bsp_create_node(const Face3 *p_faces, const Vector<int> &p_indices,
const Face3 &f = p_faces[indices[i]];
/*
- if (f.get_plane().is_almost_like(divisor_plane))
+ if (f.get_plane().is_equal_approx(divisor_plane))
continue;
*/
@@ -412,7 +412,7 @@ static int _bsp_create_node(const Face3 *p_faces, const Vector<int> &p_indices,
for (int i = 0; i < p_planes.size(); i++) {
- if (p_planes[i].is_almost_like(divisor_plane)) {
+ if (p_planes[i].is_equal_approx(divisor_plane)) {
divisor_plane_idx = i;
break;
}
diff --git a/core/math/delaunay.h b/core/math/delaunay.h
index 3f8013a3e6..89a34de082 100644
--- a/core/math/delaunay.h
+++ b/core/math/delaunay.h
@@ -80,11 +80,11 @@ public:
}
static bool edge_compare(const Vector<Vector2> &p_vertices, const Edge &p_a, const Edge &p_b) {
- if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[0]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[1]]) {
+ if (p_vertices[p_a.edge[0]].is_equal_approx(p_vertices[p_b.edge[0]]) && p_vertices[p_a.edge[1]].is_equal_approx(p_vertices[p_b.edge[1]])) {
return true;
}
- if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[1]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[0]]) {
+ if (p_vertices[p_a.edge[0]].is_equal_approx(p_vertices[p_b.edge[1]]) && p_vertices[p_a.edge[1]].is_equal_approx(p_vertices[p_b.edge[0]])) {
return true;
}
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 9078abea68..a94b27fcc5 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -472,7 +472,7 @@ public:
return p_step != 0 ? Math::stepify(p_target - p_offset, p_step) + p_offset : p_target;
}
- static _ALWAYS_INLINE_ float snap_scalar_seperation(float p_offset, float p_step, float p_target, float p_separation) {
+ static _ALWAYS_INLINE_ float snap_scalar_separation(float p_offset, float p_step, float p_target, float p_separation) {
if (p_step != 0) {
float a = Math::stepify(p_target - p_offset, p_step + p_separation) + p_offset;
float b = a;
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index b6bcac4b27..d55957cd0a 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -32,9 +32,6 @@
#include "core/math/math_funcs.h"
-#define _PLANE_EQ_DOT_EPSILON 0.999
-#define _PLANE_EQ_D_EPSILON 0.0001
-
void Plane::set_normal(const Vector3 &p_normal) {
normal = p_normal;
@@ -156,9 +153,9 @@ bool Plane::intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vec
/* misc */
-bool Plane::is_almost_like(const Plane &p_plane) const {
+bool Plane::is_equal_approx(const Plane &p_plane) const {
- return (normal.dot(p_plane.normal) > _PLANE_EQ_DOT_EPSILON && Math::absd(d - p_plane.d) < _PLANE_EQ_D_EPSILON);
+ return normal.is_equal_approx(p_plane.normal) && Math::is_equal_approx(d, p_plane.d);
}
Plane::operator String() const {
diff --git a/core/math/plane.h b/core/math/plane.h
index ec817edd2c..9abf24fbba 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -68,7 +68,7 @@ public:
/* misc */
Plane operator-() const { return Plane(-normal, -d); }
- bool is_almost_like(const Plane &p_plane) const;
+ bool is_equal_approx(const Plane &p_plane) const;
_FORCE_INLINE_ bool operator==(const Plane &p_plane) const;
_FORCE_INLINE_ bool operator!=(const Plane &p_plane) const;
@@ -125,12 +125,12 @@ Plane::Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_
bool Plane::operator==(const Plane &p_plane) const {
- return normal == p_plane.normal && Math::is_equal_approx(d, p_plane.d);
+ return normal == p_plane.normal && d == p_plane.d;
}
bool Plane::operator!=(const Plane &p_plane) const {
- return normal != p_plane.normal || !Math::is_equal_approx(d, p_plane.d);
+ return normal != p_plane.normal || d != p_plane.d;
}
#endif // PLANE_H
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index 1a67be7384..a4f91844b9 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -121,6 +121,11 @@ Quat Quat::operator*(const Quat &q) const {
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());
diff --git a/core/math/quat.h b/core/math/quat.h
index 3d6602e466..27885f4152 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -43,6 +43,7 @@ public:
real_t x, y, z, w;
_FORCE_INLINE_ real_t length_squared() const;
+ bool is_equal_approx(const Quat &p_quat) const;
real_t length() const;
void normalize();
Quat normalized() const;
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index fc2eb1454d..f71f00afd6 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -401,7 +401,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
ERR_CONTINUE(O == E);
ERR_CONTINUE(O == NULL);
- if (O->get().plane.is_almost_like(f.plane)) {
+ if (O->get().plane.is_equal_approx(f.plane)) {
//merge and delete edge and contiguous face, while repointing edges (uuugh!)
int ois = O->get().indices.size();
int merged = 0;
diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp
index fea128afbd..e31776672e 100644
--- a/core/math/rect2.cpp
+++ b/core/math/rect2.cpp
@@ -30,6 +30,11 @@
#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;
diff --git a/core/math/rect2.h b/core/math/rect2.h
index f58756ee40..71221ffb1b 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -153,6 +153,7 @@ struct Rect2 {
return true;
}
+ bool is_equal_approx(const Rect2 &p_rect) const;
bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; }
bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 4056975da8..5dcc6ab9f0 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -182,6 +182,11 @@ Transform Transform::orthonormalized() const {
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);
diff --git a/core/math/transform.h b/core/math/transform.h
index 90e2b07583..da65a183cf 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -70,6 +70,7 @@ public:
void orthonormalize();
Transform orthonormalized() const;
+ bool is_equal_approx(const Transform &p_transform) const;
bool operator==(const Transform &p_transform) const;
bool operator!=(const Transform &p_transform) const;
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 1d0387bd45..a1c0814637 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -147,6 +147,7 @@ void Transform2D::orthonormalize() {
elements[0] = x;
elements[1] = y;
}
+
Transform2D Transform2D::orthonormalized() const {
Transform2D on = *this;
@@ -154,6 +155,11 @@ Transform2D Transform2D::orthonormalized() const {
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++) {
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index e8b44ab197..0ec39a1765 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -96,6 +96,7 @@ struct Transform2D {
void orthonormalize();
Transform2D orthonormalized() const;
+ bool is_equal_approx(const Transform2D &p_transform) const;
bool operator==(const Transform2D &p_transform) const;
bool operator!=(const Transform2D &p_transform) const;
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index 972bccc0ac..fbedeb8eb2 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -203,6 +203,10 @@ Vector2 Vector2::reflect(const Vector2 &p_normal) const {
return 2.0 * p_normal * this->dot(p_normal) - *this;
}
+bool Vector2::is_equal_approx(const Vector2 &p_v) const {
+ return Math::is_equal_approx(x, p_v.x) && Math::is_equal_approx(y, p_v.y);
+}
+
/* Vector2i */
Vector2i Vector2i::operator+(const Vector2i &p_v) const {
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 1a73831891..7fcaadab00 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -92,6 +92,8 @@ struct Vector2 {
Vector2 bounce(const Vector2 &p_normal) const;
Vector2 reflect(const Vector2 &p_normal) const;
+ bool is_equal_approx(const Vector2 &p_v) const;
+
Vector2 operator+(const Vector2 &p_v) const;
void operator+=(const Vector2 &p_v);
Vector2 operator-(const Vector2 &p_v) const;
@@ -221,11 +223,11 @@ _FORCE_INLINE_ Vector2 Vector2::operator-() const {
_FORCE_INLINE_ bool Vector2::operator==(const Vector2 &p_vec2) const {
- return Math::is_equal_approx(x, p_vec2.x) && Math::is_equal_approx(y, p_vec2.y);
+ return x == p_vec2.x && y == p_vec2.y;
}
_FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const {
- return !Math::is_equal_approx(x, p_vec2.x) || !Math::is_equal_approx(y, p_vec2.y);
+ return x != p_vec2.x || y != p_vec2.y;
}
Vector2 Vector2::linear_interpolate(const Vector2 &p_b, real_t p_t) const {
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index ebc1599820..e3211c8fb1 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -149,6 +149,11 @@ Basis Vector3::to_diagonal_matrix() const {
0, 0, z);
}
+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 de1743d88f..43fa09ffac 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -119,6 +119,8 @@ struct Vector3 {
_FORCE_INLINE_ Vector3 bounce(const Vector3 &p_normal) const;
_FORCE_INLINE_ Vector3 reflect(const Vector3 &p_normal) const;
+ bool is_equal_approx(const Vector3 &p_v) const;
+
/* Operators */
_FORCE_INLINE_ Vector3 &operator+=(const Vector3 &p_v);
@@ -330,11 +332,12 @@ Vector3 Vector3::operator-() const {
bool Vector3::operator==(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));
+ return x == p_v.x && y == p_v.y && z == p_v.z;
}
bool Vector3::operator!=(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));
+
+ return x != p_v.x || y != p_v.y || z != p_v.z;
}
bool Vector3::operator<(const Vector3 &p_v) const {
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index 30fca0c155..f09a904953 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -49,11 +49,11 @@ 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) const {
+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 && !is_echo();
+ return valid && pressed && (p_allow_echo || !is_echo());
}
bool InputEvent::is_action_released(const StringName &p_action) const {
@@ -112,7 +112,7 @@ void InputEvent::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_device"), &InputEvent::get_device);
ClassDB::bind_method(D_METHOD("is_action", "action"), &InputEvent::is_action);
- ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &InputEvent::is_action_pressed);
+ ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "allow_echo"), &InputEvent::is_action_pressed, DEFVAL(false));
ClassDB::bind_method(D_METHOD("is_action_released", "action"), &InputEvent::is_action_released);
ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &InputEvent::get_action_strength);
@@ -557,10 +557,31 @@ InputEventMouseButton::InputEventMouseButton() {
////////////////////////////////////////////
+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;
@@ -570,6 +591,7 @@ void InputEventMouseMotion::set_speed(const Vector2 &p_speed) {
speed = p_speed;
}
+
Vector2 InputEventMouseMotion::get_speed() const {
return speed;
@@ -590,6 +612,8 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co
mm->set_modifiers_from_event(this);
mm->set_position(l);
+ mm->set_pressure(get_pressure());
+ mm->set_tilt(get_tilt());
mm->set_global_position(g);
mm->set_button_mask(get_button_mask());
@@ -665,17 +689,27 @@ 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);
+
+ ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventMouseMotion::set_pressure);
+ ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventMouseMotion::get_pressure);
+
ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative);
ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InputEventMouseMotion::set_speed);
ClassDB::bind_method(D_METHOD("get_speed"), &InputEventMouseMotion::get_speed);
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure"), "set_pressure", "get_pressure");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed");
}
InputEventMouseMotion::InputEventMouseMotion() {
+
+ pressure = 0;
}
////////////////////////////////////////
diff --git a/core/os/input_event.h b/core/os/input_event.h
index 28658e3865..a4db618bfe 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -184,7 +184,7 @@ public:
int get_device() const;
bool is_action(const StringName &p_action) const;
- bool is_action_pressed(const StringName &p_action) const;
+ bool is_action_pressed(const StringName &p_action, bool p_allow_echo = false) const;
bool is_action_released(const StringName &p_action) const;
float get_action_strength(const StringName &p_action) const;
@@ -351,6 +351,9 @@ public:
class InputEventMouseMotion : public InputEventMouse {
GDCLASS(InputEventMouseMotion, InputEventMouse);
+
+ Vector2 tilt;
+ float pressure;
Vector2 relative;
Vector2 speed;
@@ -358,6 +361,12 @@ protected:
static void _bind_methods();
public:
+ void set_tilt(const Vector2 &p_tilt);
+ Vector2 get_tilt() const;
+
+ void set_pressure(float p_pressure);
+ float get_pressure() const;
+
void set_relative(const Vector2 &p_relative);
Vector2 get_relative() const;
diff --git a/core/pool_vector.h b/core/pool_vector.h
index fbd4d630be..a698e72e18 100644
--- a/core/pool_vector.h
+++ b/core/pool_vector.h
@@ -385,6 +385,7 @@ public:
}
inline int size() const;
+ inline bool empty() const;
T get(int p_index) const;
void set(int p_index, const T &p_val);
void push_back(const T &p_val);
@@ -475,6 +476,12 @@ int PoolVector<T>::size() const {
}
template <class T>
+bool PoolVector<T>::empty() const {
+
+ return alloc ? alloc->size == 0 : true;
+}
+
+template <class T>
T PoolVector<T>::get(int p_index) const {
return operator[](p_index);
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index c2241ed926..7704c7b377 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -107,7 +107,7 @@ String ProjectSettings::localize_path(const String &p_path) const {
if (plocal == "") {
return "";
};
- return plocal + path.substr(sep, path.size() - sep);
+ return plocal + path.substr((sep + 1), path.size() - (sep + 1));
};
}
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 7201773ea5..cbe4681eca 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -218,6 +218,7 @@ void ScriptServer::global_classes_clear() {
}
void ScriptServer::add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path) {
+ ERR_FAIL_COND_MSG(p_class == p_base || (global_classes.has(p_base) && get_global_class_native_base(p_base) == p_class), "Cyclic inheritance in script class.");
GlobalScriptClass g;
g.language = p_language;
g.path = p_path;
diff --git a/core/script_language.h b/core/script_language.h
index 116918fdc0..f90bb4b6c3 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -427,31 +427,6 @@ class ScriptDebugger {
ScriptLanguage *break_lang;
public:
- typedef void (*RequestSceneTreeMessageFunc)(void *);
-
- struct LiveEditFuncs {
-
- void *udata;
- void (*node_path_func)(void *, const NodePath &p_path, int p_id);
- void (*res_path_func)(void *, const String &p_path, int p_id);
-
- void (*node_set_func)(void *, int p_id, const StringName &p_prop, const Variant &p_value);
- void (*node_set_res_func)(void *, int p_id, const StringName &p_prop, const String &p_value);
- void (*node_call_func)(void *, int p_id, const StringName &p_method, VARIANT_ARG_DECLARE);
- void (*res_set_func)(void *, int p_id, const StringName &p_prop, const Variant &p_value);
- void (*res_set_res_func)(void *, int p_id, const StringName &p_prop, const String &p_value);
- void (*res_call_func)(void *, int p_id, const StringName &p_method, VARIANT_ARG_DECLARE);
- void (*root_func)(void *, const NodePath &p_scene_path, const String &p_scene_from);
-
- void (*tree_create_node_func)(void *, const NodePath &p_parent, const String &p_type, const String &p_name);
- void (*tree_instance_node_func)(void *, const NodePath &p_parent, const String &p_path, const String &p_name);
- void (*tree_remove_node_func)(void *, const NodePath &p_at);
- void (*tree_remove_and_keep_node_func)(void *, const NodePath &p_at, ObjectID p_keep_id);
- void (*tree_restore_node_func)(void *, ObjectID p_id, const NodePath &p_at, int p_at_pos);
- void (*tree_duplicate_node_func)(void *, const NodePath &p_at, const String &p_new_name);
- void (*tree_reparent_node_func)(void *, const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos);
- };
-
_FORCE_INLINE_ static ScriptDebugger *get_singleton() { return singleton; }
void set_lines_left(int p_left);
int get_lines_left() const;
@@ -480,8 +455,6 @@ public:
virtual bool is_remote() const { return false; }
virtual void request_quit() {}
- virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata) {}
- virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs) {}
virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {}
virtual bool is_profiling() const = 0;
diff --git a/core/ustring.cpp b/core/ustring.cpp
index f029ae4200..0f82ca7e15 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -1337,7 +1337,17 @@ String String::num_scientific(double p_num) {
char buf[256];
#if defined(__GNUC__) || defined(_MSC_VER)
+
+#if (defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900)) && defined(_TWO_DIGIT_EXPONENT) && !defined(_UCRT)
+ // MinGW and old MSC require _set_output_format() to conform to C99 output for printf
+ unsigned int old_exponent_format = _set_output_format(_TWO_DIGIT_EXPONENT);
+#endif
snprintf(buf, 256, "%lg", p_num);
+
+#if (defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER < 1900)) && defined(_TWO_DIGIT_EXPONENT) && !defined(_UCRT)
+ _set_output_format(old_exponent_format);
+#endif
+
#else
sprintf(buf, "%.16lg", p_num);
#endif
@@ -4058,6 +4068,11 @@ 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);
diff --git a/core/ustring.h b/core/ustring.h
index 15e2c07d9f..dfc5044942 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -369,6 +369,7 @@ String operator+(const char *p_chr, const String &p_str);
String operator+(CharType p_chr, const String &p_str);
String itos(int64_t p_val);
+String uitos(uint64_t p_val);
String rtos(double p_val);
String rtoss(double p_val); //scientific version
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 40b944744b..6e593a308d 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -351,12 +351,13 @@ struct _VariantCall {
r_ret = retval;
}
- VCALL_LOCALMEM0R(Vector2, normalized);
+ VCALL_LOCALMEM1R(Vector2, distance_to);
+ VCALL_LOCALMEM1R(Vector2, distance_squared_to);
VCALL_LOCALMEM0R(Vector2, length);
VCALL_LOCALMEM0R(Vector2, length_squared);
+ VCALL_LOCALMEM0R(Vector2, normalized);
VCALL_LOCALMEM0R(Vector2, is_normalized);
- VCALL_LOCALMEM1R(Vector2, distance_to);
- VCALL_LOCALMEM1R(Vector2, distance_squared_to);
+ VCALL_LOCALMEM1R(Vector2, is_equal_approx);
VCALL_LOCALMEM1R(Vector2, posmod);
VCALL_LOCALMEM1R(Vector2, posmodv);
VCALL_LOCALMEM1R(Vector2, project);
@@ -385,24 +386,28 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Vector2, sign);
VCALL_LOCALMEM0R(Rect2, get_area);
+ VCALL_LOCALMEM0R(Rect2, has_no_area);
+ VCALL_LOCALMEM1R(Rect2, has_point);
+ VCALL_LOCALMEM1R(Rect2, is_equal_approx);
VCALL_LOCALMEM1R(Rect2, intersects);
VCALL_LOCALMEM1R(Rect2, encloses);
- VCALL_LOCALMEM0R(Rect2, has_no_area);
VCALL_LOCALMEM1R(Rect2, clip);
VCALL_LOCALMEM1R(Rect2, merge);
- VCALL_LOCALMEM1R(Rect2, has_point);
+ VCALL_LOCALMEM1R(Rect2, expand);
VCALL_LOCALMEM1R(Rect2, grow);
VCALL_LOCALMEM2R(Rect2, grow_margin);
VCALL_LOCALMEM4R(Rect2, grow_individual);
- VCALL_LOCALMEM1R(Rect2, expand);
VCALL_LOCALMEM0R(Rect2, abs);
VCALL_LOCALMEM0R(Vector3, min_axis);
VCALL_LOCALMEM0R(Vector3, max_axis);
+ VCALL_LOCALMEM1R(Vector3, distance_to);
+ VCALL_LOCALMEM1R(Vector3, distance_squared_to);
VCALL_LOCALMEM0R(Vector3, length);
VCALL_LOCALMEM0R(Vector3, length_squared);
- VCALL_LOCALMEM0R(Vector3, is_normalized);
VCALL_LOCALMEM0R(Vector3, normalized);
+ VCALL_LOCALMEM0R(Vector3, is_normalized);
+ VCALL_LOCALMEM1R(Vector3, is_equal_approx);
VCALL_LOCALMEM0R(Vector3, inverse);
VCALL_LOCALMEM1R(Vector3, snapped);
VCALL_LOCALMEM2R(Vector3, rotated);
@@ -418,8 +423,6 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Vector3, floor);
VCALL_LOCALMEM0R(Vector3, ceil);
VCALL_LOCALMEM0R(Vector3, round);
- VCALL_LOCALMEM1R(Vector3, distance_to);
- VCALL_LOCALMEM1R(Vector3, distance_squared_to);
VCALL_LOCALMEM1R(Vector3, posmod);
VCALL_LOCALMEM1R(Vector3, posmodv);
VCALL_LOCALMEM1R(Vector3, project);
@@ -433,6 +436,7 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Plane, normalized);
VCALL_LOCALMEM0R(Plane, center);
VCALL_LOCALMEM0R(Plane, get_any_point);
+ VCALL_LOCALMEM1R(Plane, is_equal_approx);
VCALL_LOCALMEM1R(Plane, is_point_over);
VCALL_LOCALMEM1R(Plane, distance_to);
VCALL_LOCALMEM2R(Plane, has_point);
@@ -467,6 +471,7 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Quat, length_squared);
VCALL_LOCALMEM0R(Quat, normalized);
VCALL_LOCALMEM0R(Quat, is_normalized);
+ VCALL_LOCALMEM1R(Quat, is_equal_approx);
VCALL_LOCALMEM0R(Quat, inverse);
VCALL_LOCALMEM1R(Quat, dot);
VCALL_LOCALMEM1R(Quat, xform);
@@ -492,6 +497,7 @@ struct _VariantCall {
VCALL_LOCALMEM1R(Color, darkened);
VCALL_LOCALMEM1R(Color, to_html);
VCALL_LOCALMEM4R(Color, from_hsv);
+ VCALL_LOCALMEM1R(Color, is_equal_approx);
VCALL_LOCALMEM0R(RID, get_id);
@@ -626,6 +632,7 @@ struct _VariantCall {
}
VCALL_LOCALMEM0R(PoolByteArray, size);
+ VCALL_LOCALMEM0R(PoolByteArray, empty);
VCALL_LOCALMEM2(PoolByteArray, set);
VCALL_LOCALMEM1R(PoolByteArray, get);
VCALL_LOCALMEM1(PoolByteArray, push_back);
@@ -638,6 +645,7 @@ struct _VariantCall {
VCALL_LOCALMEM2R(PoolByteArray, subarray);
VCALL_LOCALMEM0R(PoolIntArray, size);
+ VCALL_LOCALMEM0R(PoolIntArray, empty);
VCALL_LOCALMEM2(PoolIntArray, set);
VCALL_LOCALMEM1R(PoolIntArray, get);
VCALL_LOCALMEM1(PoolIntArray, push_back);
@@ -649,6 +657,7 @@ struct _VariantCall {
VCALL_LOCALMEM0(PoolIntArray, invert);
VCALL_LOCALMEM0R(PoolRealArray, size);
+ VCALL_LOCALMEM0R(PoolRealArray, empty);
VCALL_LOCALMEM2(PoolRealArray, set);
VCALL_LOCALMEM1R(PoolRealArray, get);
VCALL_LOCALMEM1(PoolRealArray, push_back);
@@ -660,6 +669,7 @@ struct _VariantCall {
VCALL_LOCALMEM0(PoolRealArray, invert);
VCALL_LOCALMEM0R(PoolStringArray, size);
+ VCALL_LOCALMEM0R(PoolStringArray, empty);
VCALL_LOCALMEM2(PoolStringArray, set);
VCALL_LOCALMEM1R(PoolStringArray, get);
VCALL_LOCALMEM1(PoolStringArray, push_back);
@@ -672,6 +682,7 @@ struct _VariantCall {
VCALL_LOCALMEM1R(PoolStringArray, join);
VCALL_LOCALMEM0R(PoolVector2Array, size);
+ VCALL_LOCALMEM0R(PoolVector2Array, empty);
VCALL_LOCALMEM2(PoolVector2Array, set);
VCALL_LOCALMEM1R(PoolVector2Array, get);
VCALL_LOCALMEM1(PoolVector2Array, push_back);
@@ -683,6 +694,7 @@ struct _VariantCall {
VCALL_LOCALMEM0(PoolVector2Array, invert);
VCALL_LOCALMEM0R(PoolVector3Array, size);
+ VCALL_LOCALMEM0R(PoolVector3Array, empty);
VCALL_LOCALMEM2(PoolVector3Array, set);
VCALL_LOCALMEM1R(PoolVector3Array, get);
VCALL_LOCALMEM1(PoolVector3Array, push_back);
@@ -694,6 +706,7 @@ struct _VariantCall {
VCALL_LOCALMEM0(PoolVector3Array, invert);
VCALL_LOCALMEM0R(PoolColorArray, size);
+ VCALL_LOCALMEM0R(PoolColorArray, empty);
VCALL_LOCALMEM2(PoolColorArray, set);
VCALL_LOCALMEM1R(PoolColorArray, get);
VCALL_LOCALMEM1(PoolColorArray, push_back);
@@ -732,13 +745,16 @@ struct _VariantCall {
VCALL_PTR0R(AABB, get_area);
VCALL_PTR0R(AABB, has_no_area);
VCALL_PTR0R(AABB, has_no_surface);
+ VCALL_PTR1R(AABB, has_point);
+ VCALL_PTR1R(AABB, is_equal_approx);
VCALL_PTR1R(AABB, intersects);
VCALL_PTR1R(AABB, encloses);
- VCALL_PTR1R(AABB, merge);
- VCALL_PTR1R(AABB, intersection);
VCALL_PTR1R(AABB, intersects_plane);
VCALL_PTR2R(AABB, intersects_segment);
- VCALL_PTR1R(AABB, has_point);
+ VCALL_PTR1R(AABB, intersection);
+ VCALL_PTR1R(AABB, merge);
+ VCALL_PTR1R(AABB, expand);
+ VCALL_PTR1R(AABB, grow);
VCALL_PTR1R(AABB, get_support);
VCALL_PTR0R(AABB, get_longest_axis);
VCALL_PTR0R(AABB, get_longest_axis_index);
@@ -746,8 +762,6 @@ struct _VariantCall {
VCALL_PTR0R(AABB, get_shortest_axis);
VCALL_PTR0R(AABB, get_shortest_axis_index);
VCALL_PTR0R(AABB, get_shortest_axis_size);
- VCALL_PTR1R(AABB, expand);
- VCALL_PTR1R(AABB, grow);
VCALL_PTR1R(AABB, get_endpoint);
VCALL_PTR0R(Transform2D, inverse);
@@ -760,6 +774,7 @@ struct _VariantCall {
VCALL_PTR1R(Transform2D, scaled);
VCALL_PTR1R(Transform2D, translated);
VCALL_PTR2R(Transform2D, interpolate_with);
+ VCALL_PTR1R(Transform2D, is_equal_approx);
static void _call_Transform2D_xform(Variant &r_ret, Variant &p_self, const Variant **p_args) {
@@ -816,7 +831,7 @@ struct _VariantCall {
VCALL_PTR0R(Basis, get_orthogonal_index);
VCALL_PTR0R(Basis, orthonormalized);
VCALL_PTR2R(Basis, slerp);
- VCALL_PTR2R(Basis, is_equal_approx);
+ VCALL_PTR2R(Basis, is_equal_approx); // TODO: Break compatibility in 4.0 to change this to an instance method (a.is_equal_approx(b) as VCALL_PTR1R) for consistency.
VCALL_PTR0R(Basis, get_rotation_quat);
VCALL_PTR0R(Transform, inverse);
@@ -827,6 +842,7 @@ struct _VariantCall {
VCALL_PTR0R(Transform, orthonormalized);
VCALL_PTR2R(Transform, looking_at);
VCALL_PTR2R(Transform, interpolate_with);
+ VCALL_PTR1R(Transform, is_equal_approx);
static void _call_Transform_xform(Variant &r_ret, Variant &p_self, const Variant **p_args) {
@@ -1607,19 +1623,20 @@ void register_variant_methods() {
ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, to_ascii, varray());
ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, to_utf8, varray());
- ADDFUNC0R(VECTOR2, VECTOR2, Vector2, normalized, varray());
- ADDFUNC0R(VECTOR2, REAL, Vector2, length, varray());
ADDFUNC0R(VECTOR2, REAL, Vector2, angle, varray());
- ADDFUNC0R(VECTOR2, REAL, Vector2, length_squared, varray());
- ADDFUNC0R(VECTOR2, BOOL, Vector2, is_normalized, varray());
+ ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to, VECTOR2, "to", varray());
+ ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to_point, VECTOR2, "to", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, direction_to, VECTOR2, "b", varray());
ADDFUNC1R(VECTOR2, REAL, Vector2, distance_to, VECTOR2, "to", varray());
ADDFUNC1R(VECTOR2, REAL, Vector2, distance_squared_to, VECTOR2, "to", varray());
+ ADDFUNC0R(VECTOR2, REAL, Vector2, length, varray());
+ ADDFUNC0R(VECTOR2, REAL, Vector2, length_squared, varray());
+ ADDFUNC0R(VECTOR2, VECTOR2, Vector2, normalized, varray());
+ ADDFUNC0R(VECTOR2, BOOL, Vector2, is_normalized, varray());
+ ADDFUNC1R(VECTOR2, BOOL, Vector2, is_equal_approx, VECTOR2, "v", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmod, REAL, "mod", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmodv, VECTOR2, "modv", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, project, VECTOR2, "b", varray());
- ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to, VECTOR2, "to", varray());
- ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to_point, VECTOR2, "to", varray());
ADDFUNC2R(VECTOR2, VECTOR2, Vector2, linear_interpolate, VECTOR2, "b", REAL, "t", varray());
ADDFUNC2R(VECTOR2, VECTOR2, Vector2, slerp, VECTOR2, "b", REAL, "t", varray());
ADDFUNC4R(VECTOR2, VECTOR2, Vector2, cubic_interpolate, VECTOR2, "b", VECTOR2, "pre_a", VECTOR2, "post_b", REAL, "t", varray());
@@ -1641,31 +1658,36 @@ void register_variant_methods() {
ADDFUNC0R(VECTOR2, VECTOR2, Vector2, sign, varray());
ADDFUNC0R(RECT2, REAL, Rect2, get_area, varray());
+ ADDFUNC0R(RECT2, BOOL, Rect2, has_no_area, varray());
+ ADDFUNC1R(RECT2, BOOL, Rect2, has_point, VECTOR2, "point", varray());
+ ADDFUNC1R(RECT2, BOOL, Rect2, is_equal_approx, RECT2, "rect", varray());
ADDFUNC1R(RECT2, BOOL, Rect2, intersects, RECT2, "b", varray());
ADDFUNC1R(RECT2, BOOL, Rect2, encloses, RECT2, "b", varray());
- ADDFUNC0R(RECT2, BOOL, Rect2, has_no_area, varray());
ADDFUNC1R(RECT2, RECT2, Rect2, clip, RECT2, "b", varray());
ADDFUNC1R(RECT2, RECT2, Rect2, merge, RECT2, "b", varray());
- ADDFUNC1R(RECT2, BOOL, Rect2, has_point, VECTOR2, "point", varray());
+ ADDFUNC1R(RECT2, RECT2, Rect2, expand, VECTOR2, "to", varray());
ADDFUNC1R(RECT2, RECT2, Rect2, grow, REAL, "by", varray());
ADDFUNC2R(RECT2, RECT2, Rect2, grow_margin, INT, "margin", REAL, "by", varray());
ADDFUNC4R(RECT2, RECT2, Rect2, grow_individual, REAL, "left", REAL, "top", REAL, "right", REAL, " bottom", varray());
- ADDFUNC1R(RECT2, RECT2, Rect2, expand, VECTOR2, "to", varray());
ADDFUNC0R(RECT2, RECT2, Rect2, abs, varray());
ADDFUNC0R(VECTOR3, INT, Vector3, min_axis, varray());
ADDFUNC0R(VECTOR3, INT, Vector3, max_axis, varray());
+ ADDFUNC1R(VECTOR3, REAL, Vector3, angle_to, VECTOR3, "to", varray());
+ ADDFUNC1R(VECTOR3, VECTOR3, Vector3, direction_to, VECTOR3, "b", varray());
+ ADDFUNC1R(VECTOR3, REAL, Vector3, distance_to, VECTOR3, "b", varray());
+ ADDFUNC1R(VECTOR3, REAL, Vector3, distance_squared_to, VECTOR3, "b", varray());
ADDFUNC0R(VECTOR3, REAL, Vector3, length, varray());
ADDFUNC0R(VECTOR3, REAL, Vector3, length_squared, varray());
- ADDFUNC0R(VECTOR3, BOOL, Vector3, is_normalized, varray());
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, normalized, varray());
+ ADDFUNC0R(VECTOR3, BOOL, Vector3, is_normalized, varray());
+ ADDFUNC1R(VECTOR3, BOOL, Vector3, is_equal_approx, VECTOR3, "v", varray());
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, inverse, varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, snapped, VECTOR3, "by", varray());
ADDFUNC2R(VECTOR3, VECTOR3, Vector3, rotated, VECTOR3, "axis", REAL, "phi", varray());
ADDFUNC2R(VECTOR3, VECTOR3, Vector3, linear_interpolate, VECTOR3, "b", REAL, "t", varray());
ADDFUNC2R(VECTOR3, VECTOR3, Vector3, slerp, VECTOR3, "b", REAL, "t", varray());
ADDFUNC4R(VECTOR3, VECTOR3, Vector3, cubic_interpolate, VECTOR3, "b", VECTOR3, "pre_a", VECTOR3, "post_b", REAL, "t", varray());
- ADDFUNC1R(VECTOR3, VECTOR3, Vector3, direction_to, VECTOR3, "b", varray());
ADDFUNC2R(VECTOR3, VECTOR3, Vector3, move_toward, VECTOR3, "to", REAL, "delta", varray());
ADDFUNC1R(VECTOR3, REAL, Vector3, dot, VECTOR3, "b", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, cross, VECTOR3, "b", varray());
@@ -1675,12 +1697,9 @@ void register_variant_methods() {
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, floor, varray());
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, ceil, varray());
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, round, varray());
- ADDFUNC1R(VECTOR3, REAL, Vector3, distance_to, VECTOR3, "b", varray());
- ADDFUNC1R(VECTOR3, REAL, Vector3, distance_squared_to, VECTOR3, "b", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmod, REAL, "mod", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmodv, VECTOR3, "modv", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, project, VECTOR3, "b", varray());
- ADDFUNC1R(VECTOR3, REAL, Vector3, angle_to, VECTOR3, "to", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, slide, VECTOR3, "n", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, bounce, VECTOR3, "n", varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, reflect, VECTOR3, "n", varray());
@@ -1689,6 +1708,7 @@ void register_variant_methods() {
ADDFUNC0R(PLANE, PLANE, Plane, normalized, varray());
ADDFUNC0R(PLANE, VECTOR3, Plane, center, varray());
ADDFUNC0R(PLANE, VECTOR3, Plane, get_any_point, varray());
+ ADDFUNC1R(PLANE, BOOL, Plane, is_equal_approx, PLANE, "plane", varray());
ADDFUNC1R(PLANE, BOOL, Plane, is_point_over, VECTOR3, "point", varray());
ADDFUNC1R(PLANE, REAL, Plane, distance_to, VECTOR3, "point", varray());
ADDFUNC2R(PLANE, BOOL, Plane, has_point, VECTOR3, "point", REAL, "epsilon", varray(CMP_EPSILON));
@@ -1701,6 +1721,7 @@ void register_variant_methods() {
ADDFUNC0R(QUAT, REAL, Quat, length_squared, varray());
ADDFUNC0R(QUAT, QUAT, Quat, normalized, varray());
ADDFUNC0R(QUAT, BOOL, Quat, is_normalized, varray());
+ ADDFUNC1R(QUAT, BOOL, Quat, is_equal_approx, QUAT, "quat", varray());
ADDFUNC0R(QUAT, QUAT, Quat, inverse, varray());
ADDFUNC1R(QUAT, REAL, Quat, dot, QUAT, "b", varray());
ADDFUNC1R(QUAT, VECTOR3, Quat, xform, VECTOR3, "v", varray());
@@ -1726,6 +1747,7 @@ void register_variant_methods() {
ADDFUNC1R(COLOR, COLOR, Color, darkened, REAL, "amount", varray());
ADDFUNC1R(COLOR, STRING, Color, to_html, BOOL, "with_alpha", varray(true));
ADDFUNC4R(COLOR, COLOR, Color, from_hsv, REAL, "h", REAL, "s", REAL, "v", REAL, "a", varray(1.0));
+ ADDFUNC1R(COLOR, BOOL, Color, is_equal_approx, COLOR, "color", varray());
ADDFUNC0R(_RID, INT, RID, get_id, varray());
@@ -1782,6 +1804,7 @@ void register_variant_methods() {
ADDFUNC0R(ARRAY, NIL, Array, min, varray());
ADDFUNC0R(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray());
+ ADDFUNC0R(POOL_BYTE_ARRAY, BOOL, PoolByteArray, empty, varray());
ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray());
ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, push_back, INT, "byte", varray());
ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, append, INT, "byte", varray());
@@ -1799,6 +1822,7 @@ void register_variant_methods() {
ADDFUNC2R(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0));
ADDFUNC0R(POOL_INT_ARRAY, INT, PoolIntArray, size, varray());
+ ADDFUNC0R(POOL_INT_ARRAY, BOOL, PoolIntArray, empty, varray());
ADDFUNC2(POOL_INT_ARRAY, NIL, PoolIntArray, set, INT, "idx", INT, "integer", varray());
ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, push_back, INT, "integer", varray());
ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, append, INT, "integer", varray());
@@ -1809,6 +1833,7 @@ void register_variant_methods() {
ADDFUNC0(POOL_INT_ARRAY, NIL, PoolIntArray, invert, varray());
ADDFUNC0R(POOL_REAL_ARRAY, INT, PoolRealArray, size, varray());
+ ADDFUNC0R(POOL_REAL_ARRAY, BOOL, PoolRealArray, empty, varray());
ADDFUNC2(POOL_REAL_ARRAY, NIL, PoolRealArray, set, INT, "idx", REAL, "value", varray());
ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, push_back, REAL, "value", varray());
ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, append, REAL, "value", varray());
@@ -1819,6 +1844,7 @@ void register_variant_methods() {
ADDFUNC0(POOL_REAL_ARRAY, NIL, PoolRealArray, invert, varray());
ADDFUNC0R(POOL_STRING_ARRAY, INT, PoolStringArray, size, varray());
+ ADDFUNC0R(POOL_STRING_ARRAY, BOOL, PoolStringArray, empty, varray());
ADDFUNC2(POOL_STRING_ARRAY, NIL, PoolStringArray, set, INT, "idx", STRING, "string", varray());
ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, push_back, STRING, "string", varray());
ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, append, STRING, "string", varray());
@@ -1830,6 +1856,7 @@ void register_variant_methods() {
ADDFUNC1(POOL_STRING_ARRAY, STRING, PoolStringArray, join, STRING, "delimiter", varray());
ADDFUNC0R(POOL_VECTOR2_ARRAY, INT, PoolVector2Array, size, varray());
+ ADDFUNC0R(POOL_VECTOR2_ARRAY, BOOL, PoolVector2Array, empty, varray());
ADDFUNC2(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, set, INT, "idx", VECTOR2, "vector2", varray());
ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, push_back, VECTOR2, "vector2", varray());
ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, append, VECTOR2, "vector2", varray());
@@ -1840,6 +1867,7 @@ void register_variant_methods() {
ADDFUNC0(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, invert, varray());
ADDFUNC0R(POOL_VECTOR3_ARRAY, INT, PoolVector3Array, size, varray());
+ ADDFUNC0R(POOL_VECTOR3_ARRAY, BOOL, PoolVector3Array, empty, varray());
ADDFUNC2(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, set, INT, "idx", VECTOR3, "vector3", varray());
ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, push_back, VECTOR3, "vector3", varray());
ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, append, VECTOR3, "vector3", varray());
@@ -1850,6 +1878,7 @@ void register_variant_methods() {
ADDFUNC0(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, invert, varray());
ADDFUNC0R(POOL_COLOR_ARRAY, INT, PoolColorArray, size, varray());
+ ADDFUNC0R(POOL_COLOR_ARRAY, BOOL, PoolColorArray, empty, varray());
ADDFUNC2(POOL_COLOR_ARRAY, NIL, PoolColorArray, set, INT, "idx", COLOR, "color", varray());
ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, push_back, COLOR, "color", varray());
ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, append, COLOR, "color", varray());
@@ -1864,13 +1893,16 @@ void register_variant_methods() {
ADDFUNC0R(AABB, REAL, AABB, get_area, varray());
ADDFUNC0R(AABB, BOOL, AABB, has_no_area, varray());
ADDFUNC0R(AABB, BOOL, AABB, has_no_surface, varray());
+ ADDFUNC1R(AABB, BOOL, AABB, has_point, VECTOR3, "point", varray());
+ ADDFUNC1R(AABB, BOOL, AABB, is_equal_approx, AABB, "aabb", varray());
ADDFUNC1R(AABB, BOOL, AABB, intersects, AABB, "with", varray());
ADDFUNC1R(AABB, BOOL, AABB, encloses, AABB, "with", varray());
- ADDFUNC1R(AABB, AABB, AABB, merge, AABB, "with", varray());
- ADDFUNC1R(AABB, AABB, AABB, intersection, AABB, "with", varray());
ADDFUNC1R(AABB, BOOL, AABB, intersects_plane, PLANE, "plane", varray());
ADDFUNC2R(AABB, BOOL, AABB, intersects_segment, VECTOR3, "from", VECTOR3, "to", varray());
- ADDFUNC1R(AABB, BOOL, AABB, has_point, VECTOR3, "point", varray());
+ ADDFUNC1R(AABB, AABB, AABB, intersection, AABB, "with", varray());
+ ADDFUNC1R(AABB, AABB, AABB, merge, AABB, "with", varray());
+ ADDFUNC1R(AABB, AABB, AABB, expand, VECTOR3, "to_point", varray());
+ ADDFUNC1R(AABB, AABB, AABB, grow, REAL, "by", varray());
ADDFUNC1R(AABB, VECTOR3, AABB, get_support, VECTOR3, "dir", varray());
ADDFUNC0R(AABB, VECTOR3, AABB, get_longest_axis, varray());
ADDFUNC0R(AABB, INT, AABB, get_longest_axis_index, varray());
@@ -1878,8 +1910,6 @@ void register_variant_methods() {
ADDFUNC0R(AABB, VECTOR3, AABB, get_shortest_axis, varray());
ADDFUNC0R(AABB, INT, AABB, get_shortest_axis_index, varray());
ADDFUNC0R(AABB, REAL, AABB, get_shortest_axis_size, varray());
- ADDFUNC1R(AABB, AABB, AABB, expand, VECTOR3, "to_point", varray());
- ADDFUNC1R(AABB, AABB, AABB, grow, REAL, "by", varray());
ADDFUNC1R(AABB, VECTOR3, AABB, get_endpoint, INT, "idx", varray());
ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, inverse, varray());
@@ -1896,6 +1926,7 @@ void register_variant_methods() {
ADDFUNC1R(TRANSFORM2D, VECTOR2, Transform2D, basis_xform, VECTOR2, "v", varray());
ADDFUNC1R(TRANSFORM2D, VECTOR2, Transform2D, basis_xform_inv, VECTOR2, "v", varray());
ADDFUNC2R(TRANSFORM2D, TRANSFORM2D, Transform2D, interpolate_with, TRANSFORM2D, "transform", REAL, "weight", varray());
+ ADDFUNC1R(TRANSFORM2D, BOOL, Transform2D, is_equal_approx, TRANSFORM2D, "transform", varray());
ADDFUNC0R(BASIS, BASIS, Basis, inverse, varray());
ADDFUNC0R(BASIS, BASIS, Basis, transposed, varray());
@@ -1912,7 +1943,7 @@ void register_variant_methods() {
ADDFUNC1R(BASIS, VECTOR3, Basis, xform_inv, VECTOR3, "v", varray());
ADDFUNC0R(BASIS, INT, Basis, get_orthogonal_index, varray());
ADDFUNC2R(BASIS, BASIS, Basis, slerp, BASIS, "b", REAL, "t", varray());
- ADDFUNC2R(BASIS, BOOL, Basis, is_equal_approx, BASIS, "b", REAL, "epsilon", varray(CMP_EPSILON));
+ ADDFUNC2R(BASIS, BOOL, Basis, is_equal_approx, BASIS, "b", REAL, "epsilon", varray(CMP_EPSILON)); // TODO: Replace in 4.0, see other TODO.
ADDFUNC0R(BASIS, QUAT, Basis, get_rotation_quat, varray());
ADDFUNC0R(TRANSFORM, TRANSFORM, Transform, inverse, varray());
@@ -1923,6 +1954,7 @@ void register_variant_methods() {
ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, translated, VECTOR3, "ofs", varray());
ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, looking_at, VECTOR3, "target", VECTOR3, "up", varray());
ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, interpolate_with, TRANSFORM, "transform", REAL, "weight", varray());
+ ADDFUNC1R(TRANSFORM, BOOL, Transform, is_equal_approx, TRANSFORM, "transform", varray());
ADDFUNC1R(TRANSFORM, NIL, Transform, xform, NIL, "v", varray());
ADDFUNC1R(TRANSFORM, NIL, Transform, xform_inv, NIL, "v", varray());
diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml
index 7dcfa5345d..61e1ea9b8d 100644
--- a/doc/classes/AABB.xml
+++ b/doc/classes/AABB.xml
@@ -176,6 +176,14 @@
Returns [code]true[/code] if the [AABB] intersects the line segment between [code]from[/code] and [code]to[/code].
</description>
</method>
+ <method name="is_equal_approx">
+ <return type="bool">
+ </return>
+ <argument index="0" name="aabb" type="AABB">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="merge">
<return type="AABB">
</return>
diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml
index e835af01e8..6304bd34f6 100644
--- a/doc/classes/AStar.xml
+++ b/doc/classes/AStar.xml
@@ -1,11 +1,23 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="AStar" inherits="Reference" category="Core" version="3.2">
<brief_description>
- AStar class representation that uses 3d-vectors as edges.
+ An implementation of A* to find shortest paths among connected points in space.
</brief_description>
<description>
- A* (A star) is a computer algorithm that is widely used in pathfinding and graph traversal, the process of plotting an efficiently directed path between multiple points. It enjoys widespread use due to its performance and accuracy. Godot's A* implementation make use of vectors as points.
- You must add points manually with [method add_point] and create segments manually with [method connect_points]. So you can test if there is a path between two points with the [method are_points_connected] function, get the list of existing ids in the found path with [method get_id_path], or the points list with [method get_point_path].
+ A* (A star) is a computer algorithm that is widely used in pathfinding and graph traversal, the process of plotting short paths among vertices (points), passing through a given set of edges (segments). It enjoys widespread use due to its performance and accuracy. Godot's A* implementation uses points in three-dimensional space and Euclidean distances by default.
+ You must add points manually with [method add_point] and create segments manually with [method connect_points]. Then you can test if there is a path between two points with the [method are_points_connected] function, get a path containing indices by [method get_id_path], or one containing actual coordinates with [method get_point_path].
+ It is also possible to use non-Euclidean distances. To do so, create a class that extends [code]AStar[/code] and override methods [method _compute_cost] and [method _estimate_cost]. Both take two indices and return a length, as is shown in the following example.
+ [codeblock]
+ class MyAStar:
+ extends AStar
+
+ func _compute_cost(u, v):
+ return abs(u - v)
+
+ func _estimate_cost(u, v):
+ return min(0, abs(u - v) - 1)
+ [/codeblock]
+ [method _estimate_cost] should return a lower bound of the distance, i.e. [code]_estimate_cost(u, v) &lt;= _compute_cost(u, v)[/code]. This serves as a hint to the algorithm because the custom [code]_compute_cost[/code] might be computation-heavy. If this is not the case, make [method _estimate_cost] return the same value as [method _compute_cost] to provide the algorithm with the most accurate information.
</description>
<tutorials>
</tutorials>
@@ -19,6 +31,7 @@
</argument>
<description>
Called when computing the cost between two connected points.
+ Note that this function is hidden in the default [code]AStar[/code] class.
</description>
</method>
<method name="_estimate_cost" qualifiers="virtual">
@@ -30,6 +43,7 @@
</argument>
<description>
Called when estimating the cost between a point and the path's ending point.
+ Note that this function is hidden in the default [code]AStar[/code] class.
</description>
</method>
<method name="add_point">
@@ -57,8 +71,10 @@
</argument>
<argument index="1" name="to_id" type="int">
</argument>
+ <argument index="2" name="bidirectional" type="bool" default="true">
+ </argument>
<description>
- Returns whether there is a connection/segment between the given points.
+ Returns whether the two given points are directly connected by a segment. If [code]bidirectional[/code] is [code]false[/code], returns whether movement from [code]id[/code] to [code]to_id[/code] is possible through this segment.
</description>
</method>
<method name="clear">
@@ -94,8 +110,10 @@
</argument>
<argument index="1" name="to_id" type="int">
</argument>
+ <argument index="2" name="bidirectional" type="bool" default="true">
+ </argument>
<description>
- Deletes the segment between the given points.
+ Deletes the segment between the given points. If [code]bidirectional[/code] is [code]false[/code], only movement from [code]id[/code] to [code]to_id[/code] is prevented, and a unidirectional segment possibly remains.
</description>
</method>
<method name="get_available_point_id" qualifiers="const">
diff --git a/doc/classes/AnimationNodeBlendSpace2D.xml b/doc/classes/AnimationNodeBlendSpace2D.xml
index c71a06d931..d8ea7fea5b 100644
--- a/doc/classes/AnimationNodeBlendSpace2D.xml
+++ b/doc/classes/AnimationNodeBlendSpace2D.xml
@@ -125,7 +125,7 @@
</methods>
<members>
<member name="auto_triangles" type="bool" setter="set_auto_triangles" getter="get_auto_triangles" default="true">
- If true, the blend space is triangulated automatically. The mesh updates every time you add or remove points with [method add_blend_point] and [method remove_blend_point].
+ If [code]true[/code], the blend space is triangulated automatically. The mesh updates every time you add or remove points with [method add_blend_point] and [method remove_blend_point].
</member>
<member name="blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" enum="AnimationNodeBlendSpace2D.BlendMode" default="0">
Controls the interpolation between animations. See [enum BlendMode] constants.
diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml
index e1cb9056da..9a5870c73d 100644
--- a/doc/classes/Area2D.xml
+++ b/doc/classes/Area2D.xml
@@ -7,6 +7,7 @@
2D area that detects [CollisionObject2D] nodes overlapping, entering, or exiting. Can also alter or override local physics parameters (gravity, damping).
</description>
<tutorials>
+ <link>https://docs.godotengine.org/en/latest/tutorials/physics/using_area_2d.html</link>
</tutorials>
<methods>
<method name="get_collision_layer_bit" qualifiers="const">
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index a1529f3eb3..e09c1f4b08 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -316,7 +316,7 @@
<argument index="3" name="deep" type="bool" default="False">
</argument>
<description>
- Duplicates the subset described in the function and returns it in an array, deeply copying the array if [code]deep[/code] is true. Lower and upper index are inclusive, with the [code]step[/code] describing the change between indices while slicing.
+ Duplicates the subset described in the function and returns it in an array, deeply copying the array if [code]deep[/code] is [code]true[/code]. Lower and upper index are inclusive, with the [code]step[/code] describing the change between indices while slicing.
</description>
</method>
<method name="sort">
diff --git a/doc/classes/BackBufferCopy.xml b/doc/classes/BackBufferCopy.xml
index 9bb32e0444..945af0c701 100644
--- a/doc/classes/BackBufferCopy.xml
+++ b/doc/classes/BackBufferCopy.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BackBufferCopy" inherits="Node2D" category="Core" version="3.2">
<brief_description>
- Copies a region of the screen (or the whole screen) to a buffer so it can be accessed with [code]SCREEN_TEXTURE[/code] in the [code]texture()[/code] function.
+ Copies a region of the screen (or the whole screen) to a buffer so it can be accessed in your shader scripts through the [code]texture(SCREEN_TEXTURE, ...)[/code] function.
</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 [code]SCREEN_TEXTURE[/code] in the [code]texture()[/code] function to access the buffer.
+ 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.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index a920001de4..8372d15324 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -363,6 +363,7 @@
<return type="void">
</return>
<description>
+ 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.
</description>
</method>
<method name="get_canvas" qualifiers="const">
diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml
index 46499ed349..deba30712e 100644
--- a/doc/classes/Color.xml
+++ b/doc/classes/Color.xml
@@ -151,6 +151,14 @@
[/codeblock]
</description>
</method>
+ <method name="is_equal_approx">
+ <return type="bool">
+ </return>
+ <argument index="0" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="lightened">
<return type="Color">
</return>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 05ffac803a..75d5a72fb1 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -62,7 +62,7 @@
</argument>
<description>
Virtual method to be implemented by the user. Returns a [Control] node that should be used as a tooltip instead of the default one. Use [code]for_text[/code] parameter to determine what text the tooltip should contain (likely the contents of [member hint_tooltip]).
- The returned node must be of type [Control] or Control-derieved. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance, not e.g. a node from scene. When null or non-Control node is returned, the default tooltip will be used instead.
+ The returned node must be of type [Control] or Control-derieved. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance, not e.g. a node from scene. When [code]null[/code] or non-Control node is returned, the default tooltip will be used instead.
[b]Note:[/b] The tooltip is shrunk to minimal size. If you want to ensure it's fully visible, you might want to set its [member rect_min_size] to some non-zero value.
Example of usage with custom-constructed node:
[codeblock]
@@ -652,7 +652,18 @@
<argument index="0" name="control" type="Control">
</argument>
<description>
- Shows the given control at the mouse pointer. A good time to call this method is in [method get_drag_data].
+ Shows the given control at the mouse pointer. A good time to call this method is in [method get_drag_data]. The control must not be in the scene tree.
+ [codeblock]
+ export (Color, RGBA) var color = Color(1, 0, 0, 1)
+
+ func get_drag_data(position):
+ # Use a control that is not in the tree
+ var cpb = ColorPickerButton.new()
+ cpb.color = color
+ cpb.rect_size = Vector2(50, 50)
+ set_drag_preview(cpb)
+ return color
+ [/codeblock]
</description>
</method>
<method name="set_end">
diff --git a/doc/classes/EditorInspectorPlugin.xml b/doc/classes/EditorInspectorPlugin.xml
index cab5af3985..a713e06585 100644
--- a/doc/classes/EditorInspectorPlugin.xml
+++ b/doc/classes/EditorInspectorPlugin.xml
@@ -6,7 +6,7 @@
<description>
This plugins allows adding custom property editors to [EditorInspector].
Plugins are registered via [method EditorPlugin.add_inspector_plugin].
- When an object is edited, the [method can_handle] function is called and must return true if the object type is supported.
+ When an object is edited, the [method can_handle] function is called and must return [code]true[/code] if the object type is supported.
If supported, the function [method parse_begin] will be called, allowing to place custom controls at the beginning of the class.
Subsequently, the [method parse_category] and [method parse_property] are called for every category and property. They offer the ability to add custom controls to the inspector too.
Finally [method parse_end] will be called.
@@ -54,7 +54,7 @@
<argument index="0" name="object" type="Object">
</argument>
<description>
- Returns true if this object can be handled by this plugin.
+ Returns [code]true[/code] if this object can be handled by this plugin.
</description>
</method>
<method name="parse_begin" qualifiers="virtual">
diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml
index 3a73d44a01..d0e8a5972f 100644
--- a/doc/classes/HTTPRequest.xml
+++ b/doc/classes/HTTPRequest.xml
@@ -1,13 +1,43 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HTTPRequest" inherits="Node" category="Core" version="3.2">
<brief_description>
- A node with the ability to send HTTP requests.
+ A node with the ability to send HTTP(S) requests.
</brief_description>
<description>
A node with the ability to send HTTP requests. Uses [HTTPClient] internally.
Can be used to make HTTP requests, i.e. download or upload files or web content via HTTP.
+ [b]Example of loading and displaying an image using HTTPRequest:[/b]
+ [codeblock]
+ func _ready():
+ # Create an HTTP request node and connect its completion signal.
+ var http_request = HTTPRequest.new()
+ add_child(http_request)
+ http_request.connect("request_completed", self, "_http_request_completed")
+
+ # Perform the HTTP request. The URL below returns a PNG image as of writing.
+ var error = http_request.request("https://via.placeholder.com/512")
+ if error != OK:
+ push_error("An error occurred in the HTTP request.")
+
+
+ # Called when the HTTP request is completed.
+ func _http_request_completed(result, response_code, headers, body):
+ var image = Image.new()
+ var error = image.load_png_from_buffer(body)
+ if error != OK:
+ push_error("Couldn't load the image.")
+
+ var texture = ImageTexture.new()
+ texture.create_from_image(image)
+
+ # Display the image in a TextureRect node.
+ var texture_rect = TextureRect.new()
+ add_child(texture_rect)
+ texture_rect.texture = texture
+ [/codeblock]
</description>
<tutorials>
+ <link>https://docs.godotengine.org/en/latest/tutorials/networking/http_request_class.html</link>
<link>https://docs.godotengine.org/en/latest/tutorials/networking/ssl_certificates.html</link>
</tutorials>
<methods>
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index d297bc98ae..d37ab64cb3 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -415,7 +415,7 @@
<argument index="1" name="grayscale" type="bool" default="false">
</argument>
<description>
- Saves the image as an EXR file to [code]path[/code]. If grayscale is true and the image has only one channel, it will be saved explicitly as monochrome rather than one red channel. This function will return [constant ERR_UNAVAILABLE] if Godot was compiled without the TinyEXR module.
+ Saves the image as an EXR file to [code]path[/code]. If grayscale is [code]true[/code] and the image has only one channel, it will be saved explicitly as monochrome rather than one red channel. This function will return [constant ERR_UNAVAILABLE] if Godot was compiled without the TinyEXR module.
</description>
</method>
<method name="save_png" qualifiers="const">
@@ -456,6 +456,15 @@
<argument index="1" name="color" type="Color">
</argument>
<description>
+ Sets the [Color] of the pixel at [code](dst.x, dst.y)[/code] if the image is locked. Note that the [code]dst[/code] values must be integers. Example:
+ [codeblock]
+ var img = Image.new()
+ img.create(img_width, img_height, false, Image.FORMAT_RGBA8)
+ img.lock()
+ img.set_pixelv(Vector2(x, y), color) # Works
+ img.unlock()
+ img.set_pixelv(Vector2(x, y), color) # Does not have an effect
+ [/codeblock]
</description>
</method>
<method name="shrink_x2">
diff --git a/doc/classes/InputEvent.xml b/doc/classes/InputEvent.xml
index 4c8d83adba..d412ce09e2 100644
--- a/doc/classes/InputEvent.xml
+++ b/doc/classes/InputEvent.xml
@@ -51,8 +51,10 @@
</return>
<argument index="0" name="action" type="String">
</argument>
+ <argument index="1" name="allow_echo" type="bool" default="false">
+ </argument>
<description>
- Returns [code]true[/code] if the given action is being pressed (and is not an echo event for [InputEventKey] events). Not relevant for events of type [InputEventMouseMotion] or [InputEventScreenDrag].
+ Returns [code]true[/code] if the given action is being pressed (and is not an echo event for [InputEventKey] events, unless [code]allow_echo[/code] is [code]true[/code]). Not relevant for events of type [InputEventMouseMotion] or [InputEventScreenDrag].
</description>
</method>
<method name="is_action_released" qualifiers="const">
diff --git a/doc/classes/InputEventMouseMotion.xml b/doc/classes/InputEventMouseMotion.xml
index fab4cc0fb9..5cd6a0c285 100644
--- a/doc/classes/InputEventMouseMotion.xml
+++ b/doc/classes/InputEventMouseMotion.xml
@@ -4,7 +4,7 @@
Input event type for mouse motion events.
</brief_description>
<description>
- Contains mouse motion information. Supports relative, absolute positions and speed. See [method Node._input].
+ Contains mouse and pen motion information. Supports relative, absolute positions and speed. See [method Node._input].
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/inputs/mouse_and_input_coordinates.html</link>
@@ -12,12 +12,18 @@
<methods>
</methods>
<members>
+ <member name="pressure" type="float" setter="set_pressure" getter="get_pressure" default="0.0">
+ Represents the pressure the user puts on the pen. Ranges from [code]0.0[/code] to [code]1.0[/code].
+ </member>
<member name="relative" type="Vector2" setter="set_relative" getter="get_relative" default="Vector2( 0, 0 )">
The mouse position relative to the previous position (position at the last frame).
</member>
<member name="speed" type="Vector2" setter="set_speed" getter="get_speed" default="Vector2( 0, 0 )">
The mouse speed in pixels per second.
</member>
+ <member name="tilt" type="Vector2" setter="set_tilt" getter="get_tilt" default="Vector2( 0, 0 )">
+ Represents the angles of tilt of the pen. Positive X-coordinate value indicates a tilt to the right. Positive Y-coordinate value indicates a tilt toward the user. Ranges from [code]-1.0[/code] to [code]1.0[/code] for both axes.
+ </member>
</members>
<constants>
</constants>
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index b6eeed4a21..5aeeb61647 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -157,6 +157,8 @@
<return type="PoolStringArray">
</return>
<description>
+ Returns an array of MIDI device names.
+ The returned array will be empty if the system MIDI driver has not previously been initialised with [method open_midi_inputs].
</description>
</method>
<method name="get_current_video_driver" qualifiers="const">
@@ -699,6 +701,7 @@
<return type="void">
</return>
<description>
+ Initialises the singleton for the system MIDI driver.
</description>
</method>
<method name="print_all_resources">
diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml
index 69dfe28ac4..bb72f2734e 100644
--- a/doc/classes/Plane.xml
+++ b/doc/classes/Plane.xml
@@ -116,6 +116,14 @@
Returns the intersection point of a segment from position [code]begin[/code] to position [code]end[/code] with this plane. If no intersection is found, [code]null[/code] is returned.
</description>
</method>
+ <method name="is_equal_approx">
+ <return type="bool">
+ </return>
+ <argument index="0" name="plane" type="Plane">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="is_point_over">
<return type="bool">
</return>
diff --git a/doc/classes/PoolByteArray.xml b/doc/classes/PoolByteArray.xml
index 21bf078017..867f042cd2 100644
--- a/doc/classes/PoolByteArray.xml
+++ b/doc/classes/PoolByteArray.xml
@@ -53,6 +53,13 @@
Returns a new [PoolByteArray] with the data decompressed. Set [code]buffer_size[/code] to the size of the uncompressed data. Set the compression mode using one of [enum File.CompressionMode]'s constants.
</description>
</method>
+ <method name="empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="get_string_from_ascii">
<return type="String">
</return>
diff --git a/doc/classes/PoolColorArray.xml b/doc/classes/PoolColorArray.xml
index a1fb868ef5..34cfa0ab53 100644
--- a/doc/classes/PoolColorArray.xml
+++ b/doc/classes/PoolColorArray.xml
@@ -33,6 +33,13 @@
Appends a [PoolColorArray] at the end of this array.
</description>
</method>
+ <method name="empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="insert">
<return type="int">
</return>
diff --git a/doc/classes/PoolIntArray.xml b/doc/classes/PoolIntArray.xml
index 28a28b2bba..25e1e718f7 100644
--- a/doc/classes/PoolIntArray.xml
+++ b/doc/classes/PoolIntArray.xml
@@ -34,6 +34,13 @@
Appends a [PoolIntArray] at the end of this array.
</description>
</method>
+ <method name="empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="insert">
<return type="int">
</return>
diff --git a/doc/classes/PoolRealArray.xml b/doc/classes/PoolRealArray.xml
index 7eaec82338..e8afe46640 100644
--- a/doc/classes/PoolRealArray.xml
+++ b/doc/classes/PoolRealArray.xml
@@ -33,6 +33,13 @@
Appends a [PoolRealArray] at the end of this array.
</description>
</method>
+ <method name="empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="insert">
<return type="int">
</return>
diff --git a/doc/classes/PoolStringArray.xml b/doc/classes/PoolStringArray.xml
index a408a18b19..f41a3c7a68 100644
--- a/doc/classes/PoolStringArray.xml
+++ b/doc/classes/PoolStringArray.xml
@@ -33,6 +33,13 @@
Appends a [PoolStringArray] at the end of this array.
</description>
</method>
+ <method name="empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="insert">
<return type="int">
</return>
diff --git a/doc/classes/PoolVector2Array.xml b/doc/classes/PoolVector2Array.xml
index 623247e639..321846d08b 100644
--- a/doc/classes/PoolVector2Array.xml
+++ b/doc/classes/PoolVector2Array.xml
@@ -33,6 +33,13 @@
Appends a [PoolVector2Array] at the end of this array.
</description>
</method>
+ <method name="empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="insert">
<return type="int">
</return>
diff --git a/doc/classes/PoolVector3Array.xml b/doc/classes/PoolVector3Array.xml
index adc28b46cb..c82bd62a11 100644
--- a/doc/classes/PoolVector3Array.xml
+++ b/doc/classes/PoolVector3Array.xml
@@ -33,6 +33,13 @@
Appends a [PoolVector3Array] at the end of this array.
</description>
</method>
+ <method name="empty">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the array is empty.
+ </description>
+ </method>
<method name="insert">
<return type="int">
</return>
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 691aec2eb1..bdb6ca84ee 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -444,7 +444,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
- Sets the type of the item at the specified index [code]idx[/code] to radio button. If false, sets the type of the item to plain text.
+ Sets the type of the item at the specified index [code]idx[/code] to radio button. If [code]false[/code], sets the type of the item to plain text.
</description>
</method>
<method name="set_item_as_separator">
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index fa735b8918..772c2f5073 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -145,6 +145,7 @@
<argument index="1" name="value" type="Variant">
</argument>
<description>
+ Sets the specified property's initial value. This is the value the property reverts to.
</description>
</method>
<method name="set_order">
@@ -166,6 +167,11 @@
<argument index="1" name="value" type="Variant">
</argument>
<description>
+ Sets the value of a setting.
+ [b]Example:[/b]
+ [codeblock]
+ ProjectSettings.set_setting("application/config/name", "Example")
+ [/codeblock]
</description>
</method>
</methods>
@@ -276,6 +282,9 @@
<member name="debug/gdscript/warnings/enable" type="bool" setter="" getter="" default="true">
If [code]true[/code], enables specific GDScript warnings (see [code]debug/gdscript/warnings/*[/code] settings). If [code]false[/code], disables all GDScript warnings.
</member>
+ <member name="debug/gdscript/warnings/exclude_addons" type="bool" setter="" getter="" default="true">
+ If [code]true[/code], scripts in the [code]res://addons[/code] folder will not generate warnings.
+ </member>
<member name="debug/gdscript/warnings/function_conflicts_constant" type="bool" setter="" getter="" default="true">
If [code]true[/code], enables warnings when a function is declared with the same name as a constant.
</member>
@@ -422,9 +431,6 @@
<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>
- <member name="editor/active" type="bool" setter="" getter="" default="false">
- Internal editor setting, don't touch.
- </member>
<member name="editor/script_templates_search_path" type="String" setter="" getter="" default="&quot;res://script_templates&quot;">
</member>
<member name="editor/search_in_file_extensions" type="PoolStringArray" setter="" getter="" default="PoolStringArray( &quot;gd&quot;, &quot;shader&quot; )">
diff --git a/doc/classes/Quat.xml b/doc/classes/Quat.xml
index 9d163e926c..f5ee99d30c 100644
--- a/doc/classes/Quat.xml
+++ b/doc/classes/Quat.xml
@@ -94,6 +94,14 @@
Returns the inverse of the quaternion.
</description>
</method>
+ <method name="is_equal_approx">
+ <return type="bool">
+ </return>
+ <argument index="0" name="quat" type="Quat">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="is_normalized">
<return type="bool">
</return>
diff --git a/doc/classes/RayCast.xml b/doc/classes/RayCast.xml
index 19f62a57bd..5e17d6e7d7 100644
--- a/doc/classes/RayCast.xml
+++ b/doc/classes/RayCast.xml
@@ -11,6 +11,7 @@
RayCast calculates intersection every physics frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between physics frames (or during the same frame), use [method force_raycast_update] after adjusting the raycast.
</description>
<tutorials>
+ <link>https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
</tutorials>
<methods>
<method name="add_exception">
diff --git a/doc/classes/RayCast2D.xml b/doc/classes/RayCast2D.xml
index 81d66ef496..c5ba5da24e 100644
--- a/doc/classes/RayCast2D.xml
+++ b/doc/classes/RayCast2D.xml
@@ -11,6 +11,7 @@
RayCast2D calculates intersection every physics frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between physics frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast.
</description>
<tutorials>
+ <link>https://docs.godotengine.org/en/latest/tutorials/physics/ray-casting.html</link>
</tutorials>
<methods>
<method name="add_exception">
diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml
index 9d6bfbf398..07fa7777fe 100644
--- a/doc/classes/Rect2.xml
+++ b/doc/classes/Rect2.xml
@@ -137,6 +137,14 @@
Returns [code]true[/code] if the [Rect2] overlaps with another.
</description>
</method>
+ <method name="is_equal_approx">
+ <return type="bool">
+ </return>
+ <argument index="0" name="rect" type="Rect2">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="merge">
<return type="Rect2">
</return>
diff --git a/doc/classes/SoftBody.xml b/doc/classes/SoftBody.xml
index 5cde31fa59..a51907b1bf 100644
--- a/doc/classes/SoftBody.xml
+++ b/doc/classes/SoftBody.xml
@@ -7,6 +7,7 @@
A deformable physics body. Used to create elastic or deformable objects such as cloth, rubber, or other flexible materials.
</description>
<tutorials>
+ <link>https://docs.godotengine.org/en/latest/tutorials/physics/soft_body.html</link>
</tutorials>
<methods>
<method name="add_collision_exception_with">
@@ -43,12 +44,6 @@
Returns an individual bit on the collision mask.
</description>
</method>
- <method name="is_ray_pickable" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
<method name="remove_collision_exception_with">
<return type="void">
</return>
@@ -80,25 +75,17 @@
Sets individual bits on the collision mask. Use this if you only need to change one layer's value.
</description>
</method>
- <method name="set_ray_pickable">
- <return type="void">
- </return>
- <argument index="0" name="ray_pickable" type="bool">
- </argument>
- <description>
- </description>
- </method>
</methods>
<members>
<member name="areaAngular_stiffness" type="float" setter="set_areaAngular_stiffness" getter="get_areaAngular_stiffness" default="0.5">
</member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" default="1">
- The physics layers this area is in.
+ The physics layers this SoftBody is in.
Collidable objects can exist in any of 32 different layers. These layers work like a tagging system, and are not visual. A collidable can use these layers to select with which objects it can collide, using the collision_mask property.
A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A.
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The physics layers this area scans for collisions.
+ The physics layers this SoftBody scans for collisions.
</member>
<member name="damping_coefficient" type="float" setter="set_damping_coefficient" getter="get_damping_coefficient" default="0.01">
</member>
@@ -107,15 +94,20 @@
<member name="linear_stiffness" type="float" setter="set_linear_stiffness" getter="get_linear_stiffness" default="0.5">
</member>
<member name="parent_collision_ignore" type="NodePath" setter="set_parent_collision_ignore" getter="get_parent_collision_ignore" default="NodePath(&quot;&quot;)">
+ [NodePath] to a [CollisionObject] this SoftBody should avoid clipping.
</member>
<member name="pose_matching_coefficient" type="float" setter="set_pose_matching_coefficient" getter="get_pose_matching_coefficient" default="0.0">
</member>
<member name="pressure_coefficient" type="float" setter="set_pressure_coefficient" getter="get_pressure_coefficient" default="0.0">
</member>
+ <member name="ray_pickable" type="bool" setter="set_ray_pickable" getter="is_ray_pickable" default="true">
+ If [code]true[/code], the [SoftBody] will respond to [RayCast]s.
+ </member>
<member name="simulation_precision" type="int" setter="set_simulation_precision" getter="get_simulation_precision" default="5">
Increasing this value will improve the resulting simulation, but can affect performance. Use with care.
</member>
<member name="total_mass" type="float" setter="set_total_mass" getter="get_total_mass" default="1.0">
+ The SoftBody's mass.
</member>
<member name="volume_stiffness" type="float" setter="set_volume_stiffness" getter="get_volume_stiffness" default="0.5">
</member>
diff --git a/doc/classes/Spatial.xml b/doc/classes/Spatial.xml
index 128aa93f15..0309e73eec 100644
--- a/doc/classes/Spatial.xml
+++ b/doc/classes/Spatial.xml
@@ -15,6 +15,7 @@
<return type="void">
</return>
<description>
+ 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.
</description>
</method>
<method name="get_parent_spatial" qualifiers="const">
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index cf152e716e..e0a4a24299 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -459,7 +459,7 @@
<argument index="1" name="what" type="String">
</argument>
<description>
- Inserts a substring at a given position.
+ Returns a copy of the string with the substring [code]what[/code] inserted at the given position.
</description>
</method>
<method name="is_abs_path">
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 0dd2d75cd5..75fceac500 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -94,7 +94,7 @@
</argument>
<description>
Moves the cursor at the specified [code]column[/code] index.
- If [code]adjust_viewport[/code] is set to true, the viewport will center at the cursor position after the move occurs.
+ If [code]adjust_viewport[/code] is set to [code]true[/code], the viewport will center at the cursor position after the move occurs.
</description>
</method>
<method name="cursor_set_line">
@@ -110,8 +110,8 @@
</argument>
<description>
Moves the cursor at the specified [code]line[/code] index.
- If [code]adjust_viewport[/code] is set to true, the viewport will center at the cursor position after the move occurs.
- If [code]can_be_hidden[/code] is set to true, the specified [code]line[/code] can be hidden using [method set_line_as_hidden].
+ If [code]adjust_viewport[/code] is set to [code]true[/code], the viewport will center at the cursor position after the move occurs.
+ If [code]can_be_hidden[/code] is set to [code]true[/code], the specified [code]line[/code] can be hidden using [method set_line_as_hidden].
</description>
</method>
<method name="cut">
@@ -310,7 +310,15 @@
<argument index="3" name="from_column" type="int">
</argument>
<description>
- Perform a search inside the text. Search flags can be specified in the[code]SEARCH_*[/code] enum.
+ Perform a search inside the text. Search flags can be specified in the [enum SearchFlags] enum.
+ Returns an empty [code]PoolIntArray[/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:
+ [codeblock]
+ var result = search(key, flags, line, column)
+ if result.size() &gt; 0:
+ # result found
+ var res_line = result[TextEdit.SEARCH_RESULT_LINE]
+ var res_column = result[TextEdit.SEARCH_RESULT_COLUMN]
+ [/codeblock]
</description>
</method>
<method name="select">
@@ -504,8 +512,14 @@
<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.
+ Cuts (copies and clears) the selected text.
</constant>
<constant name="MENU_COPY" value="1" enum="MenuItems">
Copies the selected text.
diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml
index e4db9243ef..dd12c5af23 100644
--- a/doc/classes/Theme.xml
+++ b/doc/classes/Theme.xml
@@ -15,6 +15,7 @@
<return type="void">
</return>
<description>
+ Clears all values on the theme.
</description>
</method>
<method name="clear_color">
@@ -85,6 +86,7 @@
<argument index="0" name="other" type="Theme">
</argument>
<description>
+ Sets the Theme's values to a copy of a given theme.
</description>
</method>
<method name="get_color" qualifiers="const">
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index 75eb8b5862..7376f624cb 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -43,6 +43,7 @@
<argument index="1" name="y" type="int">
</argument>
<description>
+ Returns the coordinate of the autotile variation in the tileset. Returns a zero vector if the cell doesn't have autotiling.
</description>
</method>
<method name="get_cellv" qualifiers="const">
@@ -255,6 +256,7 @@
</methods>
<members>
<member name="cell_clip_uv" type="bool" setter="set_clip_uv" getter="get_clip_uv" default="false">
+ If [code]true[/code], the cell's UVs will be clipped.
</member>
<member name="cell_custom_transform" type="Transform2D" setter="set_custom_transform" getter="get_custom_transform" default="Transform2D( 64, 0, 0, 64, 0, 0 )">
The custom [Transform2D] to be applied to the TileMap's cells.
@@ -294,6 +296,7 @@
If [code]true[/code], TileMap collisions will be handled as a kinematic body. If [code]false[/code], collisions will be handled as static body.
</member>
<member name="collision_use_parent" type="bool" setter="set_collision_use_parent" getter="get_collision_use_parent" default="false">
+ If [code]true[/code], this tilemap's collision shape will be added to the collision shape of the parent. The parent has to be a [CollisionObject2D].
</member>
<member name="compatibility_mode" type="bool" setter="set_compatibility_mode" getter="is_compatibility_mode_enabled" default="false">
If [code]true[/code], the compatibility with the tilemaps made in Godot 3.1 or earlier is maintained (textures move when the tile origin changes and rotate if the texture size is not homogeneous). This mode presents problems when doing [code]flip_h[/code], [code]flip_v[/code] and [code]transpose[/code] tile operations on non-homogeneous isometric tiles (e.g. 2:1), in which the texture could not coincide with the collision, thus it is not recommended for isometric or non-square tiles.
diff --git a/doc/classes/TouchScreenButton.xml b/doc/classes/TouchScreenButton.xml
index fccfb4cd6d..3d18534a68 100644
--- a/doc/classes/TouchScreenButton.xml
+++ b/doc/classes/TouchScreenButton.xml
@@ -37,7 +37,7 @@
The button's shape.
</member>
<member name="shape_centered" type="bool" setter="set_shape_centered" getter="is_shape_centered" default="true">
- If [code]true[/code], the button's shape is centered.
+ If [code]true[/code], the button's shape is centered in the provided texture. If no texture is used, this property has no effect.
</member>
<member name="shape_visible" type="bool" setter="set_shape_visible" getter="is_shape_visible" default="true">
If [code]true[/code], the button's shape is visible.
diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml
index 6ebc389ed7..034a1b2f5b 100644
--- a/doc/classes/Transform.xml
+++ b/doc/classes/Transform.xml
@@ -89,6 +89,14 @@
Returns the inverse of the transform, under the assumption that the transformation is composed of rotation and translation (no scaling, use affine_inverse for transforms with scaling).
</description>
</method>
+ <method name="is_equal_approx">
+ <return type="bool">
+ </return>
+ <argument index="0" name="transform" type="Transform">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="looking_at">
<return type="Transform">
</return>
diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml
index 580da080b3..89ccffc2e9 100644
--- a/doc/classes/Transform2D.xml
+++ b/doc/classes/Transform2D.xml
@@ -106,6 +106,14 @@
Returns the inverse of the transform, under the assumption that the transformation is composed of rotation and translation (no scaling, use affine_inverse for transforms with scaling).
</description>
</method>
+ <method name="is_equal_approx">
+ <return type="bool">
+ </return>
+ <argument index="0" name="transform" type="Transform2D">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="orthonormalized">
<return type="Transform2D">
</return>
diff --git a/doc/classes/Variant.xml b/doc/classes/Variant.xml
index 522e131b45..9d55f5846f 100644
--- a/doc/classes/Variant.xml
+++ b/doc/classes/Variant.xml
@@ -4,7 +4,37 @@
The most important data type in Godot.
</brief_description>
<description>
+ In computer programming, a Variant class is a class that is designed to store a variety of other types. Dynamic programming languages like PHP, Lua, JavaScript and GDScript like to use them to store variables' data on the backend. With these Variants, properties are able to change value types freely.
+ [codeblock]
+ var foo = 2 # foo is dynamically an integer
+ foo = "Now foo is a string!"
+ foo = Reference.new() # foo is an Object
+ var bar: int = 2 # bar is a statically typed integer.
+ # bar = "Uh oh! I can't make static variables become a different type!"
+ [/codeblock]
+ Godot tracks all scripting API variables within Variants. Without even realizing it, you use Variants all the time. When a particular language enforces its own rules for keeping data typed, then that language is applying its own custom logic over the base Variant scripting API.
+ - GDScript automatically wrap values in them. It keeps all data in plain Variants by default and then optionally enforces custom static typing rules on variable types.
+ - VisualScript tracks properties inside Variants as well, but it also uses static typing. The GUI interface enforces that properties have a particular type that doesn't change over time.
+ - C# is statically typed, but uses the Mono [code]object[/code] type in place of Godot's Variant class when it needs to represent a dynamic value. [code]object[/code] is the Mono runtime's equivalent of the same concept.
+ - The statically-typed language NativeScript C++ does not define a built-in Variant-like class. Godot's GDNative bindings provide their own godot::Variant class for users; Any point at which the C++ code starts interacting with the Godot runtime is a place where you might have to start wrapping data inside Variant objects.
+ The global [method @GDScript.typeof] function returns the enumerated value of the Variant type stored in the current variable. These correspond to [code]TYPE_*[/code] constants in the [@GlobalScope] docs.
+ [codeblock]
+ var foo = 2
+ match typeof(foo):
+ TYPE_NIL:
+ print("foo is null")
+ TYPE_INTEGER:
+ print("foo is an integer")
+ TYPE_OBJECT:
+ # Note that Objects are their own special category.
+ # To get the name of the underlying Object type, you need the `get_class()` method.
+ print("foo is a(n) %s" % foo.get_class()) # inject the class name into a formatted string.
+ # Note also that there is not yet any way to get a script's `class_name` string easily.
+ # To fetch that value, you need to dig deeply into a hidden ProjectSettings setting: an Array of Dictionaries called "_global_script_classes".
+ # Open your project.godot file to see it up close.
+ [/codeblock]
A Variant takes up only 20 bytes and can store almost any engine datatype inside of it. Variants are rarely used to hold information for long periods of time. Instead, they are used mainly for communication, editing, serialization and moving data around.
+ Godot has specifically invested in making its Variant class as flexible as possible; so much so that it is used for a multitude of operations to facilitate communication between all of Godot's systems.
A Variant:
- Can store almost any datatype.
- Can perform operations between many variants. GDScript uses Variant as its atomic/native datatype.
@@ -16,10 +46,11 @@
- Can be serialized to text and use it for printing values and editable settings.
- Can work as an exported property, so the editor can edit it universally.
- Can be used for dictionaries, arrays, parsers, etc.
- [b]Containers ([Array] and [Dictionary]):[/b] Both are implemented using variants. A [Dictionary] can match any datatype used as key to any other datatype. An [Array] just holds an array of Variants. Of course, a Variant can also hold a [Dictionary] and an [Array] inside, making it even more flexible.
+ [b]Containers (Array and Dictionary):[/b] Both are implemented using variants. A [Dictionary] can match any datatype used as key to any other datatype. An [Array] just holds an array of Variants. Of course, a Variant can also hold a [Dictionary] and an [Array] inside, making it even more flexible.
Modifications to a container will modify all references to it. A [Mutex] should be created to lock it if multi-threaded access is desired.
</description>
<tutorials>
+ <link>https://docs.godotengine.org/en/latest/development/cpp/variant_class.html</link>
</tutorials>
<methods>
</methods>
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 987ed9867b..8ae5caf68c 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -153,6 +153,14 @@
Returns the vector with all components rounded down.
</description>
</method>
+ <method name="is_equal_approx">
+ <return type="bool">
+ </return>
+ <argument index="0" name="v" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="is_normalized">
<return type="bool">
</return>
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index 05ce6c43ae..29c24709e2 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -129,6 +129,14 @@
Returns the inverse of the vector. This is the same as [code]Vector3( 1.0 / v.x, 1.0 / v.y, 1.0 / v.z )[/code].
</description>
</method>
+ <method name="is_equal_approx">
+ <return type="bool">
+ </return>
+ <argument index="0" name="v" type="Vector3">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="is_normalized">
<return type="bool">
</return>
diff --git a/doc/classes/VisualShaderNodeInput.xml b/doc/classes/VisualShaderNodeInput.xml
index 302c8dff71..bfcd4c734c 100644
--- a/doc/classes/VisualShaderNodeInput.xml
+++ b/doc/classes/VisualShaderNodeInput.xml
@@ -7,6 +7,12 @@
<tutorials>
</tutorials>
<methods>
+ <method name="get_input_real_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="default_input_values" type="Array" setter="_set_default_input_values" getter="_get_default_input_values" override="true" default="[ ]" />
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index 16e5e92abd..e34705f7b7 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -494,10 +494,8 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
if (line->width <= 1) {
Vector2 verts[2] = {
- // Offset the line slightly to make sure we always draw the pixel at the from coordinate.
- // Without this, corners of rectangles might be missing a pixel. (See diamond exit rule and #32657)
- Vector2(Math::floor(line->from.x) + 0.5, Math::floor(line->from.y) + 0.5),
- Vector2(Math::floor(line->to.x) + 0.5, Math::floor(line->to.y) + 0.5)
+ Vector2(line->from.x, line->from.y),
+ Vector2(line->to.x, line->to.y)
};
#ifdef GLES_OVER_GL
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index f712219a64..6bcda62e7f 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -2767,6 +2767,8 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
if (use_post_process) {
next_buffer = storage->frame.current_rt->mip_maps[0].sizes[0].fbo;
+ } else if (storage->frame.current_rt->external.fbo != 0) {
+ next_buffer = storage->frame.current_rt->external.fbo;
} else {
// set next_buffer to front buffer so multisample blit can happen if needed
next_buffer = storage->frame.current_rt->fbo;
@@ -2795,9 +2797,15 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
// In GLES2 Android Blit is not available, so just copy color texture manually
_copy_texture_to_buffer(storage->frame.current_rt->multisample_color, next_buffer);
+#else
+ // TODO: any other platform not supported? this will fail.. maybe we should just call _copy_texture_to_buffer here as well?
#endif
} else if (use_post_process) {
- _copy_texture_to_buffer(storage->frame.current_rt->color, storage->frame.current_rt->mip_maps[0].sizes[0].fbo);
+ if (storage->frame.current_rt->external.fbo != 0) {
+ _copy_texture_to_buffer(storage->frame.current_rt->external.color, storage->frame.current_rt->mip_maps[0].sizes[0].fbo);
+ } else {
+ _copy_texture_to_buffer(storage->frame.current_rt->color, storage->frame.current_rt->mip_maps[0].sizes[0].fbo);
+ }
}
if (!use_post_process) {
@@ -3220,14 +3228,12 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
} else {
state.render_no_shadows = false;
- if (storage->frame.current_rt->external.fbo != 0) {
+ if (storage->frame.current_rt->multisample_active) {
+ current_fb = storage->frame.current_rt->multisample_fbo;
+ } else if (storage->frame.current_rt->external.fbo != 0) {
current_fb = storage->frame.current_rt->external.fbo;
} else {
- if (storage->frame.current_rt->multisample_active) {
- current_fb = storage->frame.current_rt->multisample_fbo;
- } else {
- current_fb = storage->frame.current_rt->fbo;
- }
+ current_fb = storage->frame.current_rt->fbo;
}
env = environment_owner.getornull(p_environment);
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 0f51d07b6e..9d9bceb243 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -4742,16 +4742,33 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
+ // Delete allocated resources and default to no MSAA
WARN_PRINT_ONCE("Cannot allocate back framebuffer for MSAA");
printf("err status: %x\n", status);
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ config.multisample_supported = false;
+ rt->multisample_active = false;
+
+ glDeleteFramebuffers(1, &rt->multisample_fbo);
+ rt->multisample_fbo = 0;
+
+ glDeleteRenderbuffers(1, &rt->multisample_depth);
+ rt->multisample_depth = 0;
+#ifdef ANDROID_ENABLED
+ glDeleteTextures(1, &rt->multisample_color);
+#else
+ glDeleteRenderbuffers(1, &rt->multisample_color);
+#endif
+ rt->multisample_color = 0;
}
glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+#ifdef ANDROID_ENABLED
+ glBindTexture(GL_TEXTURE_2D, 0);
+#endif
} else
-#endif
+#endif // JAVASCRIPT_ENABLED
{
rt->multisample_active = false;
}
@@ -4987,10 +5004,10 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) {
glDeleteRenderbuffers(1, &rt->multisample_depth);
rt->multisample_depth = 0;
-#ifdef GLES_OVER_GL
- glDeleteRenderbuffers(1, &rt->multisample_color);
-#else
+#ifdef ANDROID_ENABLED
glDeleteTextures(1, &rt->multisample_color);
+#else
+ glDeleteRenderbuffers(1, &rt->multisample_color);
#endif
rt->multisample_color = 0;
}
@@ -5731,14 +5748,20 @@ void RasterizerStorageGLES2::initialize() {
config.support_npot_repeat_mipmap = true;
config.depth_internalformat = GL_DEPTH_COMPONENT;
config.depth_type = GL_UNSIGNED_INT;
-
#else
config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float");
config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc");
config.etc1_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture") || config.extensions.has("WEBGL_compressed_texture_etc1");
config.pvrtc_supported = config.extensions.has("IMG_texture_compression_pvrtc") || config.extensions.has("WEBGL_compressed_texture_pvrtc");
config.support_npot_repeat_mipmap = config.extensions.has("GL_OES_texture_npot");
-
+ // on mobile check for 24 bit depth support
+ if (config.extensions.has("GL_OES_depth24")) {
+ config.depth_internalformat = _DEPTH_COMPONENT24_OES;
+ config.depth_type = GL_UNSIGNED_INT;
+ } else {
+ config.depth_internalformat = GL_DEPTH_COMPONENT16;
+ config.depth_type = GL_UNSIGNED_SHORT;
+ }
#endif
#ifndef GLES_OVER_GL
@@ -5815,7 +5838,7 @@ void RasterizerStorageGLES2::initialize() {
GLuint depth;
glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, 32, 32, 0, config.depth_internalformat, config.depth_type, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -5831,10 +5854,7 @@ void RasterizerStorageGLES2::initialize() {
glBindTexture(GL_TEXTURE_2D, 0);
glDeleteTextures(1, &depth);
- if (status == GL_FRAMEBUFFER_COMPLETE) {
- config.depth_internalformat = GL_DEPTH_COMPONENT;
- config.depth_type = GL_UNSIGNED_INT;
- } else {
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
// If it fails, test to see if it supports a framebuffer texture using UNSIGNED_SHORT
// This is needed because many OSX devices don't support either UNSIGNED_INT or UNSIGNED_SHORT
@@ -5867,15 +5887,6 @@ void RasterizerStorageGLES2::initialize() {
glBindTexture(GL_TEXTURE_2D, 0);
glDeleteTextures(1, &depth);
}
- } else {
- // Will use renderbuffer for depth, on mobile check for 24 bit depth support
- if (config.extensions.has("GL_OES_depth24")) {
- config.depth_internalformat = _DEPTH_COMPONENT24_OES;
- config.depth_type = GL_UNSIGNED_INT;
- } else {
- config.depth_internalformat = GL_DEPTH_COMPONENT16;
- config.depth_type = GL_UNSIGNED_SHORT;
- }
}
//picky requirements for these
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 1db8a870a2..7e9b6fdb82 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -809,15 +809,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += "else\n";
code += _dump_node_code(cf_node->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
}
- } else if (cf_node->flow_op == SL::FLOW_OP_SWITCH) {
- code += _mktab(p_level) + "switch (" + _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\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_CASE) {
- code += _mktab(p_level) + "case " + _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ":\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_DEFAULT) {
- code += _mktab(p_level) + "default:\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_DO) {
code += _mktab(p_level);
code += "do";
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index e09ba755ea..edffe852a2 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -548,10 +548,8 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
if (line->width <= 1) {
Vector2 verts[2] = {
- // Offset the line slightly to make sure we always draw the pixel at the from coordinate.
- // Without this, corners of rectangles might be missing a pixel. (See diamond exit rule and #32657)
- Vector2(Math::floor(line->from.x) + 0.5, Math::floor(line->from.y) + 0.5),
- Vector2(Math::floor(line->to.x) + 0.5, Math::floor(line->to.y) + 0.5)
+ Vector2(line->from.x, line->from.y),
+ Vector2(line->to.x, line->to.y)
};
#ifdef GLES_OVER_GL
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index 99425d5002..e3026f9fd9 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -275,6 +275,7 @@ void FileAccessUnix::store_8(uint8_t p_dest) {
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);
}
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 7183d34d4f..33f833afa4 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -5818,6 +5818,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
info_message->set_valign(Label::VALIGN_CENTER);
info_message->set_align(Label::ALIGN_CENTER);
info_message->set_autowrap(true);
+ info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
main_panel->add_child(info_message);
diff --git a/editor/array_property_edit.cpp b/editor/array_property_edit.cpp
index f2471e80d4..906139e239 100644
--- a/editor/array_property_edit.cpp
+++ b/editor/array_property_edit.cpp
@@ -267,9 +267,9 @@ void ArrayPropertyEdit::edit(Object *p_obj, const StringName &p_prop, const Stri
default_type = p_deftype;
if (!p_hint_string.empty()) {
- int hint_subtype_seperator = p_hint_string.find(":");
- if (hint_subtype_seperator >= 0) {
- String subtype_string = p_hint_string.substr(0, hint_subtype_seperator);
+ int hint_subtype_separator = p_hint_string.find(":");
+ if (hint_subtype_separator >= 0) {
+ String subtype_string = p_hint_string.substr(0, hint_subtype_separator);
int slash_pos = subtype_string.find("/");
if (slash_pos >= 0) {
@@ -277,7 +277,7 @@ void ArrayPropertyEdit::edit(Object *p_obj, const StringName &p_prop, const Stri
subtype_string = subtype_string.substr(0, slash_pos);
}
- subtype_hint_string = p_hint_string.substr(hint_subtype_seperator + 1, p_hint_string.size() - hint_subtype_seperator - 1);
+ subtype_hint_string = p_hint_string.substr(hint_subtype_separator + 1, p_hint_string.size() - hint_subtype_separator - 1);
subtype = Variant::Type(subtype_string.to_int());
}
}
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 5344658223..fb7cf494cd 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -151,6 +151,10 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
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))
return;
@@ -352,7 +356,12 @@ void CreateDialog::_update_search() {
} else {
bool found = false;
- String type2 = I->get();
+ String type2 = type;
+
+ if (!cpp_type && !search_loaded_scripts.has(type)) {
+ search_loaded_scripts[type] = ed.script_class_load_script(type);
+ }
+
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)) {
@@ -361,10 +370,15 @@ void CreateDialog::_update_search() {
}
type2 = cpp_type ? ClassDB::get_parent_class(type2) : ed.script_class_get_base(type2);
+
+ if (!cpp_type && !search_loaded_scripts.has(type2)) {
+ search_loaded_scripts[type2] = ed.script_class_load_script(type2);
+ }
}
- if (found)
- add_type(I->get(), search_options_types, root, &to_select);
+ if (found) {
+ add_type(type, search_options_types, root, &to_select);
+ }
}
if (EditorNode::get_editor_data().get_custom_types().has(type) && ClassDB::is_parent_class(type, base_type)) {
@@ -470,6 +484,7 @@ void CreateDialog::_notification(int p_what) {
} break;
case NOTIFICATION_POPUP_HIDE: {
EditorSettings::get_singleton()->get_project_metadata("dialog_bounds", "create_new_node", get_rect());
+ search_loaded_scripts.clear();
} break;
}
}
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index f3ed1d7af6..1150ac60da 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -51,6 +51,7 @@ class CreateDialog : public ConfirmationDialog {
LineEdit *search_box;
Tree *search_options;
HashMap<String, TreeItem *> search_options_types;
+ HashMap<String, RES> search_loaded_scripts;
bool is_replace_mode;
String base_type;
String preferred_search_result_type;
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index 8a03292708..f75d9c98e0 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -58,6 +58,7 @@ 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));
}
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index b331a39535..acfdea28e2 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -1329,7 +1329,8 @@ EditorAudioBuses::EditorAudioBuses() {
add_child(top_hb);
file = memnew(Label);
- file->set_text(String(TTR("Layout")) + ": " + "default_bus_layout.tres");
+ String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout");
+ file->set_text(String(TTR("Layout")) + ": " + layout_path.get_file());
file->set_clip_text(true);
file->set_h_size_flags(SIZE_EXPAND_FILL);
top_hb->add_child(file);
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 777eda2170..4855d3f69d 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -870,7 +870,7 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i
if (!ScriptServer::is_global_class(p_class))
return false;
String base = script_class_get_base(p_class);
- Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(p_class), "Script");
+ Ref<Script> script = script_class_load_script(p_class);
Ref<Script> base_script = script->get_base_script();
while (p_inherits != base) {
@@ -889,12 +889,7 @@ 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 {
- if (!ScriptServer::is_global_class(p_class))
- return StringName();
-
- String path = ScriptServer::get_global_class_path(p_class);
-
- Ref<Script> script = ResourceLoader::load(path, "Script");
+ Ref<Script> script = script_class_load_script(p_class);
if (script.is_null())
return StringName();
@@ -910,7 +905,7 @@ Object *EditorData::script_class_instance(const String &p_class) {
if (ScriptServer::is_global_class(p_class)) {
Object *obj = ClassDB::instance(ScriptServer::get_global_class_native_base(p_class));
if (obj) {
- RES script = ResourceLoader::load(ScriptServer::get_global_class_path(p_class));
+ Ref<Script> script = script_class_load_script(p_class);
if (script.is_valid())
obj->set_script(script.get_ref_ptr());
return obj;
@@ -919,6 +914,15 @@ Object *EditorData::script_class_instance(const String &p_class) {
return NULL;
}
+Ref<Script> EditorData::script_class_load_script(const String &p_class) const {
+
+ if (!ScriptServer::is_global_class(p_class))
+ return Ref<Script>();
+
+ String path = ScriptServer::get_global_class_path(p_class);
+ return ResourceLoader::load(path, "Script");
+}
+
void EditorData::script_class_set_icon_path(const String &p_class, const String &p_icon_path) {
_script_class_icon_paths[p_class] = p_icon_path;
}
@@ -1142,6 +1146,16 @@ List<Node *> &EditorSelection::get_selected_node_list() {
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());
+ }
+
+ return node_list;
+}
+
void EditorSelection::clear() {
while (!selection.empty()) {
diff --git a/editor/editor_data.h b/editor/editor_data.h
index df83135942..aa3e84d5a4 100644
--- a/editor/editor_data.h
+++ b/editor/editor_data.h
@@ -219,6 +219,8 @@ public:
StringName script_class_get_base(const String &p_class) const;
Object *script_class_instance(const String &p_class);
+ Ref<Script> script_class_load_script(const String &p_class) const;
+
StringName script_class_get_name(const String &p_path) const;
void script_class_set_name(const String &p_path, const StringName &p_class);
@@ -273,6 +275,7 @@ public:
void clear();
List<Node *> &get_selected_node_list();
+ List<Node *> get_full_selected_node_list();
Map<Node *, Object *> &get_selection() { return selection; }
EditorSelection();
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index 3663bdee27..2467e1f722 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -325,14 +325,12 @@ void EditorFileSystem::_save_filesystem_cache() {
String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME);
FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE);
- if (f == NULL) {
- ERR_PRINTS("Error writing fscache '" + fscache + "'.");
- } else {
- f->store_line(filesystem_settings_version_for_import);
- _save_filesystem_cache(filesystem, f);
- f->close();
- memdelete(f);
- }
+ ERR_FAIL_COND_MSG(!f, "Cannot create file '" + fscache + "'. Check user write permissions.");
+
+ f->store_line(filesystem_settings_version_for_import);
+ _save_filesystem_cache(filesystem, f);
+ f->close();
+ memdelete(f);
}
void EditorFileSystem::_thread_func(void *_userdata) {
@@ -1373,6 +1371,7 @@ void EditorFileSystem::_save_late_updated_files() {
//files that already existed, and were modified, need re-scanning for dependencies upon project restart. This is done via saving this special file
String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update4");
FileAccessRef f = FileAccess::open(fscache, FileAccess::WRITE);
+ ERR_FAIL_COND_MSG(!f, "Cannot create file '" + fscache + "'. Check user write permissions.");
for (Set<String>::Element *E = late_update_files.front(); E; E = E->next()) {
f->store_line(E->get());
}
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index d2306abfd7..dd49e38d7f 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -1224,11 +1224,18 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
Ref<Font> doc_font = p_rt->get_font("doc", "EditorFonts");
Ref<Font> doc_bold_font = p_rt->get_font("doc_bold", "EditorFonts");
Ref<Font> doc_code_font = p_rt->get_font("doc_source", "EditorFonts");
+
Color font_color_hl = p_rt->get_color("headline_color", "EditorHelp");
- Color link_color = p_rt->get_color("accent_color", "Editor").linear_interpolate(font_color_hl, 0.8);
+ Color accent_color = p_rt->get_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);
String bbcode = p_bbcode.dedent().replace("\t", "").replace("\r", "").strip_edges();
+ // remove extra new lines around code blocks
+ bbcode = bbcode.replace("[codeblock]\n", "[codeblock]");
+ bbcode = bbcode.replace("\n[/codeblock]", "[/codeblock]");
+
List<String> tag_stack;
bool code_tag = false;
@@ -1276,9 +1283,14 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
tag_stack.pop_front();
pos = brk_end + 1;
- code_tag = false;
- if (tag != "/img")
+ if (tag != "/img") {
p_rt->pop();
+ if (code_tag) {
+ p_rt->pop();
+ }
+ }
+ code_tag = false;
+
} else if (code_tag) {
p_rt->add_text("[");
@@ -1323,6 +1335,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
//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);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 9fa33044e1..d42345d9a2 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5171,14 +5171,20 @@ void EditorNode::_open_imported() {
}
void EditorNode::dim_editor(bool p_dimming, bool p_force_dim) {
- // Dimming can be forced regardless of the editor setting, which is useful when quitting the editor
+ // Dimming can be forced regardless of the editor setting, which is useful when quitting the editor.
if ((p_force_dim || EditorSettings::get_singleton()->get("interface/editor/dim_editor_on_dialog_popup")) && p_dimming) {
+ dimmed = true;
gui_base->set_modulate(Color(0.5, 0.5, 0.5));
} else {
+ dimmed = false;
gui_base->set_modulate(Color(1, 1, 1));
}
}
+bool EditorNode::is_editor_dimmed() const {
+ return dimmed;
+}
+
void EditorNode::open_export_template_manager() {
export_template_manager->popup_manager();
@@ -5487,6 +5493,7 @@ EditorNode::EditorNode() {
singleton = this;
exiting = false;
+ dimmed = false;
last_checked_version = 0;
changing_scene = false;
_initializing_addons = false;
diff --git a/editor/editor_node.h b/editor/editor_node.h
index fb7e81d2d2..b7775b5e83 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -260,6 +260,7 @@ private:
int tab_closing;
bool exiting;
+ bool dimmed;
int old_split_ofs;
VSplitContainer *top_split;
@@ -850,6 +851,7 @@ public:
void restart_editor();
void dim_editor(bool p_dimming, bool p_force_dim = false);
+ bool is_editor_dimmed() const;
void edit_current() { _edit_current(); };
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index d3d91e6e0d..e14beabfa2 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -1884,6 +1884,23 @@ 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();
+
+ // Add a tooltip to display each channel's values without having to click the ColorPickerButton
+ if (picker->is_editing_alpha()) {
+ picker->set_tooltip(vformat(
+ "R: %s\nG: %s\nB: %s\nA: %s",
+ rtos(color.r).pad_decimals(2),
+ rtos(color.g).pad_decimals(2),
+ rtos(color.b).pad_decimals(2),
+ rtos(color.a).pad_decimals(2)));
+ } else {
+ picker->set_tooltip(vformat(
+ "R: %s\nG: %s\nB: %s",
+ rtos(color.r).pad_decimals(2),
+ rtos(color.g).pad_decimals(2),
+ rtos(color.b).pad_decimals(2)));
+ }
}
void EditorPropertyColor::setup(bool p_show_alpha) {
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index 8abe91bdc1..c75b66c601 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -475,16 +475,16 @@ void EditorPropertyArray::setup(Variant::Type p_array_type, const String &p_hint
array_type = p_array_type;
if (array_type == Variant::ARRAY && !p_hint_string.empty()) {
- int hint_subtype_seperator = p_hint_string.find(":");
- if (hint_subtype_seperator >= 0) {
- String subtype_string = p_hint_string.substr(0, hint_subtype_seperator);
+ int hint_subtype_separator = p_hint_string.find(":");
+ if (hint_subtype_separator >= 0) {
+ String subtype_string = p_hint_string.substr(0, hint_subtype_separator);
int slash_pos = subtype_string.find("/");
if (slash_pos >= 0) {
subtype_hint = PropertyHint(subtype_string.substr(slash_pos + 1, subtype_string.size() - slash_pos - 1).to_int());
subtype_string = subtype_string.substr(0, slash_pos);
}
- subtype_hint_string = p_hint_string.substr(hint_subtype_seperator + 1, p_hint_string.size() - hint_subtype_seperator - 1);
+ subtype_hint_string = p_hint_string.substr(hint_subtype_separator + 1, p_hint_string.size() - hint_subtype_separator - 1);
subtype = Variant::Type(subtype_string.to_int());
}
}
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index 65a1704770..55f9347045 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -201,9 +201,8 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<
if (has_small_texture) {
ResourceSaver::save(cache_base + "_small.png", r_small_texture);
}
- Error err;
- FileAccess *f = FileAccess::open(cache_base + ".txt", FileAccess::WRITE, &err);
- ERR_FAIL_COND_MSG(err != OK, "Cannot create file '" + cache_base + ".txt'.");
+ FileAccess *f = FileAccess::open(cache_base + ".txt", FileAccess::WRITE);
+ ERR_FAIL_COND_MSG(!f, "Cannot create file '" + cache_base + ".txt'. Check user write permissions.");
f->store_line(itos(thumbnail_size));
f->store_line(itos(has_small_texture));
f->store_line(itos(FileAccess::get_modified_time(p_item.path)));
@@ -295,11 +294,17 @@ void EditorResourcePreview::_thread() {
//update modified time
f = FileAccess::open(file, FileAccess::WRITE);
- f->store_line(itos(thumbnail_size));
- f->store_line(itos(has_small_texture));
- f->store_line(itos(modtime));
- f->store_line(md5);
- memdelete(f);
+ if (!f) {
+ // Not returning as this would leave the thread hanging and would require
+ // some proper cleanup/disabling of resource preview generation.
+ ERR_PRINTS("Cannot create file '" + file + "'. Check user write permissions.");
+ } else {
+ f->store_line(itos(thumbnail_size));
+ f->store_line(itos(has_small_texture));
+ f->store_line(itos(modtime));
+ f->store_line(md5);
+ memdelete(f);
+ }
}
} else {
memdelete(f);
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index d80176f00d..fbc4a5ee5c 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -112,7 +112,7 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
if (mm->get_control()) {
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 * 10);
+ set_value(pre_grab_value + get_step() * grabbing_spinner_dist_cache);
}
}
} else if (updown_offset != -1) {
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index a49c3eac73..f05c7709d4 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1089,7 +1089,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("port", "GraphNode", theme->get_icon("GuiGraphNodePort", "EditorIcons"));
// GridContainer
- theme->set_constant("vseperation", "GridContainer", (extra_spacing + default_margin_size) * EDSCALE);
+ theme->set_constant("vseparation", "GridContainer", (extra_spacing + default_margin_size) * EDSCALE);
// FileDialog
theme->set_icon("folder", "FileDialog", theme->get_icon("Folder", "EditorIcons"));
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index fa171ddb0c..5409ef65ea 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -71,11 +71,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
subdirectory_item->select(0);
}
- if ((path.begins_with(lpath) && path != lpath)) {
- subdirectory_item->set_collapsed(false);
- } else {
- subdirectory_item->set_collapsed(uncollapsed_paths.find(lpath) < 0);
- }
+ subdirectory_item->set_collapsed(uncollapsed_paths.find(lpath) < 0);
if (searched_string.length() > 0 && dname.to_lower().find(searched_string) >= 0) {
parent_should_expand = true;
}
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index 4cefb53617..74d81bf561 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -529,6 +529,7 @@ GroupDialog::GroupDialog() {
group_empty->set_valign(Label::VALIGN_CENTER);
group_empty->set_align(Label::ALIGN_CENTER);
group_empty->set_autowrap(true);
+ group_empty->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
nodes_to_remove->add_child(group_empty);
group_empty->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index bc22d9315e..ce400ad6dd 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -1117,15 +1117,17 @@ void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) {
undo_redo->add_do_method(this, "_update_graph");
undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
+ name_edit->hide();
updating = false;
state_machine_draw->update();
-
- name_edit->hide();
}
void AnimationNodeStateMachineEditor::_name_edited_focus_out() {
+ if (updating)
+ return;
+
_name_edited(name_edit->get_text());
}
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 9dd6c600bf..9e338186f2 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -70,11 +70,15 @@ class SnapDialog : public ConfirmationDialog {
SpinBox *primary_grid_steps;
SpinBox *rotation_offset;
SpinBox *rotation_step;
+ SpinBox *scale_step;
public:
SnapDialog() {
const int SPIN_BOX_GRID_RANGE = 16384;
const int SPIN_BOX_ROTATION_RANGE = 360;
+ const float SPIN_BOX_SCALE_MIN = 0.01f;
+ const float SPIN_BOX_SCALE_MAX = 100;
+
Label *label;
VBoxContainer *container;
GridContainer *child_container;
@@ -133,8 +137,12 @@ public:
grid_step_y->set_h_size_flags(SIZE_EXPAND_FILL);
child_container->add_child(grid_step_y);
+ child_container = memnew(GridContainer);
+ child_container->set_columns(2);
+ container->add_child(child_container);
+
label = memnew(Label);
- label->set_text(TTR("Primary Line Every"));
+ label->set_text(TTR("Primary Line Every:"));
label->set_h_size_flags(SIZE_EXPAND_FILL);
child_container->add_child(label);
@@ -143,16 +151,14 @@ public:
primary_grid_steps->set_step(1);
primary_grid_steps->set_max(100);
primary_grid_steps->set_allow_greater(true);
+ primary_grid_steps->set_suffix(TTR("steps"));
primary_grid_steps->set_h_size_flags(SIZE_EXPAND_FILL);
child_container->add_child(primary_grid_steps);
- label = memnew(Label);
- label->set_text(TTR("steps"));
- label->set_h_size_flags(SIZE_EXPAND_FILL);
- child_container->add_child(label);
-
container->add_child(memnew(HSeparator));
+ // We need to create another GridContainer with the same column count,
+ // so we can put an HSeparator above
child_container = memnew(GridContainer);
child_container->set_columns(2);
container->add_child(child_container);
@@ -180,9 +186,27 @@ public:
rotation_step->set_suffix("deg");
rotation_step->set_h_size_flags(SIZE_EXPAND_FILL);
child_container->add_child(rotation_step);
+
+ container->add_child(memnew(HSeparator));
+
+ child_container = memnew(GridContainer);
+ child_container->set_columns(2);
+ container->add_child(child_container);
+ label = memnew(Label);
+ label->set_text(TTR("Scale Step:"));
+ child_container->add_child(label);
+ label->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ scale_step = memnew(SpinBox);
+ scale_step->set_min(SPIN_BOX_SCALE_MIN);
+ scale_step->set_max(SPIN_BOX_SCALE_MAX);
+ scale_step->set_allow_greater(true);
+ scale_step->set_h_size_flags(SIZE_EXPAND_FILL);
+ scale_step->set_step(0.01f);
+ child_container->add_child(scale_step);
}
- void set_fields(const Point2 p_grid_offset, const Point2 p_grid_step, const int p_primary_grid_steps, const float p_rotation_offset, const float p_rotation_step) {
+ void set_fields(const Point2 p_grid_offset, const Point2 p_grid_step, const int p_primary_grid_steps, const float p_rotation_offset, const float p_rotation_step, const float p_scale_step) {
grid_offset_x->set_value(p_grid_offset.x);
grid_offset_y->set_value(p_grid_offset.y);
grid_step_x->set_value(p_grid_step.x);
@@ -190,14 +214,16 @@ public:
primary_grid_steps->set_value(p_primary_grid_steps);
rotation_offset->set_value(p_rotation_offset * (180 / Math_PI));
rotation_step->set_value(p_rotation_step * (180 / Math_PI));
+ scale_step->set_value(p_scale_step);
}
- void get_fields(Point2 &p_grid_offset, Point2 &p_grid_step, int &p_primary_grid_steps, float &p_rotation_offset, float &p_rotation_step) {
+ void get_fields(Point2 &p_grid_offset, Point2 &p_grid_step, int &p_primary_grid_steps, float &p_rotation_offset, float &p_rotation_step, float &p_scale_step) {
p_grid_offset = Point2(grid_offset_x->get_value(), grid_offset_y->get_value());
p_grid_step = Point2(grid_step_x->get_value(), grid_step_y->get_value());
p_primary_grid_steps = int(primary_grid_steps->get_value());
p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI);
p_rotation_step = rotation_step->get_value() / (180 / Math_PI);
+ p_scale_step = scale_step->get_value();
}
};
@@ -919,7 +945,7 @@ void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_ite
}
void CanvasItemEditor::_snap_changed() {
- ((SnapDialog *)snap_dialog)->get_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step);
+ ((SnapDialog *)snap_dialog)->get_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step, snap_scale_step);
grid_step_multiplier = 0;
viewport->update();
}
@@ -1201,8 +1227,8 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo
}
if (panning) {
- if (!b->is_pressed()) {
- // Stop panning the viewport (for any mouse button press)
+ if (!b->is_pressed() && (pan_on_scroll || (b->get_button_index() != BUTTON_WHEEL_DOWN && b->get_button_index() != BUTTON_WHEEL_UP))) {
+ // Stop panning the viewport (for any mouse button press except zooming)
panning = false;
}
}
@@ -1289,6 +1315,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) {
// Start dragging if we still have nodes
if (drag_selection.size() > 0) {
+ _save_canvas_item_state(drag_selection);
drag_from = transform.affine_inverse().xform((b.is_valid()) ? b->get_position() : viewport->get_local_mouse_position());
Vector2 new_pos;
if (drag_selection.size() == 1) {
@@ -1302,7 +1329,6 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) {
}
drag_type = DRAG_PIVOT;
- _save_canvas_item_state(drag_selection);
}
return true;
}
@@ -1850,6 +1876,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 = 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);
@@ -1880,6 +1907,12 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
}
}
}
+
+ if (snap_scale && !is_ctrl) {
+ scale.x = roundf(scale.x / snap_scale_step) * snap_scale_step;
+ scale.y = roundf(scale.y / snap_scale_step) * snap_scale_step;
+ }
+
canvas_item->call("set_scale", scale);
return true;
}
@@ -3778,6 +3811,7 @@ void CanvasItemEditor::_notification(int p_what) {
grid_snap_button->set_icon(get_icon("SnapGrid", "EditorIcons"));
snap_config_menu->set_icon(get_icon("GuiTabMenu", "EditorIcons"));
skeleton_menu->set_icon(get_icon("Bone", "EditorIcons"));
+ override_camera_button->set_icon(get_icon("Camera2D", "EditorIcons"));
pan_button->set_icon(get_icon("ToolPan", "EditorIcons"));
ruler_button->set_icon(get_icon("Ruler", "EditorIcons"));
pivot_button->set_icon(get_icon("EditPivot", "EditorIcons"));
@@ -3847,6 +3881,15 @@ void CanvasItemEditor::_notification(int p_what) {
anchor_mode_button->set_icon(get_icon("Anchor", "EditorIcons"));
}
+
+ if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ if (!is_visible() && override_camera_button->is_pressed()) {
+ ScriptEditorDebugger *debugger = ScriptEditor::get_singleton()->get_debugger();
+
+ debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
+ override_camera_button->set_pressed(false);
+ }
+ }
}
void CanvasItemEditor::_selection_changed() {
@@ -4188,6 +4231,15 @@ void CanvasItemEditor::_button_toggle_grid_snap(bool p_status) {
grid_snap_active = p_status;
viewport->update();
}
+void CanvasItemEditor::_button_override_camera(bool p_pressed) {
+ ScriptEditorDebugger *debugger = ScriptEditor::get_singleton()->get_debugger();
+
+ if (p_pressed) {
+ debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_2D);
+ } else {
+ debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
+ }
+}
void CanvasItemEditor::_button_tool_select(int p_index) {
@@ -4285,6 +4337,17 @@ void CanvasItemEditor::_button_toggle_anchor_mode(bool p_status) {
viewport->update();
}
+void CanvasItemEditor::_update_override_camera_button(bool p_game_running) {
+ if (p_game_running) {
+ override_camera_button->set_disabled(false);
+ override_camera_button->set_tooltip(TTR("Game camera override\nOverrides game camera with editor viewport camera."));
+ } else {
+ override_camera_button->set_disabled(true);
+ override_camera_button->set_pressed(false);
+ override_camera_button->set_tooltip(TTR("Game camera override\nNo game instance running."));
+ }
+}
+
void CanvasItemEditor::_popup_callback(int p_op) {
last_option = MenuOption(p_op);
@@ -4349,6 +4412,11 @@ void CanvasItemEditor::_popup_callback(int p_op) {
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation);
} break;
+ case SNAP_USE_SCALE: {
+ snap_scale = !snap_scale;
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_SCALE);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_scale);
+ } break;
case SNAP_RELATIVE: {
snap_relative = !snap_relative;
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE);
@@ -4361,7 +4429,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
snap_config_menu->get_popup()->set_item_checked(idx, snap_pixel);
} break;
case SNAP_CONFIGURE: {
- ((SnapDialog *)snap_dialog)->set_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step);
+ ((SnapDialog *)snap_dialog)->set_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step, snap_scale_step);
snap_dialog->popup_centered(Size2(220, 160) * EDSCALE);
} break;
case SKELETON_SHOW_BONES: {
@@ -4877,6 +4945,8 @@ void CanvasItemEditor::_bind_methods() {
ClassDB::bind_method("_button_zoom_plus", &CanvasItemEditor::_button_zoom_plus);
ClassDB::bind_method("_button_toggle_smart_snap", &CanvasItemEditor::_button_toggle_smart_snap);
ClassDB::bind_method("_button_toggle_grid_snap", &CanvasItemEditor::_button_toggle_grid_snap);
+ ClassDB::bind_method(D_METHOD("_button_override_camera", "pressed"), &CanvasItemEditor::_button_override_camera);
+ ClassDB::bind_method(D_METHOD("_update_override_camera_button", "game_running"), &CanvasItemEditor::_update_override_camera_button);
ClassDB::bind_method("_button_toggle_anchor_mode", &CanvasItemEditor::_button_toggle_anchor_mode);
ClassDB::bind_method("_update_scroll", &CanvasItemEditor::_update_scroll);
ClassDB::bind_method("_update_scrollbars", &CanvasItemEditor::_update_scrollbars);
@@ -4912,6 +4982,7 @@ Dictionary CanvasItemEditor::get_state() const {
state["primary_grid_steps"] = primary_grid_steps;
state["snap_rotation_offset"] = snap_rotation_offset;
state["snap_rotation_step"] = snap_rotation_step;
+ state["snap_scale_step"] = snap_scale_step;
state["smart_snap_active"] = smart_snap_active;
state["grid_snap_active"] = grid_snap_active;
state["snap_node_parent"] = snap_node_parent;
@@ -4929,6 +5000,7 @@ Dictionary CanvasItemEditor::get_state() const {
state["show_zoom_control"] = zoom_hb->is_visible();
state["show_edit_locks"] = show_edit_locks;
state["snap_rotation"] = snap_rotation;
+ state["snap_scale"] = snap_scale;
state["snap_relative"] = snap_relative;
state["snap_pixel"] = snap_pixel;
state["skeleton_show_bones"] = skeleton_show_bones;
@@ -4970,6 +5042,10 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
snap_rotation_offset = state["snap_rotation_offset"];
}
+ if (state.has("snap_scale_step")) {
+ snap_scale_step = state["snap_scale_step"];
+ }
+
if (state.has("smart_snap_active")) {
smart_snap_active = state["smart_snap_active"];
smart_snap_button->set_pressed(smart_snap_active);
@@ -5070,6 +5146,12 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation);
}
+ if (state.has("snap_scale")) {
+ snap_scale = state["snap_scale"];
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_SCALE);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_scale);
+ }
+
if (state.has("snap_relative")) {
snap_relative = state["snap_relative"];
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE);
@@ -5155,6 +5237,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
grid_step_multiplier = 0;
snap_rotation_offset = 0;
snap_rotation_step = 15 / (180 / Math_PI);
+ snap_scale_step = 0.1f;
smart_snap_active = false;
grid_snap_active = false;
snap_node_parent = true;
@@ -5195,6 +5278,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
editor_selection->connect("selection_changed", this, "update");
editor_selection->connect("selection_changed", this, "_selection_changed");
+ editor->call_deferred("connect", "play_pressed", this, "_update_override_camera_button", make_binds(true));
+ editor->call_deferred("connect", "stop_pressed", this, "_update_override_camera_button", make_binds(false));
+
hb = memnew(HBoxContainer);
add_child(hb);
hb->set_anchors_and_margins_preset(Control::PRESET_WIDE);
@@ -5377,6 +5463,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->connect("id_pressed", this, "_popup_callback");
p->set_hide_on_checkable_item_selection(false);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_scale_snap", TTR("Use Scale Snap")), SNAP_USE_SCALE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL);
p->add_submenu_item(TTR("Smart Snapping"), "SmartSnapping");
@@ -5439,6 +5526,15 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
hb->add_child(memnew(VSeparator));
+ override_camera_button = memnew(ToolButton);
+ hb->add_child(override_camera_button);
+ override_camera_button->connect("toggled", this, "_button_override_camera");
+ override_camera_button->set_toggle_mode(true);
+ override_camera_button->set_disabled(true);
+ _update_override_camera_button(false);
+
+ hb->add_child(memnew(VSeparator));
+
view_menu = memnew(MenuButton);
view_menu->set_text(TTR("View"));
hb->add_child(view_menu);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 35efc14b5e..3fdf00d611 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -108,6 +108,7 @@ private:
SNAP_USE_GRID,
SNAP_USE_GUIDES,
SNAP_USE_ROTATION,
+ SNAP_USE_SCALE,
SNAP_RELATIVE,
SNAP_CONFIGURE,
SNAP_USE_PIXEL,
@@ -260,6 +261,7 @@ private:
float snap_rotation_step;
float snap_rotation_offset;
+ float snap_scale_step;
bool smart_snap_active;
bool grid_snap_active;
@@ -270,6 +272,7 @@ private:
bool snap_other_nodes;
bool snap_guides;
bool snap_rotation;
+ bool snap_scale;
bool snap_relative;
bool snap_pixel;
bool skeleton_show_bones;
@@ -361,6 +364,7 @@ private:
ToolButton *ungroup_button;
MenuButton *skeleton_menu;
+ ToolButton *override_camera_button;
MenuButton *view_menu;
HBoxContainer *animation_hb;
MenuButton *animation_menu;
@@ -534,8 +538,11 @@ private:
void _button_zoom_plus();
void _button_toggle_smart_snap(bool p_status);
void _button_toggle_grid_snap(bool p_status);
+ void _button_override_camera(bool p_pressed);
void _button_tool_select(int p_index);
+ void _update_override_camera_button(bool p_game_running);
+
HSplitContainer *palette_split;
VSplitContainer *bottom_split;
diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp
index 635b934333..22df8fd8f4 100644
--- a/editor/plugins/mesh_instance_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_editor_plugin.cpp
@@ -180,6 +180,7 @@ void MeshInstanceEditor::_menu_option(int p_option) {
CollisionShape *cshape = memnew(CollisionShape);
cshape->set_shape(shapes[i]);
+ cshape->set_transform(node->get_transform());
Node *owner = node->get_owner();
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 603a2365c1..f63445dab8 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -571,6 +571,7 @@ void ScriptTextEditor::_validate_script() {
String error_text = "error(" + itos(line) + "," + itos(col) + "): " + errortxt;
code_editor->set_error(error_text);
code_editor->set_error_pos(line - 1, col - 1);
+ script_is_valid = false;
} else {
code_editor->set_error("");
line = -1;
@@ -585,6 +586,7 @@ void ScriptTextEditor::_validate_script() {
functions.push_back(E->get());
}
+ script_is_valid = true;
}
_update_connected_methods();
@@ -967,7 +969,7 @@ void ScriptTextEditor::_update_connected_methods() {
text_edit->clear_info_icons();
missing_connections.clear();
- if (!script->is_valid()) {
+ if (!script_is_valid) {
return;
}
@@ -1000,10 +1002,18 @@ void ScriptTextEditor::_update_connected_methods() {
if (!ClassDB::has_method(script->get_instance_base_type(), connection.method)) {
int line = -1;
- if (script->has_method(connection.method)) {
- line = script->get_member_line(connection.method);
- text_edit->set_line_info_icon(line - 1, get_parent_control()->get_icon("Slot", "EditorIcons"), connection.method);
- methods_found.insert(connection.method);
+
+ for (int j = 0; j < functions.size(); j++) {
+ String name = functions[j].get_slice(":", 0);
+ if (name == connection.method) {
+ line = functions[j].get_slice(":", 1).to_int();
+ text_edit->set_line_info_icon(line - 1, get_parent_control()->get_icon("Slot", "EditorIcons"), connection.method);
+ methods_found.insert(connection.method);
+ break;
+ }
+ }
+
+ if (line >= 0) {
continue;
}
@@ -1728,6 +1738,7 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
ScriptTextEditor::ScriptTextEditor() {
theme_loaded = false;
+ script_is_valid = false;
VSplitContainer *editor_box = memnew(VSplitContainer);
add_child(editor_box);
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index eba75befd4..2ba0be8feb 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -59,6 +59,7 @@ class ScriptTextEditor : public ScriptEditorBase {
RichTextLabel *warnings_panel;
Ref<Script> script;
+ bool script_is_valid;
Vector<String> functions;
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index eb39496106..ef99256081 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -901,6 +901,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid()) {
+ emit_signal("clicked", this);
+
float zoom_factor = 1 + (ZOOM_MULTIPLIER - 1) * b->get_factor();
switch (b->get_button_index()) {
@@ -3101,6 +3103,7 @@ void SpatialEditorViewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpatialEditorViewport::drop_data_fw);
ADD_SIGNAL(MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")));
+ ADD_SIGNAL(MethodInfo("clicked", PropertyInfo(Variant::OBJECT, "viewport")));
}
void SpatialEditorViewport::reset() {
@@ -4373,6 +4376,19 @@ void SpatialEditor::_menu_item_toggled(bool pressed, int p_option) {
tool_option_button[TOOL_OPT_USE_SNAP]->set_pressed(pressed);
snap_enabled = pressed;
} break;
+
+ case MENU_TOOL_OVERRIDE_CAMERA: {
+ ScriptEditorDebugger *const debugger = ScriptEditor::get_singleton()->get_debugger();
+
+ if (pressed) {
+ using Override = ScriptEditorDebugger::CameraOverride;
+
+ debugger->set_camera_override((Override)(Override::OVERRIDE_3D_1 + camera_override_viewport_id));
+ } else {
+ debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
+ }
+
+ } break;
}
}
@@ -4400,6 +4416,35 @@ void SpatialEditor::_menu_gizmo_toggled(int p_option) {
update_all_gizmos();
}
+void SpatialEditor::_update_camera_override_button(bool p_game_running) {
+ Button *const button = tool_option_button[TOOL_OPT_OVERRIDE_CAMERA];
+
+ if (p_game_running) {
+ button->set_disabled(false);
+ button->set_tooltip(TTR("Game camera override\nNo game instance running."));
+ } else {
+ button->set_disabled(true);
+ button->set_pressed(false);
+ button->set_tooltip(TTR("Game camera override\nOverrides game camera with editor viewport camera."));
+ }
+}
+
+void SpatialEditor::_update_camera_override_viewport(Object *p_viewport) {
+ SpatialEditorViewport *current_viewport = Object::cast_to<SpatialEditorViewport>(p_viewport);
+
+ if (!current_viewport)
+ return;
+
+ ScriptEditorDebugger *const debugger = ScriptEditor::get_singleton()->get_debugger();
+
+ camera_override_viewport_id = current_viewport->index;
+ if (debugger->get_camera_override() >= ScriptEditorDebugger::OVERRIDE_3D_1) {
+ using Override = ScriptEditorDebugger::CameraOverride;
+
+ debugger->set_camera_override((Override)(Override::OVERRIDE_3D_1 + camera_override_viewport_id));
+ }
+}
+
void SpatialEditor::_menu_item_pressed(int p_option) {
switch (p_option) {
@@ -5294,6 +5339,7 @@ void SpatialEditor::_notification(int p_what) {
tool_option_button[SpatialEditor::TOOL_OPT_LOCAL_COORDS]->set_icon(get_icon("Object", "EditorIcons"));
tool_option_button[SpatialEditor::TOOL_OPT_USE_SNAP]->set_icon(get_icon("Snap", "EditorIcons"));
+ tool_option_button[SpatialEditor::TOOL_OPT_OVERRIDE_CAMERA]->set_icon(get_icon("Camera", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_icon("Panels1", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_icon("Panels2", "EditorIcons"));
@@ -5309,6 +5355,9 @@ void SpatialEditor::_notification(int p_what) {
get_tree()->connect("node_removed", this, "_node_removed");
EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->connect("node_changed", this, "_refresh_menu_icons");
editor_selection->connect("selection_changed", this, "_refresh_menu_icons");
+
+ editor->connect("stop_pressed", this, "_update_camera_override_button", make_binds(false));
+ editor->connect("play_pressed", this, "_update_camera_override_button", make_binds(true));
} else if (p_what == NOTIFICATION_ENTER_TREE) {
_register_all_gizmos();
@@ -5343,6 +5392,13 @@ void SpatialEditor::_notification(int p_what) {
// Update grid color by rebuilding grid.
_finish_grid();
_init_grid();
+ } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ if (!is_visible() && tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->is_pressed()) {
+ ScriptEditorDebugger *debugger = ScriptEditor::get_singleton()->get_debugger();
+
+ debugger->set_camera_override(ScriptEditorDebugger::OVERRIDE_NONE);
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_pressed(false);
+ }
}
}
@@ -5487,6 +5543,8 @@ void SpatialEditor::_bind_methods() {
ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo);
ClassDB::bind_method("_toggle_maximize_view", &SpatialEditor::_toggle_maximize_view);
ClassDB::bind_method("_refresh_menu_icons", &SpatialEditor::_refresh_menu_icons);
+ ClassDB::bind_method("_update_camera_override_button", &SpatialEditor::_update_camera_override_button);
+ ClassDB::bind_method("_update_camera_override_viewport", &SpatialEditor::_update_camera_override_viewport);
ADD_SIGNAL(MethodInfo("transform_key_request"));
ADD_SIGNAL(MethodInfo("item_lock_status_changed"));
@@ -5540,6 +5598,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
snap_key_enabled = false;
tool_mode = TOOL_MODE_SELECT;
+ camera_override_viewport_id = 0;
+
hbc_menu = memnew(HBoxContainer);
vbc->add_child(hbc_menu);
@@ -5637,6 +5697,17 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(memnew(VSeparator));
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA] = memnew(ToolButton);
+ hbc_menu->add_child(tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]);
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_toggle_mode(true);
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_flat(true);
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->set_disabled(true);
+ button_binds.write[0] = MENU_TOOL_OVERRIDE_CAMERA;
+ tool_option_button[TOOL_OPT_OVERRIDE_CAMERA]->connect("toggled", this, "_menu_item_toggled", button_binds);
+ _update_camera_override_button(false);
+
+ hbc_menu->add_child(memnew(VSeparator));
+
// Drag and drop support;
preview_node = memnew(Spatial);
preview_bounds = AABB();
@@ -5725,6 +5796,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
viewports[i] = memnew(SpatialEditorViewport(this, editor, i));
viewports[i]->connect("toggle_maximize_view", this, "_toggle_maximize_view");
+ viewports[i]->connect("clicked", this, "_update_camera_override_viewport");
viewports[i]->assign_pending_data_pointers(preview_node, &preview_bounds, accept);
viewport_base->add_child(viewports[i]);
}
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index fe91c33642..65e3c32ca8 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -494,6 +494,7 @@ public:
TOOL_OPT_LOCAL_COORDS,
TOOL_OPT_USE_SNAP,
+ TOOL_OPT_OVERRIDE_CAMERA,
TOOL_OPT_MAX
};
@@ -559,6 +560,7 @@ private:
MENU_TOOL_LIST_SELECT,
MENU_TOOL_LOCAL_COORDS,
MENU_TOOL_USE_SNAP,
+ MENU_TOOL_OVERRIDE_CAMERA,
MENU_TRANSFORM_CONFIGURE_SNAP,
MENU_TRANSFORM_DIALOG,
MENU_VIEW_USE_1_VIEWPORT,
@@ -585,9 +587,6 @@ private:
PopupMenu *gizmos_menu;
MenuButton *view_menu;
- ToolButton *lock_button;
- ToolButton *unlock_button;
-
AcceptDialog *accept;
ConfirmationDialog *snap_dialog;
@@ -615,13 +614,16 @@ private:
void _menu_item_pressed(int p_option);
void _menu_item_toggled(bool pressed, int p_option);
void _menu_gizmo_toggled(int p_option);
+ void _update_camera_override_button(bool p_game_running);
+ void _update_camera_override_viewport(Object *p_viewport);
HBoxContainer *hbc_menu;
void _generate_selection_box();
UndoRedo *undo_redo;
- void _instance_scene();
+ int camera_override_viewport_id;
+
void _init_indicators();
void _update_gizmos_menu();
void _update_gizmos_menu_theme();
@@ -716,7 +718,7 @@ public:
void set_can_preview(Camera *p_preview);
SpatialEditorViewport *get_editor_viewport(int p_idx) {
- ERR_FAIL_INDEX_V(p_idx, 4, NULL);
+ ERR_FAIL_INDEX_V(p_idx, static_cast<int>(VIEWPORTS_COUNT), NULL);
return viewports[p_idx];
}
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 21eebf9ca2..bda3d142fa 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -866,8 +866,8 @@ void TextureRegionEditor::_edit_region() {
Vector2 TextureRegionEditor::snap_point(Vector2 p_target) const {
if (snap_mode == SNAP_GRID) {
- p_target.x = Math::snap_scalar_seperation(snap_offset.x, snap_step.x, p_target.x, snap_separation.x);
- p_target.y = Math::snap_scalar_seperation(snap_offset.y, snap_step.y, p_target.y, snap_separation.y);
+ p_target.x = Math::snap_scalar_separation(snap_offset.x, snap_step.x, p_target.x, snap_separation.x);
+ p_target.y = Math::snap_scalar_separation(snap_offset.y, snap_step.y, p_target.y, snap_separation.y);
}
return p_target;
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 2d66087699..10567557d6 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -1996,6 +1996,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
info_message->set_valign(Label::VALIGN_CENTER);
info_message->set_align(Label::ALIGN_CENTER);
info_message->set_autowrap(true);
+ info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
palette->add_child(info_message);
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index e0bf8dfdb2..cc4c21cc04 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -584,6 +584,7 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
empty_message->set_valign(Label::VALIGN_CENTER);
empty_message->set_align(Label::ALIGN_CENTER);
empty_message->set_autowrap(true);
+ empty_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
empty_message->set_v_size_flags(SIZE_EXPAND_FILL);
main_vb->add_child(empty_message);
@@ -3038,8 +3039,8 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) {
}
if (tools[TOOL_GRID_SNAP]->is_pressed()) {
- p.x = Math::snap_scalar_seperation(snap_offset.x, snap_step.x, p.x, snap_separation.x);
- p.y = Math::snap_scalar_seperation(snap_offset.y, snap_step.y, p.y, snap_separation.y);
+ p.x = Math::snap_scalar_separation(snap_offset.x, snap_step.x, p.x, snap_separation.x);
+ 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)
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 3a9e48cfdb..90eb3045df 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -109,11 +109,12 @@ void VisualShaderEditor::clear_custom_types() {
for (int i = 0; i < add_options.size(); i++) {
if (add_options[i].is_custom) {
add_options.remove(i);
+ i--;
}
}
}
-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, const String &p_sub_category) {
+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, const String &p_subcategory) {
ERR_FAIL_COND(!p_name.is_valid_identifier());
ERR_FAIL_COND(!p_script.is_valid());
@@ -131,9 +132,25 @@ void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script>
ao.return_type = p_return_icon_type;
ao.description = p_description;
ao.category = p_category;
- ao.sub_category = p_sub_category;
+ ao.sub_category = p_subcategory;
ao.is_custom = true;
+ bool begin = false;
+
+ for (int i = 0; i < add_options.size(); i++) {
+ if (add_options[i].is_custom) {
+ if (add_options[i].category == p_category) {
+ if (!begin) {
+ begin = true;
+ }
+ } else {
+ if (begin) {
+ add_options.insert(i, ao);
+ return;
+ }
+ }
+ }
+ }
add_options.push_back(ao);
}
@@ -184,6 +201,7 @@ void VisualShaderEditor::update_custom_nodes() {
clear_custom_types();
List<StringName> class_list;
ScriptServer::get_global_class_list(&class_list);
+ Dictionary added;
for (int i = 0; i < class_list.size(); i++) {
if (ScriptServer::get_global_class_native_base(class_list[i]) == "VisualShaderNodeCustom") {
@@ -222,14 +240,44 @@ void VisualShaderEditor::update_custom_nodes() {
category = "Custom";
}
- String sub_category = "";
+ String subcategory = "";
if (ref->has_method("_get_subcategory")) {
- sub_category = (String)ref->call("_get_subcategory");
+ subcategory = (String)ref->call("_get_subcategory");
}
- add_custom_type(name, script, description, return_icon_type, category, sub_category);
+ Dictionary dict;
+ dict["name"] = name;
+ dict["script"] = script;
+ dict["description"] = description;
+ dict["return_icon_type"] = return_icon_type;
+ dict["category"] = category;
+ dict["subcategory"] = subcategory;
+
+ String key;
+ key = category;
+ key += "/";
+ if (subcategory != "") {
+ key += subcategory;
+ key += "/";
+ }
+ key += name;
+
+ added[key] = dict;
}
}
+
+ Array keys = added.keys();
+ keys.sort();
+
+ for (int i = 0; i < keys.size(); i++) {
+
+ const Variant &key = keys.get(i);
+
+ const Dictionary &value = (Dictionary)added[key];
+
+ add_custom_type(value["name"], value["script"], value["description"], value["return_icon_type"], value["category"], value["subcategory"]);
+ }
+
_update_options_menu();
}
@@ -2483,9 +2531,11 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("DepthTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "depth_texture"), "depth_texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("FrontFacing", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "front_facing"), "front_facing", VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), "screen_texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Side", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "side"), "side", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL));
@@ -2519,9 +2569,12 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("LightPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "light_pass"), "light_pass", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("NormalTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "normal_texture"), "normal_texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ScreenPixelSize", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_pixel_size"), "screen_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), "screen_texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ 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));
@@ -2533,6 +2586,7 @@ VisualShaderEditor::VisualShaderEditor() {
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("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("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));
add_options.push_back(AddOption("LightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "light_pass"), "light_pass", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM));
@@ -2830,11 +2884,12 @@ public:
void setup(const Ref<VisualShaderNodeInput> &p_input) {
input = p_input;
- Ref<Texture> type_icon[4] = {
+ Ref<Texture> type_icon[5] = {
EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons"),
EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons"),
EditorNode::get_singleton()->get_gui_base()->get_icon("bool", "EditorIcons"),
EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"),
+ EditorNode::get_singleton()->get_gui_base()->get_icon("ImageTexture", "EditorIcons"),
};
add_item("[None]");
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index 6f77641936..5197f8c77f 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -264,7 +264,7 @@ public:
static VisualShaderEditor *get_singleton() { return singleton; }
void clear_custom_types();
- void 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, const String &p_sub_category);
+ void 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, const String &p_subcategory);
virtual Size2 get_minimum_size() const;
void edit(VisualShader *p_visual_shader);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index f56f7ef7ca..9ac775e456 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -442,15 +442,7 @@ void ProjectSettingsEditor::_wait_for_key(const Ref<InputEvent> &p_event) {
if (k.is_valid() && k->is_pressed() && k->get_scancode() != 0) {
last_wait_for_key = p_event;
- String str = keycode_get_string(k->get_scancode()).capitalize();
- if (k->get_metakey())
- str = vformat("%s+", find_keycode_name(KEY_META)) + str;
- if (k->get_shift())
- str = TTR("Shift+") + str;
- if (k->get_alt())
- str = TTR("Alt+") + str;
- if (k->get_control())
- str = TTR("Control+") + str;
+ const String str = keycode_get_string(k->get_scancode_with_modifiers());
press_a_key_label->set_text(str);
press_a_key->accept_event();
@@ -740,15 +732,7 @@ void ProjectSettingsEditor::_update_actions() {
Ref<InputEventKey> k = event;
if (k.is_valid()) {
- String str = keycode_get_string(k->get_scancode()).capitalize();
- if (k->get_metakey())
- str = vformat("%s+", find_keycode_name(KEY_META)) + str;
- if (k->get_shift())
- str = TTR("Shift+") + str;
- if (k->get_alt())
- str = TTR("Alt+") + str;
- if (k->get_control())
- str = TTR("Control+") + str;
+ const String str = keycode_get_string(k->get_scancode_with_modifiers());
action2->set_text(0, str);
action2->set_icon(0, get_icon("Keyboard", "EditorIcons"));
@@ -1546,28 +1530,33 @@ void ProjectSettingsEditor::_update_translations() {
Array l_filter = l_filter_all[1];
int s = names.size();
- if (!translation_locales_list_created) {
+ bool is_short_list_when_show_all_selected = filter_mode == SHOW_ALL_LOCALES && translation_filter_treeitems.size() < s;
+ bool is_full_list_when_show_only_selected = filter_mode == SHOW_ONLY_SELECTED_LOCALES && translation_filter_treeitems.size() == s;
+ 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(NULL);
translation_filter->set_hide_root(true);
- translation_filter_treeitems.resize(s);
-
+ translation_filter_treeitems.clear();
for (int i = 0; i < s; i++) {
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;
+
TreeItem *t = translation_filter->create_item(root);
t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
t->set_text(0, n);
t->set_editable(0, true);
t->set_tooltip(0, l);
- t->set_checked(0, l_filter.has(l));
- translation_filter_treeitems.write[i] = t;
+ t->set_checked(0, is_checked);
+ translation_filter_treeitems.push_back(t);
}
} else {
- for (int i = 0; i < s; i++) {
-
+ for (int i = 0; i < translation_filter_treeitems.size(); i++) {
TreeItem *t = translation_filter_treeitems[i];
t->set_checked(0, l_filter.has(t->get_tooltip(0)));
}
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 0884620e5d..71e93750f0 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -340,8 +340,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!profile_allow_editing) {
break;
}
- Tree *tree = scene_tree->get_scene_tree();
- if (tree->is_anything_selected()) {
+ if (editor_selection->get_selected_node_list().size() > 1) {
rename_dialog->popup_centered();
}
} break;
@@ -2404,6 +2403,7 @@ 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)
return;
@@ -2438,21 +2438,40 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
}
if (profile_allow_script_editing) {
+ bool add_separator = false;
- if (selection.size() == 1) {
+ if (full_selection.size() == 1) {
+ add_separator = true;
menu->add_icon_shortcut(get_icon("ScriptCreate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/attach_script"), TOOL_ATTACH_SCRIPT);
if (existing_script.is_valid()) {
menu->add_icon_shortcut(get_icon("ScriptExtend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/extend_script"), TOOL_EXTEND_SCRIPT);
}
}
- if (selection.size() > 1 || (existing_script.is_valid() && exisiting_script_removable)) {
+ if (existing_script.is_valid() && exisiting_script_removable) {
+ add_separator = true;
menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ } else if (full_selection.size() > 1) {
+ bool script_exists = false;
+ for (List<Node *>::Element *E = full_selection.front(); E; E = E->next()) {
+ if (!E->get()->get_script().is_null()) {
+ script_exists = true;
+ break;
+ }
+ }
+
+ if (script_exists) {
+ add_separator = true;
+ menu->add_icon_shortcut(get_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ }
+ }
+
+ if (add_separator) {
+ menu->add_separator();
}
- menu->add_separator();
}
if (profile_allow_editing) {
- if (selection.size() == 1) {
+ if (full_selection.size() == 1) {
menu->add_icon_shortcut(get_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/rename"), TOOL_RENAME);
}
menu->add_icon_shortcut(get_icon("Reload", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/change_node_type"), TOOL_REPLACE);
@@ -2464,7 +2483,9 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/duplicate"), TOOL_DUPLICATE);
menu->add_icon_shortcut(get_icon("Reparent", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent"), TOOL_REPARENT);
menu->add_icon_shortcut(get_icon("ReparentToNewNode", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/reparent_to_new_node"), TOOL_REPARENT_TO_NEW_NODE);
- menu->add_icon_shortcut(get_icon("NewRoot", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/make_root"), TOOL_MAKE_ROOT);
+ if (selection.size() == 1) {
+ menu->add_icon_shortcut(get_icon("NewRoot", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/make_root"), TOOL_MAKE_ROOT);
+ }
}
}
if (selection.size() == 1) {
@@ -2473,9 +2494,11 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_separator();
menu->add_icon_shortcut(get_icon("Blend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/merge_from_scene"), TOOL_MERGE_FROM_SCENE);
menu->add_icon_shortcut(get_icon("CreateNewSceneFrom", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/save_branch_as_scene"), TOOL_NEW_SCENE_FROM);
+ }
+ if (full_selection.size() == 1) {
menu->add_separator();
+ menu->add_icon_shortcut(get_icon("CopyNodePath", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/copy_node_path"), TOOL_COPY_NODE_PATH);
}
- menu->add_icon_shortcut(get_icon("CopyNodePath", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/copy_node_path"), TOOL_COPY_NODE_PATH);
bool is_external = (selection[0]->get_filename() != "");
if (is_external) {
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index c1899b2bde..afbd8832f2 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -33,6 +33,8 @@
#include "core/io/marshalls.h"
#include "core/project_settings.h"
#include "core/ustring.h"
+#include "editor/plugins/canvas_item_editor_plugin.h"
+#include "editor/plugins/spatial_editor_plugin.h"
#include "editor_network_profiler.h"
#include "editor_node.h"
#include "editor_profiler.h"
@@ -1232,6 +1234,42 @@ void ScriptEditorDebugger::_notification(int p_what) {
}
}
}
+
+ if (camera_override == OVERRIDE_2D) {
+ CanvasItemEditor *editor = CanvasItemEditor::get_singleton();
+
+ Dictionary state = editor->get_state();
+ float zoom = state["zoom"];
+ Point2 offset = state["ofs"];
+ Transform2D transform;
+
+ transform.scale_basis(Size2(zoom, zoom));
+ transform.elements[2] = -offset * zoom;
+
+ Array msg;
+ msg.push_back("override_camera_2D:transform");
+ msg.push_back(transform);
+ ppeer->put_var(msg);
+
+ } else if (camera_override >= OVERRIDE_3D_1) {
+ int viewport_idx = camera_override - OVERRIDE_3D_1;
+ SpatialEditorViewport *viewport = SpatialEditor::get_singleton()->get_editor_viewport(viewport_idx);
+ Camera *const cam = viewport->get_camera();
+
+ Array msg;
+ msg.push_back("override_camera_3D:transform");
+ msg.push_back(cam->get_camera_transform());
+ if (cam->get_projection() == Camera::PROJECTION_ORTHOGONAL) {
+ msg.push_back(false);
+ msg.push_back(cam->get_size());
+ } else {
+ msg.push_back(true);
+ msg.push_back(cam->get_fov());
+ }
+ msg.push_back(cam->get_znear());
+ msg.push_back(cam->get_zfar());
+ ppeer->put_var(msg);
+ }
}
if (error_count != last_error_count || warning_count != last_warning_count) {
@@ -1446,6 +1484,7 @@ void ScriptEditorDebugger::start() {
set_process(true);
breaked = false;
+ camera_override = OVERRIDE_NONE;
}
void ScriptEditorDebugger::pause() {
@@ -1890,6 +1929,45 @@ void ScriptEditorDebugger::live_debug_reparent_node(const NodePath &p_at, const
}
}
+ScriptEditorDebugger::CameraOverride ScriptEditorDebugger::get_camera_override() const {
+ return camera_override;
+}
+
+void ScriptEditorDebugger::set_camera_override(CameraOverride p_override) {
+
+ if (p_override == OVERRIDE_2D && camera_override != OVERRIDE_2D) {
+ if (connection.is_valid()) {
+ Array msg;
+ msg.push_back("override_camera_2D:set");
+ msg.push_back(true);
+ ppeer->put_var(msg);
+ }
+ } else if (p_override != OVERRIDE_2D && camera_override == OVERRIDE_2D) {
+ if (connection.is_valid()) {
+ Array msg;
+ msg.push_back("override_camera_2D:set");
+ msg.push_back(false);
+ ppeer->put_var(msg);
+ }
+ } else if (p_override >= OVERRIDE_3D_1 && camera_override < OVERRIDE_3D_1) {
+ if (connection.is_valid()) {
+ Array msg;
+ msg.push_back("override_camera_3D:set");
+ msg.push_back(true);
+ ppeer->put_var(msg);
+ }
+ } else if (p_override < OVERRIDE_3D_1 && camera_override >= OVERRIDE_3D_1) {
+ if (connection.is_valid()) {
+ Array msg;
+ msg.push_back("override_camera_3D:set");
+ msg.push_back(false);
+ ppeer->put_var(msg);
+ }
+ }
+
+ camera_override = p_override;
+}
+
void ScriptEditorDebugger::set_breakpoint(const String &p_path, int p_line, bool p_enabled) {
if (connection.is_valid()) {
@@ -2424,6 +2502,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
info_message->set_valign(Label::VALIGN_CENTER);
info_message->set_align(Label::ALIGN_CENTER);
info_message->set_autowrap(true);
+ info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
perf_draw->add_child(info_message);
}
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index cc284476c0..14b024d066 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -35,6 +35,7 @@
#include "core/io/tcp_server.h"
#include "editor/editor_inspector.h"
#include "editor/property_editor.h"
+#include "scene/3d/camera.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
@@ -58,6 +59,17 @@ class ScriptEditorDebugger : public Control {
GDCLASS(ScriptEditorDebugger, Control);
+public:
+ enum CameraOverride {
+ OVERRIDE_NONE,
+ OVERRIDE_2D,
+ OVERRIDE_3D_1, // 3D Viewport 1
+ OVERRIDE_3D_2, // 3D Viewport 2
+ OVERRIDE_3D_3, // 3D Viewport 3
+ OVERRIDE_3D_4 // 3D Viewport 4
+ };
+
+private:
enum MessageType {
MESSAGE_ERROR,
MESSAGE_WARNING,
@@ -165,6 +177,8 @@ class ScriptEditorDebugger : public Control {
bool live_debug;
+ CameraOverride camera_override;
+
void _performance_draw();
void _performance_select();
void _stack_dump_frame_selected();
@@ -250,6 +264,9 @@ public:
void live_debug_duplicate_node(const NodePath &p_at, const String &p_new_name);
void live_debug_reparent_node(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos);
+ CameraOverride get_camera_override() const;
+ void set_camera_override(CameraOverride p_override);
+
void set_breakpoint(const String &p_path, int p_line, bool p_enabled);
void update_live_edit_root();
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index f8425ebe22..a38c6b98cc 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -310,15 +310,7 @@ void EditorSettingsDialog::_wait_for_key(const Ref<InputEvent> &p_event) {
if (k.is_valid() && k->is_pressed() && k->get_scancode() != 0) {
last_wait_for_key = k;
- String str = keycode_get_string(k->get_scancode()).capitalize();
- if (k->get_metakey())
- str = vformat("%s+", find_keycode_name(KEY_META)) + str;
- if (k->get_shift())
- str = TTR("Shift+") + str;
- if (k->get_alt())
- str = TTR("Alt+") + str;
- if (k->get_control())
- str = TTR("Control+") + str;
+ const String str = keycode_get_string(k->get_scancode_with_modifiers());
press_a_key_label->set_text(str);
press_a_key->accept_event();
diff --git a/main/main.cpp b/main/main.cpp
index fe0f5a0215..3911ae77dc 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -44,7 +44,6 @@
#include "core/project_settings.h"
#include "core/register_core_types.h"
#include "core/script_debugger_local.h"
-#include "core/script_debugger_remote.h"
#include "core/script_language.h"
#include "core/translation.h"
#include "core/version.h"
@@ -59,6 +58,7 @@
#include "main/tests/test_main.h"
#include "modules/register_module_types.h"
#include "platform/register_platform_apis.h"
+#include "scene/debugger/script_debugger_remote.h"
#include "scene/main/scene_tree.h"
#include "scene/main/viewport.h"
#include "scene/register_scene_types.h"
@@ -1348,8 +1348,8 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
ClassDB::set_current_api(ClassDB::API_NONE); //no more api is registered at this point
- print_verbose("CORE API HASH: " + itos(ClassDB::get_api_hash(ClassDB::API_CORE)));
- print_verbose("EDITOR API HASH: " + itos(ClassDB::get_api_hash(ClassDB::API_EDITOR)));
+ print_verbose("CORE API HASH: " + uitos(ClassDB::get_api_hash(ClassDB::API_CORE)));
+ print_verbose("EDITOR API HASH: " + uitos(ClassDB::get_api_hash(ClassDB::API_EDITOR)));
MAIN_PRINT("Main: Done");
return OK;
@@ -1423,8 +1423,6 @@ bool Main::start() {
}
}
- GLOBAL_DEF("editor/active", editor);
-
String main_loop_type;
#ifdef TOOLS_ENABLED
if (doc_tool != "") {
@@ -1583,6 +1581,12 @@ bool Main::start() {
if (!project_manager && !editor) { // game
if (game_path != "" || script != "") {
+ if (script_debugger && script_debugger->is_remote()) {
+ ScriptDebuggerRemote *remote_debugger = static_cast<ScriptDebuggerRemote *>(script_debugger);
+
+ remote_debugger->set_scene_tree(sml);
+ }
+
//autoload
List<PropertyInfo> props;
ProjectSettings::get_singleton()->get_property_list(&props);
diff --git a/main/splash_editor.png b/main/splash_editor.png
index 2967d8dd3e..8c605f0eed 100644
--- a/main/splash_editor.png
+++ b/main/splash_editor.png
Binary files differ
diff --git a/main/tests/test_astar.cpp b/main/tests/test_astar.cpp
index d34ff0d95e..4b60a3e94a 100644
--- a/main/tests/test_astar.cpp
+++ b/main/tests/test_astar.cpp
@@ -31,8 +31,10 @@
#include "test_astar.h"
#include "core/math/a_star.h"
+#include "core/math/math_funcs.h"
#include "core/os/os.h"
+#include <math.h>
#include <stdio.h>
namespace TestAStar {
@@ -87,11 +89,268 @@ bool test_abcx() {
return ok;
}
+bool test_add_remove() {
+ AStar a;
+ bool ok = true;
+
+ // Manual tests
+ a.add_point(1, Vector3(0, 0, 0));
+ a.add_point(2, Vector3(0, 1, 0));
+ a.add_point(3, Vector3(1, 1, 0));
+ a.add_point(4, Vector3(2, 0, 0));
+ a.connect_points(1, 2, true);
+ a.connect_points(1, 3, true);
+ a.connect_points(1, 4, false);
+
+ ok = ok && (a.are_points_connected(2, 1) == true);
+ ok = ok && (a.are_points_connected(4, 1) == true);
+ ok = ok && (a.are_points_connected(2, 1, false) == true);
+ ok = ok && (a.are_points_connected(4, 1, false) == false);
+
+ a.disconnect_points(1, 2, true);
+ ok = ok && (a.get_point_connections(1).size() == 2); // 3, 4
+ ok = ok && (a.get_point_connections(2).size() == 0);
+
+ a.disconnect_points(4, 1, false);
+ ok = ok && (a.get_point_connections(1).size() == 2); // 3, 4
+ ok = ok && (a.get_point_connections(4).size() == 0);
+
+ a.disconnect_points(4, 1, true);
+ ok = ok && (a.get_point_connections(1).size() == 1); // 3
+ ok = ok && (a.get_point_connections(4).size() == 0);
+
+ a.connect_points(2, 3, false);
+ ok = ok && (a.get_point_connections(2).size() == 1); // 3
+ ok = ok && (a.get_point_connections(3).size() == 1); // 1
+
+ a.connect_points(2, 3, true);
+ ok = ok && (a.get_point_connections(2).size() == 1); // 3
+ ok = ok && (a.get_point_connections(3).size() == 2); // 1, 2
+
+ a.disconnect_points(2, 3, false);
+ ok = ok && (a.get_point_connections(2).size() == 0);
+ ok = ok && (a.get_point_connections(3).size() == 2); // 1, 2
+
+ a.connect_points(4, 3, true);
+ ok = ok && (a.get_point_connections(3).size() == 3); // 1, 2, 4
+ ok = ok && (a.get_point_connections(4).size() == 1); // 3
+
+ a.disconnect_points(3, 4, false);
+ ok = ok && (a.get_point_connections(3).size() == 2); // 1, 2
+ ok = ok && (a.get_point_connections(4).size() == 1); // 3
+
+ a.remove_point(3);
+ ok = ok && (a.get_point_connections(1).size() == 0);
+ ok = ok && (a.get_point_connections(2).size() == 0);
+ ok = ok && (a.get_point_connections(4).size() == 0);
+
+ a.add_point(0, Vector3(0, -1, 0));
+ a.add_point(3, Vector3(2, 1, 0));
+ // 0: (0, -1)
+ // 1: (0, 0)
+ // 2: (0, 1)
+ // 3: (2, 1)
+ // 4: (2, 0)
+
+ // Tests for get_closest_position_in_segment
+ a.connect_points(2, 3);
+ ok = ok && (a.get_closest_position_in_segment(Vector3(0.5, 0.5, 0)) == Vector3(0.5, 1, 0));
+
+ a.connect_points(3, 4);
+ a.connect_points(0, 3);
+ a.connect_points(1, 4);
+ a.disconnect_points(1, 4, false);
+ a.disconnect_points(4, 3, false);
+ a.disconnect_points(3, 4, false);
+ // Remaining edges: <2, 3>, <0, 3>, <1, 4> (directed)
+ ok = ok && (a.get_closest_position_in_segment(Vector3(2, 0.5, 0)) == Vector3(1.75, 0.75, 0));
+ ok = ok && (a.get_closest_position_in_segment(Vector3(-1, 0.2, 0)) == Vector3(0, 0, 0));
+ ok = ok && (a.get_closest_position_in_segment(Vector3(3, 2, 0)) == Vector3(2, 1, 0));
+
+ Math::seed(0);
+
+ // Random tests for connectivity checks
+ for (int i = 0; i < 20000; i++) {
+ int u = Math::rand() % 5;
+ int v = Math::rand() % 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);
+ ok = ok && (a.are_points_connected(u, v, false) == true);
+ } else {
+ // Remove a (possibly nonexistent) directed edge and confirm disconnectivity
+ a.disconnect_points(u, v, false);
+ ok = ok && (a.are_points_connected(u, v, false) == false);
+ }
+ }
+
+ // Random tests for point removal
+ for (int i = 0; i < 20000; i++) {
+ a.clear();
+ 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)
+ a.connect_points(u, v, false);
+ else
+ a.disconnect_points(u, v, false);
+ }
+
+ // Remove point 0
+ a.remove_point(0);
+ // White box: this will check all edges remaining in the segments set
+ for (int j = 1; j < 5; j++) {
+ ok = ok && (a.are_points_connected(0, j, true) == false);
+ }
+ }
+
+ // It's been great work, cheers \(^ ^)/
+ return ok;
+}
+
+bool test_solutions() {
+ // Random stress tests with Floyd-Warshall
+
+ const int N = 30;
+ Math::seed(0);
+
+ for (int test = 0; test < 1000; test++) {
+ AStar a;
+ Vector3 p[N];
+ bool adj[N][N] = { { false } };
+
+ // Assign initial coordinates
+ for (int u = 0; u < N; u++) {
+ p[u].x = Math::rand() % 100;
+ p[u].y = Math::rand() % 100;
+ p[u].z = Math::rand() % 100;
+ a.add_point(u, p[u]);
+ }
+
+ // Generate a random sequence of operations
+ for (int i = 0; i < 1000; i++) {
+ // Pick two different vertices
+ int u, v;
+ u = Math::rand() % N;
+ v = Math::rand() % (N - 1);
+ if (u == v) v = N - 1;
+
+ // Pick a random operation
+ int op = Math::rand();
+ switch (op % 9) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ // Add edge (u, v); possibly bidirectional
+ a.connect_points(u, v, op % 2);
+ adj[u][v] = 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;
+ break;
+ case 8:
+ // Remove point u and add it back; clears adjacent edges and changes coordinates
+ a.remove_point(u);
+ p[u].x = Math::rand() % 100;
+ p[u].y = Math::rand() % 100;
+ p[u].z = Math::rand() % 100;
+ a.add_point(u, p[u]);
+ 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++)
+ 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])
+ 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++;
+ 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++;
+ 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++)
+ if (u != v) {
+ PoolVector<int> route = a.get_id_path(u, v);
+ if (!Math::is_inf(d[u][v])) {
+ // Reachable
+ if (route.size() == 0) {
+ printf("From %d to %d: A* did not find a path\n", u, v);
+ match = false;
+ goto exit;
+ }
+ float astar_dist = 0;
+ for (int i = 1; i < route.size(); i++) {
+ if (!adj[route[i - 1]][route[i]]) {
+ printf("From %d to %d: edge (%d, %d) does not exist\n",
+ u, v, route[i - 1], route[i]);
+ match = false;
+ goto exit;
+ }
+ astar_dist += p[route[i - 1]].distance_to(p[route[i]]);
+ }
+ if (!Math::is_equal_approx(astar_dist, d[u][v])) {
+ printf("From %d to %d: Floyd-Warshall gives %.6f, A* gives %.6f\n",
+ u, v, d[u][v], astar_dist);
+ match = false;
+ goto exit;
+ }
+ } else {
+ // Unreachable
+ if (route.size() > 0) {
+ printf("From %d to %d: A* somehow found a nonexistent path\n", u, v);
+ match = false;
+ goto exit;
+ }
+ }
+ }
+
+ exit:
+ if (!match) return false;
+ }
+ return true;
+}
+
typedef bool (*TestFunc)(void);
TestFunc test_funcs[] = {
test_abc,
test_abcx,
+ test_add_remove,
+ test_solutions,
NULL
};
diff --git a/modules/assimp/SCsub b/modules/assimp/SCsub
index 275f1ff5e9..5e66b50de3 100644
--- a/modules/assimp/SCsub
+++ b/modules/assimp/SCsub
@@ -72,6 +72,9 @@ env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_X3D_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF2_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_SINGLETHREADED'])
+env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_M3D_IMPORTER'])
+env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MMD_IMPORTER'])
+
if(env['platform'] == 'windows'):
env_assimp.Append(CPPDEFINES=['PLATFORM_WINDOWS'])
diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp
index 1ea9399c02..830e6e7e0c 100644
--- a/modules/assimp/editor_scene_importer_assimp.cpp
+++ b/modules/assimp/editor_scene_importer_assimp.cpp
@@ -29,35 +29,42 @@
/*************************************************************************/
#include "editor_scene_importer_assimp.h"
-
-#include "core/bind/core_bind.h"
#include "core/io/image_loader.h"
-#include "editor/editor_file_system.h"
-#include "editor/editor_settings.h"
#include "editor/import/resource_importer_scene.h"
#include "import_utils.h"
#include "scene/3d/camera.h"
#include "scene/3d/light.h"
#include "scene/3d/mesh_instance.h"
-#include "scene/animation/animation_player.h"
#include "scene/main/node.h"
#include "scene/resources/material.h"
#include "scene/resources/surface_tool.h"
-#include <assimp/SceneCombiner.h>
-#include <assimp/cexport.h>
-#include <assimp/cimport.h>
#include <assimp/matrix4x4.h>
-#include <assimp/pbrmaterial.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
-#include <zutil.h>
-#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
#include <assimp/LogStream.hpp>
-#include <assimp/Logger.hpp>
#include <string>
+// move into assimp
+aiBone *get_bone_by_name(const aiScene *scene, aiString bone_name) {
+ for (unsigned int mesh_id = 0; mesh_id < scene->mNumMeshes; ++mesh_id) {
+ aiMesh *mesh = scene->mMeshes[mesh_id];
+
+ // 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());
+ return bone;
+ }
+ }
+ }
+
+ return NULL;
+}
+
void EditorSceneImporterAssimp::get_extensions(List<String> *r_extensions) const {
const String import_setting_string = "filesystem/import/open_asset_import/";
@@ -69,18 +76,15 @@ void EditorSceneImporterAssimp::get_extensions(List<String> *r_extensions) const
ImportFormat import = { exts, true };
import_format.insert("fbx", import);
}
- {
- Vector<String> exts;
- exts.push_back("pmx");
- ImportFormat import = { exts, true };
- import_format.insert("mmd", import);
- }
for (Map<String, ImportFormat>::Element *E = import_format.front(); E; E = E->next()) {
- _register_project_setting_import(E->key(), import_setting_string, E->get().extensions, r_extensions, E->get().is_default);
+ _register_project_setting_import(E->key(), import_setting_string, E->get().extensions, r_extensions,
+ E->get().is_default);
}
}
-void EditorSceneImporterAssimp::_register_project_setting_import(const String generic, const String import_setting_string, const Vector<String> &exts, List<String> *r_extensions, const bool p_enabled) const {
+void EditorSceneImporterAssimp::_register_project_setting_import(const String generic, const String import_setting_string,
+ const Vector<String> &exts, List<String> *r_extensions,
+ const bool p_enabled) const {
const String use_generic = "use_" + generic;
_GLOBAL_DEF(import_setting_string + use_generic, p_enabled, true);
if (ProjectSettings::get_singleton()->get(import_setting_string + use_generic)) {
@@ -97,7 +101,8 @@ uint32_t EditorSceneImporterAssimp::get_import_flags() const {
void EditorSceneImporterAssimp::_bind_methods() {
}
-Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps,
+ List<String> *r_missing_deps, Error *r_err) {
Assimp::Importer importer;
std::wstring w_path = ProjectSettings::get_singleton()->globalize_path(p_path).c_str();
std::string s_path(w_path.begin(), w_path.end());
@@ -115,9 +120,11 @@ Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_f
//importer.SetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD, 1.0f);
int32_t post_process_Steps = aiProcess_CalcTangentSpace |
- aiProcess_GlobalScale | // imports models and listens to their file scale for CM to M conversions
+ aiProcess_GlobalScale |
+ // imports models and listens to their file scale for CM to M conversions
//aiProcess_FlipUVs |
- aiProcess_FlipWindingOrder | // very important for culling so that it is done in the correct order.
+ aiProcess_FlipWindingOrder |
+ // very important for culling so that it is done in the correct order.
//aiProcess_DropNormals |
//aiProcess_GenSmoothNormals |
//aiProcess_JoinIdenticalVertices |
@@ -132,8 +139,9 @@ Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_f
aiProcess_TransformUVCoords |
aiProcess_FindInstances |
//aiProcess_FixInfacingNormals |
- aiProcess_ValidateDataStructure |
+ //aiProcess_ValidateDataStructure |
aiProcess_OptimizeMeshes |
+ aiProcess_PopulateArmatureData |
//aiProcess_OptimizeGraph |
//aiProcess_Debone |
// aiProcess_EmbedTextures |
@@ -158,7 +166,8 @@ struct EditorSceneImporterAssetImportInterpolate {
float t2 = t * t;
float t3 = t2 * t;
- return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
+ return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 +
+ (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
}
T bezier(T start, T control_1, T control_2, T end, float t) {
@@ -200,7 +209,8 @@ struct EditorSceneImporterAssetImportInterpolate<Quat> {
};
template <class T>
-T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp) {
+T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time,
+ AssetImportAnimation::Interpolation p_interp) {
//could use binary search, worth it?
int idx = -1;
for (int i = 0; i < p_times.size(); i++) {
@@ -272,48 +282,257 @@ T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, co
ERR_FAIL_V(p_values[0]);
}
-Spatial *EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights) {
+aiBone *EditorSceneImporterAssimp::get_bone_from_stack(ImportState &state, aiString name) {
+ List<aiBone *>::Element *iter;
+ aiBone *bone = NULL;
+ for (iter = state.bone_stack.front(); iter; iter = iter->next()) {
+ bone = (aiBone *)iter->get();
+
+ if (bone && bone->mName == name) {
+ state.bone_stack.erase(bone);
+ return bone;
+ }
+ }
+
+ return NULL;
+}
+
+Spatial *
+EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps,
+ const int32_t p_max_bone_weights) {
ERR_FAIL_COND_V(scene == NULL, NULL);
ImportState state;
state.path = p_path;
state.assimp_scene = scene;
state.max_bone_weights = p_max_bone_weights;
- state.root = memnew(Spatial);
- state.fbx = false;
state.animation_player = NULL;
- //fill light map cache
- for (size_t l = 0; l < scene->mNumLights; l++) {
+ // populate light map
+ for (unsigned int l = 0; l < scene->mNumLights; l++) {
aiLight *ai_light = scene->mLights[l];
ERR_CONTINUE(ai_light == NULL);
state.light_cache[AssimpUtils::get_assimp_string(ai_light->mName)] = l;
}
- //fill camera cache
- for (size_t c = 0; c < scene->mNumCameras; c++) {
+ // fill camera cache
+ for (unsigned int c = 0; c < scene->mNumCameras; c++) {
aiCamera *ai_camera = scene->mCameras[c];
ERR_CONTINUE(ai_camera == NULL);
state.camera_cache[AssimpUtils::get_assimp_string(ai_camera->mName)] = c;
}
if (scene->mRootNode) {
+ state.nodes.push_back(scene->mRootNode);
- //generate nodes
- for (uint32_t i = 0; i < scene->mRootNode->mNumChildren; i++) {
- _generate_node(state, NULL, scene->mRootNode->mChildren[i], state.root);
+ // make flat node tree - in order to make processing deterministic
+ for (unsigned int i = 0; i < scene->mRootNode->mNumChildren; i++) {
+ _generate_node(state, scene->mRootNode->mChildren[i]);
}
- // finalize skeleton
- for (Map<Skeleton *, const Spatial *>::Element *key_value_pair = state.armature_skeletons.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
- Skeleton *skeleton = key_value_pair->key();
- // convert world to local for skeleton bone rests
- skeleton->localize_rests();
+ RegenerateBoneStack(state);
+
+ Node *last_valid_parent = NULL;
+
+ List<const aiNode *>::Element *iter;
+ for (iter = state.nodes.front(); iter; iter = iter->next()) {
+ const aiNode *element_assimp_node = iter->get();
+ const aiNode *parent_assimp_node = element_assimp_node->mParent;
+
+ String node_name = AssimpUtils::get_assimp_string(element_assimp_node->mName);
+ //print_verbose("node: " + node_name);
+
+ Spatial *spatial = NULL;
+ Transform transform = AssimpUtils::assimp_matrix_transform(element_assimp_node->mTransformation);
+
+ // retrieve this node bone
+ aiBone *bone = get_bone_from_stack(state, element_assimp_node->mName);
+
+ if (state.light_cache.has(node_name)) {
+ spatial = create_light(state, node_name, transform);
+ } else if (state.camera_cache.has(node_name)) {
+ spatial = create_camera(state, node_name, transform);
+ } else if (state.armature_nodes.find(element_assimp_node)) {
+ // create skeleton
+ print_verbose("Making skeleton: " + node_name);
+ Skeleton *skeleton = memnew(Skeleton);
+ spatial = skeleton;
+ if (!state.armature_skeletons.has(element_assimp_node)) {
+ state.armature_skeletons.insert(element_assimp_node, skeleton);
+ }
+ } else if (bone != NULL) {
+ continue;
+ } else if (element_assimp_node->mNumMeshes > 0) {
+ spatial = memnew(Spatial);
+ } else {
+ spatial = memnew(Spatial);
+ }
+
+ ERR_CONTINUE_MSG(spatial == NULL, "FBX Import - are we out of ram?");
+ // we on purpose set the transform and name after creating the node.
+
+ spatial->set_name(node_name);
+ spatial->set_global_transform(transform);
+
+ // first element is root
+ if (iter == state.nodes.front()) {
+ state.root = spatial;
+ }
+
+ // flat node map parent lookup tool
+ state.flat_node_map.insert(element_assimp_node, spatial);
+
+ Map<const aiNode *, Spatial *>::Element *parent_lookup = state.flat_node_map.find(parent_assimp_node);
+
+ // note: this always fails on the root node :) keep that in mind this is by design
+ if (parent_lookup) {
+ Spatial *parent_node = parent_lookup->value();
+
+ ERR_FAIL_COND_V_MSG(parent_node == NULL, state.root,
+ "Parent node invalid even though lookup successful, out of ram?")
+
+ if (parent_node && spatial != state.root) {
+ parent_node->add_child(spatial);
+ spatial->set_owner(state.root);
+ } else if (spatial == state.root) {
+ // required - think about it root never has a parent yet is valid, anything else without a parent is not valid.
+ } else // Safety for instances
+ {
+ WARN_PRINT(
+ "Failed to find parent node instance after lookup, serious warning report to godot with model");
+ memdelete(spatial); // this node is broken
+ }
+ } else if (spatial != state.root) {
+ // if the ainode is not in the tree
+ // parent it to the last good parent found
+ if (last_valid_parent) {
+ last_valid_parent->add_child(spatial);
+ spatial->set_owner(state.root);
+ } else {
+ // this is a serious error?
+ memdelete(spatial);
+ }
+ }
+
+ // update last valid parent
+ last_valid_parent = spatial;
+ }
+ print_verbose("node counts: " + itos(state.nodes.size()));
+
+ // make clean bone stack
+ RegenerateBoneStack(state);
+
+ print_verbose("generating godot bone data");
+
+ print_verbose("Godot bone stack count: " + itos(state.bone_stack.size()));
+
+ // This is a list of bones, duplicates are from other meshes and must be dealt with properly
+ for (List<aiBone *>::Element *element = state.bone_stack.front(); element; element = element->next()) {
+ aiBone *bone = element->get();
+
+ ERR_CONTINUE_MSG(!bone, "invalid bone read from assimp?");
+
+ // Utilities for armature lookup - for now only FBX makes these
+ aiNode *armature_for_bone = bone->mArmature;
+
+ // Utilities for bone node lookup - for now only FBX makes these
+ aiNode *bone_node = bone->mNode;
+ aiNode *parent_node = bone_node->mParent;
+
+ String bone_name = AssimpUtils::get_anim_string_from_assimp(bone->mName);
+ ERR_CONTINUE_MSG(armature_for_bone == NULL, "Armature for bone invalid: " + bone_name);
+ Skeleton *skeleton = state.armature_skeletons[armature_for_bone];
+
+ state.skeleton_bone_map[bone] = skeleton;
+
+ if (bone_name.empty()) {
+ bone_name = "untitled_bone_name";
+ WARN_PRINT("Untitled bone name detected... report with file please");
+ }
+
+ // todo: this is where skin support goes
+ if (skeleton && skeleton->find_bone(bone_name) == -1) {
+ print_verbose("[Godot Glue] Imported bone" + bone_name);
+ int boneIdx = skeleton->get_bone_count();
+
+ Transform pform = AssimpUtils::assimp_matrix_transform(bone->mNode->mTransformation);
+ skeleton->add_bone(bone_name);
+ skeleton->set_bone_rest(boneIdx, pform);
+ skeleton->set_bone_pose(boneIdx, pform);
+
+ if (parent_node != NULL) {
+ int parent_bone_id = skeleton->find_bone(AssimpUtils::get_anim_string_from_assimp(parent_node->mName));
+ int current_bone_id = boneIdx;
+ skeleton->set_bone_parent(current_bone_id, parent_bone_id);
+ }
+ }
}
print_verbose("generating mesh phase from skeletal mesh");
- generate_mesh_phase_from_skeletal_mesh(state);
+
+ List<Spatial *> cleanup_template_nodes;
+
+ for (Map<const aiNode *, Spatial *>::Element *key_value_pair = state.flat_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
+ const aiNode *assimp_node = key_value_pair->key();
+ Spatial *mesh_template = key_value_pair->value();
+ Node *parent_node = mesh_template->get_parent();
+
+ ERR_CONTINUE(assimp_node == NULL);
+ ERR_CONTINUE(mesh_template == NULL);
+
+ if (mesh_template == state.root) {
+ continue;
+ }
+
+ if (parent_node == NULL) {
+ print_error("Found invalid parent node!");
+ continue; // root node
+ }
+
+ String node_name = AssimpUtils::get_assimp_string(assimp_node->mName);
+ Transform node_transform = AssimpUtils::assimp_matrix_transform(assimp_node->mTransformation);
+
+ if (assimp_node->mNumMeshes > 0) {
+ MeshInstance *mesh = create_mesh(state, assimp_node, node_name, parent_node, node_transform);
+ if (mesh) {
+
+ parent_node->remove_child(mesh_template);
+
+ // re-parent children
+ List<Node *> children;
+ // re-parent all children to new node
+ // note: since get_child_count will change during execution we must build a list first to be safe.
+ for (int childId = 0; childId < mesh_template->get_child_count(); childId++) {
+ // get child
+ Node *child = mesh_template->get_child(childId);
+ children.push_back(child);
+ }
+
+ for (List<Node *>::Element *element = children.front(); element; element = element->next()) {
+ // reparent the children to the real mesh node.
+ mesh_template->remove_child(element->get());
+ mesh->add_child(element->get());
+ element->get()->set_owner(state.root);
+ }
+
+ // update mesh in list so that each mesh node is available
+ // this makes the template unavailable which is the desired behaviour
+ state.flat_node_map[assimp_node] = mesh;
+
+ cleanup_template_nodes.push_back(mesh_template);
+
+ // clean up this list we don't need it
+ children.clear();
+ }
+ }
+ }
+
+ for (List<Spatial *>::Element *element = cleanup_template_nodes.front(); element; element = element->next()) {
+ if (element->get()) {
+ memdelete(element->get());
+ }
+ }
}
if (p_flags & IMPORT_ANIMATION && scene->mNumAnimations) {
@@ -327,29 +546,39 @@ Spatial *EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScen
}
}
+ //
+ // Cleanup operations
+ //
+
+ state.mesh_cache.clear();
+ state.material_cache.clear();
+ state.light_cache.clear();
+ state.camera_cache.clear();
+ state.assimp_node_map.clear();
+ state.path_to_image_cache.clear();
+ state.nodes.clear();
+ state.flat_node_map.clear();
+ state.armature_skeletons.clear();
+ state.bone_stack.clear();
return state.root;
}
-void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int p_track, int p_bake_fps, Ref<Animation> animation, float ticks_per_second, Skeleton *p_skeleton, const NodePath &p_path, const String &p_name) {
-
- const aiNodeAnim *assimp_track = assimp_anim->mChannels[p_track];
+void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int track_id,
+ int anim_fps, Ref<Animation> animation, float ticks_per_second,
+ Skeleton *skeleton, const NodePath &node_path,
+ const String &node_name, aiBone *track_bone) {
+ const aiNodeAnim *assimp_track = assimp_anim->mChannels[track_id];
//make transform track
int track_idx = animation->get_track_count();
animation->add_track(Animation::TYPE_TRANSFORM);
- animation->track_set_path(track_idx, p_path);
+ animation->track_set_path(track_idx, node_path);
//first determine animation length
- float increment = 1.0 / float(p_bake_fps);
+ float increment = 1.0 / float(anim_fps);
float time = 0.0;
bool last = false;
- int skeleton_bone = -1;
-
- if (p_skeleton) {
- skeleton_bone = p_skeleton->find_bone(p_name);
- }
-
Vector<Vector3> pos_values;
Vector<float> pos_times;
Vector<Vector3> scale_values;
@@ -374,6 +603,7 @@ void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, cons
scale_values.push_back(Vector3(scale.x, scale.y, scale.z));
scale_times.push_back(assimp_track->mScalingKeys[sc].mTime / ticks_per_second);
}
+
while (true) {
Vector3 pos;
Quat rot;
@@ -384,26 +614,34 @@ void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, cons
}
if (rot_values.size()) {
- rot = _interpolate_track<Quat>(rot_times, rot_values, time, AssetImportAnimation::INTERP_LINEAR).normalized();
+ rot = _interpolate_track<Quat>(rot_times, rot_values, time,
+ AssetImportAnimation::INTERP_LINEAR)
+ .normalized();
}
if (scale_values.size()) {
scale = _interpolate_track<Vector3>(scale_times, scale_values, time, AssetImportAnimation::INTERP_LINEAR);
}
- if (skeleton_bone >= 0) {
- Transform xform;
- xform.basis.set_quat_scale(rot, scale);
- xform.origin = pos;
+ if (skeleton) {
+ int skeleton_bone = skeleton->find_bone(node_name);
- Transform rest_xform = p_skeleton->get_bone_rest(skeleton_bone);
- xform = rest_xform.affine_inverse() * xform;
- rot = xform.basis.get_rotation_quat();
- scale = xform.basis.get_scale();
- pos = xform.origin;
- }
+ if (skeleton_bone >= 0 && track_bone) {
- rot.normalize();
+ Transform xform;
+ xform.basis.set_quat_scale(rot, scale);
+ xform.origin = pos;
+
+ xform = skeleton->get_bone_pose(skeleton_bone).inverse() * xform;
+
+ rot = xform.basis.get_rotation_quat();
+ rot.normalize();
+ scale = xform.basis.get_scale();
+ pos = xform.origin;
+ } else {
+ ERR_FAIL_MSG("Skeleton bone lookup failed for skeleton: " + skeleton->get_name());
+ }
+ }
animation->track_set_interpolation_type(track_idx, Animation::INTERPOLATION_LINEAR);
animation->transform_track_insert_key(track_idx, time, pos, rot, scale);
@@ -418,6 +656,53 @@ void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, cons
}
}
+// I really do not like this but need to figure out a better way of removing it later.
+Node *EditorSceneImporterAssimp::get_node_by_name(ImportState &state, String name) {
+ for (Map<const aiNode *, Spatial *>::Element *key_value_pair = state.flat_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
+ const aiNode *assimp_node = key_value_pair->key();
+ Spatial *node = key_value_pair->value();
+
+ String node_name = AssimpUtils::get_assimp_string(assimp_node->mName);
+ if (name == node_name && node) {
+ return node;
+ }
+ }
+ return NULL;
+}
+
+/* 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) {
+ aiMesh *mesh = state.assimp_scene->mMeshes[mesh_id];
+
+ // 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];
+
+ // doubtful this is required right now but best to check
+ if (!state.bone_stack.find(bone)) {
+ //print_verbose("[assimp] bone stack added: " + String(bone->mName.C_Str()) );
+ state.bone_stack.push_back(bone);
+ }
+ }
+ }
+}
+
+/* Bone stack is a fifo handler for multiple armatures since armatures aren't a thing in assimp (yet) */
+void EditorSceneImporterAssimp::RegenerateBoneStack(ImportState &state, aiMesh *mesh) {
+ state.bone_stack.clear();
+ // 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 (state.bone_stack.find(bone) == NULL) {
+ state.bone_stack.push_back(bone);
+ }
+ }
+}
+
// animation tracks are per bone
void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_animation_index, int p_bake_fps) {
@@ -429,7 +714,7 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
if (name == String()) {
name = "Animation " + itos(p_animation_index + 1);
}
-
+ print_verbose("import animation: " + name);
float ticks_per_second = anim->mTicksPerSecond;
if (state.assimp_scene->mMetaData != NULL && Math::is_equal_approx(ticks_per_second, 0.0f)) {
@@ -452,34 +737,60 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
animation->set_name(name);
animation->set_length(anim->mDuration / ticks_per_second);
- //regular tracks
+ // generate bone stack for animation import
+ RegenerateBoneStack(state);
+ //regular tracks
for (size_t i = 0; i < anim->mNumChannels; i++) {
const aiNodeAnim *track = anim->mChannels[i];
String node_name = AssimpUtils::get_assimp_string(track->mNodeName);
-
+ print_verbose("track name import: " + node_name);
if (track->mNumRotationKeys == 0 && track->mNumPositionKeys == 0 && track->mNumScalingKeys == 0) {
continue; //do not bother
}
- for (Map<Skeleton *, const Spatial *>::Element *key_value_pair = state.armature_skeletons.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
- Skeleton *skeleton = key_value_pair->key();
-
- bool is_bone = skeleton->find_bone(node_name) != -1;
- //print_verbose("Bone " + node_name + " is bone? " + (is_bone ? "Yes" : "No"));
- NodePath node_path;
+ Skeleton *skeleton = NULL;
+ NodePath node_path;
+ aiBone *bone = NULL;
- if (is_bone) {
- String path = state.root->get_path_to(skeleton);
- path += ":" + node_name;
- node_path = path;
- } else {
- ERR_CONTINUE(!state.node_map.has(node_name));
- Node *node = state.node_map[node_name];
- node_path = state.root->get_path_to(node);
+ // Import skeleton bone animation for this track
+ // Any bone will do, no point in processing more than just what is in the skeleton
+ {
+ bone = get_bone_from_stack(state, track->mNodeName);
+
+ if (bone) {
+ // get skeleton by bone
+ skeleton = state.armature_skeletons[bone->mArmature];
+
+ if (skeleton) {
+ String path = state.root->get_path_to(skeleton);
+ path += ":" + node_name;
+ node_path = path;
+
+ if (node_path != NodePath()) {
+ _insert_animation_track(state, anim, i, p_bake_fps, animation, ticks_per_second, skeleton,
+ node_path, node_name, bone);
+ } else {
+ print_error("Failed to find valid node path for animation");
+ }
+ }
}
+ }
- _insert_animation_track(state, anim, i, p_bake_fps, animation, ticks_per_second, skeleton, node_path, node_name);
+ // not a bone
+ // note this is flaky it uses node names which is unreliable
+ Node *allocated_node = get_node_by_name(state, node_name);
+ // todo: implement skeleton grabbing for node based animations too :)
+ // check if node exists, if it does then also apply animation track for node and bones above are all handled.
+ // this is now inclusive animation handling so that
+ // we import all the data and do not miss anything.
+ if (allocated_node) {
+ node_path = state.root->get_path_to(allocated_node);
+
+ if (node_path != NodePath()) {
+ _insert_animation_track(state, anim, i, p_bake_fps, animation, ticks_per_second, skeleton,
+ node_path, node_name, nullptr);
+ }
}
}
@@ -494,10 +805,9 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
ERR_CONTINUE(prop_name.split("*").size() != 2);
- ERR_CONTINUE(!state.node_map.has(mesh_name));
-
- const MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(state.node_map[mesh_name]);
-
+ Node *item = get_node_by_name(state, mesh_name);
+ ERR_CONTINUE_MSG(!item, "failed to look up node by name");
+ const MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(item);
ERR_CONTINUE(mesh_instance == NULL);
String base_path = state.root->get_path_to(mesh_instance);
@@ -528,15 +838,13 @@ 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]
-Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
- ImportState &state,
- const Vector<int> &p_surface_indices,
- const aiNode *assimp_node,
- Skeleton *p_skeleton) {
+Ref<Mesh>
+EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices,
+ const aiNode *assimp_node, Ref<Skin> &skin,
+ Skeleton *&skeleton_assigned) {
Ref<ArrayMesh> mesh;
mesh.instance();
@@ -548,7 +856,6 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
const unsigned int mesh_idx = p_surface_indices[0];
const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_idx];
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 (!morph_mesh_string_lookup.has(ai_anim_mesh_name)) {
morph_mesh_string_lookup.insert(ai_anim_mesh_name, j);
@@ -560,7 +867,6 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
}
}
}
-
//
// Process Vertex Weights
//
@@ -570,19 +876,30 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
Map<uint32_t, Vector<BoneInfo> > vertex_weights;
- if (p_skeleton) {
+ if (ai_mesh->mNumBones > 0) {
for (size_t b = 0; b < ai_mesh->mNumBones; b++) {
aiBone *bone = ai_mesh->mBones[b];
- String bone_name = AssimpUtils::get_assimp_string(bone->mName);
- int bone_index = p_skeleton->find_bone(bone_name);
- ERR_CONTINUE(bone_index == -1); //bone refers to an unexisting index, wtf.
+ if (!skeleton_assigned) {
+ print_verbose("Assigned mesh skeleton during mesh creation");
+ skeleton_assigned = state.skeleton_bone_map[bone];
+
+ if (!skin.is_valid()) {
+ print_verbose("Configured new skin");
+ skin.instance();
+ } else {
+ print_verbose("Reusing existing skin!");
+ }
+ }
+ // skeleton_assigned =
+ String bone_name = AssimpUtils::get_assimp_string(bone->mName);
+ 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;
-
uint32_t vertex_index = ai_weights.mVertexId;
bi.bone = bone_index;
bi.weight = ai_weights.mWeight;
@@ -619,7 +936,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
// Assign vertex colors
if (ai_mesh->HasVertexColors(0)) {
- Color color = Color(ai_mesh->mColors[0]->r, ai_mesh->mColors[0]->g, ai_mesh->mColors[0]->b, ai_mesh->mColors[0]->a);
+ Color color = Color(ai_mesh->mColors[0]->r, ai_mesh->mColors[0]->g, ai_mesh->mColors[0]->b,
+ ai_mesh->mColors[0]->a);
st->add_color(color);
}
@@ -685,6 +1003,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
if (AI_SUCCESS == ai_material->Get(AI_MATKEY_TWOSIDED, mat_two_sided)) {
if (mat_two_sided > 0) {
mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ } else {
+ mat->set_cull_mode(SpatialMaterial::CULL_BACK);
}
}
@@ -697,7 +1017,7 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
// Culling handling for meshes
// cull all back faces
- mat->set_cull_mode(SpatialMaterial::CULL_BACK);
+ mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
// Now process materials
aiTextureType base_color = aiTextureType_BASE_COLOR;
@@ -712,7 +1032,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) {
mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
+ mat->set_cull_mode(
+ SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
}
mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture);
@@ -731,7 +1052,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) {
mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
+ mat->set_cull_mode(
+ SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
}
mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture);
@@ -742,7 +1064,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
if (Math::is_equal_approx(clr_diffuse.a, 1.0f) == false) {
mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
- mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
+ mat->set_cull_mode(
+ SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
}
mat->set_albedo(Color(clr_diffuse.r, clr_diffuse.g, clr_diffuse.b, clr_diffuse.a));
}
@@ -838,7 +1161,8 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
} else {
// Process emission textures
aiString texture_emissive_path;
- if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_EMISSION_TEXTURE, AI_PROPERTIES, texture_emissive_path)) {
+ if (AI_SUCCESS ==
+ ai_material->Get(AI_MATKEY_FBX_MAYA_EMISSION_TEXTURE, AI_PROPERTIES, texture_emissive_path)) {
if (AssimpUtils::CreateAssimpTexture(state, texture_emissive_path, filename, path, image_data)) {
mat->set_feature(SpatialMaterial::FEATURE_EMISSION, true);
mat->set_texture(SpatialMaterial::TEXTURE_EMISSION, image_data.texture);
@@ -981,62 +1305,27 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
return mesh;
}
-/* to be moved into assimp */
-aiBone *get_bone_by_name(const aiScene *scene, aiString bone_name) {
- for (unsigned int mesh_id = 0; mesh_id < scene->mNumMeshes; ++mesh_id) {
- aiMesh *mesh = scene->mMeshes[mesh_id];
-
- // 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());
- return bone;
- }
- }
- }
-
- return NULL;
-}
-
/**
* Create a new mesh for the node supplied
*/
-void EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *current_node, Node *parent_node, Transform node_transform) {
+MeshInstance *
+EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *active_node, Transform node_transform) {
/* MESH NODE */
Ref<Mesh> mesh;
- Skeleton *skeleton = NULL;
+ Ref<Skin> skin;
// see if we have mesh cache for this.
Vector<int> surface_indices;
- for (uint32_t i = 0; i < assimp_node->mNumMeshes; i++) {
- int mesh_index = assimp_node->mMeshes[i];
- aiMesh *ai_mesh = state.assimp_scene->mMeshes[assimp_node->mMeshes[i]];
- // Map<aiBone*, Skeleton*> // this is what we need
- if (ai_mesh->mNumBones > 0) {
- // we only need the first bone to retrieve the skeleton
- const aiBone *first = ai_mesh->mBones[0];
-
- ERR_FAIL_COND(first == NULL);
+ RegenerateBoneStack(state);
- Map<const aiBone *, Skeleton *>::Element *match = state.bone_to_skeleton_lookup.find(first);
- if (match != NULL) {
- skeleton = match->value();
-
- if (skeleton == NULL) {
- print_error("failed to find bone skeleton for bone: " + AssimpUtils::get_assimp_string(first->mName));
- } else {
- print_verbose("successfully found skeleton for first bone on mesh, can properly handle animations now!");
- }
- // I really need the skeleton and bone to be known as this is something flaky in model exporters.
- ERR_FAIL_COND(skeleton == NULL); // should not happen if bone was successfully created in previous step.
- }
- }
+ // Configure indicies
+ for (uint32_t i = 0; i < assimp_node->mNumMeshes; i++) {
+ int mesh_index = assimp_node->mMeshes[i];
+ // create list of mesh indexes
surface_indices.push_back(mesh_index);
}
- surface_indices.sort();
+ //surface_indices.sort();
String mesh_key;
for (int i = 0; i < surface_indices.size(); i++) {
if (i > 0) {
@@ -1045,262 +1334,154 @@ void EditorSceneImporterAssimp::create_mesh(ImportState &state, const aiNode *as
mesh_key += itos(surface_indices[i]);
}
+ Skeleton *skeleton = NULL;
+ aiNode *armature = NULL;
+
if (!state.mesh_cache.has(mesh_key)) {
- mesh = _generate_mesh_from_surface_indices(state, surface_indices, assimp_node, skeleton);
+ mesh = _generate_mesh_from_surface_indices(state, surface_indices, assimp_node, skin, skeleton);
state.mesh_cache[mesh_key] = mesh;
}
- //Transform transform = recursive_state.node_transform;
-
- // we must unfortunately overwrite mesh and skeleton transform with armature data
- if (skeleton != NULL) {
- print_verbose("Applying mesh and skeleton to armature");
- // required for blender, maya etc
- Map<Skeleton *, const Spatial *>::Element *match = state.armature_skeletons.find(skeleton);
- node_transform = match->value()->get_transform();
- }
-
MeshInstance *mesh_node = memnew(MeshInstance);
mesh = state.mesh_cache[mesh_key];
mesh_node->set_mesh(mesh);
- attach_new_node(state,
- mesh_node,
- assimp_node,
- parent_node,
- node_name,
- node_transform);
-
- // set this once and for all
- if (skeleton != NULL) {
- // root must be informed of its new child
- parent_node->add_child(skeleton);
+ // if we have a valid skeleton set it up
+ if (skin.is_valid()) {
+ for (uint32_t i = 0; i < assimp_node->mNumMeshes; i++) {
+ unsigned int mesh_index = assimp_node->mMeshes[i];
+ const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_index];
+
+ // please remember bone id relative to the skin is NOT the mesh relative index.
+ // it is the index relative to the skeleton that is why
+ // we have state.bone_id_map, it allows for duplicate bone id's too :)
+ // hope this makes sense
+
+ int bind_count = 0;
+ for (unsigned int boneId = 0; boneId < ai_mesh->mNumBones; ++boneId) {
+ aiBone *iterBone = ai_mesh->mBones[boneId];
+
+ // used to reparent mesh to the correct armature later on if assigned.
+ if (!armature) {
+ print_verbose("Configured mesh armature, will reparent later to armature");
+ armature = iterBone->mArmature;
+ }
- // owner must be set after adding to tree
- skeleton->set_owner(state.root);
+ if (skeleton) {
+ int id = skeleton->find_bone(AssimpUtils::get_assimp_string(iterBone->mName));
+ if (id != -1) {
+ print_verbose("Set bind bone: mesh: " + itos(mesh_index) + " bone index: " + itos(id));
+ Transform t = AssimpUtils::assimp_matrix_transform(iterBone->mOffsetMatrix);
- skeleton->set_transform(node_transform);
+ skin->add_bind(bind_count, t);
+ skin->set_bind_bone(bind_count, id);
+ bind_count++;
+ }
+ }
+ }
+ }
- // must be done after added to tree
- mesh_node->set_skeleton_path(mesh_node->get_path_to(skeleton));
+ print_verbose("Finished configuring bind pose for skin mesh");
}
-}
-
-/** generate_mesh_phase_from_skeletal_mesh
- * This must be executed after generate_nodes because the skeleton doesn't exist until that has completed the first pass
- */
-void EditorSceneImporterAssimp::generate_mesh_phase_from_skeletal_mesh(ImportState &state) {
- // prevent more than one skeleton existing per mesh
- // * multiple root bones have this
- // * this simply filters the node out if it has already been added then references the skeleton so we know the actual skeleton for this node
- for (Map<const aiNode *, const Node *>::Element *key_value_pair = state.assimp_node_map.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
- const aiNode *assimp_node = key_value_pair->key();
- Node *current_node = (Node *)key_value_pair->value();
- Node *parent_node = current_node->get_parent();
- ERR_CONTINUE(assimp_node == NULL);
- ERR_CONTINUE(parent_node == NULL);
-
- String node_name = AssimpUtils::get_assimp_string(assimp_node->mName);
- Transform node_transform = AssimpUtils::assimp_matrix_transform(assimp_node->mTransformation);
+ // this code parents all meshes with bones to the armature they are for
+ // GLTF2 specification relies on this and we are enforcing it for FBX.
+ if (armature && state.flat_node_map[armature]) {
+ Node *armature_parent = state.flat_node_map[armature];
+ print_verbose("Parented mesh " + node_name + " to armature " + armature_parent->get_name());
+ // static mesh handling
+ armature_parent->add_child(mesh_node);
+ // transform must be identity
+ mesh_node->set_global_transform(Transform());
+ mesh_node->set_name(node_name);
+ mesh_node->set_owner(state.root);
+ } else {
+ // static mesh handling
+ active_node->add_child(mesh_node);
+ mesh_node->set_global_transform(node_transform);
+ mesh_node->set_name(node_name);
+ mesh_node->set_owner(state.root);
+ }
- if (assimp_node->mNumMeshes > 0) {
- create_mesh(state, assimp_node, node_name, current_node, parent_node, node_transform);
- }
+ if (skeleton) {
+ print_verbose("Attempted to set skeleton path!");
+ mesh_node->set_skeleton_path(mesh_node->get_path_to(skeleton));
+ mesh_node->set_skin(skin);
}
-}
-/**
- * attach_new_node
- * configures node, assigns parent node
-**/
-void EditorSceneImporterAssimp::attach_new_node(ImportState &state, Spatial *new_node, const aiNode *node, Node *parent_node, String Name, Transform &transform) {
- ERR_FAIL_COND(new_node == NULL);
- ERR_FAIL_COND(node == NULL);
- ERR_FAIL_COND(parent_node == NULL);
- ERR_FAIL_COND(state.root == NULL);
-
- // assign properties to new godot note
- new_node->set_name(Name);
- new_node->set_transform(transform);
-
- // add element as child to parent
- parent_node->add_child(new_node);
-
- // owner must be set after
- new_node->set_owner(state.root);
-
- // cache node mapping results by name and then by aiNode*
- state.node_map[Name] = new_node;
- state.assimp_node_map[node] = new_node;
+ return mesh_node;
}
/**
* Create a light for the scene
* Automatically caches lights for lookup later
*/
-void EditorSceneImporterAssimp::create_light(ImportState &state, RecursiveState &recursive_state) {
+Spatial *EditorSceneImporterAssimp::create_light(
+ ImportState &state,
+ const String &node_name,
+ Transform &look_at_transform) {
Light *light = NULL;
- aiLight *ai_light = state.assimp_scene->mLights[state.light_cache[recursive_state.node_name]];
- ERR_FAIL_COND(!ai_light);
+ aiLight *assimp_light = state.assimp_scene->mLights[state.light_cache[node_name]];
+ ERR_FAIL_COND_V(!assimp_light, NULL);
- if (ai_light->mType == aiLightSource_DIRECTIONAL) {
+ if (assimp_light->mType == aiLightSource_DIRECTIONAL) {
light = memnew(DirectionalLight);
- Vector3 dir = Vector3(ai_light->mDirection.y, ai_light->mDirection.x, ai_light->mDirection.z);
- dir.normalize();
- Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z);
- Vector3 up = Vector3(ai_light->mUp.x, ai_light->mUp.y, ai_light->mUp.z);
- up.normalize();
-
- Transform light_transform;
- light_transform.set_look_at(pos, pos + dir, up);
-
- recursive_state.node_transform *= light_transform;
-
- } else if (ai_light->mType == aiLightSource_POINT) {
+ } else if (assimp_light->mType == aiLightSource_POINT) {
light = memnew(OmniLight);
- Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z);
- Transform xform;
- xform.origin = pos;
-
- recursive_state.node_transform *= xform;
-
- light->set_transform(xform);
-
- //light->set_param(Light::PARAM_ATTENUATION, 1);
- } else if (ai_light->mType == aiLightSource_SPOT) {
+ } else if (assimp_light->mType == aiLightSource_SPOT) {
light = memnew(SpotLight);
-
- Vector3 dir = Vector3(ai_light->mDirection.y, ai_light->mDirection.x, ai_light->mDirection.z);
- dir.normalize();
- Vector3 pos = Vector3(ai_light->mPosition.x, ai_light->mPosition.y, ai_light->mPosition.z);
- Vector3 up = Vector3(ai_light->mUp.x, ai_light->mUp.y, ai_light->mUp.z);
- up.normalize();
-
- Transform light_transform;
- light_transform.set_look_at(pos, pos + dir, up);
- recursive_state.node_transform *= light_transform;
-
- //light->set_param(Light::PARAM_ATTENUATION, 0.0f);
}
- ERR_FAIL_COND(light == NULL);
+ ERR_FAIL_COND_V(light == NULL, NULL);
+
+ if (assimp_light->mType != aiLightSource_POINT) {
+ Vector3 pos = Vector3(
+ assimp_light->mPosition.x,
+ assimp_light->mPosition.y,
+ assimp_light->mPosition.z);
+ Vector3 look_at = Vector3(
+ assimp_light->mDirection.y,
+ assimp_light->mDirection.x,
+ assimp_light->mDirection.z)
+ .normalized();
+ Vector3 up = Vector3(
+ assimp_light->mUp.x,
+ assimp_light->mUp.y,
+ assimp_light->mUp.z);
+
+ look_at_transform.set_look_at(pos, look_at, up);
+ }
+ // properties for light variables should be put here.
+ // not really hugely important yet but we will need them in the future
- light->set_color(Color(ai_light->mColorDiffuse.r, ai_light->mColorDiffuse.g, ai_light->mColorDiffuse.b));
- recursive_state.new_node = light;
+ light->set_color(
+ Color(assimp_light->mColorDiffuse.r, assimp_light->mColorDiffuse.g, assimp_light->mColorDiffuse.b));
- attach_new_node(state,
- recursive_state.new_node,
- recursive_state.assimp_node,
- recursive_state.parent_node,
- recursive_state.node_name,
- recursive_state.node_transform);
+ return light;
}
/**
* Create camera for the scene
*/
-void EditorSceneImporterAssimp::create_camera(ImportState &state, RecursiveState &recursive_state) {
- aiCamera *ai_camera = state.assimp_scene->mCameras[state.camera_cache[recursive_state.node_name]];
- ERR_FAIL_COND(!ai_camera);
-
- Camera *camera = memnew(Camera);
-
- float near = ai_camera->mClipPlaneNear;
+Spatial *EditorSceneImporterAssimp::create_camera(
+ ImportState &state,
+ const String &node_name,
+ Transform &look_at_transform) {
+ aiCamera *camera = state.assimp_scene->mCameras[state.camera_cache[node_name]];
+ ERR_FAIL_COND_V(!camera, NULL);
+
+ Camera *camera_node = memnew(Camera);
+ ERR_FAIL_COND_V(!camera_node, NULL);
+ float near = camera->mClipPlaneNear;
if (Math::is_equal_approx(near, 0.0f)) {
near = 0.1f;
}
- camera->set_perspective(Math::rad2deg(ai_camera->mHorizontalFOV) * 2.0f, near, ai_camera->mClipPlaneFar);
+ camera_node->set_perspective(Math::rad2deg(camera->mHorizontalFOV) * 2.0f, near, camera->mClipPlaneFar);
+ Vector3 pos = Vector3(camera->mPosition.x, camera->mPosition.y, camera->mPosition.z);
+ Vector3 look_at = Vector3(camera->mLookAt.y, camera->mLookAt.x, camera->mLookAt.z).normalized();
+ Vector3 up = Vector3(camera->mUp.x, camera->mUp.y, camera->mUp.z);
- Vector3 pos = Vector3(ai_camera->mPosition.x, ai_camera->mPosition.y, ai_camera->mPosition.z);
- Vector3 look_at = Vector3(ai_camera->mLookAt.y, ai_camera->mLookAt.x, ai_camera->mLookAt.z).normalized();
- Vector3 up = Vector3(ai_camera->mUp.x, ai_camera->mUp.y, ai_camera->mUp.z);
-
- Transform xform;
- xform.set_look_at(pos, look_at, up);
-
- recursive_state.new_node = camera;
-
- attach_new_node(state,
- recursive_state.new_node,
- recursive_state.assimp_node,
- recursive_state.parent_node,
- recursive_state.node_name,
- recursive_state.node_transform);
-}
-
-/**
- * Create Bone
- * Create a bone in the scene
- */
-void EditorSceneImporterAssimp::create_bone(ImportState &state, RecursiveState &recursive_state) {
- // for each armature node we must make a new skeleton but ensure it
- // has a bone in the child to ensure we don't make too many
- // the reason you must do this is because a skeleton exists per mesh?
- // and duplicate bone names are very bad for determining what is going on.
- aiBone *parent_bone_assimp = get_bone_by_name(state.assimp_scene, recursive_state.assimp_node->mParent->mName);
-
- // set to true when you want to use skeleton reference from cache.
- bool do_not_create_armature = false;
-
- // prevent more than one skeleton existing per mesh
- // * multiple root bones have this
- // * this simply filters the node out if it has already been added then references the skeleton so we know the actual skeleton for this node
- for (Map<Skeleton *, const Spatial *>::Element *key_value_pair = state.armature_skeletons.front(); key_value_pair; key_value_pair = key_value_pair->next()) {
- if (key_value_pair->value() == recursive_state.parent_node) {
- // apply the skeleton for this mesh
- recursive_state.skeleton = key_value_pair->key();
-
- // force this off
- do_not_create_armature = true;
- }
- }
-
- // check if parent was a bone
- // if parent was not a bone this is the first bone.
- // therefore parent is the 'armature'?
- // also for multi root bone support make sure we don't already have the skeleton cached.
- // if we do we must merge them - as this is all godot supports right now.
- if (!parent_bone_assimp && recursive_state.skeleton == NULL && !do_not_create_armature) {
- // create new skeleton on the root.
- recursive_state.skeleton = memnew(Skeleton);
-
- ERR_FAIL_COND(state.root == NULL);
- ERR_FAIL_COND(recursive_state.skeleton == NULL);
-
- print_verbose("Parent armature node is called " + recursive_state.parent_node->get_name());
- // store root node for this skeleton / used in animation playback and bone detection.
-
- state.armature_skeletons.insert(recursive_state.skeleton, Object::cast_to<Spatial>(recursive_state.parent_node));
-
- //skeleton->set_use_bones_in_world_transform(true);
- print_verbose("Created new FBX skeleton for armature node");
- }
-
- ERR_FAIL_COND_MSG(recursive_state.skeleton == NULL, "Mesh has invalid armature detection - report this");
-
- // this transform is a bone
- recursive_state.skeleton->add_bone(recursive_state.node_name);
-
- //ERR_FAIL_COND(recursive_state.skeleton->get_name() == "");
- print_verbose("Bone added to lookup: " + AssimpUtils::get_assimp_string(recursive_state.bone->mName));
- print_verbose("Skeleton attached to: " + recursive_state.skeleton->get_name());
- // make sure to write the bone lookup inverse so we can retrieve the mesh for this bone later
- state.bone_to_skeleton_lookup.insert(recursive_state.bone, recursive_state.skeleton);
-
- Transform xform = AssimpUtils::assimp_matrix_transform(recursive_state.bone->mOffsetMatrix);
- recursive_state.skeleton->set_bone_rest(recursive_state.skeleton->get_bone_count() - 1, xform.affine_inverse());
-
- // get parent node of assimp node
- const aiNode *parent_node_assimp = recursive_state.assimp_node->mParent;
-
- // ensure we have a parent
- if (parent_node_assimp != NULL) {
- int parent_bone_id = recursive_state.skeleton->find_bone(AssimpUtils::get_assimp_string(parent_node_assimp->mName));
- int current_bone_id = recursive_state.skeleton->find_bone(recursive_state.node_name);
- print_verbose("Parent bone id " + itos(parent_bone_id) + " current bone id" + itos(current_bone_id));
- print_verbose("Bone debug: " + AssimpUtils::get_assimp_string(parent_node_assimp->mName));
- recursive_state.skeleton->set_bone_parent(current_bone_id, parent_bone_id);
- }
+ look_at_transform.set_look_at(pos + look_at_transform.origin, look_at, up);
+ return camera_node;
}
/**
@@ -1309,46 +1490,30 @@ void EditorSceneImporterAssimp::create_bone(ImportState &state, RecursiveState &
*/
void EditorSceneImporterAssimp::_generate_node(
ImportState &state,
- Skeleton *skeleton,
- const aiNode *assimp_node, Node *parent_node) {
+ const aiNode *assimp_node) {
- // sanity check
- ERR_FAIL_COND(state.root == NULL);
- ERR_FAIL_COND(state.assimp_scene == NULL);
ERR_FAIL_COND(assimp_node == NULL);
- ERR_FAIL_COND(parent_node == NULL);
-
- Spatial *new_node = NULL;
+ state.nodes.push_back(assimp_node);
String node_name = AssimpUtils::get_assimp_string(assimp_node->mName);
- Transform node_transform = AssimpUtils::assimp_matrix_transform(assimp_node->mTransformation);
-
- // can safely return null - is this node a bone?
- aiBone *bone = get_bone_by_name(state.assimp_scene, assimp_node->mName);
-
- // out arguments helper - for pushing state down into creation functions
- RecursiveState recursive_state(node_transform, skeleton, new_node, node_name, assimp_node, parent_node, bone);
-
- // Creation code
- if (state.light_cache.has(node_name)) {
- create_light(state, recursive_state);
- } else if (state.camera_cache.has(node_name)) {
- create_camera(state, recursive_state);
- } else if (bone != NULL) {
- create_bone(state, recursive_state);
- } else {
- //generic node
- recursive_state.new_node = memnew(Spatial);
- attach_new_node(state,
- recursive_state.new_node,
- recursive_state.assimp_node,
- recursive_state.parent_node,
- recursive_state.node_name,
- recursive_state.node_transform);
+ String parent_name = AssimpUtils::get_assimp_string(assimp_node->mParent->mName);
+
+ // please note
+ // duplicate bone names exist
+ // this is why we only check if the bone exists
+ // so everything else is useless but the name
+ // please do not copy any other values from get_bone_by_name.
+ aiBone *parent_bone = get_bone_by_name(state.assimp_scene, assimp_node->mParent->mName);
+ aiBone *current_bone = get_bone_by_name(state.assimp_scene, assimp_node->mName);
+
+ // is this an armature
+ // parent null
+ // and this is the first bone :)
+ if (parent_bone == NULL && current_bone) {
+ state.armature_nodes.push_back(assimp_node->mParent);
+ print_verbose("found valid armature: " + parent_name);
}
- // recurse into all child elements
- for (size_t i = 0; i < recursive_state.assimp_node->mNumChildren; i++) {
- _generate_node(state, recursive_state.skeleton, recursive_state.assimp_node->mChildren[i],
- recursive_state.new_node != NULL ? recursive_state.new_node : recursive_state.parent_node);
+ for (size_t i = 0; i < assimp_node->mNumChildren; i++) {
+ _generate_node(state, assimp_node->mChildren[i]);
}
}
diff --git a/modules/assimp/editor_scene_importer_assimp.h b/modules/assimp/editor_scene_importer_assimp.h
index 787376c9af..a47d7ac46e 100644
--- a/modules/assimp/editor_scene_importer_assimp.h
+++ b/modules/assimp/editor_scene_importer_assimp.h
@@ -50,6 +50,7 @@
#include <assimp/DefaultLogger.hpp>
#include <assimp/LogStream.hpp>
#include <assimp/Logger.hpp>
+#include <map>
#include "import_state.h"
#include "import_utils.h"
@@ -72,7 +73,6 @@ public:
class EditorSceneImporterAssimp : public EditorSceneImporter {
private:
GDCLASS(EditorSceneImporterAssimp, EditorSceneImporter);
- const String ASSIMP_FBX_KEY = "_$AssimpFbx$";
struct AssetImportAnimation {
enum Interpolation {
@@ -88,40 +88,32 @@ private:
float weight;
};
- struct SkeletonHole { //nodes may be part of the skeleton by used by vertex
- String name;
- String parent;
- Transform pose;
- const aiNode *node;
- };
-
- void _calc_tangent_from_mesh(const aiMesh *ai_mesh, int i, int tri_index, int index, PoolColorArray::Write &w);
- void _set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<Texture> texture);
+ Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices,
+ const aiNode *assimp_node, Ref<Skin> &skin,
+ Skeleton *&skeleton_assigned);
- Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, const aiNode *assimp_node, Skeleton *p_skeleton = NULL);
-
- // utility for node creation
- void attach_new_node(ImportState &state, Spatial *new_node, const aiNode *node, Node *parent_node, String Name, Transform &transform);
// simple object creation functions
- void create_light(ImportState &state, RecursiveState &recursive_state);
- void create_camera(ImportState &state, RecursiveState &recursive_state);
- void create_bone(ImportState &state, RecursiveState &recursive_state);
+ Spatial *create_light(ImportState &state,
+ const String &node_name,
+ Transform &look_at_transform);
+ Spatial *create_camera(
+ ImportState &state,
+ const String &node_name,
+ Transform &look_at_transform);
// non recursive - linear so must not use recursive arguments
- void create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *current_node, Node *parent_node, Transform node_transform);
-
+ MeshInstance *create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *active_node, Transform node_transform);
// recursive node generator
- void _generate_node(ImportState &state, Skeleton *skeleton, const aiNode *assimp_node, Node *parent_node);
- // runs after _generate_node as it must then use pre-created godot skeleton.
- void generate_mesh_phase_from_skeletal_mesh(ImportState &state);
- void _insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int p_track, int p_bake_fps, Ref<Animation> animation, float ticks_per_second, Skeleton *p_skeleton, const NodePath &p_path, const String &p_name);
+ void _generate_node(ImportState &state, const aiNode *assimp_node);
+ void _insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int track_id,
+ int anim_fps, Ref<Animation> animation, float ticks_per_second,
+ Skeleton *skeleton, const NodePath &node_path,
+ const String &node_name, aiBone *track_bone);
void _import_animation(ImportState &state, int p_animation_index, int p_bake_fps);
-
+ Node *get_node_by_name(ImportState &state, String name);
+ aiBone *get_bone_from_stack(ImportState &state, aiString name);
Spatial *_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights);
- String _assimp_anim_string_to_string(const aiString &p_string) const;
- String _assimp_raw_string_to_string(const aiString &p_string) const;
- float _get_fbx_fps(int32_t time_mode, const aiScene *p_scene);
template <class T>
T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp);
void _register_project_setting_import(const String generic, const String import_setting_string, const Vector<String> &exts, List<String> *r_extensions, const bool p_enabled) const;
@@ -148,6 +140,10 @@ public:
virtual uint32_t get_import_flags() const;
virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL);
Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path);
+
+ static void RegenerateBoneStack(ImportState &state);
+
+ void RegenerateBoneStack(ImportState &state, aiMesh *mesh);
};
#endif
#endif
diff --git a/modules/assimp/import_state.h b/modules/assimp/import_state.h
index 56d89ffea7..9859a88c1c 100644
--- a/modules/assimp/import_state.h
+++ b/modules/assimp/import_state.h
@@ -52,28 +52,42 @@
namespace AssimpImporter {
/** Import state is for global scene import data
- * This makes the code simpler and contains useful lookups.
- */
+ * This makes the code simpler and contains useful lookups.
+ */
struct ImportState {
String path;
+ Spatial *root;
const aiScene *assimp_scene;
uint32_t max_bone_weights;
- Spatial *root;
Map<String, Ref<Mesh> > mesh_cache;
Map<int, Ref<Material> > material_cache;
Map<String, int> light_cache;
Map<String, int> camera_cache;
- //Vector<Skeleton *> skeletons;
- Map<Skeleton *, const Spatial *> armature_skeletons; // maps skeletons based on their armature nodes.
- Map<const aiBone *, Skeleton *> bone_to_skeleton_lookup; // maps bones back into their skeleton
+
// very useful for when you need to ask assimp for the bone mesh
- Map<String, Node *> node_map;
- Map<const aiNode *, const Node *> assimp_node_map;
+
+ Map<const aiNode *, Node *> assimp_node_map;
Map<String, Ref<Image> > path_to_image_cache;
- bool fbx; //for some reason assimp does some things different for FBX
+
+ // Generation 3 - determinisitic iteration
+ // to lower potential recursion errors
+ List<const aiNode *> nodes;
+ Map<const aiNode *, Spatial *> flat_node_map;
AnimationPlayer *animation_player;
+
+ // Generation 3 - deterministic armatures
+ // list of armature nodes - flat and simple to parse
+ // assimp node, node in godot
+ List<aiNode *> armature_nodes;
+ Map<const aiNode *, Skeleton *> armature_skeletons;
+ Map<aiBone *, Skeleton *> skeleton_bone_map;
+ // Generation 3 - deterministic bone handling
+ // bones from the stack are popped when found
+ // this means we can detect
+ // what bones are for other armatures
+ List<aiBone *> bone_stack;
};
struct AssimpImageData {
@@ -86,14 +100,15 @@ struct AssimpImageData {
* This makes the code easier to handle too and add extra arguments without breaking things
*/
struct RecursiveState {
+ RecursiveState() {} // do not construct :)
RecursiveState(
Transform &_node_transform,
Skeleton *_skeleton,
Spatial *_new_node,
- const String &_node_name,
- const aiNode *_assimp_node,
+ String &_node_name,
+ aiNode *_assimp_node,
Node *_parent_node,
- const aiBone *_bone) :
+ aiBone *_bone) :
node_transform(_node_transform),
skeleton(_skeleton),
new_node(_new_node),
@@ -102,13 +117,13 @@ struct RecursiveState {
parent_node(_parent_node),
bone(_bone) {}
- Transform &node_transform;
- Skeleton *skeleton;
- Spatial *new_node;
- const String &node_name;
- const aiNode *assimp_node;
- Node *parent_node;
- const aiBone *bone;
+ Transform node_transform;
+ Skeleton *skeleton = NULL;
+ Spatial *new_node = NULL;
+ String node_name;
+ aiNode *assimp_node = NULL;
+ Node *parent_node = NULL;
+ aiBone *bone = NULL;
};
} // namespace AssimpImporter
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index 5a76f32977..925fff0cc8 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -242,7 +242,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_
//check if edge and poly share a vertex, of so, assign it to segment_idx
for (int i = 0; i < points.size(); i++) {
for (int j = 0; j < 2; j++) {
- if (segment[j] == points[i].point) {
+ if (segment[j].is_equal_approx(points[i].point)) {
segment_idx[j] = i;
inserted_points.push_back(i);
break;
@@ -310,7 +310,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_
Vector2 edgeseg[2] = { points[edges[i].points[0]].point, points[edges[i].points[1]].point };
Vector2 closest = Geometry::get_closest_point_to_segment_2d(segment[j], edgeseg);
- if (closest == segment[j]) {
+ if (closest.is_equal_approx(segment[j])) {
//point rest of this edge
res = closest;
found = true;
@@ -439,7 +439,7 @@ void CSGBrushOperation::BuildPoly::clip(const CSGBrush *p_brush, int p_face, Mes
//transform A points to 2D
- if (segment[0] == segment[1])
+ if (segment[0].is_equal_approx(segment[1]))
return; //too small
_clip_segment(p_brush, p_face, segment, mesh_merge, p_for_B);
@@ -461,10 +461,10 @@ void CSGBrushOperation::_collision_callback(const CSGBrush *A, int p_face_a, Map
{
//check if either is a degenerate
- if (va[0] == va[1] || va[0] == va[2] || va[1] == va[2])
+ if (va[0].is_equal_approx(va[1]) || va[0].is_equal_approx(va[2]) || va[1].is_equal_approx(va[2]))
return;
- if (vb[0] == vb[1] || vb[0] == vb[2] || vb[1] == vb[2])
+ if (vb[0].is_equal_approx(vb[1]) || vb[0].is_equal_approx(vb[2]) || vb[1].is_equal_approx(vb[2]))
return;
}
diff --git a/modules/gdnative/gdnative/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp
index 74c540ca14..23791af67e 100644
--- a/modules/gdnative/gdnative/pool_arrays.cpp
+++ b/modules/gdnative/gdnative/pool_arrays.cpp
@@ -129,6 +129,11 @@ godot_int GDAPI godot_pool_byte_array_size(const godot_pool_byte_array *p_self)
return self->size();
}
+godot_bool GDAPI godot_pool_byte_array_empty(const godot_pool_byte_array *p_self) {
+ const PoolVector<uint8_t> *self = (const PoolVector<uint8_t> *)p_self;
+ return self->empty();
+}
+
void GDAPI godot_pool_byte_array_destroy(godot_pool_byte_array *p_self) {
((PoolVector<uint8_t> *)p_self)->~PoolVector();
}
@@ -218,6 +223,11 @@ godot_int GDAPI godot_pool_int_array_size(const godot_pool_int_array *p_self) {
return self->size();
}
+godot_bool GDAPI godot_pool_int_array_empty(const godot_pool_int_array *p_self) {
+ const PoolVector<godot_int> *self = (const PoolVector<godot_int> *)p_self;
+ return self->empty();
+}
+
void GDAPI godot_pool_int_array_destroy(godot_pool_int_array *p_self) {
((PoolVector<godot_int> *)p_self)->~PoolVector();
}
@@ -307,6 +317,11 @@ godot_int GDAPI godot_pool_real_array_size(const godot_pool_real_array *p_self)
return self->size();
}
+godot_bool GDAPI godot_pool_real_array_empty(const godot_pool_real_array *p_self) {
+ const PoolVector<godot_real> *self = (const PoolVector<godot_real> *)p_self;
+ return self->empty();
+}
+
void GDAPI godot_pool_real_array_destroy(godot_pool_real_array *p_self) {
((PoolVector<godot_real> *)p_self)->~PoolVector();
}
@@ -404,6 +419,11 @@ godot_int GDAPI godot_pool_string_array_size(const godot_pool_string_array *p_se
return self->size();
}
+godot_bool GDAPI godot_pool_string_array_empty(const godot_pool_string_array *p_self) {
+ const PoolVector<String> *self = (const PoolVector<String> *)p_self;
+ return self->empty();
+}
+
void GDAPI godot_pool_string_array_destroy(godot_pool_string_array *p_self) {
((PoolVector<String> *)p_self)->~PoolVector();
}
@@ -500,6 +520,11 @@ godot_int GDAPI godot_pool_vector2_array_size(const godot_pool_vector2_array *p_
return self->size();
}
+godot_bool GDAPI godot_pool_vector2_array_empty(const godot_pool_vector2_array *p_self) {
+ const PoolVector<Vector2> *self = (const PoolVector<Vector2> *)p_self;
+ return self->empty();
+}
+
void GDAPI godot_pool_vector2_array_destroy(godot_pool_vector2_array *p_self) {
((PoolVector<Vector2> *)p_self)->~PoolVector();
}
@@ -596,6 +621,11 @@ godot_int GDAPI godot_pool_vector3_array_size(const godot_pool_vector3_array *p_
return self->size();
}
+godot_bool GDAPI godot_pool_vector3_array_empty(const godot_pool_vector3_array *p_self) {
+ const PoolVector<Vector3> *self = (const PoolVector<Vector3> *)p_self;
+ return self->empty();
+}
+
void GDAPI godot_pool_vector3_array_destroy(godot_pool_vector3_array *p_self) {
((PoolVector<Vector3> *)p_self)->~PoolVector();
}
@@ -692,6 +722,11 @@ godot_int GDAPI godot_pool_color_array_size(const godot_pool_color_array *p_self
return self->size();
}
+godot_bool GDAPI godot_pool_color_array_empty(const godot_pool_color_array *p_self) {
+ const PoolVector<Color> *self = (const PoolVector<Color> *)p_self;
+ return self->empty();
+}
+
void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_self) {
((PoolVector<Color> *)p_self)->~PoolVector();
}
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 55ba4ecc1e..9e5295a936 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -91,6 +91,55 @@
["const godot_int", "p_step"],
["const godot_bool", "p_deep"]
]
+ },
+ {
+ "name": "godot_pool_byte_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_byte_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_int_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_int_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_real_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_real_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_string_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_string_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector2_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_vector2_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_vector3_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_vector3_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_pool_color_array_empty",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_pool_color_array *", "p_self"]
+ ]
}
]
},
diff --git a/modules/gdnative/include/gdnative/pool_arrays.h b/modules/gdnative/include/gdnative/pool_arrays.h
index 96730ab085..63e8267f0e 100644
--- a/modules/gdnative/include/gdnative/pool_arrays.h
+++ b/modules/gdnative/include/gdnative/pool_arrays.h
@@ -191,6 +191,8 @@ uint8_t GDAPI godot_pool_byte_array_get(const godot_pool_byte_array *p_self, con
godot_int GDAPI godot_pool_byte_array_size(const godot_pool_byte_array *p_self);
+godot_bool GDAPI godot_pool_byte_array_empty(const godot_pool_byte_array *p_self);
+
void GDAPI godot_pool_byte_array_destroy(godot_pool_byte_array *p_self);
// int
@@ -222,6 +224,8 @@ godot_int GDAPI godot_pool_int_array_get(const godot_pool_int_array *p_self, con
godot_int GDAPI godot_pool_int_array_size(const godot_pool_int_array *p_self);
+godot_bool GDAPI godot_pool_int_array_empty(const godot_pool_int_array *p_self);
+
void GDAPI godot_pool_int_array_destroy(godot_pool_int_array *p_self);
// real
@@ -253,6 +257,8 @@ godot_real GDAPI godot_pool_real_array_get(const godot_pool_real_array *p_self,
godot_int GDAPI godot_pool_real_array_size(const godot_pool_real_array *p_self);
+godot_bool GDAPI godot_pool_real_array_empty(const godot_pool_real_array *p_self);
+
void GDAPI godot_pool_real_array_destroy(godot_pool_real_array *p_self);
// string
@@ -284,6 +290,8 @@ godot_string GDAPI godot_pool_string_array_get(const godot_pool_string_array *p_
godot_int GDAPI godot_pool_string_array_size(const godot_pool_string_array *p_self);
+godot_bool GDAPI godot_pool_string_array_empty(const godot_pool_string_array *p_self);
+
void GDAPI godot_pool_string_array_destroy(godot_pool_string_array *p_self);
// vector2
@@ -315,6 +323,8 @@ godot_vector2 GDAPI godot_pool_vector2_array_get(const godot_pool_vector2_array
godot_int GDAPI godot_pool_vector2_array_size(const godot_pool_vector2_array *p_self);
+godot_bool GDAPI godot_pool_vector2_array_empty(const godot_pool_vector2_array *p_self);
+
void GDAPI godot_pool_vector2_array_destroy(godot_pool_vector2_array *p_self);
// vector3
@@ -346,6 +356,8 @@ godot_vector3 GDAPI godot_pool_vector3_array_get(const godot_pool_vector3_array
godot_int GDAPI godot_pool_vector3_array_size(const godot_pool_vector3_array *p_self);
+godot_bool GDAPI godot_pool_vector3_array_empty(const godot_pool_vector3_array *p_self);
+
void GDAPI godot_pool_vector3_array_destroy(godot_pool_vector3_array *p_self);
// color
@@ -377,6 +389,8 @@ godot_color GDAPI godot_pool_color_array_get(const godot_pool_color_array *p_sel
godot_int GDAPI godot_pool_color_array_size(const godot_pool_color_array *p_self);
+godot_bool GDAPI godot_pool_color_array_empty(const godot_pool_color_array *p_self);
+
void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_self);
//
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 1d0567dd8d..840971dcf8 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -21,7 +21,7 @@
<argument index="3" name="a8" type="int" default="255">
</argument>
<description>
- Returns a 32 bit color with red, green, blue and alpha channels. Each channel has 8 bits of information ranging from 0 to 255.
+ Returns a color constructed from integer red, green, blue, and alpha channels. Each channel should have 8 bits of information ranging from 0 to 255.
[code]r8[/code] red channel
[code]g8[/code] green channel
[code]b8[/code] blue channel
@@ -839,6 +839,7 @@
printraw("B")
# Prints AB
[/codeblock]
+ [b]Note:[/b] Due to limitations with Godot's built-in console, this only prints to the terminal. If you need to print in the editor, use another method, such as [method print].
</description>
</method>
<method name="prints" qualifiers="vararg">
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index db7f8d22e6..b90fab8221 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -199,7 +199,7 @@ StringName GDScript::get_instance_base_type() const {
if (native.is_valid())
return native->get_name();
- if (base.is_valid())
+ if (base.is_valid() && base->is_valid())
return base->get_instance_base_type();
return StringName();
}
@@ -486,7 +486,7 @@ bool GDScript::_update_exports() {
placeholder_fallback_enabled = false;
- if (base_cache.is_valid()) {
+ if (base_cache.is_valid() && base_cache->is_valid()) {
if (base_cache->_update_exports()) {
changed = true;
}
@@ -2141,6 +2141,7 @@ GDScriptLanguage::GDScriptLanguage() {
#ifdef DEBUG_ENABLED
GLOBAL_DEF("debug/gdscript/warnings/enable", true);
GLOBAL_DEF("debug/gdscript/warnings/treat_warnings_as_errors", false);
+ GLOBAL_DEF("debug/gdscript/warnings/exclude_addons", true);
GLOBAL_DEF("debug/gdscript/completion/autocomplete_setters_and_getters", false);
for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) {
String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower();
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index 83d02e4977..d8816726ce 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -1561,14 +1561,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
//error
// function, file, line, error, explanation
String err_file;
- if (p_instance && p_instance->script->is_valid() && p_instance->script->path != "")
+ if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->path != "")
err_file = p_instance->script->path;
else if (script)
err_file = script->path;
if (err_file == "")
err_file = "<built-in>";
String err_func = name;
- if (p_instance && p_instance->script->is_valid() && p_instance->script->name != "")
+ if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->name != "")
err_func = p_instance->script->name + "." + err_func;
int err_line = line;
if (err_text == "") {
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index c4c7ba5ef7..bbafef68ed 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -1126,7 +1126,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
Dictionary d;
d["@subpath"] = cp;
- d["@path"] = p->path;
+ d["@path"] = p->get_path();
p = base.ptr();
@@ -1274,6 +1274,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
if (err != OK) {
r_ret = Variant();
+ ERR_PRINTS(vformat("Error parsing JSON at line %s: %s", errl, errs));
}
} break;
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 9d229adb2a..74b9440b3a 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -8373,6 +8373,9 @@ void GDScriptParser::_add_warning(int p_code, int p_line, const String &p_symbol
}
void GDScriptParser::_add_warning(int p_code, int p_line, const Vector<String> &p_symbols) {
+ if (GLOBAL_GET("debug/gdscript/warnings/exclude_addons").booleanize() && base_path.begins_with("res://addons/")) {
+ return;
+ }
if (tokenizer->is_ignoring_warnings() || !GLOBAL_GET("debug/gdscript/warnings/enable").booleanize()) {
return;
}
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index f79aea9531..1bd570c55f 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -1330,6 +1330,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
info_message->set_valign(Label::VALIGN_CENTER);
info_message->set_align(Label::ALIGN_CENTER);
info_message->set_autowrap(true);
+ info_message->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
mesh_library_palette->add_child(info_message);
diff --git a/modules/mono/glue/Managed/Files/AABB.cs b/modules/mono/glue/Managed/Files/AABB.cs
index 98a73382f4..6a4f785551 100644
--- a/modules/mono/glue/Managed/Files/AABB.cs
+++ b/modules/mono/glue/Managed/Files/AABB.cs
@@ -458,6 +458,11 @@ namespace Godot
return _position == other._position && _size == other._size;
}
+ public bool IsEqualApprox(AABB other)
+ {
+ return _position.IsEqualApprox(other._position) && _size.IsEqualApprox(other._size);
+ }
+
public override int GetHashCode()
{
return _position.GetHashCode() ^ _size.GetHashCode();
diff --git a/modules/mono/glue/Managed/Files/Basis.cs b/modules/mono/glue/Managed/Files/Basis.cs
index 0eb76e9c63..c5e62b77c8 100644
--- a/modules/mono/glue/Managed/Files/Basis.cs
+++ b/modules/mono/glue/Managed/Files/Basis.cs
@@ -654,6 +654,11 @@ namespace Godot
return Row0.Equals(other.Row0) && Row1.Equals(other.Row1) && Row2.Equals(other.Row2);
}
+ public bool IsEqualApprox(Basis other)
+ {
+ return Row0.IsEqualApprox(other.Row0) && Row1.IsEqualApprox(other.Row1) && Row2.IsEqualApprox(other.Row2);
+ }
+
public override int GetHashCode()
{
return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode();
diff --git a/modules/mono/glue/Managed/Files/Color.cs b/modules/mono/glue/Managed/Files/Color.cs
index 3a52a1a13b..df817e47e9 100644
--- a/modules/mono/glue/Managed/Files/Color.cs
+++ b/modules/mono/glue/Managed/Files/Color.cs
@@ -661,6 +661,11 @@ namespace Godot
public bool Equals(Color other)
{
+ return r == other.r && g == other.g && b == other.b && a == other.a;
+ }
+
+ public bool IsEqualApprox(Color other)
+ {
return Mathf.IsEqualApprox(r, other.r) && Mathf.IsEqualApprox(g, other.g) && Mathf.IsEqualApprox(b, other.b) && Mathf.IsEqualApprox(a, other.a);
}
diff --git a/modules/mono/glue/Managed/Files/Mathf.cs b/modules/mono/glue/Managed/Files/Mathf.cs
index ce34cd6a99..54821fe790 100644
--- a/modules/mono/glue/Managed/Files/Mathf.cs
+++ b/modules/mono/glue/Managed/Files/Mathf.cs
@@ -19,12 +19,12 @@ namespace Godot
private const real_t Deg2RadConst = (real_t) 0.0174532925199432957692369077M; // 0.0174532924f and 0.0174532925199433
private const real_t Rad2DegConst = (real_t) 57.295779513082320876798154814M; // 57.29578f and 57.2957795130823
- public static real_t Abs(real_t s)
+ public static int Abs(int s)
{
return Math.Abs(s);
}
- public static int Abs(int s)
+ public static real_t Abs(real_t s)
{
return Math.Abs(s);
}
@@ -79,29 +79,6 @@ namespace Godot
return (real_t)Math.Cosh(s);
}
- public static int StepDecimals(real_t step)
- {
- double[] sd = new double[] {
- 0.9999,
- 0.09999,
- 0.009999,
- 0.0009999,
- 0.00009999,
- 0.000009999,
- 0.0000009999,
- 0.00000009999,
- 0.000000009999,
- };
- double abs = Mathf.Abs(step);
- double decs = abs - (int)abs; // Strip away integer part
- for (int i = 0; i < sd.Length; i++) {
- if (decs >= sd[i]) {
- return i;
- }
- }
- return 0;
- }
-
public static real_t Deg2Rad(real_t deg)
{
return deg * Deg2RadConst;
@@ -159,12 +136,14 @@ namespace Godot
public static bool IsEqualApprox(real_t a, real_t b)
{
// Check for exact equality first, required to handle "infinity" values.
- if (a == b) {
+ if (a == b)
+ {
return true;
}
// Then check for approximate equality.
real_t tolerance = Epsilon * Abs(a);
- if (tolerance < Epsilon) {
+ if (tolerance < Epsilon)
+ {
tolerance = Epsilon;
}
return Abs(a - b) < tolerance;
@@ -190,7 +169,8 @@ namespace Godot
return from + (to - from) * weight;
}
- public static real_t LerpAngle(real_t from, real_t to, real_t weight) {
+ public static real_t LerpAngle(real_t from, real_t to, real_t weight)
+ {
real_t difference = (to - from) % Mathf.Tau;
real_t distance = ((2 * difference) % Mathf.Tau) - difference;
return from + distance * weight;
@@ -246,9 +226,9 @@ namespace Godot
/// <summary>
/// Performs a canonical Modulus operation, where the output is on the range [0, b).
/// </summary>
- public static real_t PosMod(real_t a, real_t b)
+ public static int PosMod(int a, int b)
{
- real_t c = a % b;
+ int c = a % b;
if ((c < 0 && b > 0) || (c > 0 && b < 0))
{
c += b;
@@ -259,9 +239,9 @@ namespace Godot
/// <summary>
/// Performs a canonical Modulus operation, where the output is on the range [0, b).
/// </summary>
- public static int PosMod(int a, int b)
+ public static real_t PosMod(real_t a, real_t b)
{
- int c = a % b;
+ real_t c = a % b;
if ((c < 0 && b > 0) || (c > 0 && b < 0))
{
c += b;
@@ -319,6 +299,31 @@ namespace Godot
return (real_t)Math.Sqrt(s);
}
+ public static int StepDecimals(real_t step)
+ {
+ double[] sd = new double[] {
+ 0.9999,
+ 0.09999,
+ 0.009999,
+ 0.0009999,
+ 0.00009999,
+ 0.000009999,
+ 0.0000009999,
+ 0.00000009999,
+ 0.000000009999,
+ };
+ double abs = Mathf.Abs(step);
+ double decs = abs - (int)abs; // Strip away integer part
+ for (int i = 0; i < sd.Length; i++)
+ {
+ if (decs >= sd[i])
+ {
+ return i;
+ }
+ }
+ return 0;
+ }
+
public static real_t Stepify(real_t s, real_t step)
{
if (step != 0f)
diff --git a/modules/mono/glue/Managed/Files/MathfEx.cs b/modules/mono/glue/Managed/Files/MathfEx.cs
index 6cffc7f01d..1b7fd4906f 100644
--- a/modules/mono/glue/Managed/Files/MathfEx.cs
+++ b/modules/mono/glue/Managed/Files/MathfEx.cs
@@ -49,7 +49,8 @@ namespace Godot
public static bool IsEqualApprox(real_t a, real_t b, real_t tolerance)
{
// Check for exact equality first, required to handle "infinity" values.
- if (a == b) {
+ if (a == b)
+ {
return true;
}
// Then check for approximate equality.
diff --git a/modules/mono/glue/Managed/Files/Plane.cs b/modules/mono/glue/Managed/Files/Plane.cs
index 26e717e089..885845e3a4 100644
--- a/modules/mono/glue/Managed/Files/Plane.cs
+++ b/modules/mono/glue/Managed/Files/Plane.cs
@@ -204,7 +204,12 @@ namespace Godot
public bool Equals(Plane other)
{
- return _normal == other._normal && Mathf.IsEqualApprox(D, other.D);
+ return _normal == other._normal && D == other.D;
+ }
+
+ public bool IsEqualApprox(Plane other)
+ {
+ return _normal.IsEqualApprox(other._normal) && Mathf.IsEqualApprox(D, other.D);
}
public override int GetHashCode()
diff --git a/modules/mono/glue/Managed/Files/Quat.cs b/modules/mono/glue/Managed/Files/Quat.cs
index 845c7c730e..8f60867ac3 100644
--- a/modules/mono/glue/Managed/Files/Quat.cs
+++ b/modules/mono/glue/Managed/Files/Quat.cs
@@ -363,6 +363,11 @@ namespace Godot
public bool Equals(Quat other)
{
+ return x == other.x && y == other.y && z == other.z && w == other.w;
+ }
+
+ public bool IsEqualApprox(Quat other)
+ {
return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z) && Mathf.IsEqualApprox(w, other.w);
}
diff --git a/modules/mono/glue/Managed/Files/Rect2.cs b/modules/mono/glue/Managed/Files/Rect2.cs
index 99542d0c0a..91e614dc7b 100644
--- a/modules/mono/glue/Managed/Files/Rect2.cs
+++ b/modules/mono/glue/Managed/Files/Rect2.cs
@@ -231,6 +231,11 @@ namespace Godot
return _position.Equals(other._position) && _size.Equals(other._size);
}
+ public bool IsEqualApprox(Rect2 other)
+ {
+ return _position.IsEqualApprox(other._position) && _size.IsEqualApprox(other.Size);
+ }
+
public override int GetHashCode()
{
return _position.GetHashCode() ^ _size.GetHashCode();
diff --git a/modules/mono/glue/Managed/Files/Transform.cs b/modules/mono/glue/Managed/Files/Transform.cs
index cc4d26158d..0b84050f07 100644
--- a/modules/mono/glue/Managed/Files/Transform.cs
+++ b/modules/mono/glue/Managed/Files/Transform.cs
@@ -185,6 +185,11 @@ namespace Godot
return basis.Equals(other.basis) && origin.Equals(other.origin);
}
+ public bool IsEqualApprox(Transform other)
+ {
+ return basis.IsEqualApprox(other.basis) && origin.IsEqualApprox(other.origin);
+ }
+
public override int GetHashCode()
{
return basis.GetHashCode() ^ origin.GetHashCode();
diff --git a/modules/mono/glue/Managed/Files/Transform2D.cs b/modules/mono/glue/Managed/Files/Transform2D.cs
index 814332dc07..77ea3e5830 100644
--- a/modules/mono/glue/Managed/Files/Transform2D.cs
+++ b/modules/mono/glue/Managed/Files/Transform2D.cs
@@ -357,6 +357,11 @@ namespace Godot
return x.Equals(other.x) && y.Equals(other.y) && origin.Equals(other.origin);
}
+ public bool IsEqualApprox(Transform2D other)
+ {
+ return x.IsEqualApprox(other.x) && y.IsEqualApprox(other.y) && origin.IsEqualApprox(other.origin);
+ }
+
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode() ^ origin.GetHashCode();
diff --git a/modules/mono/glue/Managed/Files/Vector2.cs b/modules/mono/glue/Managed/Files/Vector2.cs
index 0daa94057e..f92453f546 100644
--- a/modules/mono/glue/Managed/Files/Vector2.cs
+++ b/modules/mono/glue/Managed/Files/Vector2.cs
@@ -455,6 +455,11 @@ namespace Godot
public bool Equals(Vector2 other)
{
+ return x == other.x && y == other.y;
+ }
+
+ public bool IsEqualApprox(Vector2 other)
+ {
return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y);
}
diff --git a/modules/mono/glue/Managed/Files/Vector3.cs b/modules/mono/glue/Managed/Files/Vector3.cs
index 9076dbd3b0..025b09199f 100644
--- a/modules/mono/glue/Managed/Files/Vector3.cs
+++ b/modules/mono/glue/Managed/Files/Vector3.cs
@@ -513,6 +513,11 @@ namespace Godot
public bool Equals(Vector3 other)
{
+ return x == other.x && y == other.y && z == other.z;
+ }
+
+ public bool IsEqualApprox(Vector3 other)
+ {
return Mathf.IsEqualApprox(x, other.x) && Mathf.IsEqualApprox(y, other.y) && Mathf.IsEqualApprox(z, other.z);
}
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 0cacd0f0b5..bb8612af6f 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -1361,6 +1361,7 @@ void VisualScript::_bind_methods() {
VisualScript::VisualScript() {
base_type = "Object";
+ is_tool_script = false;
}
StringName VisualScript::get_default_func() const {
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index ca0d77f047..6aae2fd15b 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -3515,6 +3515,7 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
}
Ref<VisualScriptNode> vnode;
+ Ref<VisualScriptPropertySet> script_prop_set;
if (p_category == String("method")) {
@@ -3525,8 +3526,8 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
Ref<VisualScriptPropertySet> n;
n.instance();
- n->set_property(p_text);
vnode = n;
+ script_prop_set = n;
} else if (p_category == String("get")) {
Ref<VisualScriptPropertyGet> n;
@@ -3578,6 +3579,9 @@ 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())
+ script_prop_set->set_property(p_text);
+
port_action_new_node = new_id;
Ref<VisualScriptNode> vsn = script->get_node(func, port_action_new_node);
@@ -4221,7 +4225,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
if (nd.is_valid() && nd->has_input_sequence_port())
start_node = nodes.front()->key();
else {
- EditorNode::get_singleton()->show_warning(TTR("Select atleast one node with sequence port."));
+ EditorNode::get_singleton()->show_warning(TTR("Select at least one node with sequence port."));
return;
}
} else {
@@ -4252,7 +4256,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
if (nd.is_valid() && nd->has_input_sequence_port())
start_node = top_nd;
else {
- EditorNode::get_singleton()->show_warning(TTR("Select atleast one node with sequence port."));
+ EditorNode::get_singleton()->show_warning(TTR("Select at least one node with sequence port."));
return;
}
} else {
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index defee8f1f1..9156181bbe 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -49,6 +49,9 @@
#include "java_godot_io_wrapper.h"
#include "java_godot_wrapper.h"
+#define PAN_GESTURE_MIN_DELTA 5 // only advertise PanGesture event with dx and dy greater than this
+#define MAGNIFY_GESTURE_MIN_FACTOR 0.1 // only advertise MagnifyGesture event with a factor difference from 1.0 greater than this
+
class AndroidLogger : public Logger {
public:
virtual void logv(const char *p_format, va_list p_list, bool p_err) {
@@ -406,6 +409,35 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
ERR_FAIL_COND(touch.size() != p_points.size());
+ if (touch.size() == 1) {
+ Point2 d = (p_points[0].pos - touch.write[0].pos);
+ if (fabs(d.x) > PAN_GESTURE_MIN_DELTA || fabs(d.y) > PAN_GESTURE_MIN_DELTA) {
+ Ref<InputEventPanGesture> ev;
+ ev.instance();
+ ev->set_position(p_points[0].pos);
+ ev->set_delta(d);
+ input->parse_input_event(ev);
+ touch.write[0].pos = p_points[0].pos;
+ }
+ } else if (touch.size() == 2) {
+ Point2 v0 = touch[1].pos - touch[0].pos;
+ float l0 = (v0.x * v0.x) + (v0.y * v0.y);
+ if (l0 != 0.0) {
+ Point2 v1 = p_points[1].pos - p_points[0].pos;
+ float l1 = (v1.x * v1.x) + (v1.y * v1.y);
+ float f = (l1 / l0);
+ if (fabs(f - 1.0) > MAGNIFY_GESTURE_MIN_FACTOR) {
+ Ref<InputEventMagnifyGesture> ev;
+ ev.instance();
+ ev->set_position(p_points[0].pos + v1 / 2);
+ ev->set_factor(sqrt(f));
+ input->parse_input_event(ev);
+ touch.write[0].pos = p_points[0].pos;
+ touch.write[1].pos = p_points[1].pos;
+ }
+ }
+ }
+
for (int i = 0; i < touch.size(); i++) {
int idx = -1;
@@ -420,7 +452,7 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
ERR_CONTINUE(idx == -1);
if (touch[i].pos == p_points[idx].pos)
- continue; //no move unncesearily
+ continue; //no unnecessary move
Ref<InputEventScreenDrag> ev;
ev.instance();
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index 2ac158e6d3..4e6b8e1ada 100644
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -340,6 +340,7 @@ static void clear_touches() {
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
+ [self drawView];
}
- (BOOL)createFramebuffer {
@@ -455,23 +456,23 @@ static void clear_touches() {
// Updates the OpenGL view when the timer fires
- (void)drawView {
+
+ if (!active) {
+ printf("draw view not active!\n");
+ return;
+ };
if (useCADisplayLink) {
// Pause the CADisplayLink to avoid recursion
[displayLink setPaused:YES];
// Process all input events
- while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource)
+ while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, TRUE) == kCFRunLoopRunHandledSource)
;
// We are good to go, resume the CADisplayLink
[displayLink setPaused:NO];
}
- if (!active) {
- printf("draw view not active!\n");
- return;
- };
-
// Make sure that you are drawing to the current context
[EAGLContext setCurrentContext:context];
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 15885e1266..ba3ac9862e 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -709,6 +709,11 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
const CGFloat backingScaleFactor = [[event window] backingScaleFactor];
const Vector2 pos = get_mouse_pos([event locationInWindow], backingScaleFactor);
mm->set_position(pos);
+ mm->set_pressure([event pressure]);
+ if ([event subtype] == NSTabletPointEventSubtype) {
+ const NSPoint p = [event tilt];
+ mm->set_tilt(Vector2(p.x, p.y));
+ }
mm->set_global_position(pos);
mm->set_speed(OS_OSX::singleton->input->get_last_mouse_speed());
Vector2 relativeMotion = Vector2();
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 55d667c101..e73cfcf241 100644..100755
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -70,6 +70,10 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
#define WM_TOUCH 576
#endif
+#ifndef WM_POINTERUPDATE
+#define WM_POINTERUPDATE 0x0245
+#endif
+
typedef struct {
int count;
int screen;
@@ -192,6 +196,9 @@ BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) {
}
}
+GetPointerTypePtr OS_Windows::win8p_GetPointerType = NULL;
+GetPointerPenInfoPtr OS_Windows::win8p_GetPointerPenInfo = NULL;
+
void OS_Windows::initialize_debugging() {
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
@@ -481,6 +488,119 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
delete[] lpb;
} break;
+ case WM_POINTERUPDATE: {
+ if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
+ break;
+ }
+
+ if (!win8p_GetPointerType || !win8p_GetPointerPenInfo) {
+ 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;
+ }
+
+ POINTER_PEN_INFO pen_info;
+ if (!win8p_GetPointerPenInfo(pointer_id, &pen_info)) {
+ break;
+ }
+
+ if (input->is_emulating_mouse_from_touch()) {
+ // Universal translation enabled; ignore OS translation
+ LPARAM extra = GetMessageExtraInfo();
+ if (IsTouchEvent(extra)) {
+ break;
+ }
+ }
+
+ if (outside) {
+ //mouse enter
+
+ if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
+ main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
+
+ CursorShape c = cursor_shape;
+ cursor_shape = CURSOR_MAX;
+ set_cursor_shape(c);
+ outside = false;
+
+ //Once-Off notification, must call again....
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hWnd;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ TrackMouseEvent(&tme);
+ }
+
+ // Don't calculate relative mouse movement if we don't have focus in CAPTURED mode.
+ if (!window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED)
+ break;
+
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
+
+ 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));
+
+ mm->set_control((wParam & MK_CONTROL) != 0);
+ mm->set_shift((wParam & MK_SHIFT) != 0);
+ mm->set_alt(alt_mem);
+
+ mm->set_button_mask(last_button_state);
+
+ POINT coords; //client coords
+ coords.x = GET_X_LPARAM(lParam);
+ coords.y = GET_Y_LPARAM(lParam);
+
+ ScreenToClient(hWnd, &coords);
+
+ 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(video_mode.width / 2, video_mode.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(hWnd, &pos);
+ SetCursorPos(pos.x, pos.y);
+ }
+
+ input->set_mouse_position(mm->get_position());
+ mm->set_speed(input->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 (window_has_focus && main_loop)
+ input->parse_input_event(mm);
+
+ return 0; //Pointer event handled return 0 to avoid duplicate WM_MOUSEMOVE event
+ } break;
case WM_MOUSEMOVE: {
if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
break;
@@ -3256,6 +3376,13 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
was_maximized = false;
console_visible = IsWindowVisible(GetConsoleWindow());
+ //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");
+ }
+
hInstance = _hInstance;
pressrc = 0;
old_invalid = true;
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index b0e665e574..ce279fb033 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -56,6 +56,71 @@
#include <windows.h>
#include <windowsx.h>
+#ifndef POINTER_STRUCTURES
+
+#define POINTER_STRUCTURES
+
+typedef DWORD POINTER_INPUT_TYPE;
+typedef UINT32 POINTER_FLAGS;
+typedef UINT32 PEN_FLAGS;
+typedef UINT32 PEN_MASK;
+
+enum tagPOINTER_INPUT_TYPE {
+ PT_POINTER = 0x00000001,
+ PT_TOUCH = 0x00000002,
+ PT_PEN = 0x00000003,
+ PT_MOUSE = 0x00000004,
+ PT_TOUCHPAD = 0x00000005
+};
+
+typedef enum tagPOINTER_BUTTON_CHANGE_TYPE {
+ POINTER_CHANGE_NONE,
+ POINTER_CHANGE_FIRSTBUTTON_DOWN,
+ POINTER_CHANGE_FIRSTBUTTON_UP,
+ POINTER_CHANGE_SECONDBUTTON_DOWN,
+ POINTER_CHANGE_SECONDBUTTON_UP,
+ POINTER_CHANGE_THIRDBUTTON_DOWN,
+ POINTER_CHANGE_THIRDBUTTON_UP,
+ POINTER_CHANGE_FOURTHBUTTON_DOWN,
+ POINTER_CHANGE_FOURTHBUTTON_UP,
+ POINTER_CHANGE_FIFTHBUTTON_DOWN,
+ POINTER_CHANGE_FIFTHBUTTON_UP,
+} POINTER_BUTTON_CHANGE_TYPE;
+
+typedef struct tagPOINTER_INFO {
+ POINTER_INPUT_TYPE pointerType;
+ UINT32 pointerId;
+ UINT32 frameId;
+ POINTER_FLAGS pointerFlags;
+ HANDLE sourceDevice;
+ HWND hwndTarget;
+ POINT ptPixelLocation;
+ POINT ptHimetricLocation;
+ POINT ptPixelLocationRaw;
+ POINT ptHimetricLocationRaw;
+ DWORD dwTime;
+ UINT32 historyCount;
+ INT32 InputData;
+ DWORD dwKeyStates;
+ UINT64 PerformanceCount;
+ POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
+} POINTER_INFO;
+
+typedef struct tagPOINTER_PEN_INFO {
+ POINTER_INFO pointerInfo;
+ PEN_FLAGS penFlags;
+ PEN_MASK penMask;
+ UINT32 pressure;
+ UINT32 rotation;
+ INT32 tiltX;
+ INT32 tiltY;
+} POINTER_PEN_INFO;
+
+#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);
+
typedef struct {
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
@@ -77,6 +142,9 @@ typedef struct {
class JoypadWindows;
class OS_Windows : public OS {
+ static GetPointerTypePtr win8p_GetPointerType;
+ static GetPointerPenInfoPtr win8p_GetPointerPenInfo;
+
enum {
KEY_EVENT_BUFFER_SIZE = 512
};
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 694aea7462..c695d657e7 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -83,6 +83,12 @@
#define XINPUT_CLIENT_VERSION_MAJOR 2
#define XINPUT_CLIENT_VERSION_MINOR 2
+#define VALUATOR_ABSX 0
+#define VALUATOR_ABSY 1
+#define VALUATOR_PRESSURE 2
+#define VALUATOR_TILTX 3
+#define VALUATOR_TILTY 4
+
static const double abs_resolution_mult = 10000.0;
static const double abs_resolution_range_mult = 10.0;
@@ -665,6 +671,15 @@ bool OS_X11::refresh_device_info() {
int range_min_y = 0;
int range_max_x = 0;
int range_max_y = 0;
+ int pressure_resolution = 0;
+ int pressure_min = 0;
+ int pressure_max = 0;
+ int tilt_resolution_x = 0;
+ int tilt_resolution_y = 0;
+ int tilt_range_min_x = 0;
+ int tilt_range_min_y = 0;
+ int tilt_range_max_x = 0;
+ int tilt_range_max_y = 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) {
@@ -674,16 +689,28 @@ bool OS_X11::refresh_device_info() {
if (dev->classes[j]->type == XIValuatorClass) {
XIValuatorClassInfo *class_info = (XIValuatorClassInfo *)dev->classes[j];
- if (class_info->number == 0 && class_info->mode == XIModeAbsolute) {
+ 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;
absolute_mode = true;
- } else if (class_info->number == 1 && class_info->mode == XIModeAbsolute) {
+ } 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;
absolute_mode = true;
+ } else if (class_info->number == VALUATOR_PRESSURE && class_info->mode == XIModeAbsolute) {
+ pressure_resolution = class_info->resolution;
+ 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->resolution;
+ tilt_range_min_x = class_info->min;
+ tilt_range_max_x = class_info->max;
+ } else if (class_info->number == VALUATOR_TILTY && class_info->mode == XIModeAbsolute) {
+ tilt_resolution_y = class_info->resolution;
+ tilt_range_min_y = class_info->min;
+ tilt_range_max_y = class_info->max;
}
}
}
@@ -703,6 +730,18 @@ bool OS_X11::refresh_device_info() {
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));
}
+
+ if (pressure_resolution <= 0) {
+ pressure_resolution = (pressure_max - pressure_min);
+ }
+ if (tilt_resolution_x <= 0) {
+ tilt_resolution_x = (tilt_range_max_x - tilt_range_min_x);
+ }
+ if (tilt_resolution_y <= 0) {
+ tilt_resolution_y = (tilt_range_max_y - tilt_range_min_y);
+ }
+ xi.pressure = 0;
+ xi.pen_devices[dev->deviceid] = Vector3(pressure_resolution, tilt_resolution_x, tilt_resolution_y);
}
XIFreeDeviceInfo(info);
@@ -2095,14 +2134,39 @@ void OS_X11::process_xevents() {
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, 0)) {
+ if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_ABSX)) {
rel_x = *values;
values++;
}
- if (XIMaskIsSet(raw_event->valuators.mask, 1)) {
+ if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_ABSY)) {
rel_y = *values;
+ values++;
+ }
+
+ if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_PRESSURE)) {
+ pressure = *values;
+ values++;
+ }
+
+ if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_TILTX)) {
+ tilt_x = *values;
+ values++;
+ }
+
+ if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_TILTY)) {
+ tilt_y = *values;
+ }
+
+ 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);
}
// https://bugs.freedesktop.org/show_bug.cgi?id=71609
@@ -2417,6 +2481,9 @@ void OS_X11::process_xevents() {
Ref<InputEventMouseMotion> mm;
mm.instance();
+ mm->set_pressure(xi.pressure);
+ mm->set_tilt(xi.tilt);
+
// Make the absolute position integral so it doesn't look _too_ weird :)
Point2i posi(pos);
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index e6c2effacf..a5576f4402 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -131,9 +131,12 @@ class OS_X11 : public OS_Unix {
int opcode;
Vector<int> touch_devices;
Map<int, Vector2> absolute_devices;
+ Map<int, Vector3> pen_devices;
XIEventMask all_event_mask;
XIEventMask all_master_event_mask;
Map<int, Vector2> state;
+ double pressure;
+ Vector2 tilt;
Vector2 mouse_pos_to_filter;
Vector2 relative_motion;
Vector2 raw_pos;
diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp
index 5cf28d6c89..c7d2dabbae 100644
--- a/scene/2d/navigation_2d.cpp
+++ b/scene/2d/navigation_2d.cpp
@@ -541,7 +541,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
if (CLOCK_TANGENT(apex_point, portal_left, left) >= 0) {
//process
- if (Math::is_zero_approx(portal_left.distance_squared_to(apex_point)) || CLOCK_TANGENT(apex_point, left, portal_right) > 0) {
+ if (portal_left.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, left, portal_right) > 0) {
left_poly = p;
portal_left = left;
} else {
@@ -551,7 +551,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
left_poly = p;
portal_left = apex_point;
portal_right = apex_point;
- if (!path.size() || path[path.size() - 1] != apex_point)
+ if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point))
path.push_back(apex_point);
skip = true;
}
@@ -559,7 +559,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
if (!skip && CLOCK_TANGENT(apex_point, portal_right, right) <= 0) {
//process
- if (Math::is_zero_approx(portal_right.distance_squared_to(apex_point)) || CLOCK_TANGENT(apex_point, right, portal_left) < 0) {
+ if (portal_right.is_equal_approx(apex_point) || CLOCK_TANGENT(apex_point, right, portal_left) < 0) {
right_poly = p;
portal_right = right;
} else {
@@ -569,7 +569,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
right_poly = p;
portal_right = apex_point;
portal_left = apex_point;
- if (!path.size() || path[path.size() - 1] != apex_point)
+ if (!path.size() || !path[path.size() - 1].is_equal_approx(apex_point))
path.push_back(apex_point);
}
}
@@ -595,7 +595,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
}
}
- if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_squared_to(begin_point))) {
+ if (!path.size() || !path[path.size() - 1].is_equal_approx(begin_point)) {
path.push_back(begin_point); // Add the begin point
} else {
path.write[path.size() - 1] = begin_point; // Replace first midpoint by the exact begin point
@@ -603,7 +603,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect
path.invert();
- if (path.size() <= 1 || !Math::is_zero_approx(path[path.size() - 1].distance_squared_to(end_point))) {
+ if (path.size() <= 1 || !path[path.size() - 1].is_equal_approx(end_point)) {
path.push_back(end_point); // Add the end point
} else {
path.write[path.size() - 1] = end_point; // Replace last midpoint by the exact end point
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index cf68528388..9a1a759e72 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -325,12 +325,8 @@ void TouchScreenButton::_release(bool p_exiting_tree) {
}
Rect2 TouchScreenButton::_edit_get_rect() const {
- if (texture.is_null()) {
- if (shape.is_valid())
- return shape->get_rect();
- else
- return CanvasItem::_edit_get_rect();
- }
+ if (texture.is_null())
+ return CanvasItem::_edit_get_rect();
return Rect2(Size2(), texture->get_size());
}
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index a02cc4bee6..a107c3bf7a 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1201,7 +1201,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
if (p_stop_on_slope) {
if ((lv_n + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) {
Transform gt = get_global_transform();
- gt.origin -= collision.travel;
+ gt.origin -= collision.travel.slide(p_floor_direction);
set_global_transform(gt);
return Vector3();
}
@@ -1265,7 +1265,7 @@ Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity
if (p_stop_on_slope) {
// move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case.
- col.travel = p_floor_direction * p_floor_direction.dot(col.travel);
+ col.travel = col.travel.project(p_floor_direction);
}
} else {
apply = false; //snapped with floor direction, but did not snap to a floor, do not snap.
diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp
index 9bd89f1121..6883da7f6d 100644
--- a/scene/3d/soft_body.cpp
+++ b/scene/3d/soft_body.cpp
@@ -115,7 +115,7 @@ SoftBody::PinnedPoint SoftBody::PinnedPoint::operator=(const PinnedPoint &obj) {
void SoftBody::_update_pickable() {
if (!is_inside_tree())
return;
- bool pickable = ray_pickable && is_inside_tree() && is_visible_in_tree();
+ bool pickable = ray_pickable && is_visible_in_tree();
PhysicsServer::get_singleton()->soft_body_set_ray_pickable(physics_rid, pickable);
}
@@ -395,6 +395,8 @@ void SoftBody::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "pose_matching_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_pose_matching_coefficient", "get_pose_matching_coefficient");
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ray_pickable"), "set_ray_pickable", "is_ray_pickable");
}
String SoftBody::get_configuration_warning() const {
@@ -700,7 +702,8 @@ SoftBody::SoftBody() :
collision_mask(1),
collision_layer(1),
simulation_started(false),
- pinned_points_cache_dirty(true) {
+ pinned_points_cache_dirty(true),
+ ray_pickable(true) {
PhysicsServer::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id());
//set_notify_transform(true);
diff --git a/scene/SCsub b/scene/SCsub
index d8839ce3a8..1c5b87b87a 100644
--- a/scene/SCsub
+++ b/scene/SCsub
@@ -30,6 +30,7 @@ SConscript('2d/SCsub')
SConscript('animation/SCsub')
SConscript('audio/SCsub')
SConscript('resources/SCsub')
+SConscript('debugger/SCsub')
# Build it all as a library
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp
index 416a291da1..7fe544eaab 100644
--- a/scene/animation/animation_blend_space_1d.cpp
+++ b/scene/animation/animation_blend_space_1d.cpp
@@ -157,6 +157,7 @@ Ref<AnimationRootNode> AnimationNodeBlendSpace1D::get_blend_point_node(int p_poi
void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) {
ERR_FAIL_INDEX(p_point, blend_points_used);
+ ERR_FAIL_COND(blend_points[p_point].node.is_null());
blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
for (int i = p_point; i < blend_points_used - 1; i++) {
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index 75031f0149..b04eefbe31 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -113,6 +113,7 @@ Ref<AnimationRootNode> AnimationNodeBlendSpace2D::get_blend_point_node(int p_poi
void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
ERR_FAIL_INDEX(p_point, blend_points_used);
+ ERR_FAIL_COND(blend_points[p_point].node.is_null());
blend_points[p_point].node->disconnect("tree_changed", this, "_tree_changed");
for (int i = 0; i < triangles.size(); i++) {
diff --git a/scene/debugger/SCsub b/scene/debugger/SCsub
new file mode 100644
index 0000000000..b01e2fd54d
--- /dev/null
+++ b/scene/debugger/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import('env')
+
+env.add_source_files(env.scene_sources, "*.cpp")
diff --git a/core/script_debugger_remote.cpp b/scene/debugger/script_debugger_remote.cpp
index 65ef2a0978..c3c6a088cb 100644
--- a/core/script_debugger_remote.cpp
+++ b/scene/debugger/script_debugger_remote.cpp
@@ -37,7 +37,10 @@
#include "core/os/os.h"
#include "core/project_settings.h"
#include "scene/main/node.h"
+#include "scene/main/scene_tree.h"
+#include "scene/main/viewport.h"
#include "scene/resources/packed_scene.h"
+#include "servers/visual_server.h"
void ScriptDebuggerRemote::_send_video_memory() {
@@ -150,7 +153,10 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue,
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;
while (true) {
+ loop_begin_usec = OS::get_singleton()->get_ticks_usec();
_get_output();
@@ -279,9 +285,10 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue,
break;
} else if (command == "request_scene_tree") {
- if (request_scene_tree)
- request_scene_tree(request_scene_tree_ud);
-
+#ifdef DEBUG_ENABLED
+ if (scene_tree)
+ scene_tree->_debugger_request_tree();
+#endif
} else if (command == "request_video_mem") {
_send_video_memory();
@@ -293,6 +300,40 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue,
_set_object_property(cmd[1], cmd[2], cmd[3]);
+ } else if (command == "override_camera_2D:set") {
+ bool enforce = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->enable_canvas_transform_override(enforce);
+ }
+ } else if (command == "override_camera_2D:transform") {
+ Transform2D transform = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->set_canvas_transform_override(transform);
+ }
+ } else if (command == "override_camera_3D:set") {
+ bool enable = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->enable_camera_override(enable);
+ }
+ } else if (command == "override_camera_3D:transform") {
+ Transform transform = cmd[1];
+ bool is_perspective = cmd[2];
+ float size_or_fov = cmd[3];
+ float near = cmd[4];
+ float far = cmd[5];
+
+ if (scene_tree) {
+ if (is_perspective) {
+ scene_tree->get_root()->set_camera_override_perspective(size_or_fov, near, far);
+ } else {
+ scene_tree->get_root()->set_camera_override_orthogonal(size_or_fov, near, far);
+ }
+ scene_tree->get_root()->set_camera_override_transform(transform);
+ }
+
} else if (command == "reload_scripts") {
reload_all_scripts = true;
} else if (command == "breakpoint") {
@@ -315,6 +356,13 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue,
OS::get_singleton()->delay_usec(10000);
OS::get_singleton()->process_and_drop_events();
}
+
+ // This is for the camera override to stay live even when the game is paused from the editor
+ loop_time_sec = (OS::get_singleton()->get_ticks_usec() - loop_begin_usec) / 1000000.0f;
+ VisualServer::get_singleton()->sync();
+ if (VisualServer::get_singleton()->has_changed()) {
+ VisualServer::get_singleton()->draw(true, loop_time_sec * Engine::get_singleton()->get_time_scale());
+ }
}
packet_peer_stream->put_var("debug_exit");
@@ -446,93 +494,75 @@ void ScriptDebuggerRemote::_err_handler(void *ud, const char *p_func, const char
bool ScriptDebuggerRemote::_parse_live_edit(const Array &p_command) {
+#ifdef DEBUG_ENABLED
+
String cmdstr = p_command[0];
- if (!live_edit_funcs || !cmdstr.begins_with("live_"))
+ if (!scene_tree || !cmdstr.begins_with("live_"))
return false;
- //print_line(Variant(cmd).get_construct_string());
if (cmdstr == "live_set_root") {
- if (!live_edit_funcs->root_func)
- return true;
- //print_line("root: "+Variant(cmd).get_construct_string());
- live_edit_funcs->root_func(live_edit_funcs->udata, p_command[1], p_command[2]);
+ scene_tree->_live_edit_root_func(p_command[1], p_command[2]);
} else if (cmdstr == "live_node_path") {
- if (!live_edit_funcs->node_path_func)
- return true;
- //print_line("path: "+Variant(cmd).get_construct_string());
-
- live_edit_funcs->node_path_func(live_edit_funcs->udata, p_command[1], p_command[2]);
+ scene_tree->_live_edit_node_path_func(p_command[1], p_command[2]);
} else if (cmdstr == "live_res_path") {
- if (!live_edit_funcs->res_path_func)
- return true;
- live_edit_funcs->res_path_func(live_edit_funcs->udata, p_command[1], p_command[2]);
+ scene_tree->_live_edit_res_path_func(p_command[1], p_command[2]);
} else if (cmdstr == "live_node_prop_res") {
- if (!live_edit_funcs->node_set_res_func)
- return true;
- live_edit_funcs->node_set_res_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_node_set_res_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_node_prop") {
- if (!live_edit_funcs->node_set_func)
- return true;
- live_edit_funcs->node_set_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_node_set_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_res_prop_res") {
- if (!live_edit_funcs->res_set_res_func)
- return true;
- live_edit_funcs->res_set_res_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_res_set_res_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_res_prop") {
- if (!live_edit_funcs->res_set_func)
- return true;
- live_edit_funcs->res_set_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_res_set_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_node_call") {
- if (!live_edit_funcs->node_call_func)
- return true;
- live_edit_funcs->node_call_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3], p_command[4], p_command[5], p_command[6], p_command[7]);
+ scene_tree->_live_edit_node_call_func(p_command[1], p_command[2], p_command[3], p_command[4], p_command[5], p_command[6], p_command[7]);
} else if (cmdstr == "live_res_call") {
- if (!live_edit_funcs->res_call_func)
- return true;
- live_edit_funcs->res_call_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3], p_command[4], p_command[5], p_command[6], p_command[7]);
+ scene_tree->_live_edit_res_call_func(p_command[1], p_command[2], p_command[3], p_command[4], p_command[5], p_command[6], p_command[7]);
} else if (cmdstr == "live_create_node") {
- live_edit_funcs->tree_create_node_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_create_node_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_instance_node") {
- live_edit_funcs->tree_instance_node_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_instance_node_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_remove_node") {
- live_edit_funcs->tree_remove_node_func(live_edit_funcs->udata, p_command[1]);
+ scene_tree->_live_edit_remove_node_func(p_command[1]);
} else if (cmdstr == "live_remove_and_keep_node") {
- live_edit_funcs->tree_remove_and_keep_node_func(live_edit_funcs->udata, p_command[1], p_command[2]);
+ scene_tree->_live_edit_remove_and_keep_node_func(p_command[1], p_command[2]);
+
} else if (cmdstr == "live_restore_node") {
- live_edit_funcs->tree_restore_node_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3]);
+ scene_tree->_live_edit_restore_node_func(p_command[1], p_command[2], p_command[3]);
} else if (cmdstr == "live_duplicate_node") {
- live_edit_funcs->tree_duplicate_node_func(live_edit_funcs->udata, p_command[1], p_command[2]);
+ scene_tree->_live_edit_duplicate_node_func(p_command[1], p_command[2]);
+
} else if (cmdstr == "live_reparent_node") {
- live_edit_funcs->tree_reparent_node_func(live_edit_funcs->udata, p_command[1], p_command[2], p_command[3], p_command[4]);
+ scene_tree->_live_edit_reparent_node_func(p_command[1], p_command[2], p_command[3], p_command[4]);
} else {
@@ -540,6 +570,10 @@ bool ScriptDebuggerRemote::_parse_live_edit(const Array &p_command) {
}
return true;
+#else
+
+ return false;
+#endif
}
void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {
@@ -732,8 +766,10 @@ void ScriptDebuggerRemote::_poll_events() {
debug(get_break_language());
} else if (command == "request_scene_tree") {
- if (request_scene_tree)
- request_scene_tree(request_scene_tree_ud);
+#ifdef DEBUG_ENABLED
+ if (scene_tree)
+ scene_tree->_debugger_request_tree();
+#endif
} else if (command == "request_video_mem") {
_send_video_memory();
@@ -777,6 +813,40 @@ void ScriptDebuggerRemote::_poll_events() {
multiplayer->profiling_end();
profiling_network = false;
+ } else if (command == "override_camera_2D:set") {
+ bool enforce = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->enable_canvas_transform_override(enforce);
+ }
+ } else if (command == "override_camera_2D:transform") {
+ Transform2D transform = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->set_canvas_transform_override(transform);
+ }
+ } else if (command == "override_camera_3D:set") {
+ bool enable = cmd[1];
+
+ if (scene_tree) {
+ scene_tree->get_root()->enable_camera_override(enable);
+ }
+ } else if (command == "override_camera_3D:transform") {
+ Transform transform = cmd[1];
+ bool is_perspective = cmd[2];
+ float size_or_fov = cmd[3];
+ float near = cmd[4];
+ float far = cmd[5];
+
+ if (scene_tree) {
+ if (is_perspective) {
+ scene_tree->get_root()->set_camera_override_perspective(size_or_fov, near, far);
+ } else {
+ scene_tree->get_root()->set_camera_override_orthogonal(size_or_fov, near, far);
+ }
+ scene_tree->get_root()->set_camera_override_transform(transform);
+ }
+
} else if (command == "reload_scripts") {
reload_all_scripts = true;
} else if (command == "breakpoint") {
@@ -1106,17 +1176,6 @@ void ScriptDebuggerRemote::request_quit() {
requested_quit = true;
}
-void ScriptDebuggerRemote::set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata) {
-
- request_scene_tree = p_func;
- request_scene_tree_ud = p_udata;
-}
-
-void ScriptDebuggerRemote::set_live_edit_funcs(LiveEditFuncs *p_funcs) {
-
- live_edit_funcs = p_funcs;
-}
-
void ScriptDebuggerRemote::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
multiplayer = p_multiplayer;
}
@@ -1195,8 +1254,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() :
msec_count(0),
locking(false),
poll_every(0),
- request_scene_tree(NULL),
- live_edit_funcs(NULL) {
+ scene_tree(NULL) {
packet_peer_stream->set_stream_peer(tcp_client);
packet_peer_stream->set_output_buffer_max_size(1024 * 1024 * 8); //8mb should be way more than enough
diff --git a/core/script_debugger_remote.h b/scene/debugger/script_debugger_remote.h
index b6dd925181..13ad7ddbe3 100644
--- a/core/script_debugger_remote.h
+++ b/scene/debugger/script_debugger_remote.h
@@ -37,6 +37,8 @@
#include "core/os/os.h"
#include "core/script_language.h"
+class SceneTree;
+
class ScriptDebuggerRemote : public ScriptDebugger {
struct Message {
@@ -116,16 +118,14 @@ class ScriptDebuggerRemote : public ScriptDebugger {
void _poll_events();
uint32_t poll_every;
- bool _parse_live_edit(const Array &p_command);
+ SceneTree *scene_tree;
- RequestSceneTreeMessageFunc request_scene_tree;
- void *request_scene_tree_ud;
+ bool _parse_live_edit(const Array &p_command);
void _set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value);
void _send_object_id(ObjectID p_id);
void _send_video_memory();
- LiveEditFuncs *live_edit_funcs;
Ref<MultiplayerAPI> multiplayer;
@@ -176,8 +176,6 @@ public:
virtual void send_message(const String &p_message, const Array &p_args);
virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<ScriptLanguage::StackInfo> &p_stack_info);
- virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata);
- virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs);
virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
virtual bool is_profiling() const;
@@ -189,6 +187,8 @@ public:
virtual void set_skip_breakpoints(bool p_skip_breakpoints);
+ void set_scene_tree(SceneTree *p_scene_tree) { scene_tree = p_scene_tree; };
+
ScriptDebuggerRemote();
~ScriptDebuggerRemote();
};
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 062089d80b..a1b584bad6 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -239,12 +239,14 @@ void WindowDialog::_notification(int p_what) {
#ifdef TOOLS_ENABLED
case NOTIFICATION_POST_POPUP: {
- if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton())
+ if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton()) {
+ was_editor_dimmed = EditorNode::get_singleton()->is_editor_dimmed();
EditorNode::get_singleton()->dim_editor(true);
+ }
} break;
case NOTIFICATION_POPUP_HIDE: {
- if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton() && !get_viewport()->gui_has_modal_stack())
+ if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton() && !was_editor_dimmed)
EditorNode::get_singleton()->dim_editor(false);
} break;
#endif
@@ -345,6 +347,10 @@ WindowDialog::WindowDialog() {
close_button = memnew(TextureButton);
add_child(close_button);
close_button->connect("pressed", this, "_closed");
+
+#ifdef TOOLS_ENABLED
+ was_editor_dimmed = false;
+#endif
}
WindowDialog::~WindowDialog() {
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index afd1173f28..2eb0978e9b 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -59,6 +59,10 @@ class WindowDialog : public Popup {
Point2 drag_offset_far;
bool resizable;
+#ifdef TOOLS_ENABLED
+ bool was_editor_dimmed;
+#endif
+
void _gui_input(const Ref<InputEvent> &p_event);
void _closed();
int _drag_hit_test(const Point2 &pos) const;
@@ -106,7 +110,6 @@ class AcceptDialog : public WindowDialog {
HBoxContainer *hbc;
Label *label;
Button *ok;
- //Button *cancel; no more cancel (there is X on that titlebar)
bool hide_on_ok;
void _custom_action(const String &p_action);
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 1a0539effa..1406586361 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -411,6 +411,7 @@ 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 {
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 4edd4b8530..9e2cd9e941 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -296,8 +296,9 @@ Size2 Label::get_minimum_size() const {
Size2 min_style = get_stylebox("normal")->get_minimum_size();
// don't want to mutable everything
- if (word_cache_dirty)
+ if (word_cache_dirty) {
const_cast<Label *>(this)->regenerate_word_cache();
+ }
if (autowrap)
return Size2(1, clip ? 1 : minsize.height) + min_style;
@@ -377,8 +378,14 @@ void Label::regenerate_word_cache() {
memdelete(current);
}
- Ref<StyleBox> style = get_stylebox("normal");
- int width = autowrap ? (get_size().width - style->get_minimum_size().width) : get_longest_line_width();
+ int width;
+ if (autowrap) {
+ Ref<StyleBox> style = get_stylebox("normal");
+ width = MAX(get_size().width, get_custom_minimum_size().width) - style->get_minimum_size().width;
+ } else {
+ width = get_longest_line_width();
+ }
+
Ref<Font> font = get_font("font");
int current_word_size = 0;
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 9f853cf0c8..ba57be1686 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -101,26 +101,26 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
if (!mm.is_valid() && !mb.is_valid()) {
- if (p_event->is_action("ui_left") && p_event->is_pressed()) {
+ if (p_event->is_action_pressed("ui_left", true)) {
if (orientation != HORIZONTAL)
return;
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
accept_event();
- } else if (p_event->is_action("ui_right") && p_event->is_pressed()) {
+ } else if (p_event->is_action_pressed("ui_right", true)) {
if (orientation != HORIZONTAL)
return;
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
accept_event();
- } else if (p_event->is_action("ui_up") && p_event->is_pressed()) {
+ } else if (p_event->is_action_pressed("ui_up", true)) {
if (orientation != VERTICAL)
return;
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
accept_event();
- } else if (p_event->is_action("ui_down") && p_event->is_pressed()) {
+ } else if (p_event->is_action_pressed("ui_down", true)) {
if (orientation != VERTICAL)
return;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 8cf6099279..c818633f48 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -3928,7 +3928,9 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
if (shift_first_line) {
text.set_breakpoint(p_line + 1, text.is_breakpoint(p_line));
text.set_hidden(p_line + 1, text.is_hidden(p_line));
- text.set_info_icon(p_line + 1, text.get_info_icon(p_line), text.get_info(p_line));
+ if (text.has_info_icon(p_line)) {
+ text.set_info_icon(p_line + 1, text.get_info_icon(p_line), text.get_info(p_line));
+ }
text.set_breakpoint(p_line, false);
text.set_hidden(p_line, false);
@@ -5443,11 +5445,11 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc
PoolVector<int> 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, col, line)) {
+ if (search(p_key, p_search_flags, p_from_line, p_from_column, line, col)) {
PoolVector<int> result;
result.resize(2);
- result.set(0, line);
- result.set(1, col);
+ result.set(SEARCH_RESULT_COLUMN, col);
+ result.set(SEARCH_RESULT_LINE, line);
return result;
} else {
@@ -6535,6 +6537,7 @@ void TextEdit::_update_completion_candidates() {
if (inquote && restore_quotes == 1 && !option.display.is_quoted()) {
String quote = single_quote ? "'" : "\"";
option.display = option.display.quote(quote);
+ option.insert_text = option.insert_text.quote(quote);
}
if (option.display.begins_with(s)) {
@@ -6960,6 +6963,9 @@ 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);
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index e640bf0ea9..594366de7d 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -504,12 +504,16 @@ public:
};
enum SearchFlags {
-
SEARCH_MATCH_CASE = 1,
SEARCH_WHOLE_WORDS = 2,
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;
@@ -768,6 +772,7 @@ public:
VARIANT_ENUM_CAST(TextEdit::MenuItems);
VARIANT_ENUM_CAST(TextEdit::SearchFlags);
+VARIANT_ENUM_CAST(TextEdit::SearchResult);
class SyntaxHighlighter {
protected:
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index c9d1295557..2c38676c83 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1234,7 +1234,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
}
- if (select_mode != SELECT_ROW && (p_item->cells[i].selected || selected_item == p_item)) {
+ if ((select_mode == SELECT_ROW && selected_item == p_item) || p_item->cells[i].selected) {
Rect2i r(cell_rect.position, cell_rect.size);
if (p_item->cells[i].text.size() > 0) {
@@ -2765,7 +2765,6 @@ bool Tree::edit_selected() {
return false;
Rect2 rect = s->get_meta("__focus_rect");
-
popup_edited_item = s;
popup_edited_item_col = col;
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 38ad6886b1..5653049060 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -40,6 +40,7 @@
#include "core/project_settings.h"
#include "main/input_default.h"
#include "node.h"
+#include "scene/debugger/script_debugger_remote.h"
#include "scene/resources/dynamic_font.h"
#include "scene/resources/material.h"
#include "scene/resources/mesh.h"
@@ -1094,27 +1095,6 @@ void SceneTree::get_nodes_in_group(const StringName &p_group, List<Node *> *p_li
}
}
-static void _fill_array(Node *p_node, Array &array, int p_level) {
-
- array.push_back(p_node->get_child_count());
- array.push_back(p_node->get_name());
- array.push_back(p_node->get_class());
- array.push_back(p_node->get_instance_id());
- for (int i = 0; i < p_node->get_child_count(); i++) {
-
- _fill_array(p_node->get_child(i), array, p_level + 1);
- }
-}
-
-void SceneTree::_debugger_request_tree(void *self) {
-
- SceneTree *sml = (SceneTree *)self;
-
- Array arr;
- _fill_array(sml->root, arr, 0);
- ScriptDebugger::get_singleton()->send_message("scene_tree", arr);
-}
-
void SceneTree::_flush_delete_queue() {
_THREAD_SAFE_METHOD_
@@ -1337,6 +1317,25 @@ void SceneTree::add_current_scene(Node *p_current) {
}
#ifdef DEBUG_ENABLED
+static void _fill_array(Node *p_node, Array &array, int p_level) {
+
+ array.push_back(p_node->get_child_count());
+ array.push_back(p_node->get_name());
+ array.push_back(p_node->get_class());
+ array.push_back(p_node->get_instance_id());
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+
+ _fill_array(p_node->get_child(i), array, p_level + 1);
+ }
+}
+
+void SceneTree::_debugger_request_tree() {
+
+ Array arr;
+ _fill_array(root, arr, 0);
+ ScriptDebugger::get_singleton()->send_message("scene_tree", arr);
+}
+
void SceneTree::_live_edit_node_path_func(const NodePath &p_path, int p_id) {
live_edit_node_path_cache[p_id] = p_path;
@@ -2117,7 +2116,11 @@ SceneTree::SceneTree() {
_update_root_rect();
if (ScriptDebugger::get_singleton()) {
- ScriptDebugger::get_singleton()->set_request_scene_tree_message_func(_debugger_request_tree, this);
+ if (ScriptDebugger::get_singleton()->is_remote()) {
+ ScriptDebuggerRemote *remote_debugger = static_cast<ScriptDebuggerRemote *>(ScriptDebugger::get_singleton());
+
+ remote_debugger->set_scene_tree(this);
+ }
ScriptDebugger::get_singleton()->set_multiplayer(multiplayer);
}
@@ -2129,29 +2132,6 @@ SceneTree::SceneTree() {
#ifdef DEBUG_ENABLED
- live_edit_funcs.udata = this;
- live_edit_funcs.node_path_func = _live_edit_node_path_funcs;
- live_edit_funcs.res_path_func = _live_edit_res_path_funcs;
- live_edit_funcs.node_set_func = _live_edit_node_set_funcs;
- live_edit_funcs.node_set_res_func = _live_edit_node_set_res_funcs;
- live_edit_funcs.node_call_func = _live_edit_node_call_funcs;
- live_edit_funcs.res_set_func = _live_edit_res_set_funcs;
- live_edit_funcs.res_set_res_func = _live_edit_res_set_res_funcs;
- live_edit_funcs.res_call_func = _live_edit_res_call_funcs;
- live_edit_funcs.root_func = _live_edit_root_funcs;
-
- live_edit_funcs.tree_create_node_func = _live_edit_create_node_funcs;
- live_edit_funcs.tree_instance_node_func = _live_edit_instance_node_funcs;
- live_edit_funcs.tree_remove_node_func = _live_edit_remove_node_funcs;
- live_edit_funcs.tree_remove_and_keep_node_func = _live_edit_remove_and_keep_node_funcs;
- live_edit_funcs.tree_restore_node_func = _live_edit_restore_node_funcs;
- live_edit_funcs.tree_duplicate_node_func = _live_edit_duplicate_node_funcs;
- live_edit_funcs.tree_reparent_node_func = _live_edit_reparent_node_funcs;
-
- if (ScriptDebugger::get_singleton()) {
- ScriptDebugger::get_singleton()->set_live_edit_funcs(&live_edit_funcs);
- }
-
live_edit_root = NodePath("/root");
#endif
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index ef847ebb5b..2cf6a117e7 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -211,7 +211,6 @@ private:
Variant _call_group_flags(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
Variant _call_group(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
- static void _debugger_request_tree(void *self);
void _flush_delete_queue();
//optimization
friend class CanvasItem;
@@ -220,6 +219,7 @@ private:
SelfList<Node>::List xform_change_list;
+ friend class ScriptDebuggerRemote;
#ifdef DEBUG_ENABLED
Map<int, NodePath> live_edit_node_path_cache;
@@ -231,7 +231,7 @@ private:
Map<String, Set<Node *> > live_scene_edit_cache;
Map<Node *, Map<ObjectID, Node *> > live_edit_remove_list;
- ScriptDebugger::LiveEditFuncs live_edit_funcs;
+ void _debugger_request_tree();
void _live_edit_node_path_func(const NodePath &p_path, int p_id);
void _live_edit_res_path_func(const String &p_path, int p_id);
@@ -252,25 +252,6 @@ private:
void _live_edit_duplicate_node_func(const NodePath &p_at, const String &p_new_name);
void _live_edit_reparent_node_func(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos);
- static void _live_edit_node_path_funcs(void *self, const NodePath &p_path, int p_id) { reinterpret_cast<SceneTree *>(self)->_live_edit_node_path_func(p_path, p_id); }
- static void _live_edit_res_path_funcs(void *self, const String &p_path, int p_id) { reinterpret_cast<SceneTree *>(self)->_live_edit_res_path_func(p_path, p_id); }
-
- static void _live_edit_node_set_funcs(void *self, int p_id, const StringName &p_prop, const Variant &p_value) { reinterpret_cast<SceneTree *>(self)->_live_edit_node_set_func(p_id, p_prop, p_value); }
- static void _live_edit_node_set_res_funcs(void *self, int p_id, const StringName &p_prop, const String &p_value) { reinterpret_cast<SceneTree *>(self)->_live_edit_node_set_res_func(p_id, p_prop, p_value); }
- static void _live_edit_node_call_funcs(void *self, int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) { reinterpret_cast<SceneTree *>(self)->_live_edit_node_call_func(p_id, p_method, VARIANT_ARG_PASS); }
- static void _live_edit_res_set_funcs(void *self, int p_id, const StringName &p_prop, const Variant &p_value) { reinterpret_cast<SceneTree *>(self)->_live_edit_res_set_func(p_id, p_prop, p_value); }
- static void _live_edit_res_set_res_funcs(void *self, int p_id, const StringName &p_prop, const String &p_value) { reinterpret_cast<SceneTree *>(self)->_live_edit_res_set_res_func(p_id, p_prop, p_value); }
- static void _live_edit_res_call_funcs(void *self, int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) { reinterpret_cast<SceneTree *>(self)->_live_edit_res_call_func(p_id, p_method, VARIANT_ARG_PASS); }
- static void _live_edit_root_funcs(void *self, const NodePath &p_scene_path, const String &p_scene_from) { reinterpret_cast<SceneTree *>(self)->_live_edit_root_func(p_scene_path, p_scene_from); }
-
- static void _live_edit_create_node_funcs(void *self, const NodePath &p_parent, const String &p_type, const String &p_name) { reinterpret_cast<SceneTree *>(self)->_live_edit_create_node_func(p_parent, p_type, p_name); }
- static void _live_edit_instance_node_funcs(void *self, const NodePath &p_parent, const String &p_path, const String &p_name) { reinterpret_cast<SceneTree *>(self)->_live_edit_instance_node_func(p_parent, p_path, p_name); }
- static void _live_edit_remove_node_funcs(void *self, const NodePath &p_at) { reinterpret_cast<SceneTree *>(self)->_live_edit_remove_node_func(p_at); }
- static void _live_edit_remove_and_keep_node_funcs(void *self, const NodePath &p_at, ObjectID p_keep_id) { reinterpret_cast<SceneTree *>(self)->_live_edit_remove_and_keep_node_func(p_at, p_keep_id); }
- static void _live_edit_restore_node_funcs(void *self, ObjectID p_id, const NodePath &p_at, int p_at_pos) { reinterpret_cast<SceneTree *>(self)->_live_edit_restore_node_func(p_id, p_at, p_at_pos); }
- static void _live_edit_duplicate_node_funcs(void *self, const NodePath &p_at, const String &p_new_name) { reinterpret_cast<SceneTree *>(self)->_live_edit_duplicate_node_func(p_at, p_new_name); }
- static void _live_edit_reparent_node_funcs(void *self, const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos) { reinterpret_cast<SceneTree *>(self)->_live_edit_reparent_node_func(p_at, p_new_place, p_new_name, p_at_pos); }
-
#endif
enum {
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 95536bbb23..1af88171f6 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -779,10 +779,45 @@ bool Viewport::is_audio_listener_2d() const {
return audio_listener_2d;
}
+void Viewport::enable_canvas_transform_override(bool p_enable) {
+ if (override_canvas_transform == p_enable) {
+ return;
+ }
+
+ override_canvas_transform = p_enable;
+ if (p_enable) {
+ VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform_override);
+ } else {
+ VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform);
+ }
+}
+
+bool Viewport::is_canvas_transform_override_enbled() const {
+ return override_canvas_transform;
+}
+
+void Viewport::set_canvas_transform_override(const Transform2D &p_transform) {
+ if (canvas_transform_override == p_transform) {
+ return;
+ }
+
+ canvas_transform_override = p_transform;
+ if (override_canvas_transform) {
+ VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform_override);
+ }
+}
+
+Transform2D Viewport::get_canvas_transform_override() const {
+ return canvas_transform_override;
+}
+
void Viewport::set_canvas_transform(const Transform2D &p_transform) {
canvas_transform = p_transform;
- VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform);
+
+ if (!override_canvas_transform) {
+ VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, find_world_2d()->get_canvas(), canvas_transform);
+ }
}
Transform2D Viewport::get_canvas_transform() const {
@@ -890,10 +925,12 @@ void Viewport::_camera_set(Camera *p_camera) {
camera->notification(Camera::NOTIFICATION_LOST_CURRENT);
}
camera = p_camera;
- if (camera)
- VisualServer::get_singleton()->viewport_attach_camera(viewport, camera->get_camera());
- else
- VisualServer::get_singleton()->viewport_attach_camera(viewport, RID());
+ if (!camera_override) {
+ if (camera)
+ VisualServer::get_singleton()->viewport_attach_camera(viewport, camera->get_camera());
+ else
+ VisualServer::get_singleton()->viewport_attach_camera(viewport, RID());
+ }
if (camera) {
camera->notification(Camera::NOTIFICATION_BECAME_CURRENT);
@@ -1108,10 +1145,82 @@ Listener *Viewport::get_listener() const {
}
Camera *Viewport::get_camera() const {
-
return camera;
}
+void Viewport::enable_camera_override(bool p_enable) {
+
+#ifndef _3D_DISABLED
+ if (p_enable == camera_override) {
+ return;
+ }
+
+ if (p_enable) {
+ camera_override.rid = VisualServer::get_singleton()->camera_create();
+ } else {
+ VisualServer::get_singleton()->free(camera_override.rid);
+ camera_override.rid = RID();
+ }
+
+ if (p_enable) {
+ VisualServer::get_singleton()->viewport_attach_camera(viewport, camera_override.rid);
+ } else if (camera) {
+ VisualServer::get_singleton()->viewport_attach_camera(viewport, camera->get_camera());
+ } else {
+ VisualServer::get_singleton()->viewport_attach_camera(viewport, RID());
+ }
+#endif
+}
+
+bool Viewport::is_camera_override_enabled() const {
+ return camera_override;
+}
+
+void Viewport::set_camera_override_transform(const Transform &p_transform) {
+ if (camera_override) {
+ camera_override.transform = p_transform;
+ VisualServer::get_singleton()->camera_set_transform(camera_override.rid, p_transform);
+ }
+}
+
+Transform Viewport::get_camera_override_transform() const {
+ if (camera_override) {
+ return camera_override.transform;
+ }
+
+ return Transform();
+}
+
+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)
+ return;
+
+ 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;
+
+ VisualServer::get_singleton()->camera_set_perspective(camera_override.rid, camera_override.fov, camera_override.z_near, camera_override.z_far);
+ }
+}
+
+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)
+ return;
+
+ 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;
+
+ VisualServer::get_singleton()->camera_set_orthogonal(camera_override.rid, camera_override.size, camera_override.z_near, camera_override.z_far);
+ }
+}
+
Transform2D Viewport::get_final_transform() const {
return stretch_transform * global_canvas_transform;
@@ -2298,12 +2407,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Input *input = Input::get_singleton();
- if (p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) {
+ if (!mods && 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")) {
+ if (!mods && p_event->is_action_pressed("ui_focus_prev") && input->is_action_just_pressed("ui_focus_prev")) {
next = from->find_prev_valid_focus();
}
@@ -3180,6 +3289,7 @@ Viewport::Viewport() {
parent = NULL;
listener = NULL;
camera = NULL;
+ override_canvas_transform = false;
canvas_layers.insert(NULL); // This eases picking code (interpreted as the canvas of the Viewport)
arvr = false;
size_override = false;
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 6393785b22..3c3b436ca1 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -160,6 +160,24 @@ private:
bool arvr;
+ struct CameraOverrideData {
+ Transform transform;
+ enum Projection {
+ PROJECTION_PERSPECTIVE,
+ PROJECTION_ORTHOGONAL
+ };
+ Projection projection;
+ float fov;
+ float size;
+ float z_near;
+ float z_far;
+ RID rid;
+
+ operator bool() const {
+ return rid != RID();
+ }
+ } camera_override;
+
Camera *camera;
Set<Camera *> cameras;
Set<CanvasLayer *> canvas_layers;
@@ -173,6 +191,9 @@ private:
bool audio_listener_2d;
RID internal_listener_2d;
+ bool override_canvas_transform;
+
+ Transform2D canvas_transform_override;
Transform2D canvas_transform;
Transform2D global_canvas_transform;
Transform2D stretch_transform;
@@ -394,6 +415,15 @@ public:
Listener *get_listener() const;
Camera *get_camera() const;
+ void enable_camera_override(bool p_enable);
+ bool is_camera_override_enabled() const;
+
+ void set_camera_override_transform(const Transform &p_transform);
+ Transform get_camera_override_transform() const;
+
+ void set_camera_override_perspective(float p_fovy_degrees, float p_z_near, float p_z_far);
+ void set_camera_override_orthogonal(float p_size, float p_z_near, float p_z_far);
+
void set_use_arvr(bool p_use_arvr);
bool use_arvr();
@@ -418,6 +448,12 @@ public:
Ref<World2D> get_world_2d() const;
Ref<World2D> find_world_2d() const;
+ void enable_canvas_transform_override(bool p_enable);
+ bool is_canvas_transform_override_enbled() const;
+
+ void set_canvas_transform_override(const Transform2D &p_transform);
+ Transform2D get_canvas_transform_override() const;
+
void set_canvas_transform(const Transform2D &p_transform);
Transform2D get_canvas_transform() const;
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index d932545da4..f4ac277d00 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -2870,9 +2870,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
const Vector3 &v1 = t1.value.loc;
const Vector3 &v2 = t2.value.loc;
- if (v0 == v2) {
+ if (v0.is_equal_approx(v2)) {
//0 and 2 are close, let's see if 1 is close
- if (v0 != v1) {
+ if (!v0.is_equal_approx(v1)) {
//not close, not optimizable
return false;
}
@@ -2909,9 +2909,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
//localize both to rotation from q0
- if (Math::is_zero_approx((q0 - q2).length())) {
+ if (q0.is_equal_approx(q2)) {
- if (!Math::is_zero_approx((q0 - q1).length()))
+ if (!q0.is_equal_approx(q1))
return false;
} else {
@@ -2959,9 +2959,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
const Vector3 &v1 = t1.value.scale;
const Vector3 &v2 = t2.value.scale;
- if (v0 == v2) {
+ if (v0.is_equal_approx(v2)) {
//0 and 2 are close, let's see if 1 is close
- if (v0 != v1) {
+ if (!v0.is_equal_approx(v1)) {
//not close, not optimizable
return false;
}
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index b10db9ee61..fab0aace14 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -476,9 +476,7 @@ void SpatialMaterial::_update_shader() {
code += ";\n";
code += "uniform vec4 albedo : hint_color;\n";
- if (textures[TEXTURE_ALBEDO] != NULL) {
- code += "uniform sampler2D texture_albedo : hint_albedo;\n";
- }
+ code += "uniform sampler2D texture_albedo : hint_albedo;\n";
code += "uniform float specular;\n";
code += "uniform float metallic;\n";
if (grow_enabled) {
@@ -781,22 +779,18 @@ void SpatialMaterial::_update_shader() {
code += "\t}\n";
}
- if (textures[TEXTURE_ALBEDO] != NULL) {
- if (flags[FLAG_USE_POINT_SIZE]) {
- code += "\tvec4 albedo_tex = texture(texture_albedo,POINT_COORD);\n";
+ if (flags[FLAG_USE_POINT_SIZE]) {
+ code += "\tvec4 albedo_tex = texture(texture_albedo,POINT_COORD);\n";
+ } else {
+ if (flags[FLAG_UV1_USE_TRIPLANAR]) {
+ code += "\tvec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
- if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tvec4 albedo_tex = triplanar_texture(texture_albedo,uv1_power_normal,uv1_triplanar_pos);\n";
- } else {
- code += "\tvec4 albedo_tex = texture(texture_albedo,base_uv);\n";
- }
+ code += "\tvec4 albedo_tex = texture(texture_albedo,base_uv);\n";
}
+ }
- if (flags[FLAG_ALBEDO_TEXTURE_FORCE_SRGB]) {
- code += "\talbedo_tex.rgb = mix(pow((albedo_tex.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex.rgb.rgb * (1.0 / 12.92),lessThan(albedo_tex.rgb,vec3(0.04045)));\n";
- }
- } else {
- code += "\tvec4 albedo_tex = vec4(1.0, 1.0, 1.0, 1.0);\n";
+ if (flags[FLAG_ALBEDO_TEXTURE_FORCE_SRGB]) {
+ code += "\talbedo_tex.rgb = mix(pow((albedo_tex.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex.rgb.rgb * (1.0 / 12.92),lessThan(albedo_tex.rgb,vec3(0.04045)));\n";
}
if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) {
@@ -1411,6 +1405,8 @@ void SpatialMaterial::set_texture(TextureParam p_param, const Ref<Texture> &p_te
textures[p_param] = p_texture;
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
VS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
+ _queue_shader_change();
+ _change_notify();
}
Ref<Texture> SpatialMaterial::get_texture(TextureParam p_param) const {
diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp
index 5a696aee23..f185263a36 100644
--- a/scene/resources/ray_shape.cpp
+++ b/scene/resources/ray_shape.cpp
@@ -90,6 +90,12 @@ void RayShape::_bind_methods() {
RayShape::RayShape() :
Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) {
- set_length(1.0);
- set_slips_on_slope(false);
+ length = 1.0;
+ slips_on_slope = false;
+
+ /* Code copied from setters to prevent the use of uninitialized variables */
+ _update_shape();
+ notify_change_to_owners();
+ _change_notify("length");
+ _change_notify("slips_on_slope");
}
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index cfc57b6e33..9f99732714 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -1064,10 +1064,11 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
String src_var = "n_out" + itos(from_node) + "p" + itos(from_port);
if (in_type == VisualShaderNode::PORT_TYPE_SAMPLER && out_type == VisualShaderNode::PORT_TYPE_SAMPLER) {
-
- VisualShaderNodeUniform *uniform = (VisualShaderNodeUniform *)graph[type].nodes[from_node].node.ptr();
- if (uniform) {
- inputs[i] = uniform->get_uniform_name();
+ VisualShaderNode *ptr = const_cast<VisualShaderNode *>(graph[type].nodes[from_node].node.ptr());
+ if (ptr->has_method("get_input_real_name")) {
+ inputs[i] = ptr->call("get_input_real_name");
+ } else if (ptr->has_method("get_uniform_name")) {
+ inputs[i] = ptr->call("get_uniform_name");
} else {
inputs[i] = "";
}
@@ -1442,6 +1443,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "front_facing", "FRONT_FACING" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "screen_texture", "SCREEN_TEXTURE" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "depth_texture", "DEPTH_TEXTURE" },
// Spatial, Light
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" },
@@ -1488,6 +1491,9 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "normal_texture", "NORMAL_TEXTURE" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "screen_texture", "SCREEN_TEXTURE" },
// Canvas Item, Light
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" },
@@ -1504,6 +1510,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ 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)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" },
// Particles, Vertex
{ Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
@@ -1604,6 +1611,10 @@ 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 "";
+ }
+
if (p_for_preview) {
int idx = 0;
@@ -1672,6 +1683,20 @@ String VisualShaderNodeInput::get_input_name() const {
return input_name;
}
+String VisualShaderNodeInput::get_input_real_name() const {
+
+ int idx = 0;
+
+ while (ports[idx].mode != Shader::MODE_MAX) {
+ if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type && ports[idx].name == input_name) {
+ return String(ports[idx].string);
+ }
+ idx++;
+ }
+
+ return "";
+}
+
VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_type_by_name(String p_name) const {
int idx = 0;
@@ -1768,6 +1793,7 @@ 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);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "input_name", PROPERTY_HINT_ENUM, ""), "set_input_name", "get_input_name");
ADD_SIGNAL(MethodInfo("input_type_changed"));
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 4f73316404..09222c8d81 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -299,6 +299,7 @@ public:
void set_input_name(String p_name);
String get_input_name() const;
+ String get_input_real_name() const;
int get_input_index_count() const;
PortType get_input_index_type(int p_index) const;
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index a7df736c78..a94fdd9d7b 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -475,27 +475,29 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
String id = p_input_vars[2];
String code;
+ code += "\t{\n";
if (id == String()) {
- code += "\tvec4 " + id + "_tex_read = vec4(0.0);\n";
+ code += "\t\tvec4 " + id + "_tex_read = vec4(0.0);\n";
} else {
if (p_input_vars[0] == String()) { // Use UV by default.
if (p_input_vars[1] == String()) {
- code += "\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n";
+ code += "\t\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n";
} else {
- code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n";
+ code += "\t\tvec4 " + id + "_tex_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n";
}
} else if (p_input_vars[1] == String()) {
//no lod
- code += "\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n";
+ code += "\t\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n";
} else {
- code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n";
+ code += "\t\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n";
}
- code += "\t" + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n";
- code += "\t" + p_output_vars[1] + " = " + id + "_tex_read.a;\n";
+ code += "\t\t" + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n";
+ code += "\t\t" + p_output_vars[1] + " = " + id + "_tex_read.a;\n";
}
+ code += "\t}\n";
return code;
}
@@ -905,6 +907,7 @@ void VisualShaderNodeCubeMap::_bind_methods() {
VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() {
texture_type = TYPE_DATA;
+ source = SOURCE_TEXTURE;
}
////////////// Scalar Op
diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq.cpp
index e8f247d3bc..a9b576b1d9 100644
--- a/servers/audio/effects/eq.cpp
+++ b/servers/audio/effects/eq.cpp
@@ -103,7 +103,9 @@ void EQ::recalculate_band_coefficients() {
//printf("band %i, precoefs = %f,%f,%f\n",i,c2a,c2b,c2c);
- double r1, r2; //roots
+ // Default initializing to silence compiler warning about potential uninitialized use.
+ // Both variables are properly set in _solve_quadratic before use, or we continue if roots == 0.
+ double r1 = 0, r2 = 0; //roots
int roots = solve_quadratic(c2a, c2b, c2c, &r1, &r2);
ERR_CONTINUE(roots == 0);
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index f7cec6a378..c944e7016e 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -56,12 +56,12 @@
#include "audio_server.h"
#include "camera/camera_feed.h"
#include "camera_server.h"
-#include "core/script_debugger_remote.h"
#include "physics/physics_server_sw.h"
#include "physics_2d/physics_2d_server_sw.h"
#include "physics_2d/physics_2d_server_wrap_mt.h"
#include "physics_2d_server.h"
#include "physics_server.h"
+#include "scene/debugger/script_debugger_remote.h"
#include "visual/shader_types.h"
#include "visual_server.h"
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 46f65bb758..9babc99349 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -31,6 +31,8 @@
#include "shader_language.h"
#include "core/os/os.h"
#include "core/print_string.h"
+#include "servers/visual_server.h"
+
static bool _is_text_char(CharType c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
@@ -1350,730 +1352,711 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
//constructors
- { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec3", TYPE_BVEC3, { TYPE_BVEC2, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC2, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_BVEC3, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
-
- { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec3", TYPE_VEC3, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
-
- { "int", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec3", TYPE_IVEC3, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
-
- { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec3", TYPE_UVEC3, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
-
- { "mat2", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "mat3", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "mat4", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "mat2", TYPE_MAT2, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "mat3", TYPE_MAT3, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "mat4", TYPE_MAT4, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
+ { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec3", TYPE_BVEC3, { TYPE_BVEC2, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC2, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_BVEC3, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec3", TYPE_VEC3, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "int", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec3", TYPE_IVEC3, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "mat2", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mat3", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mat4", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "mat2", TYPE_MAT2, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mat3", TYPE_MAT3, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mat4", TYPE_MAT4, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
//conversion scalars
- { "int", TYPE_INT, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "int", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "int", TYPE_INT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "int", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
+ { "int", TYPE_INT, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "int", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "int", TYPE_INT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "int", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
- { "float", TYPE_FLOAT, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "float", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "float", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
+ { "float", TYPE_FLOAT, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "float", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "float", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
- { "uint", TYPE_UINT, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "uint", TYPE_UINT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
+ { "uint", TYPE_UINT, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uint", TYPE_UINT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
- { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL },
- { "bool", TYPE_BOOL, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "bool", TYPE_BOOL, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "bool", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
+ { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bool", TYPE_BOOL, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bool", TYPE_BOOL, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bool", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
//conversion vectors
- { "ivec2", TYPE_IVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "ivec2", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "ivec2", TYPE_IVEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "ivec2", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
-
- { "vec2", TYPE_VEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "vec2", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "vec2", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "vec2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
-
- { "uvec2", TYPE_UVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "uvec2", TYPE_UVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "uvec2", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "uvec2", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
-
- { "bvec2", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "bvec2", TYPE_BVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "bvec2", TYPE_BVEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "bvec2", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
-
- { "ivec3", TYPE_IVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "ivec3", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "ivec3", TYPE_IVEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "ivec3", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
-
- { "vec3", TYPE_VEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "vec3", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "vec3", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "vec3", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
-
- { "uvec3", TYPE_UVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "uvec3", TYPE_UVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "uvec3", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "uvec3", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
-
- { "bvec3", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "bvec3", TYPE_BVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "bvec3", TYPE_BVEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "bvec3", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
-
- { "ivec4", TYPE_IVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "ivec4", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "vec4", TYPE_VEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "vec4", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "uvec4", TYPE_UVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "uvec4", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "bvec4", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "bvec4", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "ivec2", TYPE_IVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec2", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec2", TYPE_IVEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec2", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "vec2", TYPE_VEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec2", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec2", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "uvec2", TYPE_UVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec2", TYPE_UVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec2", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec2", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "bvec2", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec2", TYPE_BVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec2", TYPE_BVEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec2", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "ivec3", TYPE_IVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec3", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec3", TYPE_IVEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec3", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "vec3", TYPE_VEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec3", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec3", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec3", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "uvec3", TYPE_UVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "bvec3", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec3", TYPE_BVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec3", TYPE_BVEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec3", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "ivec4", TYPE_IVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ivec4", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "vec4", TYPE_VEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "vec4", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "uvec4", TYPE_UVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "bvec4", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "bvec4", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
//conversion between matrixes
- { "mat2", TYPE_MAT2, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL },
- { "mat2", TYPE_MAT2, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL },
- { "mat3", TYPE_MAT3, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL },
- { "mat3", TYPE_MAT3, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL },
- { "mat4", TYPE_MAT4, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL },
- { "mat4", TYPE_MAT4, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL },
+ { "mat2", TYPE_MAT2, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mat2", TYPE_MAT2, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mat3", TYPE_MAT3, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mat3", TYPE_MAT3, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mat4", TYPE_MAT4, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mat4", TYPE_MAT4, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL, false },
//builtins - trigonometry
- { "radians", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "radians", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "radians", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "radians", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "degrees", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "degrees", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "degrees", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "degrees", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "sin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "sin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "sin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "sin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "cos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "cos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "cos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "cos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "tan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "tan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "tan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "tan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "asin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "asin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "asin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "asin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "acos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "acos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "acos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "acos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "sinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "sinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "sinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "sinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "cosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "cosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "cosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "cosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "tanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "tanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "tanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "tanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "asinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "asinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "asinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "asinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "acosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "acosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "acosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "acosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "atanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "atanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "atanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "atanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "radians", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "radians", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "radians", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "radians", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "degrees", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "degrees", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "degrees", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "degrees", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "sin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "cos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "cos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "cos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "cos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "tan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "tan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "tan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "tan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "asin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "asin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "asin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "asin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "acos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "acos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "acos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "acos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "sinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "cosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "cosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "cosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "cosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "tanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "tanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "tanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "tanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "asinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "asinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "asinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "asinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "acosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "acosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "acosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "acosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "atanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "atanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "atanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "atanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
//builtins - exponential
- { "pow", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "exp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "exp", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "exp", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "exp", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "log", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "log", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "log", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "log", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "exp2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "exp2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "exp2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "exp2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "log2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "log2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "log2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "log2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "sqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "sqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "sqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "sqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "inversesqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "inversesqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "inversesqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "inversesqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "pow", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "exp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "exp", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "exp", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "exp", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "log", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "log", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "log", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "log", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "exp2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "exp2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "exp2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "exp2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "log2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "log2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "log2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "log2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "inversesqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "inversesqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "inversesqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "inversesqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
//builtins - common
- { "abs", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "abs", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "abs", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "abs", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "abs", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "abs", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "abs", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "abs", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "sign", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "sign", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "sign", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "sign", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "sign", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "sign", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "sign", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "sign", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "floor", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "floor", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "floor", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "floor", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "trunc", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "trunc", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "trunc", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "trunc", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "round", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "round", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "round", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "round", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "roundEven", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "roundEven", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "roundEven", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "roundEven", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "ceil", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "ceil", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "ceil", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "ceil", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "fract", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "fract", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "fract", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "fract", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "mod", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "modf", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "modf", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "modf", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "modf", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "min", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "min", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
-
- { "min", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
-
- { "max", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "max", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
-
- { "max", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
-
- { "clamp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "clamp", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
-
- { "clamp", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
-
- { "mix", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL },
- { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "step", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "step", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "step", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "step", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "step", TYPE_VEC2, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "step", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "step", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "smoothstep", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "smoothstep", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "smoothstep", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "smoothstep", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "smoothstep", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "smoothstep", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "smoothstep", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "isnan", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "isnan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "isnan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "isnan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "isinf", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "isinf", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "isinf", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "isinf", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "floatBitsToInt", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "floatBitsToInt", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "floatBitsToInt", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "floatBitsToInt", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "floatBitsToUint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "floatBitsToUint", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "floatBitsToUint", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "floatBitsToUint", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "intBitsToFloat", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "intBitsToFloat", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "intBitsToFloat", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "intBitsToFloat", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "uintBitsToFloat", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL },
- { "uintBitsToFloat", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "uintBitsToFloat", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "uintBitsToFloat", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "abs", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "abs", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "abs", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "abs", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "abs", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "abs", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "abs", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "abs", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "sign", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sign", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sign", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sign", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "sign", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sign", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sign", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "sign", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "floor", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "floor", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "floor", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "floor", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "trunc", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "trunc", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "trunc", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "trunc", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "round", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "round", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "round", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "round", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "roundEven", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "roundEven", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "roundEven", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "roundEven", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ceil", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ceil", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ceil", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "ceil", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "fract", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "fract", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "fract", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "fract", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "mod", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "modf", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "modf", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "modf", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "modf", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+
+ { "min", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "min", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "min", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "max", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "max", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "max", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "clamp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "clamp", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "clamp", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "mix", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "step", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "step", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "step", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "step", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "step", TYPE_VEC2, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "step", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "step", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "smoothstep", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "smoothstep", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "smoothstep", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "smoothstep", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "smoothstep", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "smoothstep", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "smoothstep", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "isnan", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "isnan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "isnan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "isnan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "isinf", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "isinf", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "isinf", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "isinf", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "floatBitsToInt", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "floatBitsToInt", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "floatBitsToInt", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "floatBitsToInt", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+
+ { "floatBitsToUint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "floatBitsToUint", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "floatBitsToUint", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "floatBitsToUint", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+
+ { "intBitsToFloat", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "intBitsToFloat", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "intBitsToFloat", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "intBitsToFloat", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, true },
+
+ { "uintBitsToFloat", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "uintBitsToFloat", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "uintBitsToFloat", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "uintBitsToFloat", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, true },
//builtins - geometric
- { "length", TYPE_FLOAT, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "length", TYPE_FLOAT, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "length", TYPE_FLOAT, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "distance", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "distance", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "distance", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "dot", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "dot", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "dot", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "cross", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "normalize", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "normalize", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "normalize", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "reflect", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "refract", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "faceforward", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "faceforward", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "faceforward", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "matrixCompMult", TYPE_MAT2, { TYPE_MAT2, TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL },
- { "matrixCompMult", TYPE_MAT3, { TYPE_MAT3, TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL },
- { "matrixCompMult", TYPE_MAT4, { TYPE_MAT4, TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL },
-
- { "outerProduct", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "outerProduct", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "outerProduct", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "transpose", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL },
- { "transpose", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL },
- { "transpose", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL },
-
- { "determinant", TYPE_FLOAT, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL },
- { "determinant", TYPE_FLOAT, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL },
- { "determinant", TYPE_FLOAT, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL },
-
- { "inverse", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL },
- { "inverse", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL },
- { "inverse", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL },
-
- { "lessThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "lessThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "lessThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "lessThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "lessThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "lessThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "lessThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "lessThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "lessThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "greaterThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "greaterThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "greaterThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "lessThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "lessThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "lessThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "lessThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "lessThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "lessThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "lessThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "lessThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "lessThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "greaterThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "greaterThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "greaterThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "greaterThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "equal", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "equal", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "equal", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "equal", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "equal", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "equal", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "equal", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "equal", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "equal", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "equal", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "equal", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "equal", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "notEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "notEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "notEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "notEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "notEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "notEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "length", TYPE_FLOAT, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "length", TYPE_FLOAT, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "length", TYPE_FLOAT, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "distance", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "distance", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "distance", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "dot", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "dot", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "dot", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "cross", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "normalize", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "normalize", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "normalize", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "reflect", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "refract", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "faceforward", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "faceforward", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "faceforward", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "matrixCompMult", TYPE_MAT2, { TYPE_MAT2, TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "matrixCompMult", TYPE_MAT3, { TYPE_MAT3, TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "matrixCompMult", TYPE_MAT4, { TYPE_MAT4, TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "outerProduct", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "outerProduct", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "outerProduct", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "transpose", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "transpose", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "transpose", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "determinant", TYPE_FLOAT, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "determinant", TYPE_FLOAT, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "determinant", TYPE_FLOAT, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "inverse", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "inverse", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "inverse", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "lessThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "lessThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "lessThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "greaterThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "greaterThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "greaterThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "lessThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "lessThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "lessThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "lessThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "greaterThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "greaterThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "greaterThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "greaterThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "equal", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "equal", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "equal", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "equal", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "equal", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "equal", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "equal", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "equal", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "equal", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "equal", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "equal", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "equal", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "notEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "notEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "notEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+
+ { "notEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "notEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "notEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL, false },
- { "notEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "notEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "notEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "notEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "notEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "notEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL, false },
- { "notEqual", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "notEqual", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "notEqual", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "notEqual", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "notEqual", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "notEqual", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL, false },
- { "any", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "any", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "any", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "any", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "any", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "any", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL, false },
- { "all", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "all", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "all", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "all", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "all", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "all", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL, false },
- { "not", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL },
- { "not", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL },
- { "not", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "not", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL, false },
+ { "not", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL, false },
+ { "not", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL, false },
//builtins - texture
- { "textureSize", TYPE_IVEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "textureSize", TYPE_IVEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "textureSize", TYPE_IVEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
-
- { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
- { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
-
- { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
-
- { "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "dFdx", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "dFdx", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "dFdy", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "dFdy", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "dFdy", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "dFdy", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
-
- { "fwidth", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL },
- { "fwidth", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL },
- { "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL },
- { "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL },
+ { "textureSize", TYPE_IVEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureSize", TYPE_IVEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureSize", TYPE_IVEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "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 },
+
+ { "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 },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "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 },
+
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+
+ { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "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 },
+
+ { "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 },
+ { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+
+ { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "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 },
+
+ { "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "dFdx", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "dFdx", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+
+ { "dFdy", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "dFdy", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "dFdy", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "dFdy", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
+
+ { "fwidth", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "fwidth", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
+ { "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
//sub-functions
//array
- { "length", TYPE_INT, { TYPE_VOID }, TAG_ARRAY },
+ { "length", TYPE_INT, { TYPE_VOID }, TAG_ARRAY, false },
- { NULL, TYPE_VOID, { TYPE_VOID }, TAG_GLOBAL }
+ { NULL, TYPE_VOID, { TYPE_VOID }, TAG_GLOBAL, false }
};
@@ -2100,6 +2083,8 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p
int argcount = args.size();
bool failed_builtin = false;
+ bool unsupported_builtin = false;
+ int builtin_idx = 0;
if (argcount <= 4) {
// test builtins
@@ -2126,6 +2111,16 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p
}
}
+ if (!fail) {
+ if (VisualServer::get_singleton()->is_low_end()) {
+ if (builtin_func_defs[idx].high_end) {
+ fail = true;
+ unsupported_builtin = true;
+ builtin_idx = idx;
+ }
+ }
+ }
+
if (!fail && argcount < 4 && builtin_func_defs[idx].args[argcount] != TYPE_VOID)
fail = true; //make sure the number of arguments matches
@@ -2195,6 +2190,21 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p
}
}
+ if (unsupported_builtin) {
+
+ String arglist = "";
+ for (int i = 0; i < argcount; i++) {
+ if (i > 0) {
+ arglist += ", ";
+ }
+ arglist += get_datatype_name(builtin_func_defs[builtin_idx].args[i]);
+ }
+
+ String err = "Built-in function \"" + String(name) + "(" + arglist + ")\" is supported only on high-end platform!";
+ _set_error(err);
+ return false;
+ }
+
if (failed_builtin) {
String err = "Invalid arguments for built-in function: " + String(name) + "(";
for (int i = 0; i < argcount; i++) {
@@ -4177,6 +4187,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
_set_tkpos(pos); //rollback
}
} else if (tk.type == TK_CF_SWITCH) {
+
+ if (VisualServer::get_singleton()->is_low_end()) {
+ _set_error("\"switch\" operator is supported only on high-end platform!");
+ return ERR_PARSE_ERROR;
+ }
+
// switch() {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
@@ -4630,6 +4646,47 @@ String ShaderLanguage::_get_shader_type_list(const Set<String> &p_shader_types)
return valid_types;
}
+Error ShaderLanguage::_validate_datatype(DataType p_type) {
+ if (VisualServer::get_singleton()->is_low_end()) {
+ bool invalid_type = false;
+
+ switch (p_type) {
+ case TYPE_ISAMPLER2D:
+ invalid_type = true;
+ break;
+ case TYPE_USAMPLER2D:
+ invalid_type = true;
+ break;
+ case TYPE_SAMPLER3D:
+ invalid_type = true;
+ break;
+ case TYPE_ISAMPLER3D:
+ invalid_type = true;
+ break;
+ case TYPE_USAMPLER3D:
+ invalid_type = true;
+ break;
+ case TYPE_SAMPLER2DARRAY:
+ invalid_type = true;
+ break;
+ case TYPE_USAMPLER2DARRAY:
+ invalid_type = true;
+ break;
+ case TYPE_ISAMPLER2DARRAY:
+ invalid_type = true;
+ break;
+ default:
+ break;
+ }
+
+ if (invalid_type) {
+ _set_error(vformat("\"%s\" type is supported only on high-end platform!", get_datatype_name(p_type)));
+ return ERR_UNAVAILABLE;
+ }
+ }
+ return OK;
+}
+
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();
@@ -4766,6 +4823,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (is_sampler_type(type)) {
uniform2.texture_order = texture_uniforms++;
uniform2.order = -1;
+ if (_validate_datatype(type) != OK) {
+ return ERR_PARSE_ERROR;
+ }
} else {
uniform2.texture_order = -1;
uniform2.order = uniforms++;
@@ -5151,6 +5211,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
ptype = get_token_datatype(tk.type);
+ if (_validate_datatype(ptype) != OK) {
+ return ERR_PARSE_ERROR;
+ }
+
if (ptype == TYPE_VOID) {
_set_error("void not allowed in argument");
return ERR_PARSE_ERROR;
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index e62881f5c6..0b0947da0c 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -715,7 +715,7 @@ private:
enum SubClassTag {
TAG_GLOBAL,
- TAG_ARRAY
+ TAG_ARRAY,
};
struct BuiltinFuncDef {
@@ -724,6 +724,7 @@ private:
DataType rettype;
const DataType args[MAX_ARGS];
SubClassTag tag;
+ bool high_end;
};
struct BuiltinFuncOutArgs { //arguments used as out in built in functions
@@ -743,6 +744,8 @@ private:
static const BuiltinFuncDef builtin_func_defs[];
static const BuiltinFuncOutArgs builtin_func_out_args[];
+ Error _validate_datatype(DataType p_type);
+
bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type);
bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = NULL);
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index f515af4d91..ae1f3712b0 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -184,7 +184,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get().canvas);
- Transform2D xf = p_viewport->global_transform * E->get().transform;
+ 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()) {
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 2e1f524362..4bab9b76ba 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -508,12 +508,11 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
if (p_format & ARRAY_COMPRESS_TANGENT) {
for (int i = 0; i < p_vertex_array_len; i++) {
-
- uint8_t xyzw[4] = {
- (uint8_t)CLAMP(src[i * 4 + 0] * 127, -128, 127),
- (uint8_t)CLAMP(src[i * 4 + 1] * 127, -128, 127),
- (uint8_t)CLAMP(src[i * 4 + 2] * 127, -128, 127),
- (uint8_t)CLAMP(src[i * 4 + 3] * 127, -128, 127)
+ int8_t xyzw[4] = {
+ (int8_t)CLAMP(src[i * 4 + 0] * 127, -128, 127),
+ (int8_t)CLAMP(src[i * 4 + 1] * 127, -128, 127),
+ (int8_t)CLAMP(src[i * 4 + 2] * 127, -128, 127),
+ (int8_t)CLAMP(src[i * 4 + 3] * 127, -128, 127)
};
copymem(&vw[p_offsets[ai] + i * p_stride], xyzw, 4);
diff --git a/thirdparty/README.md b/thirdparty/README.md
index bbf6bcfcfb..8928009817 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -4,7 +4,7 @@
## assimp
- Upstream: http://github.com/assimp/assimp
-- Version: git (1d565b0aab5a2ee00462f18c5b8a81f6a5454a48)
+- Version: git (308db73d0b3c2d1870cd3e465eaa283692a4cf23)
- License: BSD-3-Clause
@@ -157,12 +157,12 @@ Files extracted from upstream source:
## libogg
- Upstream: https://www.xiph.org/ogg
-- Version: 1.3.3
+- Version: git (c8fca6b, 2019)
- License: BSD-3-Clause
Files extracted from upstream source:
-- `src/*.c`
+- `src/*.{c,h}`
- `include/ogg/*.h` in ogg/
- COPYING
@@ -534,7 +534,7 @@ Files extracted from upstream source:
## zstd
- Upstream: https://github.com/facebook/zstd
-- Version: 1.4.1
+- Version: 1.4.3
- License: BSD-3-Clause
Files extracted from upstream source:
diff --git a/thirdparty/assimp/code/Common/BaseImporter.cpp b/thirdparty/assimp/code/Common/BaseImporter.cpp
index de5018a250..5c1e605549 100644
--- a/thirdparty/assimp/code/Common/BaseImporter.cpp
+++ b/thirdparty/assimp/code/Common/BaseImporter.cpp
@@ -67,7 +67,20 @@ using namespace Assimp;
// Constructor to be privately used by Importer
BaseImporter::BaseImporter() AI_NO_EXCEPT
: m_progress() {
- // nothing to do here
+ /**
+ * Assimp Importer
+ * unit conversions available
+ * if you need another measurment unit add it below.
+ * it's currently defined in assimp that we prefer meters.
+ *
+ * NOTE: Initialised here rather than in the header file
+ * to workaround a VS2013 bug with brace initialisers
+ * */
+ importerUnits[ImporterUnits::M] = 1.0;
+ importerUnits[ImporterUnits::CM] = 0.01;
+ importerUnits[ImporterUnits::MM] = 0.001;
+ importerUnits[ImporterUnits::INCHES] = 0.0254;
+ importerUnits[ImporterUnits::FEET] = 0.3048;
}
// ------------------------------------------------------------------------------------------------
@@ -85,7 +98,7 @@ void BaseImporter::UpdateImporterScale( Importer* pImp )
double activeScale = importerScale * fileScale;
// Set active scaling
- pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, activeScale);
+ pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) );
ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
}
diff --git a/thirdparty/assimp/code/Common/DefaultIOSystem.cpp b/thirdparty/assimp/code/Common/DefaultIOSystem.cpp
index d40b67de32..6fdc24dd80 100644
--- a/thirdparty/assimp/code/Common/DefaultIOSystem.cpp
+++ b/thirdparty/assimp/code/Common/DefaultIOSystem.cpp
@@ -61,83 +61,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
-// maximum path length
-// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
-#ifdef PATH_MAX
-# define PATHLIMIT PATH_MAX
-#else
-# define PATHLIMIT 4096
+#ifdef _WIN32
+static std::wstring Utf8ToWide(const char* in)
+{
+ int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0);
+ // size includes terminating null; std::wstring adds null automatically
+ std::wstring out(static_cast<size_t>(size) - 1, L'\0');
+ MultiByteToWideChar(CP_UTF8, 0, in, -1, &out[0], size);
+ return out;
+}
+
+static std::string WideToUtf8(const wchar_t* in)
+{
+ int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr);
+ // size includes terminating null; std::string adds null automatically
+ std::string out(static_cast<size_t>(size) - 1, '\0');
+ WideCharToMultiByte(CP_UTF8, 0, in, -1, &out[0], size, nullptr, nullptr);
+ return out;
+}
#endif
// ------------------------------------------------------------------------------------------------
// Tests for the existence of a file at the given path.
-bool DefaultIOSystem::Exists( const char* pFile) const
+bool DefaultIOSystem::Exists(const char* pFile) const
{
#ifdef _WIN32
- wchar_t fileName16[PATHLIMIT];
-
-#ifndef WindowsStore
- bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
- if (isUnicode) {
-
- MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
- struct __stat64 filestat;
- if (0 != _wstat64(fileName16, &filestat)) {
- return false;
- }
- } else {
-#endif
- FILE* file = ::fopen(pFile, "rb");
- if (!file)
- return false;
-
- ::fclose(file);
-#ifndef WindowsStore
+ struct __stat64 filestat;
+ if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) {
+ return false;
}
-#endif
#else
- FILE* file = ::fopen( pFile, "rb");
- if( !file)
+ FILE* file = ::fopen(pFile, "rb");
+ if (!file)
return false;
- ::fclose( file);
+ ::fclose(file);
#endif
return true;
}
// ------------------------------------------------------------------------------------------------
// Open a new file with a given path.
-IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
+IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode)
{
- ai_assert(NULL != strFile);
- ai_assert(NULL != strMode);
+ ai_assert(strFile != nullptr);
+ ai_assert(strMode != nullptr);
FILE* file;
#ifdef _WIN32
- wchar_t fileName16[PATHLIMIT];
-#ifndef WindowsStore
- bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
- if (isUnicode) {
- MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
- std::string mode8(strMode);
- file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str());
- } else {
-#endif
- file = ::fopen(strFile, strMode);
-#ifndef WindowsStore
- }
-#endif
+ file = ::_wfopen(Utf8ToWide(strFile).c_str(), Utf8ToWide(strMode).c_str());
#else
file = ::fopen(strFile, strMode);
#endif
- if (nullptr == file)
+ if (!file)
return nullptr;
- return new DefaultIOStream(file, (std::string) strFile);
+ return new DefaultIOStream(file, strFile);
}
// ------------------------------------------------------------------------------------------------
// Closes the given file and releases all resources associated with it.
-void DefaultIOSystem::Close( IOStream* pFile)
+void DefaultIOSystem::Close(IOStream* pFile)
{
delete pFile;
}
@@ -155,78 +138,56 @@ char DefaultIOSystem::getOsSeparator() const
// ------------------------------------------------------------------------------------------------
// IOSystem default implementation (ComparePaths isn't a pure virtual function)
-bool IOSystem::ComparePaths (const char* one, const char* second) const
+bool IOSystem::ComparePaths(const char* one, const char* second) const
{
- return !ASSIMP_stricmp(one,second);
+ return !ASSIMP_stricmp(one, second);
}
// ------------------------------------------------------------------------------------------------
// Convert a relative path into an absolute path
-inline static void MakeAbsolutePath (const char* in, char* _out)
+inline static std::string MakeAbsolutePath(const char* in)
{
- ai_assert(in && _out);
-#if defined( _MSC_VER ) || defined( __MINGW32__ )
-#ifndef WindowsStore
- bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0;
- if (isUnicode) {
- wchar_t out16[PATHLIMIT];
- wchar_t in16[PATHLIMIT];
- MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT);
- wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT);
- if (ret) {
- WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr);
- }
- if (!ret) {
- // preserve the input path, maybe someone else is able to fix
- // the path before it is accessed (e.g. our file system filter)
- ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
- strcpy(_out, in);
- }
-
- } else {
-#endif
- char* ret = :: _fullpath(_out, in, PATHLIMIT);
- if (!ret) {
- // preserve the input path, maybe someone else is able to fix
- // the path before it is accessed (e.g. our file system filter)
- ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
- strcpy(_out, in);
- }
-#ifndef WindowsStore
+ ai_assert(in);
+ std::string out;
+#ifdef _WIN32
+ wchar_t* ret = ::_wfullpath(nullptr, Utf8ToWide(in).c_str(), 0);
+ if (ret) {
+ out = WideToUtf8(ret);
+ free(ret);
}
-#endif
#else
- // use realpath
- char* ret = realpath(in, _out);
- if(!ret) {
+ char* ret = realpath(in, nullptr);
+ if (ret) {
+ out = ret;
+ free(ret);
+ }
+#endif
+ if (!ret) {
// preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter)
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
- strcpy(_out,in);
+ out = in;
}
-#endif
+ return out;
}
// ------------------------------------------------------------------------------------------------
// DefaultIOSystem's more specialized implementation
-bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
+bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const
{
// chances are quite good both paths are formatted identically,
// so we can hopefully return here already
- if( !ASSIMP_stricmp(one,second) )
+ if (!ASSIMP_stricmp(one, second))
return true;
- char temp1[PATHLIMIT];
- char temp2[PATHLIMIT];
-
- MakeAbsolutePath (one, temp1);
- MakeAbsolutePath (second, temp2);
+ std::string temp1 = MakeAbsolutePath(one);
+ std::string temp2 = MakeAbsolutePath(second);
- return !ASSIMP_stricmp(temp1,temp2);
+ return !ASSIMP_stricmp(temp1, temp2);
}
// ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::fileName( const std::string &path )
+std::string DefaultIOSystem::fileName(const std::string& path)
{
std::string ret = path;
std::size_t last = ret.find_last_of("\\/");
@@ -235,16 +196,16 @@ std::string DefaultIOSystem::fileName( const std::string &path )
}
// ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::completeBaseName( const std::string &path )
+std::string DefaultIOSystem::completeBaseName(const std::string& path)
{
std::string ret = fileName(path);
std::size_t pos = ret.find_last_of('.');
- if(pos != ret.npos) ret = ret.substr(0, pos);
+ if (pos != std::string::npos) ret = ret.substr(0, pos);
return ret;
}
// ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::absolutePath( const std::string &path )
+std::string DefaultIOSystem::absolutePath(const std::string& path)
{
std::string ret = path;
std::size_t last = ret.find_last_of("\\/");
@@ -253,5 +214,3 @@ std::string DefaultIOSystem::absolutePath( const std::string &path )
}
// ------------------------------------------------------------------------------------------------
-
-#undef PATHLIMIT
diff --git a/thirdparty/assimp/code/Common/Exporter.cpp b/thirdparty/assimp/code/Common/Exporter.cpp
index 090b561ae0..4ce1a2bd80 100644
--- a/thirdparty/assimp/code/Common/Exporter.cpp
+++ b/thirdparty/assimp/code/Common/Exporter.cpp
@@ -102,6 +102,8 @@ void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperti
void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
+void ExportSceneM3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneA3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportAssimp2Json(const char* , IOSystem*, const aiScene* , const Assimp::ExportProperties*);
// ------------------------------------------------------------------------------------------------
@@ -179,6 +181,11 @@ Exporter::ExportFormatEntry gExporters[] =
Exporter::ExportFormatEntry( "fbxa", "Autodesk FBX (ascii)", "fbx", &ExportSceneFBXA, 0 ),
#endif
+#ifndef ASSIMP_BUILD_NO_M3D_EXPORTER
+ Exporter::ExportFormatEntry( "m3d", "Model 3D (binary)", "m3d", &ExportSceneM3D, 0 ),
+ Exporter::ExportFormatEntry( "a3d", "Model 3D (ascii)", "m3d", &ExportSceneA3D, 0 ),
+#endif
+
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 ),
#endif
@@ -316,34 +323,6 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
}
// ------------------------------------------------------------------------------------------------
-bool IsVerboseFormat(const aiMesh* mesh) {
- // avoid slow vector<bool> specialization
- std::vector<unsigned int> seen(mesh->mNumVertices,0);
- for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
- const aiFace& f = mesh->mFaces[i];
- for(unsigned int j = 0; j < f.mNumIndices; ++j) {
- if(++seen[f.mIndices[j]] == 2) {
- // found a duplicate index
- return false;
- }
- }
- }
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool IsVerboseFormat(const aiScene* pScene) {
- for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- if(!IsVerboseFormat(pScene->mMeshes[i])) {
- return false;
- }
- }
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
unsigned int pPreprocessing, const ExportProperties* pProperties) {
ASSIMP_BEGIN_EXCEPTION_REGION();
@@ -352,7 +331,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
// format. They will likely not be aware that there is a flag in the scene to indicate
// this, however. To avoid surprises and bug reports, we check for duplicates in
// meshes upfront.
- const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
+ const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || MakeVerboseFormatProcess::IsVerboseFormat(pScene);
pimpl->mProgressHandler->UpdateFileWrite(0, 4);
@@ -472,7 +451,10 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
}
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
- exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
+ ExportProperties* pProp = pProperties ? (ExportProperties*)pProperties : &emptyProperties;
+ pProp->SetPropertyBool("bJoinIdenticalVertices", must_join_again);
+ exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
+ exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
pimpl->mProgressHandler->UpdateFileWrite(4, 4);
} catch (DeadlyExportError& err) {
diff --git a/thirdparty/assimp/code/Common/ImporterRegistry.cpp b/thirdparty/assimp/code/Common/ImporterRegistry.cpp
index 32ac3b4168..b9f28f0356 100644
--- a/thirdparty/assimp/code/Common/ImporterRegistry.cpp
+++ b/thirdparty/assimp/code/Common/ImporterRegistry.cpp
@@ -197,6 +197,9 @@ corresponding preprocessor flag to selectively disable formats.
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
# include "MMD/MMDImporter.h"
#endif
+#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
+# include "M3D/M3DImporter.h"
+#endif
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
# include "Importer/StepFile/StepFileImporter.h"
#endif
@@ -223,6 +226,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
out.push_back( new Discreet3DSImporter());
#endif
+#if (!defined ASSIMP_BUILD_NO_M3D_IMPORTER)
+ out.push_back( new M3DImporter());
+#endif
#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
out.push_back( new MD3Importer());
#endif
diff --git a/thirdparty/assimp/code/Common/PostStepRegistry.cpp b/thirdparty/assimp/code/Common/PostStepRegistry.cpp
index ef58f8ddfd..8ff4af0400 100644
--- a/thirdparty/assimp/code/Common/PostStepRegistry.cpp
+++ b/thirdparty/assimp/code/Common/PostStepRegistry.cpp
@@ -131,11 +131,15 @@ corresponding preprocessor flag to selectively disable steps.
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
# include "PostProcessing/ScaleProcess.h"
#endif
+#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS)
+# include "PostProcessing/ArmaturePopulate.h"
+#endif
#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
# include "PostProcessing/GenBoundingBoxesProcess.h"
#endif
+
namespace Assimp {
// ------------------------------------------------------------------------------------------------
@@ -180,6 +184,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
out.push_back( new ScaleProcess());
#endif
+#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS)
+ out.push_back( new ArmaturePopulate());
+#endif
#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
out.push_back( new PretransformVertices());
#endif
diff --git a/thirdparty/assimp/code/Common/SceneCombiner.cpp b/thirdparty/assimp/code/Common/SceneCombiner.cpp
index e445bd7434..f7b13cc951 100644
--- a/thirdparty/assimp/code/Common/SceneCombiner.cpp
+++ b/thirdparty/assimp/code/Common/SceneCombiner.cpp
@@ -1091,6 +1091,35 @@ void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) {
aiFace& f = dest->mFaces[i];
GetArrayCopy(f.mIndices,f.mNumIndices);
}
+
+ // make a deep copy of all blend shapes
+ CopyPtrArray(dest->mAnimMeshes, dest->mAnimMeshes, dest->mNumAnimMeshes);
+}
+
+// ------------------------------------------------------------------------------------------------
+void SceneCombiner::Copy(aiAnimMesh** _dest, const aiAnimMesh* src) {
+ if (nullptr == _dest || nullptr == src) {
+ return;
+ }
+
+ aiAnimMesh* dest = *_dest = new aiAnimMesh();
+
+ // get a flat copy
+ ::memcpy(dest, src, sizeof(aiAnimMesh));
+
+ // and reallocate all arrays
+ GetArrayCopy(dest->mVertices, dest->mNumVertices);
+ GetArrayCopy(dest->mNormals, dest->mNumVertices);
+ GetArrayCopy(dest->mTangents, dest->mNumVertices);
+ GetArrayCopy(dest->mBitangents, dest->mNumVertices);
+
+ unsigned int n = 0;
+ while (dest->HasTextureCoords(n))
+ GetArrayCopy(dest->mTextureCoords[n++], dest->mNumVertices);
+
+ n = 0;
+ while (dest->HasVertexColors(n))
+ GetArrayCopy(dest->mColors[n++], dest->mNumVertices);
}
// ------------------------------------------------------------------------------------------------
@@ -1167,6 +1196,7 @@ void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src ) {
// and reallocate all arrays
CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels );
+ CopyPtrArray( dest->mMorphMeshChannels, src->mMorphMeshChannels, dest->mNumMorphMeshChannels );
}
// ------------------------------------------------------------------------------------------------
@@ -1186,6 +1216,26 @@ void SceneCombiner::Copy(aiNodeAnim** _dest, const aiNodeAnim* src) {
GetArrayCopy( dest->mRotationKeys, dest->mNumRotationKeys );
}
+void SceneCombiner::Copy(aiMeshMorphAnim** _dest, const aiMeshMorphAnim* src) {
+ if ( nullptr == _dest || nullptr == src ) {
+ return;
+ }
+
+ aiMeshMorphAnim* dest = *_dest = new aiMeshMorphAnim();
+
+ // get a flat copy
+ ::memcpy(dest,src,sizeof(aiMeshMorphAnim));
+
+ // and reallocate all arrays
+ GetArrayCopy( dest->mKeys, dest->mNumKeys );
+ for (ai_uint i = 0; i < dest->mNumKeys;++i) {
+ dest->mKeys[i].mValues = new unsigned int[dest->mKeys[i].mNumValuesAndWeights];
+ dest->mKeys[i].mWeights = new double[dest->mKeys[i].mNumValuesAndWeights];
+ ::memcpy(dest->mKeys[i].mValues, src->mKeys[i].mValues, dest->mKeys[i].mNumValuesAndWeights * sizeof(unsigned int));
+ ::memcpy(dest->mKeys[i].mWeights, src->mKeys[i].mWeights, dest->mKeys[i].mNumValuesAndWeights * sizeof(double));
+ }
+}
+
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy( aiCamera** _dest,const aiCamera* src) {
if ( nullptr == _dest || nullptr == src ) {
diff --git a/thirdparty/assimp/code/Common/Version.cpp b/thirdparty/assimp/code/Common/Version.cpp
index cc94340ac8..cf1da7d5ba 100644
--- a/thirdparty/assimp/code/Common/Version.cpp
+++ b/thirdparty/assimp/code/Common/Version.cpp
@@ -46,8 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include "ScenePrivate.h"
-static const unsigned int MajorVersion = 4;
-static const unsigned int MinorVersion = 1;
+#include "revision.h"
// --------------------------------------------------------------------------------
// Legal information string - don't remove this.
@@ -56,9 +55,9 @@ static const char* LEGAL_INFORMATION =
"Open Asset Import Library (Assimp).\n"
"A free C/C++ library to import various 3D file formats into applications\n\n"
-"(c) 2008-2017, assimp team\n"
+"(c) 2006-2019, assimp team\n"
"License under the terms and conditions of the 3-clause BSD license\n"
-"http://assimp.sourceforge.net\n"
+"http://assimp.org\n"
;
// ------------------------------------------------------------------------------------------------
@@ -70,13 +69,13 @@ ASSIMP_API const char* aiGetLegalString () {
// ------------------------------------------------------------------------------------------------
// Get Assimp minor version
ASSIMP_API unsigned int aiGetVersionMinor () {
- return MinorVersion;
+ return VER_MINOR;
}
// ------------------------------------------------------------------------------------------------
// Get Assimp major version
ASSIMP_API unsigned int aiGetVersionMajor () {
- return MajorVersion;
+ return VER_MAJOR;
}
// ------------------------------------------------------------------------------------------------
@@ -104,9 +103,6 @@ ASSIMP_API unsigned int aiGetCompileFlags () {
return flags;
}
-// include current build revision, which is even updated from time to time -- :-)
-#include "revision.h"
-
// ------------------------------------------------------------------------------------------------
ASSIMP_API unsigned int aiGetVersionRevision() {
return GitVersion;
diff --git a/thirdparty/assimp/code/Common/scene.cpp b/thirdparty/assimp/code/Common/scene.cpp
index 2acb348d81..d15619acff 100644
--- a/thirdparty/assimp/code/Common/scene.cpp
+++ b/thirdparty/assimp/code/Common/scene.cpp
@@ -44,23 +44,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
aiNode::aiNode()
: mName("")
-, mParent(NULL)
+, mParent(nullptr)
, mNumChildren(0)
-, mChildren(NULL)
+, mChildren(nullptr)
, mNumMeshes(0)
-, mMeshes(NULL)
-, mMetaData(NULL) {
+, mMeshes(nullptr)
+, mMetaData(nullptr) {
// empty
}
aiNode::aiNode(const std::string& name)
: mName(name)
-, mParent(NULL)
+, mParent(nullptr)
, mNumChildren(0)
-, mChildren(NULL)
+, mChildren(nullptr)
, mNumMeshes(0)
-, mMeshes(NULL)
-, mMetaData(NULL) {
+, mMeshes(nullptr)
+, mMetaData(nullptr) {
// empty
}
@@ -68,7 +68,7 @@ aiNode::aiNode(const std::string& name)
aiNode::~aiNode() {
// delete all children recursively
// to make sure we won't crash if the data is invalid ...
- if (mChildren && mNumChildren)
+ if (mNumChildren && mChildren)
{
for (unsigned int a = 0; a < mNumChildren; a++)
delete mChildren[a];
diff --git a/thirdparty/assimp/code/FBX/FBXCompileConfig.h b/thirdparty/assimp/code/FBX/FBXCompileConfig.h
index 3a3841fa5b..03536a1823 100644
--- a/thirdparty/assimp/code/FBX/FBXCompileConfig.h
+++ b/thirdparty/assimp/code/FBX/FBXCompileConfig.h
@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INCLUDED_AI_FBX_COMPILECONFIG_H
#include <map>
+#include <set>
//
#if _MSC_VER > 1500 || (defined __GNUC___)
@@ -54,16 +55,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# else
# define fbx_unordered_map map
# define fbx_unordered_multimap multimap
+# define fbx_unordered_set set
+# define fbx_unordered_multiset multiset
#endif
#ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP
# include <unordered_map>
+# include <unordered_set>
# if _MSC_VER > 1600
# define fbx_unordered_map unordered_map
# define fbx_unordered_multimap unordered_multimap
+# define fbx_unordered_set unordered_set
+# define fbx_unordered_multiset unordered_multiset
# else
# define fbx_unordered_map tr1::unordered_map
# define fbx_unordered_multimap tr1::unordered_multimap
+# define fbx_unordered_set tr1::unordered_set
+# define fbx_unordered_multiset tr1::unordered_multiset
# endif
#endif
diff --git a/thirdparty/assimp/code/FBX/FBXConverter.cpp b/thirdparty/assimp/code/FBX/FBXConverter.cpp
index 3f64016ea4..d8a22d9f74 100644
--- a/thirdparty/assimp/code/FBX/FBXConverter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXConverter.cpp
@@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXImporter.h"
#include <assimp/StringComparison.h>
+#include <assimp/MathFunctions.h>
#include <assimp/scene.h>
@@ -67,7 +68,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <iomanip>
#include <cstdint>
-
+#include <iostream>
+#include <stdlib.h>
namespace Assimp {
namespace FBX {
@@ -76,7 +78,7 @@ namespace Assimp {
#define MAGIC_NODE_TAG "_$AssimpFbx$"
-#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
+#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL
FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones )
: defaultMaterialIndex()
@@ -95,6 +97,14 @@ namespace Assimp {
// populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated.
ConvertAnimations();
+ // Embedded textures in FBX could be connected to nothing but to itself,
+ // for instance Texture -> Video connection only but not to the main graph,
+ // The idea here is to traverse all objects to find these Textures and convert them,
+ // so later during material conversion it will find converted texture in the textures_converted array.
+ if (doc.Settings().readTextures)
+ {
+ ConvertOrphantEmbeddedTextures();
+ }
ConvertRootNode();
if (doc.Settings().readAllMaterials) {
@@ -144,7 +154,7 @@ namespace Assimp {
out->mRootNode->mName.Set(unique_name);
// root has ID 0
- ConvertNodes(0L, *out->mRootNode);
+ ConvertNodes(0L, out->mRootNode, out->mRootNode);
}
static std::string getAncestorBaseName(const aiNode* node)
@@ -178,8 +188,11 @@ namespace Assimp {
GetUniqueName(original_name, unique_name);
return unique_name;
}
-
- void FBXConverter::ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform) {
+ /// todo: pre-build node hierarchy
+ /// todo: get bone from stack
+ /// todo: make map of aiBone* to aiNode*
+ /// then update convert clusters to the new format
+ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
std::vector<aiNode*> nodes;
@@ -190,62 +203,69 @@ namespace Assimp {
try {
for (const Connection* con : conns) {
-
// ignore object-property links
if (con->PropertyName().length()) {
- continue;
+ // really important we document why this is ignored.
+ FBXImporter::LogInfo("ignoring property link - no docs on why this is ignored");
+ continue; //?
}
+ // convert connection source object into Object base class
const Object* const object = con->SourceObject();
if (nullptr == object) {
- FBXImporter::LogWarn("failed to convert source object for Model link");
+ FBXImporter::LogError("failed to convert source object for Model link");
continue;
}
+ // FBX Model::Cube, Model::Bone001, etc elements
+ // This detects if we can cast the object into this model structure.
const Model* const model = dynamic_cast<const Model*>(object);
if (nullptr != model) {
nodes_chain.clear();
post_nodes_chain.clear();
- aiMatrix4x4 new_abs_transform = parent_transform;
-
- std::string unique_name = MakeUniqueNodeName(model, parent);
-
+ aiMatrix4x4 new_abs_transform = parent->mTransformation;
+ std::string node_name = FixNodeName(model->Name());
// even though there is only a single input node, the design of
// assimp (or rather: the complicated transformation chain that
// is employed by fbx) means that we may need multiple aiNode's
// to represent a fbx node's transformation.
- const bool need_additional_node = GenerateTransformationNodeChain(*model, unique_name, nodes_chain, post_nodes_chain);
+
+ // generate node transforms - this includes pivot data
+ // if need_additional_node is true then you t
+ const bool need_additional_node = GenerateTransformationNodeChain(*model, node_name, nodes_chain, post_nodes_chain);
+
+ // assert that for the current node we must have at least a single transform
ai_assert(nodes_chain.size());
if (need_additional_node) {
- nodes_chain.push_back(new aiNode(unique_name));
+ nodes_chain.push_back(new aiNode(node_name));
}
//setup metadata on newest node
SetupNodeMetadata(*model, *nodes_chain.back());
// link all nodes in a row
- aiNode* last_parent = &parent;
- for (aiNode* prenode : nodes_chain) {
- ai_assert(prenode);
+ aiNode* last_parent = parent;
+ for (aiNode* child : nodes_chain) {
+ ai_assert(child);
- if (last_parent != &parent) {
+ if (last_parent != parent) {
last_parent->mNumChildren = 1;
last_parent->mChildren = new aiNode*[1];
- last_parent->mChildren[0] = prenode;
+ last_parent->mChildren[0] = child;
}
- prenode->mParent = last_parent;
- last_parent = prenode;
+ child->mParent = last_parent;
+ last_parent = child;
- new_abs_transform *= prenode->mTransformation;
+ new_abs_transform *= child->mTransformation;
}
// attach geometry
- ConvertModel(*model, *nodes_chain.back(), new_abs_transform);
+ ConvertModel(*model, nodes_chain.back(), root_node, new_abs_transform);
// check if there will be any child nodes
const std::vector<const Connection*>& child_conns
@@ -257,7 +277,7 @@ namespace Assimp {
for (aiNode* postnode : post_nodes_chain) {
ai_assert(postnode);
- if (last_parent != &parent) {
+ if (last_parent != parent) {
last_parent->mNumChildren = 1;
last_parent->mChildren = new aiNode*[1];
last_parent->mChildren[0] = postnode;
@@ -279,15 +299,15 @@ namespace Assimp {
);
}
- // attach sub-nodes (if any)
- ConvertNodes(model->ID(), *last_parent, new_abs_transform);
+ // recursion call - child nodes
+ ConvertNodes(model->ID(), last_parent, root_node);
if (doc.Settings().readLights) {
- ConvertLights(*model, unique_name);
+ ConvertLights(*model, node_name);
}
if (doc.Settings().readCameras) {
- ConvertCameras(*model, unique_name);
+ ConvertCameras(*model, node_name);
}
nodes.push_back(nodes_chain.front());
@@ -296,11 +316,17 @@ namespace Assimp {
}
if (nodes.size()) {
- parent.mChildren = new aiNode*[nodes.size()]();
- parent.mNumChildren = static_cast<unsigned int>(nodes.size());
+ parent->mChildren = new aiNode*[nodes.size()]();
+ parent->mNumChildren = static_cast<unsigned int>(nodes.size());
- std::swap_ranges(nodes.begin(), nodes.end(), parent.mChildren);
+ std::swap_ranges(nodes.begin(), nodes.end(), parent->mChildren);
}
+ else
+ {
+ parent->mNumChildren = 0;
+ parent->mChildren = nullptr;
+ }
+
}
catch (std::exception&) {
Util::delete_fun<aiNode> deleter;
@@ -553,7 +579,7 @@ namespace Assimp {
return;
}
- const float angle_epsilon = 1e-6f;
+ const float angle_epsilon = Math::getEpsilon<float>();
out = aiMatrix4x4();
@@ -694,7 +720,7 @@ namespace Assimp {
std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4());
// generate transformation matrices for all the different transformation components
- const float zero_epsilon = 1e-6f;
+ const float zero_epsilon = Math::getEpsilon<float>();
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
@@ -802,7 +828,7 @@ namespace Assimp {
// is_complex needs to be consistent with NeedsComplexTransformationChain()
// or the interplay between this code and the animation converter would
// not be guaranteed.
- ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
+ //ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
// now, if we have more than just Translation, Scaling and Rotation,
// we need to generate a full node chain to accommodate for assimp's
@@ -904,7 +930,8 @@ namespace Assimp {
}
}
- void FBXConverter::ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform)
+ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform)
{
const std::vector<const Geometry*>& geos = model.GetGeometry();
@@ -916,11 +943,12 @@ namespace Assimp {
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
const LineGeometry* const line = dynamic_cast<const LineGeometry*>(geo);
if (mesh) {
- const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform, nd);
+ const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, parent, root_node,
+ absolute_transform);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
}
else if (line) {
- const std::vector<unsigned int>& indices = ConvertLine(*line, model, node_global_transform, nd);
+ const std::vector<unsigned int>& indices = ConvertLine(*line, model, parent, root_node);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
}
else {
@@ -929,15 +957,16 @@ namespace Assimp {
}
if (meshes.size()) {
- nd.mMeshes = new unsigned int[meshes.size()]();
- nd.mNumMeshes = static_cast<unsigned int>(meshes.size());
+ parent->mMeshes = new unsigned int[meshes.size()]();
+ parent->mNumMeshes = static_cast<unsigned int>(meshes.size());
- std::swap_ranges(meshes.begin(), meshes.end(), nd.mMeshes);
+ std::swap_ranges(meshes.begin(), meshes.end(), parent->mMeshes);
}
}
- std::vector<unsigned int> FBXConverter::ConvertMesh(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd)
+ std::vector<unsigned int>
+ FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform)
{
std::vector<unsigned int> temp;
@@ -961,18 +990,18 @@ namespace Assimp {
const MatIndexArray::value_type base = mindices[0];
for (MatIndexArray::value_type index : mindices) {
if (index != base) {
- return ConvertMeshMultiMaterial(mesh, model, node_global_transform, nd);
+ return ConvertMeshMultiMaterial(mesh, model, parent, root_node, absolute_transform);
}
}
}
// faster code-path, just copy the data
- temp.push_back(ConvertMeshSingleMaterial(mesh, model, node_global_transform, nd));
+ temp.push_back(ConvertMeshSingleMaterial(mesh, model, absolute_transform, parent, root_node));
return temp;
}
std::vector<unsigned int> FBXConverter::ConvertLine(const LineGeometry& line, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd)
+ aiNode *parent, aiNode *root_node)
{
std::vector<unsigned int> temp;
@@ -983,7 +1012,7 @@ namespace Assimp {
return temp;
}
- aiMesh* const out_mesh = SetupEmptyMesh(line, nd);
+ aiMesh* const out_mesh = SetupEmptyMesh(line, root_node);
out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
// copy vertices
@@ -1018,7 +1047,7 @@ namespace Assimp {
return temp;
}
- aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode& nd)
+ aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode *parent)
{
aiMesh* const out_mesh = new aiMesh();
meshes.push_back(out_mesh);
@@ -1035,17 +1064,18 @@ namespace Assimp {
}
else
{
- out_mesh->mName = nd.mName;
+ out_mesh->mName = parent->mName;
}
return out_mesh;
}
- unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd)
+ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
+ const aiMatrix4x4 &absolute_transform, aiNode *parent,
+ aiNode *root_node)
{
const MatIndexArray& mindices = mesh.GetMaterialIndices();
- aiMesh* const out_mesh = SetupEmptyMesh(mesh, nd);
+ aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent);
const std::vector<aiVector3D>& vertices = mesh.GetVertices();
const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
@@ -1112,7 +1142,7 @@ namespace Assimp {
binormals = &tempBinormals;
}
else {
- binormals = NULL;
+ binormals = nullptr;
}
}
@@ -1162,8 +1192,9 @@ namespace Assimp {
ConvertMaterialForMesh(out_mesh, model, mesh, mindices[0]);
}
- if (doc.Settings().readWeights && mesh.DeformerSkin() != NULL) {
- ConvertWeights(out_mesh, model, mesh, node_global_transform, NO_MATERIAL_SEPARATION);
+ if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr) {
+ ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, NO_MATERIAL_SEPARATION,
+ nullptr);
}
std::vector<aiAnimMesh*> animMeshes;
@@ -1208,8 +1239,10 @@ namespace Assimp {
return static_cast<unsigned int>(meshes.size() - 1);
}
- std::vector<unsigned int> FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd)
+ std::vector<unsigned int>
+ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent,
+ aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform)
{
const MatIndexArray& mindices = mesh.GetMaterialIndices();
ai_assert(mindices.size());
@@ -1220,7 +1253,7 @@ namespace Assimp {
for (MatIndexArray::value_type index : mindices) {
if (had.find(index) == had.end()) {
- indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, node_global_transform, nd));
+ indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node, absolute_transform));
had.insert(index);
}
}
@@ -1228,18 +1261,18 @@ namespace Assimp {
return indices;
}
- unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
- MatIndexArray::value_type index,
- const aiMatrix4x4& node_global_transform,
- aiNode& nd)
+ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model,
+ MatIndexArray::value_type index,
+ aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform)
{
- aiMesh* const out_mesh = SetupEmptyMesh(mesh, nd);
+ aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent);
const MatIndexArray& mindices = mesh.GetMaterialIndices();
const std::vector<aiVector3D>& vertices = mesh.GetVertices();
const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
- const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != NULL;
+ const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != nullptr;
unsigned int count_faces = 0;
unsigned int count_vertices = 0;
@@ -1299,7 +1332,7 @@ namespace Assimp {
binormals = &tempBinormals;
}
else {
- binormals = NULL;
+ binormals = nullptr;
}
}
@@ -1398,7 +1431,7 @@ namespace Assimp {
ConvertMaterialForMesh(out_mesh, model, mesh, index);
if (process_weights) {
- ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping);
+ ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, index, &reverseMapping);
}
std::vector<aiAnimMesh*> animMeshes;
@@ -1448,10 +1481,10 @@ namespace Assimp {
return static_cast<unsigned int>(meshes.size() - 1);
}
- void FBXConverter::ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
- const aiMatrix4x4& node_global_transform,
- unsigned int materialIndex,
- std::vector<unsigned int>* outputVertStartIndices)
+ void FBXConverter::ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo,
+ const aiMatrix4x4 &absolute_transform,
+ aiNode *parent, aiNode *root_node, unsigned int materialIndex,
+ std::vector<unsigned int> *outputVertStartIndices)
{
ai_assert(geo.DeformerSkin());
@@ -1462,13 +1495,12 @@ namespace Assimp {
const Skin& sk = *geo.DeformerSkin();
std::vector<aiBone*> bones;
- bones.reserve(sk.Clusters().size());
const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
ai_assert(no_mat_check || outputVertStartIndices);
try {
-
+ // iterate over the sub deformers
for (const Cluster* cluster : sk.Clusters()) {
ai_assert(cluster);
@@ -1482,15 +1514,16 @@ namespace Assimp {
index_out_indices.clear();
out_indices.clear();
+
// now check if *any* of these weights is contained in the output mesh,
// taking notes so we don't need to do it twice.
for (WeightIndexArray::value_type index : indices) {
unsigned int count = 0;
const unsigned int* const out_idx = geo.ToOutputVertexIndex(index, count);
- // ToOutputVertexIndex only returns NULL if index is out of bounds
+ // ToOutputVertexIndex only returns nullptr if index is out of bounds
// which should never happen
- ai_assert(out_idx != NULL);
+ ai_assert(out_idx != nullptr);
index_out_indices.push_back(no_index_sentinel);
count_out_indices.push_back(0);
@@ -1519,68 +1552,107 @@ namespace Assimp {
}
}
}
-
+
// if we found at least one, generate the output bones
// XXX this could be heavily simplified by collecting the bone
// data in a single step.
- ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
- count_out_indices, node_global_transform);
+ ConvertCluster(bones, cluster, out_indices, index_out_indices,
+ count_out_indices, absolute_transform, parent, root_node);
}
+
+ bone_map.clear();
}
- catch (std::exception&) {
+ catch (std::exception&e) {
std::for_each(bones.begin(), bones.end(), Util::delete_fun<aiBone>());
throw;
}
if (bones.empty()) {
+ out->mBones = nullptr;
+ out->mNumBones = 0;
return;
- }
-
- out->mBones = new aiBone*[bones.size()]();
- out->mNumBones = static_cast<unsigned int>(bones.size());
+ } else {
+ out->mBones = new aiBone *[bones.size()]();
+ out->mNumBones = static_cast<unsigned int>(bones.size());
- std::swap_ranges(bones.begin(), bones.end(), out->mBones);
+ std::swap_ranges(bones.begin(), bones.end(), out->mBones);
+ }
}
- void FBXConverter::ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
- std::vector<size_t>& out_indices,
- std::vector<size_t>& index_out_indices,
- std::vector<size_t>& count_out_indices,
- const aiMatrix4x4& node_global_transform)
+ const aiNode* FBXConverter::GetNodeByName( const aiString& name, aiNode *current_node )
{
+ aiNode * iter = current_node;
+ //printf("Child count: %d", iter->mNumChildren);
+ return iter;
+ }
- aiBone* const bone = new aiBone();
- bones.push_back(bone);
+ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
+ std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
+ std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
+ aiNode *parent, aiNode *root_node) {
+ ai_assert(cl); // make sure cluster valid
+ std::string deformer_name = cl->TargetNode()->Name();
+ aiString bone_name = aiString(FixNodeName(deformer_name));
- bone->mName = FixNodeName(cl.TargetNode()->Name());
+ aiBone *bone = nullptr;
- bone->mOffsetMatrix = cl.TransformLink();
- bone->mOffsetMatrix.Inverse();
+ if (bone_map.count(deformer_name)) {
+ std::cout << "retrieved bone from lookup " << bone_name.C_Str() << ". Deformer: " << deformer_name
+ << std::endl;
+ bone = bone_map[deformer_name];
+ } else {
+ std::cout << "created new bone " << bone_name.C_Str() << ". Deformer: " << deformer_name << std::endl;
+ bone = new aiBone();
+ bone->mName = bone_name;
- bone->mOffsetMatrix = bone->mOffsetMatrix * node_global_transform;
+ // store local transform link for post processing
+ bone->mOffsetMatrix = cl->TransformLink();
+ bone->mOffsetMatrix.Inverse();
- bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
- aiVertexWeight* cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
+ aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
- const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
- const WeightArray& weights = cl.GetWeights();
+ bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
- const size_t c = index_out_indices.size();
- for (size_t i = 0; i < c; ++i) {
- const size_t index_index = index_out_indices[i];
- if (index_index == no_index_sentinel) {
- continue;
- }
+ //
+ // Now calculate the aiVertexWeights
+ //
+
+ aiVertexWeight *cursor = nullptr;
+
+ bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
+ cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
- const size_t cc = count_out_indices[i];
- for (size_t j = 0; j < cc; ++j) {
- aiVertexWeight& out_weight = *cursor++;
+ const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
+ const WeightArray& weights = cl->GetWeights();
- out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]);
- out_weight.mWeight = weights[i];
+ const size_t c = index_out_indices.size();
+ for (size_t i = 0; i < c; ++i) {
+ const size_t index_index = index_out_indices[i];
+
+ if (index_index == no_index_sentinel) {
+ continue;
+ }
+
+ const size_t cc = count_out_indices[i];
+ for (size_t j = 0; j < cc; ++j) {
+ // cursor runs from first element relative to the start
+ // or relative to the start of the next indexes.
+ aiVertexWeight& out_weight = *cursor++;
+
+ out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]);
+ out_weight.mWeight = weights[i];
+ }
}
+
+ bone_map.insert(std::pair<const std::string, aiBone *>(deformer_name, bone));
}
+
+ std::cout << "bone research: Indicies size: " << out_indices.size() << std::endl;
+
+ // lookup must be populated in case something goes wrong
+ // this also allocates bones to mesh instance outside
+ local_mesh_bones.push_back(bone);
}
void FBXConverter::ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@@ -1710,7 +1782,7 @@ namespace Assimp {
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
unsigned int index;
- VideoMap::const_iterator it = textures_converted.find(media);
+ VideoMap::const_iterator it = textures_converted.find(*media);
if (it != textures_converted.end()) {
index = (*it).second;
textureReady = true;
@@ -1718,7 +1790,7 @@ namespace Assimp {
else {
if (media->ContentLength() > 0) {
index = ConvertVideo(*media);
- textures_converted[media] = index;
+ textures_converted[*media] = index;
textureReady = true;
}
}
@@ -2242,13 +2314,13 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
if (media != nullptr && media->ContentLength() > 0) {
unsigned int index;
- VideoMap::const_iterator it = textures_converted.find(media);
+ VideoMap::const_iterator it = textures_converted.find(*media);
if (it != textures_converted.end()) {
index = (*it).second;
}
else {
index = ConvertVideo(*media);
- textures_converted[media] = index;
+ textures_converted[*media] = index;
}
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
@@ -2676,7 +2748,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
// sanity check whether the input is ok
static void validateAnimCurveNodes(const std::vector<const AnimationCurveNode*>& curves,
bool strictMode) {
- const Object* target(NULL);
+ const Object* target(nullptr);
for (const AnimationCurveNode* node : curves) {
if (!target) {
target = node->Target();
@@ -2707,7 +2779,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
#ifdef ASSIMP_BUILD_DEBUG
validateAnimCurveNodes(curves, doc.Settings().strictMode);
#endif
- const AnimationCurveNode* curve_node = NULL;
+ const AnimationCurveNode* curve_node = nullptr;
for (const AnimationCurveNode* node : curves) {
ai_assert(node);
@@ -2967,7 +3039,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
TransformationCompDefaultValue(comp)
);
- const float epsilon = 1e-6f;
+ const float epsilon = Math::getEpsilon<float>();
return (dyn_val - static_val).SquareLength() < epsilon;
}
@@ -3555,7 +3627,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
ai_assert(!out->mMeshes);
ai_assert(!out->mNumMeshes);
- // note: the trailing () ensures initialization with NULL - not
+ // note: the trailing () ensures initialization with nullptr - not
// many C++ users seem to know this, so pointing it out to avoid
// confusion why this code works.
@@ -3602,6 +3674,47 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
}
}
+ void FBXConverter::ConvertOrphantEmbeddedTextures()
+ {
+ // in C++14 it could be:
+ // for (auto&& [id, object] : objects)
+ for (auto&& id_and_object : doc.Objects())
+ {
+ auto&& id = std::get<0>(id_and_object);
+ auto&& object = std::get<1>(id_and_object);
+ // If an object doesn't have parent
+ if (doc.ConnectionsBySource().count(id) == 0)
+ {
+ const Texture* realTexture = nullptr;
+ try
+ {
+ const auto& element = object->GetElement();
+ const Token& key = element.KeyToken();
+ const char* obtype = key.begin();
+ const size_t length = static_cast<size_t>(key.end() - key.begin());
+ if (strncmp(obtype, "Texture", length) == 0)
+ {
+ const Texture* texture = static_cast<const Texture*>(object->Get());
+ if (texture->Media() && texture->Media()->ContentLength() > 0)
+ {
+ realTexture = texture;
+ }
+ }
+ }
+ catch (...)
+ {
+ // do nothing
+ }
+ if (realTexture)
+ {
+ const Video* media = realTexture->Media();
+ unsigned int index = ConvertVideo(*media);
+ textures_converted[*media] = index;
+ }
+ }
+ }
+ }
+
// ------------------------------------------------------------------------------------------------
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
{
diff --git a/thirdparty/assimp/code/FBX/FBXConverter.h b/thirdparty/assimp/code/FBX/FBXConverter.h
index ab610058a4..46693bdca6 100644
--- a/thirdparty/assimp/code/FBX/FBXConverter.h
+++ b/thirdparty/assimp/code/FBX/FBXConverter.h
@@ -76,16 +76,6 @@ namespace Assimp {
namespace FBX {
class Document;
-
-enum class FbxUnit {
- cm = 0,
- m,
- km,
- NumUnits,
-
- Undefined
-};
-
/**
* Convert a FBX #Document to #aiScene
* @param out Empty scene to be populated
@@ -133,7 +123,7 @@ private:
// ------------------------------------------------------------------------------------------------
// collect and assign child nodes
- void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4());
+ void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
void ConvertLights(const Model& model, const std::string &orig_name );
@@ -189,32 +179,35 @@ private:
void SetupNodeMetadata(const Model& model, aiNode& nd);
// ------------------------------------------------------------------------------------------------
- void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform);
+ void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
- std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd);
+ std::vector<unsigned int>
+ ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------
std::vector<unsigned int> ConvertLine(const LineGeometry& line, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd);
+ aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
- aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode& nd);
+ aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent);
// ------------------------------------------------------------------------------------------------
- unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd);
+ unsigned int ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
+ const aiMatrix4x4 &absolute_transform, aiNode *parent,
+ aiNode *root_node);
// ------------------------------------------------------------------------------------------------
- std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd);
+ std::vector<unsigned int>
+ ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------
- unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
- MatIndexArray::value_type index,
- const aiMatrix4x4& node_global_transform, aiNode& nd);
+ unsigned int ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, MatIndexArray::value_type index,
+ aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------
static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
@@ -227,17 +220,17 @@ private:
* - outputVertStartIndices is only used when a material index is specified, it gives for
* each output vertex the DOM index it maps to.
*/
- void ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
- const aiMatrix4x4& node_global_transform = aiMatrix4x4(),
- unsigned int materialIndex = NO_MATERIAL_SEPARATION,
- std::vector<unsigned int>* outputVertStartIndices = NULL);
-
+ void ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
+ aiNode *parent = NULL, aiNode *root_node = NULL,
+ unsigned int materialIndex = NO_MATERIAL_SEPARATION,
+ std::vector<unsigned int> *outputVertStartIndices = NULL);
+ // lookup
+ static const aiNode* GetNodeByName( const aiString& name, aiNode *current_node );
// ------------------------------------------------------------------------------------------------
- void ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
- std::vector<size_t>& out_indices,
- std::vector<size_t>& index_out_indices,
- std::vector<size_t>& count_out_indices,
- const aiMatrix4x4& node_global_transform);
+ void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
+ std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
+ std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
+ aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@@ -434,6 +427,10 @@ private:
// copy generated meshes, animations, lights, cameras and textures to the output scene
void TransferDataToScene();
+ // ------------------------------------------------------------------------------------------------
+ // FBX file could have embedded textures not connected to anything
+ void ConvertOrphantEmbeddedTextures();
+
private:
// 0: not assigned yet, others: index is value - 1
unsigned int defaultMaterialIndex;
@@ -445,28 +442,47 @@ private:
std::vector<aiCamera*> cameras;
std::vector<aiTexture*> textures;
- using MaterialMap = std::map<const Material*, unsigned int>;
+ using MaterialMap = std::fbx_unordered_map<const Material*, unsigned int>;
MaterialMap materials_converted;
- using VideoMap = std::map<const Video*, unsigned int>;
+ using VideoMap = std::fbx_unordered_map<const Video, unsigned int>;
VideoMap textures_converted;
- using MeshMap = std::map<const Geometry*, std::vector<unsigned int> >;
+ using MeshMap = std::fbx_unordered_map<const Geometry*, std::vector<unsigned int> >;
MeshMap meshes_converted;
// fixed node name -> which trafo chain components have animations?
- using NodeAnimBitMap = std::map<std::string, unsigned int> ;
+ using NodeAnimBitMap = std::fbx_unordered_map<std::string, unsigned int> ;
NodeAnimBitMap node_anim_chain_bits;
// number of nodes with the same name
- using NodeNameCache = std::unordered_map<std::string, unsigned int>;
+ using NodeNameCache = std::fbx_unordered_map<std::string, unsigned int>;
NodeNameCache mNodeNames;
+ // Deformer name is not the same as a bone name - it does contain the bone name though :)
+ // Deformer names in FBX are always unique in an FBX file.
+ std::map<const std::string, aiBone *> bone_map;
+
double anim_fps;
aiScene* const out;
const FBX::Document& doc;
- FbxUnit mCurrentUnit;
+
+ static void BuildBoneList(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
+ std::vector<aiBone*>& bones);
+
+ void BuildBoneStack(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
+ const std::vector<aiBone *> &bones,
+ std::map<aiBone *, aiNode *> &bone_stack,
+ std::vector<aiNode*> &node_stack );
+
+ static void BuildNodeList(aiNode *current_node, std::vector<aiNode *> &nodes);
+
+ static aiNode *GetNodeFromStack(const aiString &node_name, std::vector<aiNode *> &nodes);
+
+ static aiNode *GetArmatureRoot(aiNode *bone_node, std::vector<aiBone*> &bone_list);
+
+ static bool IsBoneNode(const aiString &bone_name, std::vector<aiBone *> &bones);
};
}
diff --git a/thirdparty/assimp/code/FBX/FBXDocument.h b/thirdparty/assimp/code/FBX/FBXDocument.h
index 18e5c38f13..a60d7d9efa 100644
--- a/thirdparty/assimp/code/FBX/FBXDocument.h
+++ b/thirdparty/assimp/code/FBX/FBXDocument.h
@@ -637,6 +637,20 @@ public:
return ptr;
}
+ bool operator==(const Video& other) const
+ {
+ return (
+ type == other.type
+ && relativeFileName == other.relativeFileName
+ && fileName == other.fileName
+ );
+ }
+
+ bool operator<(const Video& other) const
+ {
+ return std::tie(type, relativeFileName, fileName) < std::tie(other.type, other.relativeFileName, other.fileName);
+ }
+
private:
std::string type;
std::string relativeFileName;
@@ -1005,10 +1019,10 @@ public:
// during their entire lifetime (Document). FBX files have
// up to many thousands of objects (most of which we never use),
// so the memory overhead for them should be kept at a minimum.
-typedef std::map<uint64_t, LazyObject*> ObjectMap;
+typedef std::fbx_unordered_map<uint64_t, LazyObject*> ObjectMap;
typedef std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > PropertyTemplateMap;
-typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
+typedef std::fbx_unordered_multimap<uint64_t, const Connection*> ConnectionMap;
/** DOM class for global document settings, a single instance per document can
* be accessed via Document.Globals(). */
@@ -1177,4 +1191,25 @@ private:
} // Namespace FBX
} // Namespace Assimp
+namespace std
+{
+ template <>
+ struct hash<const Assimp::FBX::Video>
+ {
+ std::size_t operator()(const Assimp::FBX::Video& video) const
+ {
+ using std::size_t;
+ using std::hash;
+ using std::string;
+
+ size_t res = 17;
+ res = res * 31 + hash<string>()(video.Name());
+ res = res * 31 + hash<string>()(video.RelativeFilename());
+ res = res * 31 + hash<string>()(video.Type());
+
+ return res;
+ }
+ };
+}
+
#endif // INCLUDED_AI_FBX_DOCUMENT_H
diff --git a/thirdparty/assimp/code/FBX/FBXExportProperty.cpp b/thirdparty/assimp/code/FBX/FBXExportProperty.cpp
index f8593e6295..f2a63b72b9 100644
--- a/thirdparty/assimp/code/FBX/FBXExportProperty.cpp
+++ b/thirdparty/assimp/code/FBX/FBXExportProperty.cpp
@@ -59,11 +59,7 @@ namespace FBX {
FBXExportProperty::FBXExportProperty(bool v)
: type('C')
-, data(1) {
- data = {
- uint8_t(v)
- };
-}
+, data(1, uint8_t(v)) {}
FBXExportProperty::FBXExportProperty(int16_t v)
: type('Y')
diff --git a/thirdparty/assimp/code/FBX/FBXExporter.cpp b/thirdparty/assimp/code/FBX/FBXExporter.cpp
index 8ebc8555a2..9316dc4f02 100644
--- a/thirdparty/assimp/code/FBX/FBXExporter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXExporter.cpp
@@ -67,6 +67,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <array>
#include <unordered_set>
+#include <numeric>
// RESOURCES:
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/
@@ -1005,6 +1006,9 @@ void FBXExporter::WriteObjects ()
object_node.EndProperties(outstream, binary, indent);
object_node.BeginChildren(outstream, binary, indent);
+ bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true);
+ std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later
+
// geometry (aiMesh)
mesh_uids.clear();
indent = 1;
@@ -1031,21 +1035,35 @@ void FBXExporter::WriteObjects ()
std::vector<int32_t> vertex_indices;
// map of vertex value to its index in the data vector
std::map<aiVector3D,size_t> index_by_vertex_value;
- int32_t index = 0;
- for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
- aiVector3D vtx = m->mVertices[vi];
- auto elem = index_by_vertex_value.find(vtx);
- if (elem == index_by_vertex_value.end()) {
- vertex_indices.push_back(index);
- index_by_vertex_value[vtx] = index;
- flattened_vertices.push_back(vtx[0]);
- flattened_vertices.push_back(vtx[1]);
- flattened_vertices.push_back(vtx[2]);
- ++index;
- } else {
- vertex_indices.push_back(int32_t(elem->second));
+ if(bJoinIdenticalVertices){
+ int32_t index = 0;
+ for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
+ aiVector3D vtx = m->mVertices[vi];
+ auto elem = index_by_vertex_value.find(vtx);
+ if (elem == index_by_vertex_value.end()) {
+ vertex_indices.push_back(index);
+ index_by_vertex_value[vtx] = index;
+ flattened_vertices.push_back(vtx[0]);
+ flattened_vertices.push_back(vtx[1]);
+ flattened_vertices.push_back(vtx[2]);
+ ++index;
+ } else {
+ vertex_indices.push_back(int32_t(elem->second));
+ }
+ }
+ }
+ else { // do not join vertex, respect the export flag
+ vertex_indices.resize(m->mNumVertices);
+ std::iota(vertex_indices.begin(), vertex_indices.end(), 0);
+ for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
+ aiVector3D vtx = m->mVertices[v];
+ flattened_vertices.push_back(vtx.x);
+ flattened_vertices.push_back(vtx.y);
+ flattened_vertices.push_back(vtx.z);
}
}
+ vVertexIndice.push_back(vertex_indices);
+
FBX::Node::WritePropertyNode(
"Vertices", flattened_vertices, outstream, binary, indent
);
@@ -1116,6 +1134,51 @@ void FBXExporter::WriteObjects ()
normals.End(outstream, binary, indent, true);
}
+ // colors, if any
+ // TODO only one color channel currently
+ const int32_t colorChannelIndex = 0;
+ if (m->HasVertexColors(colorChannelIndex)) {
+ FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
+ vertexcolors.Begin(outstream, binary, indent);
+ vertexcolors.DumpProperties(outstream, binary, indent);
+ vertexcolors.EndProperties(outstream, binary, indent);
+ vertexcolors.BeginChildren(outstream, binary, indent);
+ indent = 3;
+ FBX::Node::WritePropertyNode(
+ "Version", int32_t(101), outstream, binary, indent
+ );
+ char layerName[8];
+ sprintf(layerName, "COLOR_%d", colorChannelIndex);
+ FBX::Node::WritePropertyNode(
+ "Name", (const char*)layerName, outstream, binary, indent
+ );
+ FBX::Node::WritePropertyNode(
+ "MappingInformationType", "ByPolygonVertex",
+ outstream, binary, indent
+ );
+ FBX::Node::WritePropertyNode(
+ "ReferenceInformationType", "Direct",
+ outstream, binary, indent
+ );
+ std::vector<double> color_data;
+ color_data.reserve(4 * polygon_data.size());
+ for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
+ const aiFace &f = m->mFaces[fi];
+ for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
+ const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]];
+ color_data.push_back(c.r);
+ color_data.push_back(c.g);
+ color_data.push_back(c.b);
+ color_data.push_back(c.a);
+ }
+ }
+ FBX::Node::WritePropertyNode(
+ "Colors", color_data, outstream, binary, indent
+ );
+ indent = 2;
+ vertexcolors.End(outstream, binary, indent, true);
+ }
+
// uvs, if any
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
if (m->mNumUVComponents[uvi] > 2) {
@@ -1209,6 +1272,11 @@ void FBXExporter::WriteObjects ()
le.AddChild("Type", "LayerElementNormal");
le.AddChild("TypedIndex", int32_t(0));
layer.AddChild(le);
+ // TODO only 1 color channel currently
+ le = FBX::Node("LayerElement");
+ le.AddChild("Type", "LayerElementColor");
+ le.AddChild("TypedIndex", int32_t(0));
+ layer.AddChild(le);
le = FBX::Node("LayerElement");
le.AddChild("Type", "LayerElementMaterial");
le.AddChild("TypedIndex", int32_t(0));
@@ -1221,7 +1289,7 @@ void FBXExporter::WriteObjects ()
for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr)
{
- FBX::Node layerExtra("Layer", int32_t(1));
+ FBX::Node layerExtra("Layer", int32_t(lr));
layerExtra.AddChild("Version", int32_t(100));
FBX::Node leExtra("LayerElement");
leExtra.AddChild("Type", "LayerElementUV");
@@ -1748,28 +1816,8 @@ void FBXExporter::WriteObjects ()
// connect it
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
- // we will be indexing by vertex...
- // but there might be a different number of "vertices"
- // between assimp and our output FBX.
- // this code is cut-and-pasted from the geometry section above...
- // ideally this should not be so.
- // ---
- // index of original vertex in vertex data vector
- std::vector<int32_t> vertex_indices;
- // map of vertex value to its index in the data vector
- std::map<aiVector3D,size_t> index_by_vertex_value;
- int32_t index = 0;
- for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
- aiVector3D vtx = m->mVertices[vi];
- auto elem = index_by_vertex_value.find(vtx);
- if (elem == index_by_vertex_value.end()) {
- vertex_indices.push_back(index);
- index_by_vertex_value[vtx] = index;
- ++index;
- } else {
- vertex_indices.push_back(int32_t(elem->second));
- }
- }
+ //computed before
+ std::vector<int32_t>& vertex_indices = vVertexIndice[mi];
// TODO, FIXME: this won't work if anything is not in the bind pose.
// for now if such a situation is detected, we throw an exception.
@@ -2435,7 +2483,7 @@ void FBXExporter::WriteModelNodes(
void FBXExporter::WriteAnimationCurveNode(
StreamWriterLE& outstream,
int64_t uid,
- std::string name, // "T", "R", or "S"
+ const std::string& name, // "T", "R", or "S"
aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc
int64_t layer_uid,
diff --git a/thirdparty/assimp/code/FBX/FBXExporter.h b/thirdparty/assimp/code/FBX/FBXExporter.h
index 71fb55c57f..1ae727eda9 100644
--- a/thirdparty/assimp/code/FBX/FBXExporter.h
+++ b/thirdparty/assimp/code/FBX/FBXExporter.h
@@ -156,7 +156,7 @@ namespace Assimp
void WriteAnimationCurveNode(
StreamWriterLE& outstream,
int64_t uid,
- std::string name, // "T", "R", or "S"
+ const std::string& name, // "T", "R", or "S"
aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc
int64_t animation_layer_uid,
diff --git a/thirdparty/assimp/code/FBX/FBXImporter.cpp b/thirdparty/assimp/code/FBX/FBXImporter.cpp
index 271935a568..afcc1ddc78 100644
--- a/thirdparty/assimp/code/FBX/FBXImporter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXImporter.cpp
@@ -48,26 +48,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXImporter.h"
-#include "FBXTokenizer.h"
+#include "FBXConverter.h"
+#include "FBXDocument.h"
#include "FBXParser.h"
+#include "FBXTokenizer.h"
#include "FBXUtil.h"
-#include "FBXDocument.h"
-#include "FBXConverter.h"
-#include <assimp/StreamReader.h>
#include <assimp/MemoryIOWrapper.h>
-#include <assimp/Importer.hpp>
+#include <assimp/StreamReader.h>
#include <assimp/importerdesc.h>
+#include <assimp/Importer.hpp>
namespace Assimp {
-template<>
-const char* LogFunctions<FBXImporter>::Prefix() {
- static auto prefix = "FBX: ";
- return prefix;
+template <>
+const char *LogFunctions<FBXImporter>::Prefix() {
+ static auto prefix = "FBX: ";
+ return prefix;
}
-}
+} // namespace Assimp
using namespace Assimp;
using namespace Assimp::Formatter;
@@ -76,136 +76,123 @@ using namespace Assimp::FBX;
namespace {
static const aiImporterDesc desc = {
- "Autodesk FBX Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "fbx"
+ "Autodesk FBX Importer",
+ "",
+ "",
+ "",
+ aiImporterFlags_SupportTextFlavour,
+ 0,
+ 0,
+ 0,
+ 0,
+ "fbx"
};
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by #Importer
-FBXImporter::FBXImporter()
-{
+FBXImporter::FBXImporter() {
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
-FBXImporter::~FBXImporter()
-{
+FBXImporter::~FBXImporter() {
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
-bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string& extension = GetExtension(pFile);
- if (extension == std::string( desc.mFileExtensions ) ) {
- return true;
- }
-
- else if ((!extension.length() || checkSig) && pIOHandler) {
- // at least ASCII-FBX files usually have a 'FBX' somewhere in their head
- const char* tokens[] = {"fbx"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
+bool FBXImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
+ const std::string &extension = GetExtension(pFile);
+ if (extension == std::string(desc.mFileExtensions)) {
+ return true;
+ }
+
+ else if ((!extension.length() || checkSig) && pIOHandler) {
+ // at least ASCII-FBX files usually have a 'FBX' somewhere in their head
+ const char *tokens[] = { "fbx" };
+ return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
+ }
+ return false;
}
// ------------------------------------------------------------------------------------------------
// List all extensions handled by this loader
-const aiImporterDesc* FBXImporter::GetInfo () const
-{
- return &desc;
+const aiImporterDesc *FBXImporter::GetInfo() const {
+ return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader
-void FBXImporter::SetupProperties(const Importer* pImp)
-{
- settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
- settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
- settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
- settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
- settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
- settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
- settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
- settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
- settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
- settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
- settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
- settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
- settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
+void FBXImporter::SetupProperties(const Importer *pImp) {
+ settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
+ settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
+ settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
+ settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
+ settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
+ settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
+ settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
+ settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
+ settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
+ settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
+ settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
+ settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
+ settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
-void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
- if (!stream) {
- ThrowException("Could not open file for reading");
- }
-
- // read entire file into memory - no streaming for this, fbx
- // files can grow large, but the assimp output data structure
- // then becomes very large, too. Assimp doesn't support
- // streaming for its output data structures so the net win with
- // streaming input data would be very low.
- std::vector<char> contents;
- contents.resize(stream->FileSize()+1);
- stream->Read( &*contents.begin(), 1, contents.size()-1 );
- contents[ contents.size() - 1 ] = 0;
- const char* const begin = &*contents.begin();
-
- // broadphase tokenizing pass in which we identify the core
- // syntax elements of FBX (brackets, commas, key:value mappings)
- TokenList tokens;
- try {
-
- bool is_binary = false;
- if (!strncmp(begin,"Kaydara FBX Binary",18)) {
- is_binary = true;
- TokenizeBinary(tokens,begin,contents.size());
- }
- else {
- Tokenize(tokens,begin);
- }
-
- // use this information to construct a very rudimentary
- // parse-tree representing the FBX scope structure
- Parser parser(tokens, is_binary);
-
- // take the raw parse-tree and convert it to a FBX DOM
- Document doc(parser,settings);
-
- FbxUnit unit(FbxUnit::cm);
- if (settings.convertToMeters) {
- unit = FbxUnit::m;
- }
-
- // convert the FBX DOM to aiScene
- ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
-
- // size relative to cm
- float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
-
- // Set FBX file scale is relative to CM must be converted to M for
- // assimp universal format (M)
- SetFileScale( size_relative_to_cm * 0.01f);
-
- std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
- }
- catch(std::exception&) {
- std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
- throw;
- }
+void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
+ std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
+ if (!stream) {
+ ThrowException("Could not open file for reading");
+ }
+
+ // read entire file into memory - no streaming for this, fbx
+ // files can grow large, but the assimp output data structure
+ // then becomes very large, too. Assimp doesn't support
+ // streaming for its output data structures so the net win with
+ // streaming input data would be very low.
+ std::vector<char> contents;
+ contents.resize(stream->FileSize() + 1);
+ stream->Read(&*contents.begin(), 1, contents.size() - 1);
+ contents[contents.size() - 1] = 0;
+ const char *const begin = &*contents.begin();
+
+ // broadphase tokenizing pass in which we identify the core
+ // syntax elements of FBX (brackets, commas, key:value mappings)
+ TokenList tokens;
+ try {
+
+ bool is_binary = false;
+ if (!strncmp(begin, "Kaydara FBX Binary", 18)) {
+ is_binary = true;
+ TokenizeBinary(tokens, begin, contents.size());
+ } else {
+ Tokenize(tokens, begin);
+ }
+
+ // use this information to construct a very rudimentary
+ // parse-tree representing the FBX scope structure
+ Parser parser(tokens, is_binary);
+
+ // take the raw parse-tree and convert it to a FBX DOM
+ Document doc(parser, settings);
+
+ // convert the FBX DOM to aiScene
+ ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
+
+ // size relative to cm
+ float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
+
+ // Set FBX file scale is relative to CM must be converted to M for
+ // assimp universal format (M)
+ SetFileScale(size_relative_to_cm * 0.01f);
+
+ std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>());
+ } catch (std::exception &) {
+ std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>());
+ throw;
+ }
}
#endif // !ASSIMP_BUILD_NO_FBX_IMPORTER
diff --git a/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp
index 5c9a0e309d..1386e2383c 100644
--- a/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp
+++ b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp
@@ -610,11 +610,11 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
const std::string& ReferenceInformationType)
{
const size_t face_count = m_faces.size();
- if(face_count <= 0)
+ if( 0 == face_count )
{
return;
}
-
+
// materials are handled separately. First of all, they are assigned per-face
// and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect
// has a slightly different meaning for materials.
@@ -625,16 +625,14 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
if (materials_out.empty()) {
FBXImporter::LogError(Formatter::format("expected material index, ignoring"));
return;
- }
- else if (materials_out.size() > 1) {
+ } else if (materials_out.size() > 1) {
FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one"));
materials_out.clear();
}
materials_out.resize(m_vertices.size());
std::fill(materials_out.begin(), materials_out.end(), materials_out.at(0));
- }
- else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
+ } else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
materials_out.resize(face_count);
if(materials_out.size() != face_count) {
@@ -643,18 +641,16 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
);
return;
}
- }
- else {
+ } else {
FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ")
<< MappingInformationType << "," << ReferenceInformationType);
}
}
// ------------------------------------------------------------------------------------------------
ShapeGeometry::ShapeGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
- : Geometry(id, element, name, doc)
-{
- const Scope* sc = element.Compound();
- if (!sc) {
+: Geometry(id, element, name, doc) {
+ const Scope *sc = element.Compound();
+ if (nullptr == sc) {
DOMError("failed to read Geometry object (class: Shape), no data scope found");
}
const Element& Indexes = GetRequiredElement(*sc, "Indexes", &element);
diff --git a/thirdparty/assimp/code/MMD/MMDCpp14.h b/thirdparty/assimp/code/MMD/MMDCpp14.h
deleted file mode 100644
index 638b0bfd2f..0000000000
--- a/thirdparty/assimp/code/MMD/MMDCpp14.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-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 MMD_CPP14_H
-#define MMD_CPP14_H
-
-#include <cstddef>
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-namespace mmd {
- template<class T> struct _Unique_if {
- typedef std::unique_ptr<T> _Single_object;
- };
-
- template<class T> struct _Unique_if<T[]> {
- typedef std::unique_ptr<T[]> _Unknown_bound;
- };
-
- template<class T, size_t N> struct _Unique_if<T[N]> {
- typedef void _Known_bound;
- };
-
- template<class T, class... Args>
- typename _Unique_if<T>::_Single_object
- make_unique(Args&&... args) {
- return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
- }
-
- template<class T>
- typename _Unique_if<T>::_Unknown_bound
- make_unique(size_t n) {
- typedef typename std::remove_extent<T>::type U;
- return std::unique_ptr<T>(new U[n]());
- }
-
- template<class T, class... Args>
- typename _Unique_if<T>::_Known_bound
- make_unique(Args&&...) = delete;
-}
-
-#endif
diff --git a/thirdparty/assimp/code/MMD/MMDImporter.cpp b/thirdparty/assimp/code/MMD/MMDImporter.cpp
deleted file mode 100644
index e7744e4cd0..0000000000
--- a/thirdparty/assimp/code/MMD/MMDImporter.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2016, assimp team
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the assimp team.
-
-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 ASSIMP_BUILD_NO_MMD_IMPORTER
-
-#include "MMD/MMDImporter.h"
-#include "MMD/MMDPmdParser.h"
-#include "MMD/MMDPmxParser.h"
-#include "MMD/MMDVmdParser.h"
-#include "PostProcessing/ConvertToLHProcess.h"
-
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/Importer.hpp>
-#include <assimp/ai_assert.h>
-#include <assimp/scene.h>
-
-#include <fstream>
-#include <iomanip>
-#include <memory>
-
-static const aiImporterDesc desc = {"MMD Importer",
- "",
- "",
- "surfaces supported?",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "pmx"};
-
-namespace Assimp {
-
-using namespace std;
-
-// ------------------------------------------------------------------------------------------------
-// Default constructor
-MMDImporter::MMDImporter()
-: m_Buffer()
-, m_strAbsPath("") {
- DefaultIOSystem io;
- m_strAbsPath = io.getOsSeparator();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-MMDImporter::~MMDImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if file is an pmx file.
-bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler,
- bool checkSig) const {
- if (!checkSig) // Check File Extension
- {
- return SimpleExtensionCheck(pFile, "pmx");
- } else // Check file Header
- {
- static const char *pTokens[] = {"PMX "};
- return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 1);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc *MMDImporter::GetInfo() const { return &desc; }
-
-// ------------------------------------------------------------------------------------------------
-// MMD import implementation
-void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
- IOSystem * /*pIOHandler*/) {
- // Read file by istream
- std::filebuf fb;
- if (!fb.open(file, std::ios::in | std::ios::binary)) {
- throw DeadlyImportError("Failed to open file " + file + ".");
- }
-
- std::istream fileStream(&fb);
-
- // Get the file-size and validate it, throwing an exception when fails
- fileStream.seekg(0, fileStream.end);
- size_t fileSize = static_cast<size_t>(fileStream.tellg());
- fileStream.seekg(0, fileStream.beg);
-
- if (fileSize < sizeof(pmx::PmxModel)) {
- throw DeadlyImportError(file + " is too small.");
- }
-
- pmx::PmxModel model;
- model.Read(&fileStream);
-
- CreateDataFromImport(&model, pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
- aiScene *pScene) {
- if (pModel == NULL) {
- return;
- }
-
- aiNode *pNode = new aiNode;
- if (!pModel->model_name.empty()) {
- pNode->mName.Set(pModel->model_name);
- }
-
- pScene->mRootNode = pNode;
-
- pNode = new aiNode;
- pScene->mRootNode->addChildren(1, &pNode);
- pNode->mName.Set(string(pModel->model_name) + string("_mesh"));
-
- // split mesh by materials
- pNode->mNumMeshes = pModel->material_count;
- pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
- for (unsigned int index = 0; index < pNode->mNumMeshes; index++) {
- pNode->mMeshes[index] = index;
- }
-
- pScene->mNumMeshes = pModel->material_count;
- pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
- for (unsigned int i = 0, indexStart = 0; i < pScene->mNumMeshes; i++) {
- const int indexCount = pModel->materials[i].index_count;
-
- pScene->mMeshes[i] = CreateMesh(pModel, indexStart, indexCount);
- pScene->mMeshes[i]->mName = pModel->materials[i].material_name;
- pScene->mMeshes[i]->mMaterialIndex = i;
- indexStart += indexCount;
- }
-
- // create node hierarchy for bone position
- std::unique_ptr<aiNode *[]> ppNode(new aiNode *[pModel->bone_count]);
- for (auto i = 0; i < pModel->bone_count; i++) {
- ppNode[i] = new aiNode(pModel->bones[i].bone_name);
- }
-
- for (auto i = 0; i < pModel->bone_count; i++) {
- const pmx::PmxBone &bone = pModel->bones[i];
-
- if (bone.parent_index < 0) {
- pScene->mRootNode->addChildren(1, ppNode.get() + i);
- } else {
- ppNode[bone.parent_index]->addChildren(1, ppNode.get() + i);
-
- aiVector3D v3 = aiVector3D(
- bone.position[0] - pModel->bones[bone.parent_index].position[0],
- bone.position[1] - pModel->bones[bone.parent_index].position[1],
- bone.position[2] - pModel->bones[bone.parent_index].position[2]);
- aiMatrix4x4::Translation(v3, ppNode[i]->mTransformation);
- }
- }
-
- // create materials
- pScene->mNumMaterials = pModel->material_count;
- pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials; i++) {
- pScene->mMaterials[i] = CreateMaterial(&pModel->materials[i], pModel);
- }
-
- // Convert everything to OpenGL space
- MakeLeftHandedProcess convertProcess;
- convertProcess.Execute(pScene);
-
- FlipUVsProcess uvFlipper;
- uvFlipper.Execute(pScene);
-
- FlipWindingOrderProcess windingFlipper;
- windingFlipper.Execute(pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
- const int indexStart, const int indexCount) {
- aiMesh *pMesh = new aiMesh;
-
- pMesh->mNumVertices = indexCount;
-
- pMesh->mNumFaces = indexCount / 3;
- pMesh->mFaces = new aiFace[pMesh->mNumFaces];
-
- const int numIndices = 3; // triangular face
- for (unsigned int index = 0; index < pMesh->mNumFaces; index++) {
- pMesh->mFaces[index].mNumIndices = numIndices;
- unsigned int *indices = new unsigned int[numIndices];
- indices[0] = numIndices * index;
- indices[1] = numIndices * index + 1;
- indices[2] = numIndices * index + 2;
- pMesh->mFaces[index].mIndices = indices;
- }
-
- pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
- pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices];
- pMesh->mNumUVComponents[0] = 2;
-
- // additional UVs
- for (int i = 1; i <= pModel->setting.uv; i++) {
- pMesh->mTextureCoords[i] = new aiVector3D[pMesh->mNumVertices];
- pMesh->mNumUVComponents[i] = 4;
- }
-
- map<int, vector<aiVertexWeight>> bone_vertex_map;
-
- // fill in contents and create bones
- for (int index = 0; index < indexCount; index++) {
- const pmx::PmxVertex *v =
- &pModel->vertices[pModel->indices[indexStart + index]];
- const float *position = v->position;
- pMesh->mVertices[index].Set(position[0], position[1], position[2]);
- const float *normal = v->normal;
-
- pMesh->mNormals[index].Set(normal[0], normal[1], normal[2]);
- pMesh->mTextureCoords[0][index].x = v->uv[0];
- pMesh->mTextureCoords[0][index].y = v->uv[1];
-
- for (int i = 1; i <= pModel->setting.uv; i++) {
- // TODO: wrong here? use quaternion transform?
- pMesh->mTextureCoords[i][index].x = v->uva[i][0];
- pMesh->mTextureCoords[i][index].y = v->uva[i][1];
- }
-
- // handle bone map
- const auto vsBDEF1_ptr =
- dynamic_cast<pmx::PmxVertexSkinningBDEF1 *>(v->skinning.get());
- const auto vsBDEF2_ptr =
- dynamic_cast<pmx::PmxVertexSkinningBDEF2 *>(v->skinning.get());
- const auto vsBDEF4_ptr =
- dynamic_cast<pmx::PmxVertexSkinningBDEF4 *>(v->skinning.get());
- const auto vsSDEF_ptr =
- dynamic_cast<pmx::PmxVertexSkinningSDEF *>(v->skinning.get());
- switch (v->skinning_type) {
- case pmx::PmxVertexSkinningType::BDEF1:
- bone_vertex_map[vsBDEF1_ptr->bone_index].push_back(
- aiVertexWeight(index, 1.0));
- break;
- case pmx::PmxVertexSkinningType::BDEF2:
- bone_vertex_map[vsBDEF2_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsBDEF2_ptr->bone_weight));
- bone_vertex_map[vsBDEF2_ptr->bone_index2].push_back(
- aiVertexWeight(index, 1.0f - vsBDEF2_ptr->bone_weight));
- break;
- case pmx::PmxVertexSkinningType::BDEF4:
- bone_vertex_map[vsBDEF4_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight1));
- bone_vertex_map[vsBDEF4_ptr->bone_index2].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight2));
- bone_vertex_map[vsBDEF4_ptr->bone_index3].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight3));
- bone_vertex_map[vsBDEF4_ptr->bone_index4].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight4));
- break;
- case pmx::PmxVertexSkinningType::SDEF: // TODO: how to use sdef_c, sdef_r0,
- // sdef_r1?
- bone_vertex_map[vsSDEF_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsSDEF_ptr->bone_weight));
- bone_vertex_map[vsSDEF_ptr->bone_index2].push_back(
- aiVertexWeight(index, 1.0f - vsSDEF_ptr->bone_weight));
- break;
- case pmx::PmxVertexSkinningType::QDEF:
- const auto vsQDEF_ptr =
- dynamic_cast<pmx::PmxVertexSkinningQDEF *>(v->skinning.get());
- bone_vertex_map[vsQDEF_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight1));
- bone_vertex_map[vsQDEF_ptr->bone_index2].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight2));
- bone_vertex_map[vsQDEF_ptr->bone_index3].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight3));
- bone_vertex_map[vsQDEF_ptr->bone_index4].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight4));
- break;
- }
- }
-
- // make all bones for each mesh
- // assign bone weights to skinned bones (otherwise just initialize)
- auto bone_ptr_ptr = new aiBone *[pModel->bone_count];
- pMesh->mNumBones = pModel->bone_count;
- pMesh->mBones = bone_ptr_ptr;
- for (auto ii = 0; ii < pModel->bone_count; ++ii) {
- auto pBone = new aiBone;
- const auto &pmxBone = pModel->bones[ii];
- pBone->mName = pmxBone.bone_name;
- aiVector3D pos(pmxBone.position[0], pmxBone.position[1], pmxBone.position[2]);
- aiMatrix4x4::Translation(-pos, pBone->mOffsetMatrix);
- auto it = bone_vertex_map.find(ii);
- if (it != bone_vertex_map.end()) {
- pBone->mNumWeights = static_cast<unsigned int>(it->second.size());
- pBone->mWeights = new aiVertexWeight[pBone->mNumWeights];
- for (unsigned int j = 0; j < pBone->mNumWeights; j++) {
- pBone->mWeights[j] = it->second[j];
- }
- }
- bone_ptr_ptr[ii] = pBone;
- }
-
- return pMesh;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMaterial *MMDImporter::CreateMaterial(const pmx::PmxMaterial *pMat,
- const pmx::PmxModel *pModel) {
- aiMaterial *mat = new aiMaterial();
- aiString name(pMat->material_english_name);
- mat->AddProperty(&name, AI_MATKEY_NAME);
-
- aiColor3D diffuse(pMat->diffuse[0], pMat->diffuse[1], pMat->diffuse[2]);
- mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- aiColor3D specular(pMat->specular[0], pMat->specular[1], pMat->specular[2]);
- mat->AddProperty(&specular, 1, AI_MATKEY_COLOR_SPECULAR);
- aiColor3D ambient(pMat->ambient[0], pMat->ambient[1], pMat->ambient[2]);
- mat->AddProperty(&ambient, 1, AI_MATKEY_COLOR_AMBIENT);
-
- float opacity = pMat->diffuse[3];
- mat->AddProperty(&opacity, 1, AI_MATKEY_OPACITY);
- float shininess = pMat->specularlity;
- mat->AddProperty(&shininess, 1, AI_MATKEY_SHININESS_STRENGTH);
-
- if(pMat->diffuse_texture_index >= 0) {
- aiString texture_path(pModel->textures[pMat->diffuse_texture_index]);
- mat->AddProperty(&texture_path, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
- }
-
- int mapping_uvwsrc = 0;
- mat->AddProperty(&mapping_uvwsrc, 1,
- AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE, 0));
-
- return mat;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_MMD_IMPORTER
diff --git a/thirdparty/assimp/code/MMD/MMDImporter.h b/thirdparty/assimp/code/MMD/MMDImporter.h
deleted file mode 100644
index 4ee94eeb00..0000000000
--- a/thirdparty/assimp/code/MMD/MMDImporter.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2016, assimp team
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the assimp team.
-
-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 MMD_FILE_IMPORTER_H_INC
-#define MMD_FILE_IMPORTER_H_INC
-
-#include <assimp/BaseImporter.h>
-#include "MMDPmxParser.h"
-#include <assimp/material.h>
-#include <vector>
-
-struct aiMesh;
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-/// \class MMDImporter
-/// \brief Imports MMD a pmx/pmd/vmd file
-// ------------------------------------------------------------------------------------------------
-class MMDImporter : public BaseImporter {
-public:
- /// \brief Default constructor
- MMDImporter();
-
- /// \brief Destructor
- ~MMDImporter();
-
-public:
- /// \brief Returns whether the class can handle the format of the given file.
- /// \remark See BaseImporter::CanRead() for details.
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-private:
- //! \brief Appends the supported extension.
- const aiImporterDesc* GetInfo () const;
-
- //! \brief File import implementation.
- void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
- //! \brief Create the data from imported content.
- void CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene);
-
- //! \brief Create the mesh
- aiMesh* CreateMesh(const pmx::PmxModel* pModel, const int indexStart, const int indexCount);
-
- //! \brief Create the material
- aiMaterial* CreateMaterial(const pmx::PmxMaterial* pMat, const pmx::PmxModel* pModel);
-
-private:
- //! Data buffer
- std::vector<char> m_Buffer;
- //! Absolute pathname of model in file system
- std::string m_strAbsPath;
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif \ No newline at end of file
diff --git a/thirdparty/assimp/code/MMD/MMDPmdParser.h b/thirdparty/assimp/code/MMD/MMDPmdParser.h
deleted file mode 100644
index d2f2224aa1..0000000000
--- a/thirdparty/assimp/code/MMD/MMDPmdParser.h
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-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
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <iostream>
-#include <fstream>
-#include "MMDCpp14.h"
-
-namespace pmd
-{
- class PmdHeader
- {
- public:
- std::string name;
- std::string name_english;
- std::string comment;
- std::string comment_english;
-
- bool Read(std::ifstream* stream)
- {
- char buffer[256];
- stream->read(buffer, 20);
- name = std::string(buffer);
- stream->read(buffer, 256);
- comment = std::string(buffer);
- return true;
- }
-
- bool ReadExtension(std::ifstream* stream)
- {
- char buffer[256];
- stream->read(buffer, 20);
- name_english = std::string(buffer);
- stream->read(buffer, 256);
- comment_english = std::string(buffer);
- return true;
- }
- };
-
- class PmdVertex
- {
- public:
- float position[3];
-
- float normal[3];
-
- float uv[2];
-
- uint16_t bone_index[2];
-
- uint8_t bone_weight;
-
- bool edge_invisible;
-
- bool Read(std::ifstream* stream)
- {
- stream->read((char*) position, sizeof(float) * 3);
- stream->read((char*) normal, sizeof(float) * 3);
- stream->read((char*) uv, sizeof(float) * 2);
- stream->read((char*) bone_index, sizeof(uint16_t) * 2);
- stream->read((char*) &bone_weight, sizeof(uint8_t));
- stream->read((char*) &edge_invisible, sizeof(uint8_t));
- return true;
- }
- };
-
- class PmdMaterial
- {
- public:
- float diffuse[4];
- float power;
- float specular[3];
- float ambient[3];
- uint8_t toon_index;
- uint8_t edge_flag;
- uint32_t index_count;
- std::string texture_filename;
- std::string sphere_filename;
-
- bool Read(std::ifstream* stream)
- {
- char buffer[20];
- stream->read((char*) &diffuse, sizeof(float) * 4);
- stream->read((char*) &power, sizeof(float));
- stream->read((char*) &specular, sizeof(float) * 3);
- stream->read((char*) &ambient, sizeof(float) * 3);
- stream->read((char*) &toon_index, sizeof(uint8_t));
- stream->read((char*) &edge_flag, sizeof(uint8_t));
- stream->read((char*) &index_count, sizeof(uint32_t));
- stream->read((char*) &buffer, sizeof(char) * 20);
- char* pstar = strchr(buffer, '*');
- if (NULL == pstar)
- {
- texture_filename = std::string(buffer);
- sphere_filename.clear();
- }
- else {
- *pstar = 0;
- texture_filename = std::string(buffer);
- sphere_filename = std::string(pstar+1);
- }
- return true;
- }
- };
-
- enum class BoneType : uint8_t
- {
- Rotation,
- RotationAndMove,
- IkEffector,
- Unknown,
- IkEffectable,
- RotationEffectable,
- IkTarget,
- Invisible,
- Twist,
- RotationMovement
- };
-
- class PmdBone
- {
- public:
- std::string name;
- std::string name_english;
- uint16_t parent_bone_index;
- uint16_t tail_pos_bone_index;
- BoneType bone_type;
- uint16_t ik_parent_bone_index;
- float bone_head_pos[3];
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name = std::string(buffer);
- stream->read((char*) &parent_bone_index, sizeof(uint16_t));
- stream->read((char*) &tail_pos_bone_index, sizeof(uint16_t));
- stream->read((char*) &bone_type, sizeof(uint8_t));
- stream->read((char*) &ik_parent_bone_index, sizeof(uint16_t));
- stream->read((char*) &bone_head_pos, sizeof(float) * 3);
- }
-
- void ReadExpantion(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name_english = std::string(buffer);
- }
- };
-
- class PmdIk
- {
- public:
- uint16_t ik_bone_index;
- uint16_t target_bone_index;
- uint16_t interations;
- float angle_limit;
- std::vector<uint16_t> ik_child_bone_index;
-
- void Read(std::istream *stream)
- {
- stream->read((char *) &ik_bone_index, sizeof(uint16_t));
- stream->read((char *) &target_bone_index, sizeof(uint16_t));
- uint8_t ik_chain_length;
- stream->read((char*) &ik_chain_length, sizeof(uint8_t));
- stream->read((char *) &interations, sizeof(uint16_t));
- stream->read((char *) &angle_limit, sizeof(float));
- ik_child_bone_index.resize(ik_chain_length);
- for (int i = 0; i < ik_chain_length; i++)
- {
- stream->read((char *) &ik_child_bone_index[i], sizeof(uint16_t));
- }
- }
- };
-
- class PmdFaceVertex
- {
- public:
- int vertex_index;
- float position[3];
-
- void Read(std::istream *stream)
- {
- stream->read((char *) &vertex_index, sizeof(int));
- stream->read((char *) position, sizeof(float) * 3);
- }
- };
-
- enum class FaceCategory : uint8_t
- {
- Base,
- Eyebrow,
- Eye,
- Mouth,
- Other
- };
-
- class PmdFace
- {
- public:
- std::string name;
- FaceCategory type;
- std::vector<PmdFaceVertex> vertices;
- std::string name_english;
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name = std::string(buffer);
- int vertex_count;
- stream->read((char*) &vertex_count, sizeof(int));
- stream->read((char*) &type, sizeof(uint8_t));
- vertices.resize(vertex_count);
- for (int i = 0; i < vertex_count; i++)
- {
- vertices[i].Read(stream);
- }
- }
-
- void ReadExpantion(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name_english = std::string(buffer);
- }
- };
-
- class PmdBoneDispName
- {
- public:
- std::string bone_disp_name;
- std::string bone_disp_name_english;
-
- void Read(std::istream *stream)
- {
- char buffer[50];
- stream->read(buffer, 50);
- bone_disp_name = std::string(buffer);
- bone_disp_name_english.clear();
- }
- void ReadExpantion(std::istream *stream)
- {
- char buffer[50];
- stream->read(buffer, 50);
- bone_disp_name_english = std::string(buffer);
- }
- };
-
- class PmdBoneDisp
- {
- public:
- uint16_t bone_index;
- uint8_t bone_disp_index;
-
- void Read(std::istream *stream)
- {
- stream->read((char*) &bone_index, sizeof(uint16_t));
- stream->read((char*) &bone_disp_index, sizeof(uint8_t));
- }
- };
-
- enum class RigidBodyShape : uint8_t
- {
- Sphere = 0,
- Box = 1,
- Cpusel = 2
- };
-
- enum class RigidBodyType : uint8_t
- {
- BoneConnected = 0,
- Physics = 1,
- ConnectedPhysics = 2
- };
-
- class PmdRigidBody
- {
- public:
- std::string name;
- uint16_t related_bone_index;
- uint8_t group_index;
- uint16_t mask;
- RigidBodyShape shape;
- float size[3];
- float position[3];
- float orientation[3];
- float weight;
- float linear_damping;
- float anglar_damping;
- float restitution;
- float friction;
- RigidBodyType rigid_type;
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, sizeof(char) * 20);
- name = (std::string(buffer));
- stream->read((char*) &related_bone_index, sizeof(uint16_t));
- stream->read((char*) &group_index, sizeof(uint8_t));
- stream->read((char*) &mask, sizeof(uint16_t));
- stream->read((char*) &shape, sizeof(uint8_t));
- stream->read((char*) size, sizeof(float) * 3);
- stream->read((char*) position, sizeof(float) * 3);
- stream->read((char*) orientation, sizeof(float) * 3);
- stream->read((char*) &weight, sizeof(float));
- stream->read((char*) &linear_damping, sizeof(float));
- stream->read((char*) &anglar_damping, sizeof(float));
- stream->read((char*) &restitution, sizeof(float));
- stream->read((char*) &friction, sizeof(float));
- stream->read((char*) &rigid_type, sizeof(char));
- }
- };
-
- class PmdConstraint
- {
- public:
- std::string name;
- uint32_t rigid_body_index_a;
- uint32_t rigid_body_index_b;
- float position[3];
- float orientation[3];
- float linear_lower_limit[3];
- float linear_upper_limit[3];
- float angular_lower_limit[3];
- float angular_upper_limit[3];
- float linear_stiffness[3];
- float angular_stiffness[3];
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name = std::string(buffer);
- stream->read((char *) &rigid_body_index_a, sizeof(uint32_t));
- stream->read((char *) &rigid_body_index_b, sizeof(uint32_t));
- stream->read((char *) position, sizeof(float) * 3);
- stream->read((char *) orientation, sizeof(float) * 3);
- stream->read((char *) linear_lower_limit, sizeof(float) * 3);
- stream->read((char *) linear_upper_limit, sizeof(float) * 3);
- stream->read((char *) angular_lower_limit, sizeof(float) * 3);
- stream->read((char *) angular_upper_limit, sizeof(float) * 3);
- stream->read((char *) linear_stiffness, sizeof(float) * 3);
- stream->read((char *) angular_stiffness, sizeof(float) * 3);
- }
- };
-
- class PmdModel
- {
- public:
- float version;
- PmdHeader header;
- std::vector<PmdVertex> vertices;
- std::vector<uint16_t> indices;
- std::vector<PmdMaterial> materials;
- std::vector<PmdBone> bones;
- std::vector<PmdIk> iks;
- std::vector<PmdFace> faces;
- std::vector<uint16_t> faces_indices;
- std::vector<PmdBoneDispName> bone_disp_name;
- std::vector<PmdBoneDisp> bone_disp;
- std::vector<std::string> toon_filenames;
- std::vector<PmdRigidBody> rigid_bodies;
- std::vector<PmdConstraint> constraints;
-
- static std::unique_ptr<PmdModel> LoadFromFile(const char *filename)
- {
- std::ifstream stream(filename, std::ios::binary);
- if (stream.fail())
- {
- std::cerr << "could not open \"" << filename << "\"" << std::endl;
- return nullptr;
- }
- auto result = LoadFromStream(&stream);
- stream.close();
- return result;
- }
-
- static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream)
- {
- auto result = mmd::make_unique<PmdModel>();
- char buffer[100];
-
- // magic
- char magic[3];
- stream->read(magic, 3);
- if (magic[0] != 'P' || magic[1] != 'm' || magic[2] != 'd')
- {
- std::cerr << "invalid file" << std::endl;
- return nullptr;
- }
-
- // version
- stream->read((char*) &(result->version), sizeof(float));
- if (result ->version != 1.0f)
- {
- std::cerr << "invalid version" << std::endl;
- return nullptr;
- }
-
- // header
- result->header.Read(stream);
-
- // vertices
- uint32_t vertex_num;
- stream->read((char*) &vertex_num, sizeof(uint32_t));
- result->vertices.resize(vertex_num);
- for (uint32_t i = 0; i < vertex_num; i++)
- {
- result->vertices[i].Read(stream);
- }
-
- // indices
- uint32_t index_num;
- stream->read((char*) &index_num, sizeof(uint32_t));
- result->indices.resize(index_num);
- for (uint32_t i = 0; i < index_num; i++)
- {
- stream->read((char*) &result->indices[i], sizeof(uint16_t));
- }
-
- // materials
- uint32_t material_num;
- stream->read((char*) &material_num, sizeof(uint32_t));
- result->materials.resize(material_num);
- for (uint32_t i = 0; i < material_num; i++)
- {
- result->materials[i].Read(stream);
- }
-
- // bones
- uint16_t bone_num;
- stream->read((char*) &bone_num, sizeof(uint16_t));
- result->bones.resize(bone_num);
- for (uint32_t i = 0; i < bone_num; i++)
- {
- result->bones[i].Read(stream);
- }
-
- // iks
- uint16_t ik_num;
- stream->read((char*) &ik_num, sizeof(uint16_t));
- result->iks.resize(ik_num);
- for (uint32_t i = 0; i < ik_num; i++)
- {
- result->iks[i].Read(stream);
- }
-
- // faces
- uint16_t face_num;
- stream->read((char*) &face_num, sizeof(uint16_t));
- result->faces.resize(face_num);
- for (uint32_t i = 0; i < face_num; i++)
- {
- result->faces[i].Read(stream);
- }
-
- // face frames
- uint8_t face_frame_num;
- stream->read((char*) &face_frame_num, sizeof(uint8_t));
- result->faces_indices.resize(face_frame_num);
- for (uint32_t i = 0; i < face_frame_num; i++)
- {
- stream->read((char*) &result->faces_indices[i], sizeof(uint16_t));
- }
-
- // bone names
- uint8_t bone_disp_num;
- stream->read((char*) &bone_disp_num, sizeof(uint8_t));
- result->bone_disp_name.resize(bone_disp_num);
- for (uint32_t i = 0; i < bone_disp_num; i++)
- {
- result->bone_disp_name[i].Read(stream);
- }
-
- // bone frame
- uint32_t bone_frame_num;
- stream->read((char*) &bone_frame_num, sizeof(uint32_t));
- result->bone_disp.resize(bone_frame_num);
- for (uint32_t i = 0; i < bone_frame_num; i++)
- {
- result->bone_disp[i].Read(stream);
- }
-
- // english name
- bool english;
- stream->read((char*) &english, sizeof(char));
- if (english)
- {
- result->header.ReadExtension(stream);
- for (uint32_t i = 0; i < bone_num; i++)
- {
- result->bones[i].ReadExpantion(stream);
- }
- for (uint32_t i = 0; i < face_num; i++)
- {
- if (result->faces[i].type == pmd::FaceCategory::Base)
- {
- continue;
- }
- result->faces[i].ReadExpantion(stream);
- }
- for (uint32_t i = 0; i < result->bone_disp_name.size(); i++)
- {
- result->bone_disp_name[i].ReadExpantion(stream);
- }
- }
-
- // toon textures
- if (stream->peek() == std::ios::traits_type::eof())
- {
- result->toon_filenames.clear();
- }
- else {
- result->toon_filenames.resize(10);
- for (uint32_t i = 0; i < 10; i++)
- {
- stream->read(buffer, 100);
- result->toon_filenames[i] = std::string(buffer);
- }
- }
-
- // physics
- if (stream->peek() == std::ios::traits_type::eof())
- {
- result->rigid_bodies.clear();
- result->constraints.clear();
- }
- else {
- uint32_t rigid_body_num;
- stream->read((char*) &rigid_body_num, sizeof(uint32_t));
- result->rigid_bodies.resize(rigid_body_num);
- for (uint32_t i = 0; i < rigid_body_num; i++)
- {
- result->rigid_bodies[i].Read(stream);
- }
- uint32_t constraint_num;
- stream->read((char*) &constraint_num, sizeof(uint32_t));
- result->constraints.resize(constraint_num);
- for (uint32_t i = 0; i < constraint_num; i++)
- {
- result->constraints[i].Read(stream);
- }
- }
-
- if (stream->peek() != std::ios::traits_type::eof())
- {
- std::cerr << "there is unknown data" << std::endl;
- }
-
- return result;
- }
- };
-}
diff --git a/thirdparty/assimp/code/MMD/MMDPmxParser.cpp b/thirdparty/assimp/code/MMD/MMDPmxParser.cpp
deleted file mode 100644
index 80f0986dd7..0000000000
--- a/thirdparty/assimp/code/MMD/MMDPmxParser.cpp
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-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.
-
-----------------------------------------------------------------------
-*/
-#include <utility>
-#include "MMDPmxParser.h"
-#include <assimp/StringUtils.h>
-#ifdef ASSIMP_USE_HUNTER
-# include <utf8/utf8.h>
-#else
-# include "../contrib/utf8cpp/source/utf8.h"
-#endif
-#include <assimp/Exceptional.h>
-
-namespace pmx
-{
- int ReadIndex(std::istream *stream, int size)
- {
- switch (size)
- {
- case 1:
- uint8_t tmp8;
- stream->read((char*) &tmp8, sizeof(uint8_t));
- if (255 == tmp8)
- {
- return -1;
- }
- else {
- return (int) tmp8;
- }
- case 2:
- uint16_t tmp16;
- stream->read((char*) &tmp16, sizeof(uint16_t));
- if (65535 == tmp16)
- {
- return -1;
- }
- else {
- return (int) tmp16;
- }
- case 4:
- int tmp32;
- stream->read((char*) &tmp32, sizeof(int));
- return tmp32;
- default:
- return -1;
- }
- }
-
- std::string ReadString(std::istream *stream, uint8_t encoding)
- {
- int size;
- stream->read((char*) &size, sizeof(int));
- std::vector<char> buffer;
- if (size == 0)
- {
- return std::string("");
- }
- buffer.reserve(size);
- stream->read((char*) buffer.data(), size);
- if (encoding == 0)
- {
- // UTF16 to UTF8
- const uint16_t* sourceStart = (uint16_t*)buffer.data();
- const unsigned int targetSize = size * 3; // enough to encode
- char *targetStart = new char[targetSize];
- std::memset(targetStart, 0, targetSize * sizeof(char));
-
- utf8::utf16to8( sourceStart, sourceStart + size/2, targetStart );
-
- std::string result(targetStart);
- delete [] targetStart;
- return result;
- }
- else
- {
- // the name is already UTF8
- return std::string((const char*)buffer.data(), size);
- }
- }
-
- void PmxSetting::Read(std::istream *stream)
- {
- uint8_t count;
- stream->read((char*) &count, sizeof(uint8_t));
- if (count < 8)
- {
- throw DeadlyImportError("MMD: invalid size");
- }
- stream->read((char*) &encoding, sizeof(uint8_t));
- stream->read((char*) &uv, sizeof(uint8_t));
- stream->read((char*) &vertex_index_size, sizeof(uint8_t));
- stream->read((char*) &texture_index_size, sizeof(uint8_t));
- stream->read((char*) &material_index_size, sizeof(uint8_t));
- stream->read((char*) &bone_index_size, sizeof(uint8_t));
- stream->read((char*) &morph_index_size, sizeof(uint8_t));
- stream->read((char*) &rigidbody_index_size, sizeof(uint8_t));
- uint8_t temp;
- for (int i = 8; i < count; i++)
- {
- stream->read((char*)&temp, sizeof(uint8_t));
- }
- }
-
- void PmxVertexSkinningBDEF1::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index = ReadIndex(stream, setting->bone_index_size);
- }
-
- void PmxVertexSkinningBDEF2::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight, sizeof(float));
- }
-
- void PmxVertexSkinningBDEF4::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight1, sizeof(float));
- stream->read((char*) &this->bone_weight2, sizeof(float));
- stream->read((char*) &this->bone_weight3, sizeof(float));
- stream->read((char*) &this->bone_weight4, sizeof(float));
- }
-
- void PmxVertexSkinningSDEF::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight, sizeof(float));
- stream->read((char*) this->sdef_c, sizeof(float) * 3);
- stream->read((char*) this->sdef_r0, sizeof(float) * 3);
- stream->read((char*) this->sdef_r1, sizeof(float) * 3);
- }
-
- void PmxVertexSkinningQDEF::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight1, sizeof(float));
- stream->read((char*) &this->bone_weight2, sizeof(float));
- stream->read((char*) &this->bone_weight3, sizeof(float));
- stream->read((char*) &this->bone_weight4, sizeof(float));
- }
-
- void PmxVertex::Read(std::istream *stream, PmxSetting *setting)
- {
- stream->read((char*) this->position, sizeof(float) * 3);
- stream->read((char*) this->normal, sizeof(float) * 3);
- stream->read((char*) this->uv, sizeof(float) * 2);
- for (int i = 0; i < setting->uv; ++i)
- {
- stream->read((char*) this->uva[i], sizeof(float) * 4);
- }
- stream->read((char*) &this->skinning_type, sizeof(PmxVertexSkinningType));
- switch (this->skinning_type)
- {
- case PmxVertexSkinningType::BDEF1:
- this->skinning = mmd::make_unique<PmxVertexSkinningBDEF1>();
- break;
- case PmxVertexSkinningType::BDEF2:
- this->skinning = mmd::make_unique<PmxVertexSkinningBDEF2>();
- break;
- case PmxVertexSkinningType::BDEF4:
- this->skinning = mmd::make_unique<PmxVertexSkinningBDEF4>();
- break;
- case PmxVertexSkinningType::SDEF:
- this->skinning = mmd::make_unique<PmxVertexSkinningSDEF>();
- break;
- case PmxVertexSkinningType::QDEF:
- this->skinning = mmd::make_unique<PmxVertexSkinningQDEF>();
- break;
- default:
- throw "invalid skinning type";
- }
- this->skinning->Read(stream, setting);
- stream->read((char*) &this->edge, sizeof(float));
- }
-
- void PmxMaterial::Read(std::istream *stream, PmxSetting *setting)
- {
- this->material_name = ReadString(stream, setting->encoding);
- this->material_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) this->diffuse, sizeof(float) * 4);
- stream->read((char*) this->specular, sizeof(float) * 3);
- stream->read((char*) &this->specularlity, sizeof(float));
- stream->read((char*) this->ambient, sizeof(float) * 3);
- stream->read((char*) &this->flag, sizeof(uint8_t));
- stream->read((char*) this->edge_color, sizeof(float) * 4);
- stream->read((char*) &this->edge_size, sizeof(float));
- this->diffuse_texture_index = ReadIndex(stream, setting->texture_index_size);
- this->sphere_texture_index = ReadIndex(stream, setting->texture_index_size);
- stream->read((char*) &this->sphere_op_mode, sizeof(uint8_t));
- stream->read((char*) &this->common_toon_flag, sizeof(uint8_t));
- if (this->common_toon_flag)
- {
- stream->read((char*) &this->toon_texture_index, sizeof(uint8_t));
- }
- else {
- this->toon_texture_index = ReadIndex(stream, setting->texture_index_size);
- }
- this->memo = ReadString(stream, setting->encoding);
- stream->read((char*) &this->index_count, sizeof(int));
- }
-
- void PmxIkLink::Read(std::istream *stream, PmxSetting *setting)
- {
- this->link_target = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->angle_lock, sizeof(uint8_t));
- if (angle_lock == 1)
- {
- stream->read((char*) this->max_radian, sizeof(float) * 3);
- stream->read((char*) this->min_radian, sizeof(float) * 3);
- }
- }
-
- void PmxBone::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_name = ReadString(stream, setting->encoding);
- this->bone_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) this->position, sizeof(float) * 3);
- this->parent_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->level, sizeof(int));
- stream->read((char*) &this->bone_flag, sizeof(uint16_t));
- if (this->bone_flag & 0x0001) {
- this->target_index = ReadIndex(stream, setting->bone_index_size);
- }
- else {
- stream->read((char*)this->offset, sizeof(float) * 3);
- }
- if (this->bone_flag & (0x0100 | 0x0200)) {
- this->grant_parent_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->grant_weight, sizeof(float));
- }
- if (this->bone_flag & 0x0400) {
- stream->read((char*)this->lock_axis_orientation, sizeof(float) * 3);
- }
- if (this->bone_flag & 0x0800) {
- stream->read((char*)this->local_axis_x_orientation, sizeof(float) * 3);
- stream->read((char*)this->local_axis_y_orientation, sizeof(float) * 3);
- }
- if (this->bone_flag & 0x2000) {
- stream->read((char*) &this->key, sizeof(int));
- }
- if (this->bone_flag & 0x0020) {
- this->ik_target_bone_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &ik_loop, sizeof(int));
- stream->read((char*) &ik_loop_angle_limit, sizeof(float));
- stream->read((char*) &ik_link_count, sizeof(int));
- this->ik_links = mmd::make_unique<PmxIkLink []>(ik_link_count);
- for (int i = 0; i < ik_link_count; i++) {
- ik_links[i].Read(stream, setting);
- }
- }
- }
-
- void PmxMorphVertexOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
- stream->read((char*)this->position_offset, sizeof(float) * 3);
- }
-
- void PmxMorphUVOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
- stream->read((char*)this->uv_offset, sizeof(float) * 4);
- }
-
- void PmxMorphBoneOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*)this->translation, sizeof(float) * 3);
- stream->read((char*)this->rotation, sizeof(float) * 4);
- }
-
- void PmxMorphMaterialOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->material_index = ReadIndex(stream, setting->material_index_size);
- stream->read((char*) &this->offset_operation, sizeof(uint8_t));
- stream->read((char*)this->diffuse, sizeof(float) * 4);
- stream->read((char*)this->specular, sizeof(float) * 3);
- stream->read((char*) &this->specularity, sizeof(float));
- stream->read((char*)this->ambient, sizeof(float) * 3);
- stream->read((char*)this->edge_color, sizeof(float) * 4);
- stream->read((char*) &this->edge_size, sizeof(float));
- stream->read((char*)this->texture_argb, sizeof(float) * 4);
- stream->read((char*)this->sphere_texture_argb, sizeof(float) * 4);
- stream->read((char*)this->toon_texture_argb, sizeof(float) * 4);
- }
-
- void PmxMorphGroupOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->morph_index = ReadIndex(stream, setting->morph_index_size);
- stream->read((char*) &this->morph_weight, sizeof(float));
- }
-
- void PmxMorphFlipOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->morph_index = ReadIndex(stream, setting->morph_index_size);
- stream->read((char*) &this->morph_value, sizeof(float));
- }
-
- void PmxMorphImplusOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->rigid_body_index = ReadIndex(stream, setting->rigidbody_index_size);
- stream->read((char*) &this->is_local, sizeof(uint8_t));
- stream->read((char*)this->velocity, sizeof(float) * 3);
- stream->read((char*)this->angular_torque, sizeof(float) * 3);
- }
-
- void PmxMorph::Read(std::istream *stream, PmxSetting *setting)
- {
- this->morph_name = ReadString(stream, setting->encoding);
- this->morph_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) &category, sizeof(MorphCategory));
- stream->read((char*) &morph_type, sizeof(MorphType));
- stream->read((char*) &this->offset_count, sizeof(int));
- switch (this->morph_type)
- {
- case MorphType::Group:
- group_offsets = mmd::make_unique<PmxMorphGroupOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- group_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::Vertex:
- vertex_offsets = mmd::make_unique<PmxMorphVertexOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- vertex_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::Bone:
- bone_offsets = mmd::make_unique<PmxMorphBoneOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- bone_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::Matrial:
- material_offsets = mmd::make_unique<PmxMorphMaterialOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- material_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::UV:
- case MorphType::AdditionalUV1:
- case MorphType::AdditionalUV2:
- case MorphType::AdditionalUV3:
- case MorphType::AdditionalUV4:
- uv_offsets = mmd::make_unique<PmxMorphUVOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- uv_offsets[i].Read(stream, setting);
- }
- break;
- default:
- throw DeadlyImportError("MMD: unknown morth type");
- }
- }
-
- void PmxFrameElement::Read(std::istream *stream, PmxSetting *setting)
- {
- stream->read((char*) &this->element_target, sizeof(uint8_t));
- if (this->element_target == 0x00)
- {
- this->index = ReadIndex(stream, setting->bone_index_size);
- }
- else {
- this->index = ReadIndex(stream, setting->morph_index_size);
- }
- }
-
- void PmxFrame::Read(std::istream *stream, PmxSetting *setting)
- {
- this->frame_name = ReadString(stream, setting->encoding);
- this->frame_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) &this->frame_flag, sizeof(uint8_t));
- stream->read((char*) &this->element_count, sizeof(int));
- this->elements = mmd::make_unique<PmxFrameElement []>(this->element_count);
- for (int i = 0; i < this->element_count; i++)
- {
- this->elements[i].Read(stream, setting);
- }
- }
-
- void PmxRigidBody::Read(std::istream *stream, PmxSetting *setting)
- {
- this->girid_body_name = ReadString(stream, setting->encoding);
- this->girid_body_english_name = ReadString(stream, setting->encoding);
- this->target_bone = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->group, sizeof(uint8_t));
- stream->read((char*) &this->mask, sizeof(uint16_t));
- stream->read((char*) &this->shape, sizeof(uint8_t));
- stream->read((char*) this->size, sizeof(float) * 3);
- stream->read((char*) this->position, sizeof(float) * 3);
- stream->read((char*) this->orientation, sizeof(float) * 3);
- stream->read((char*) &this->mass, sizeof(float));
- stream->read((char*) &this->move_attenuation, sizeof(float));
- stream->read((char*) &this->rotation_attenuation, sizeof(float));
- stream->read((char*) &this->repulsion, sizeof(float));
- stream->read((char*) &this->friction, sizeof(float));
- stream->read((char*) &this->physics_calc_type, sizeof(uint8_t));
- }
-
- void PmxJointParam::Read(std::istream *stream, PmxSetting *setting)
- {
- this->rigid_body1 = ReadIndex(stream, setting->rigidbody_index_size);
- this->rigid_body2 = ReadIndex(stream, setting->rigidbody_index_size);
- stream->read((char*) this->position, sizeof(float) * 3);
- stream->read((char*) this->orientaiton, sizeof(float) * 3);
- stream->read((char*) this->move_limitation_min, sizeof(float) * 3);
- stream->read((char*) this->move_limitation_max, sizeof(float) * 3);
- stream->read((char*) this->rotation_limitation_min, sizeof(float) * 3);
- stream->read((char*) this->rotation_limitation_max, sizeof(float) * 3);
- stream->read((char*) this->spring_move_coefficient, sizeof(float) * 3);
- stream->read((char*) this->spring_rotation_coefficient, sizeof(float) * 3);
- }
-
- void PmxJoint::Read(std::istream *stream, PmxSetting *setting)
- {
- this->joint_name = ReadString(stream, setting->encoding);
- this->joint_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) &this->joint_type, sizeof(uint8_t));
- this->param.Read(stream, setting);
- }
-
- void PmxAncherRigidBody::Read(std::istream *stream, PmxSetting *setting)
- {
- this->related_rigid_body = ReadIndex(stream, setting->rigidbody_index_size);
- this->related_vertex = ReadIndex(stream, setting->vertex_index_size);
- stream->read((char*) &this->is_near, sizeof(uint8_t));
- }
-
- void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
- {
- std::cerr << "Not Implemented Exception" << std::endl;
- throw DeadlyImportError("MMD: Not Implemented Exception");
- }
-
- void PmxModel::Init()
- {
- this->version = 0.0f;
- this->model_name.clear();
- this->model_english_name.clear();
- this->model_comment.clear();
- this->model_english_comment.clear();
- this->vertex_count = 0;
- this->vertices = nullptr;
- this->index_count = 0;
- this->indices = nullptr;
- this->texture_count = 0;
- this->textures = nullptr;
- this->material_count = 0;
- this->materials = nullptr;
- this->bone_count = 0;
- this->bones = nullptr;
- this->morph_count = 0;
- this->morphs = nullptr;
- this->frame_count = 0;
- this->frames = nullptr;
- this->rigid_body_count = 0;
- this->rigid_bodies = nullptr;
- this->joint_count = 0;
- this->joints = nullptr;
- this->soft_body_count = 0;
- this->soft_bodies = nullptr;
- }
-
- void PmxModel::Read(std::istream *stream)
- {
- char magic[4];
- stream->read((char*) magic, sizeof(char) * 4);
- if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
- {
- std::cerr << "invalid magic number." << std::endl;
- throw DeadlyImportError("MMD: invalid magic number.");
- }
- stream->read((char*) &version, sizeof(float));
- if (version != 2.0f && version != 2.1f)
- {
- std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
- throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but " + to_string(version));
- }
- this->setting.Read(stream);
-
- this->model_name = ReadString(stream, setting.encoding);
- this->model_english_name = ReadString(stream, setting.encoding);
- this->model_comment = ReadString(stream, setting.encoding);
- this->model_english_comment = ReadString(stream, setting.encoding);
-
- // read vertices
- stream->read((char*) &vertex_count, sizeof(int));
- this->vertices = mmd::make_unique<PmxVertex []>(vertex_count);
- for (int i = 0; i < vertex_count; i++)
- {
- vertices[i].Read(stream, &setting);
- }
-
- // read indices
- stream->read((char*) &index_count, sizeof(int));
- this->indices = mmd::make_unique<int []>(index_count);
- for (int i = 0; i < index_count; i++)
- {
- this->indices[i] = ReadIndex(stream, setting.vertex_index_size);
- }
-
- // read texture names
- stream->read((char*) &texture_count, sizeof(int));
- this->textures = mmd::make_unique<std::string []>(texture_count);
- for (int i = 0; i < texture_count; i++)
- {
- this->textures[i] = ReadString(stream, setting.encoding);
- }
-
- // read materials
- stream->read((char*) &material_count, sizeof(int));
- this->materials = mmd::make_unique<PmxMaterial []>(material_count);
- for (int i = 0; i < material_count; i++)
- {
- this->materials[i].Read(stream, &setting);
- }
-
- // read bones
- stream->read((char*) &this->bone_count, sizeof(int));
- this->bones = mmd::make_unique<PmxBone []>(this->bone_count);
- for (int i = 0; i < this->bone_count; i++)
- {
- this->bones[i].Read(stream, &setting);
- }
-
- // read morphs
- stream->read((char*) &this->morph_count, sizeof(int));
- this->morphs = mmd::make_unique<PmxMorph []>(this->morph_count);
- for (int i = 0; i < this->morph_count; i++)
- {
- this->morphs[i].Read(stream, &setting);
- }
-
- // read display frames
- stream->read((char*) &this->frame_count, sizeof(int));
- this->frames = mmd::make_unique<PmxFrame []>(this->frame_count);
- for (int i = 0; i < this->frame_count; i++)
- {
- this->frames[i].Read(stream, &setting);
- }
-
- // read rigid bodies
- stream->read((char*) &this->rigid_body_count, sizeof(int));
- this->rigid_bodies = mmd::make_unique<PmxRigidBody []>(this->rigid_body_count);
- for (int i = 0; i < this->rigid_body_count; i++)
- {
- this->rigid_bodies[i].Read(stream, &setting);
- }
-
- // read joints
- stream->read((char*) &this->joint_count, sizeof(int));
- this->joints = mmd::make_unique<PmxJoint []>(this->joint_count);
- for (int i = 0; i < this->joint_count; i++)
- {
- this->joints[i].Read(stream, &setting);
- }
- }
-}
diff --git a/thirdparty/assimp/code/MMD/MMDPmxParser.h b/thirdparty/assimp/code/MMD/MMDPmxParser.h
deleted file mode 100644
index cf523a1298..0000000000
--- a/thirdparty/assimp/code/MMD/MMDPmxParser.h
+++ /dev/null
@@ -1,782 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-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
-
-#include <vector>
-#include <string>
-#include <iostream>
-#include <fstream>
-#include <memory>
-#include "MMDCpp14.h"
-
-namespace pmx
-{
- class PmxSetting
- {
- public:
- PmxSetting()
- : encoding(0)
- , uv(0)
- , vertex_index_size(0)
- , texture_index_size(0)
- , material_index_size(0)
- , bone_index_size(0)
- , morph_index_size(0)
- , rigidbody_index_size(0)
- {}
-
- uint8_t encoding;
- uint8_t uv;
- uint8_t vertex_index_size;
- uint8_t texture_index_size;
- uint8_t material_index_size;
- uint8_t bone_index_size;
- uint8_t morph_index_size;
- uint8_t rigidbody_index_size;
- void Read(std::istream *stream);
- };
-
- enum class PmxVertexSkinningType : uint8_t
- {
- BDEF1 = 0,
- BDEF2 = 1,
- BDEF4 = 2,
- SDEF = 3,
- QDEF = 4,
- };
-
- class PmxVertexSkinning
- {
- public:
- virtual void Read(std::istream *stream, PmxSetting *setting) = 0;
- virtual ~PmxVertexSkinning() {}
- };
-
- class PmxVertexSkinningBDEF1 : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningBDEF1()
- : bone_index(0)
- {}
-
- int bone_index;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningBDEF2 : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningBDEF2()
- : bone_index1(0)
- , bone_index2(0)
- , bone_weight(0.0f)
- {}
-
- int bone_index1;
- int bone_index2;
- float bone_weight;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningBDEF4 : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningBDEF4()
- : bone_index1(0)
- , bone_index2(0)
- , bone_index3(0)
- , bone_index4(0)
- , bone_weight1(0.0f)
- , bone_weight2(0.0f)
- , bone_weight3(0.0f)
- , bone_weight4(0.0f)
- {}
-
- int bone_index1;
- int bone_index2;
- int bone_index3;
- int bone_index4;
- float bone_weight1;
- float bone_weight2;
- float bone_weight3;
- float bone_weight4;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningSDEF : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningSDEF()
- : bone_index1(0)
- , bone_index2(0)
- , bone_weight(0.0f)
- {
- for (int i = 0; i < 3; ++i) {
- sdef_c[i] = 0.0f;
- sdef_r0[i] = 0.0f;
- sdef_r1[i] = 0.0f;
- }
- }
-
- int bone_index1;
- int bone_index2;
- float bone_weight;
- float sdef_c[3];
- float sdef_r0[3];
- float sdef_r1[3];
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningQDEF : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningQDEF()
- : bone_index1(0)
- , bone_index2(0)
- , bone_index3(0)
- , bone_index4(0)
- , bone_weight1(0.0f)
- , bone_weight2(0.0f)
- , bone_weight3(0.0f)
- , bone_weight4(0.0f)
- {}
-
- int bone_index1;
- int bone_index2;
- int bone_index3;
- int bone_index4;
- float bone_weight1;
- float bone_weight2;
- float bone_weight3;
- float bone_weight4;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertex
- {
- public:
- PmxVertex()
- : edge(0.0f)
- {
- uv[0] = uv[1] = 0.0f;
- for (int i = 0; i < 3; ++i) {
- position[i] = 0.0f;
- normal[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- for (int k = 0; k < 4; ++k) {
- uva[i][k] = 0.0f;
- }
- }
- }
-
- float position[3];
- float normal[3];
- float uv[2];
- float uva[4][4];
- PmxVertexSkinningType skinning_type;
- std::unique_ptr<PmxVertexSkinning> skinning;
- float edge;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxMaterial
- {
- public:
- PmxMaterial()
- : specularlity(0.0f)
- , flag(0)
- , edge_size(0.0f)
- , diffuse_texture_index(0)
- , sphere_texture_index(0)
- , sphere_op_mode(0)
- , common_toon_flag(0)
- , toon_texture_index(0)
- , index_count(0)
- {
- for (int i = 0; i < 3; ++i) {
- specular[i] = 0.0f;
- ambient[i] = 0.0f;
- edge_color[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- diffuse[i] = 0.0f;
- }
- }
-
- std::string material_name;
- std::string material_english_name;
- float diffuse[4];
- float specular[3];
- float specularlity;
- float ambient[3];
- uint8_t flag;
- float edge_color[4];
- float edge_size;
- int diffuse_texture_index;
- int sphere_texture_index;
- uint8_t sphere_op_mode;
- uint8_t common_toon_flag;
- int toon_texture_index;
- std::string memo;
- int index_count;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxIkLink
- {
- public:
- PmxIkLink()
- : link_target(0)
- , angle_lock(0)
- {
- for (int i = 0; i < 3; ++i) {
- max_radian[i] = 0.0f;
- min_radian[i] = 0.0f;
- }
- }
-
- int link_target;
- uint8_t angle_lock;
- float max_radian[3];
- float min_radian[3];
- void Read(std::istream *stream, PmxSetting *settingn);
- };
-
- class PmxBone
- {
- public:
- PmxBone()
- : parent_index(0)
- , level(0)
- , bone_flag(0)
- , target_index(0)
- , grant_parent_index(0)
- , grant_weight(0.0f)
- , key(0)
- , ik_target_bone_index(0)
- , ik_loop(0)
- , ik_loop_angle_limit(0.0f)
- , ik_link_count(0)
- {
- for (int i = 0; i < 3; ++i) {
- position[i] = 0.0f;
- offset[i] = 0.0f;
- lock_axis_orientation[i] = 0.0f;
- local_axis_x_orientation[i] = 0.0f;
- local_axis_y_orientation[i] = 0.0f;
- }
- }
-
- std::string bone_name;
- std::string bone_english_name;
- float position[3];
- int parent_index;
- int level;
- uint16_t bone_flag;
- float offset[3];
- int target_index;
- int grant_parent_index;
- float grant_weight;
- float lock_axis_orientation[3];
- float local_axis_x_orientation[3];
- float local_axis_y_orientation[3];
- int key;
- int ik_target_bone_index;
- int ik_loop;
- float ik_loop_angle_limit;
- int ik_link_count;
- std::unique_ptr<PmxIkLink []> ik_links;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- enum class MorphType : uint8_t
- {
- Group = 0,
- Vertex = 1,
- Bone = 2,
- UV = 3,
- AdditionalUV1 = 4,
- AdditionalUV2 = 5,
- AdditionalUV3 = 6,
- AdditionalUV4 = 7,
- Matrial = 8,
- Flip = 9,
- Implus = 10,
- };
-
- enum class MorphCategory : uint8_t
- {
- ReservedCategory = 0,
- Eyebrow = 1,
- Eye = 2,
- Mouth = 3,
- Other = 4,
- };
-
- class PmxMorphOffset
- {
- public:
- void virtual Read(std::istream *stream, PmxSetting *setting) = 0;
- };
-
- class PmxMorphVertexOffset : public PmxMorphOffset
- {
- public:
- PmxMorphVertexOffset()
- : vertex_index(0)
- {
- for (int i = 0; i < 3; ++i) {
- position_offset[i] = 0.0f;
- }
- }
- int vertex_index;
- float position_offset[3];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphUVOffset : public PmxMorphOffset
- {
- public:
- PmxMorphUVOffset()
- : vertex_index(0)
- {
- for (int i = 0; i < 4; ++i) {
- uv_offset[i] = 0.0f;
- }
- }
- int vertex_index;
- float uv_offset[4];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphBoneOffset : public PmxMorphOffset
- {
- public:
- PmxMorphBoneOffset()
- : bone_index(0)
- {
- for (int i = 0; i < 3; ++i) {
- translation[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- rotation[i] = 0.0f;
- }
- }
- int bone_index;
- float translation[3];
- float rotation[4];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphMaterialOffset : public PmxMorphOffset
- {
- public:
- PmxMorphMaterialOffset()
- : specularity(0.0f)
- , edge_size(0.0f)
- {
- for (int i = 0; i < 3; ++i) {
- specular[i] = 0.0f;
- ambient[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- diffuse[i] = 0.0f;
- edge_color[i] = 0.0f;
- texture_argb[i] = 0.0f;
- sphere_texture_argb[i] = 0.0f;
- toon_texture_argb[i] = 0.0f;
- }
- }
- int material_index;
- uint8_t offset_operation;
- float diffuse[4];
- float specular[3];
- float specularity;
- float ambient[3];
- float edge_color[4];
- float edge_size;
- float texture_argb[4];
- float sphere_texture_argb[4];
- float toon_texture_argb[4];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphGroupOffset : public PmxMorphOffset
- {
- public:
- PmxMorphGroupOffset()
- : morph_index(0)
- , morph_weight(0.0f)
- {}
- int morph_index;
- float morph_weight;
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphFlipOffset : public PmxMorphOffset
- {
- public:
- PmxMorphFlipOffset()
- : morph_index(0)
- , morph_value(0.0f)
- {}
- int morph_index;
- float morph_value;
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphImplusOffset : public PmxMorphOffset
- {
- public:
- PmxMorphImplusOffset()
- : rigid_body_index(0)
- , is_local(0)
- {
- for (int i = 0; i < 3; ++i) {
- velocity[i] = 0.0f;
- angular_torque[i] = 0.0f;
- }
- }
- int rigid_body_index;
- uint8_t is_local;
- float velocity[3];
- float angular_torque[3];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorph
- {
- public:
- PmxMorph()
- : offset_count(0)
- {
- }
- std::string morph_name;
- std::string morph_english_name;
- MorphCategory category;
- MorphType morph_type;
- int offset_count;
- std::unique_ptr<PmxMorphVertexOffset []> vertex_offsets;
- std::unique_ptr<PmxMorphUVOffset []> uv_offsets;
- std::unique_ptr<PmxMorphBoneOffset []> bone_offsets;
- std::unique_ptr<PmxMorphMaterialOffset []> material_offsets;
- std::unique_ptr<PmxMorphGroupOffset []> group_offsets;
- std::unique_ptr<PmxMorphFlipOffset []> flip_offsets;
- std::unique_ptr<PmxMorphImplusOffset []> implus_offsets;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxFrameElement
- {
- public:
- PmxFrameElement()
- : element_target(0)
- , index(0)
- {
- }
- uint8_t element_target;
- int index;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxFrame
- {
- public:
- PmxFrame()
- : frame_flag(0)
- , element_count(0)
- {
- }
- std::string frame_name;
- std::string frame_english_name;
- uint8_t frame_flag;
- int element_count;
- std::unique_ptr<PmxFrameElement []> elements;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxRigidBody
- {
- public:
- PmxRigidBody()
- : target_bone(0)
- , group(0)
- , mask(0)
- , shape(0)
- , mass(0.0f)
- , move_attenuation(0.0f)
- , rotation_attenuation(0.0f)
- , repulsion(0.0f)
- , friction(0.0f)
- , physics_calc_type(0)
- {
- for (int i = 0; i < 3; ++i) {
- size[i] = 0.0f;
- position[i] = 0.0f;
- orientation[i] = 0.0f;
- }
- }
- std::string girid_body_name;
- std::string girid_body_english_name;
- int target_bone;
- uint8_t group;
- uint16_t mask;
- uint8_t shape;
- float size[3];
- float position[3];
- float orientation[3];
- float mass;
- float move_attenuation;
- float rotation_attenuation;
- float repulsion;
- float friction;
- uint8_t physics_calc_type;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- enum class PmxJointType : uint8_t
- {
- Generic6DofSpring = 0,
- Generic6Dof = 1,
- Point2Point = 2,
- ConeTwist = 3,
- Slider = 5,
- Hinge = 6
- };
-
- class PmxJointParam
- {
- public:
- PmxJointParam()
- : rigid_body1(0)
- , rigid_body2(0)
- {
- for (int i = 0; i < 3; ++i) {
- position[i] = 0.0f;
- orientaiton[i] = 0.0f;
- move_limitation_min[i] = 0.0f;
- move_limitation_max[i] = 0.0f;
- rotation_limitation_min[i] = 0.0f;
- rotation_limitation_max[i] = 0.0f;
- spring_move_coefficient[i] = 0.0f;
- spring_rotation_coefficient[i] = 0.0f;
- }
- }
- int rigid_body1;
- int rigid_body2;
- float position[3];
- float orientaiton[3];
- float move_limitation_min[3];
- float move_limitation_max[3];
- float rotation_limitation_min[3];
- float rotation_limitation_max[3];
- float spring_move_coefficient[3];
- float spring_rotation_coefficient[3];
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxJoint
- {
- public:
- std::string joint_name;
- std::string joint_english_name;
- PmxJointType joint_type;
- PmxJointParam param;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- enum PmxSoftBodyFlag : uint8_t
- {
- BLink = 0x01,
- Cluster = 0x02,
- Link = 0x04
- };
-
- class PmxAncherRigidBody
- {
- public:
- PmxAncherRigidBody()
- : related_rigid_body(0)
- , related_vertex(0)
- , is_near(false)
- {}
- int related_rigid_body;
- int related_vertex;
- bool is_near;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxSoftBody
- {
- public:
- PmxSoftBody()
- : shape(0)
- , target_material(0)
- , group(0)
- , mask(0)
- , blink_distance(0)
- , cluster_count(0)
- , mass(0.0)
- , collisioni_margin(0.0)
- , aero_model(0)
- , VCF(0.0f)
- , DP(0.0f)
- , DG(0.0f)
- , LF(0.0f)
- , PR(0.0f)
- , VC(0.0f)
- , DF(0.0f)
- , MT(0.0f)
- , CHR(0.0f)
- , KHR(0.0f)
- , SHR(0.0f)
- , AHR(0.0f)
- , SRHR_CL(0.0f)
- , SKHR_CL(0.0f)
- , SSHR_CL(0.0f)
- , SR_SPLT_CL(0.0f)
- , SK_SPLT_CL(0.0f)
- , SS_SPLT_CL(0.0f)
- , V_IT(0)
- , P_IT(0)
- , D_IT(0)
- , C_IT(0)
- , LST(0.0f)
- , AST(0.0f)
- , VST(0.0f)
- , anchor_count(0)
- , pin_vertex_count(0)
- {}
- std::string soft_body_name;
- std::string soft_body_english_name;
- uint8_t shape;
- int target_material;
- uint8_t group;
- uint16_t mask;
- PmxSoftBodyFlag flag;
- int blink_distance;
- int cluster_count;
- float mass;
- float collisioni_margin;
- int aero_model;
- float VCF;
- float DP;
- float DG;
- float LF;
- float PR;
- float VC;
- float DF;
- float MT;
- float CHR;
- float KHR;
- float SHR;
- float AHR;
- float SRHR_CL;
- float SKHR_CL;
- float SSHR_CL;
- float SR_SPLT_CL;
- float SK_SPLT_CL;
- float SS_SPLT_CL;
- int V_IT;
- int P_IT;
- int D_IT;
- int C_IT;
- float LST;
- float AST;
- float VST;
- int anchor_count;
- std::unique_ptr<PmxAncherRigidBody []> anchers;
- int pin_vertex_count;
- std::unique_ptr<int []> pin_vertices;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxModel
- {
- public:
- PmxModel()
- : version(0.0f)
- , vertex_count(0)
- , index_count(0)
- , texture_count(0)
- , material_count(0)
- , bone_count(0)
- , morph_count(0)
- , frame_count(0)
- , rigid_body_count(0)
- , joint_count(0)
- , soft_body_count(0)
- {}
-
- float version;
- PmxSetting setting;
- std::string model_name;
- std::string model_english_name;
- std::string model_comment;
- std::string model_english_comment;
- int vertex_count;
- std::unique_ptr<PmxVertex []> vertices;
- int index_count;
- std::unique_ptr<int []> indices;
- int texture_count;
- std::unique_ptr< std::string []> textures;
- int material_count;
- std::unique_ptr<PmxMaterial []> materials;
- int bone_count;
- std::unique_ptr<PmxBone []> bones;
- int morph_count;
- std::unique_ptr<PmxMorph []> morphs;
- int frame_count;
- std::unique_ptr<PmxFrame [] > frames;
- int rigid_body_count;
- std::unique_ptr<PmxRigidBody []> rigid_bodies;
- int joint_count;
- std::unique_ptr<PmxJoint []> joints;
- int soft_body_count;
- std::unique_ptr<PmxSoftBody []> soft_bodies;
- void Init();
- void Read(std::istream *stream);
- //static std::unique_ptr<PmxModel> ReadFromFile(const char *filename);
- //static std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream);
- };
-}
diff --git a/thirdparty/assimp/code/MMD/MMDVmdParser.h b/thirdparty/assimp/code/MMD/MMDVmdParser.h
deleted file mode 100644
index 947c3a2422..0000000000
--- a/thirdparty/assimp/code/MMD/MMDVmdParser.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-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
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <iostream>
-#include <fstream>
-#include <ostream>
-#include "MMDCpp14.h"
-
-namespace vmd
-{
- class VmdBoneFrame
- {
- public:
- std::string name;
- int frame;
- float position[3];
- float orientation[4];
- char interpolation[4][4][4];
-
- void Read(std::istream* stream)
- {
- char buffer[15];
- stream->read((char*) buffer, sizeof(char)*15);
- name = std::string(buffer);
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) position, sizeof(float)*3);
- stream->read((char*) orientation, sizeof(float)*4);
- stream->read((char*) interpolation, sizeof(char) * 4 * 4 * 4);
- }
-
- void Write(std::ostream* stream)
- {
- stream->write((char*)name.c_str(), sizeof(char) * 15);
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)position, sizeof(float) * 3);
- stream->write((char*)orientation, sizeof(float) * 4);
- stream->write((char*)interpolation, sizeof(char) * 4 * 4 * 4);
- }
- };
-
- class VmdFaceFrame
- {
- public:
- std::string face_name;
- float weight;
- uint32_t frame;
-
- void Read(std::istream* stream)
- {
- char buffer[15];
- stream->read((char*) &buffer, sizeof(char) * 15);
- face_name = std::string(buffer);
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) &weight, sizeof(float));
- }
-
- void Write(std::ostream* stream)
- {
- stream->write((char*)face_name.c_str(), sizeof(char) * 15);
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)&weight, sizeof(float));
- }
- };
-
- class VmdCameraFrame
- {
- public:
- int frame;
- float distance;
- float position[3];
- float orientation[3];
- char interpolation[6][4];
- float angle;
- char unknown[3];
-
- void Read(std::istream *stream)
- {
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) &distance, sizeof(float));
- stream->read((char*) position, sizeof(float) * 3);
- stream->read((char*) orientation, sizeof(float) * 3);
- stream->read((char*) interpolation, sizeof(char) * 24);
- stream->read((char*) &angle, sizeof(float));
- stream->read((char*) unknown, sizeof(char) * 3);
- }
-
- void Write(std::ostream *stream)
- {
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)&distance, sizeof(float));
- stream->write((char*)position, sizeof(float) * 3);
- stream->write((char*)orientation, sizeof(float) * 3);
- stream->write((char*)interpolation, sizeof(char) * 24);
- stream->write((char*)&angle, sizeof(float));
- stream->write((char*)unknown, sizeof(char) * 3);
- }
- };
-
- class VmdLightFrame
- {
- public:
- int frame;
- float color[3];
- float position[3];
-
- void Read(std::istream* stream)
- {
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) color, sizeof(float) * 3);
- stream->read((char*) position, sizeof(float) * 3);
- }
-
- void Write(std::ostream* stream)
- {
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)color, sizeof(float) * 3);
- stream->write((char*)position, sizeof(float) * 3);
- }
- };
-
- class VmdIkEnable
- {
- public:
- std::string ik_name;
- bool enable;
- };
-
- class VmdIkFrame
- {
- public:
- int frame;
- bool display;
- std::vector<VmdIkEnable> ik_enable;
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) &display, sizeof(uint8_t));
- int ik_count;
- stream->read((char*) &ik_count, sizeof(int));
- ik_enable.resize(ik_count);
- for (int i = 0; i < ik_count; i++)
- {
- stream->read(buffer, 20);
- ik_enable[i].ik_name = std::string(buffer);
- stream->read((char*) &ik_enable[i].enable, sizeof(uint8_t));
- }
- }
-
- void Write(std::ostream *stream)
- {
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)&display, sizeof(uint8_t));
- int ik_count = static_cast<int>(ik_enable.size());
- stream->write((char*)&ik_count, sizeof(int));
- for (int i = 0; i < ik_count; i++)
- {
- const VmdIkEnable& ik_enable = this->ik_enable.at(i);
- stream->write(ik_enable.ik_name.c_str(), 20);
- stream->write((char*)&ik_enable.enable, sizeof(uint8_t));
- }
- }
- };
-
- class VmdMotion
- {
- public:
- std::string model_name;
- int version;
- std::vector<VmdBoneFrame> bone_frames;
- std::vector<VmdFaceFrame> face_frames;
- std::vector<VmdCameraFrame> camera_frames;
- std::vector<VmdLightFrame> light_frames;
- std::vector<VmdIkFrame> ik_frames;
-
- static std::unique_ptr<VmdMotion> LoadFromFile(char const *filename)
- {
- std::ifstream stream(filename, std::ios::binary);
- auto result = LoadFromStream(&stream);
- stream.close();
- return result;
- }
-
- static std::unique_ptr<VmdMotion> LoadFromStream(std::ifstream *stream)
- {
-
- char buffer[30];
- auto result = mmd::make_unique<VmdMotion>();
-
- // magic and version
- stream->read((char*) buffer, 30);
- if (strncmp(buffer, "Vocaloid Motion Data", 20))
- {
- std::cerr << "invalid vmd file." << std::endl;
- return nullptr;
- }
- result->version = std::atoi(buffer + 20);
-
- // name
- stream->read(buffer, 20);
- result->model_name = std::string(buffer);
-
- // bone frames
- int bone_frame_num;
- stream->read((char*) &bone_frame_num, sizeof(int));
- result->bone_frames.resize(bone_frame_num);
- for (int i = 0; i < bone_frame_num; i++)
- {
- result->bone_frames[i].Read(stream);
- }
-
- // face frames
- int face_frame_num;
- stream->read((char*) &face_frame_num, sizeof(int));
- result->face_frames.resize(face_frame_num);
- for (int i = 0; i < face_frame_num; i++)
- {
- result->face_frames[i].Read(stream);
- }
-
- // camera frames
- int camera_frame_num;
- stream->read((char*) &camera_frame_num, sizeof(int));
- result->camera_frames.resize(camera_frame_num);
- for (int i = 0; i < camera_frame_num; i++)
- {
- result->camera_frames[i].Read(stream);
- }
-
- // light frames
- int light_frame_num;
- stream->read((char*) &light_frame_num, sizeof(int));
- result->light_frames.resize(light_frame_num);
- for (int i = 0; i < light_frame_num; i++)
- {
- result->light_frames[i].Read(stream);
- }
-
- // unknown2
- stream->read(buffer, 4);
-
- // ik frames
- if (stream->peek() != std::ios::traits_type::eof())
- {
- int ik_num;
- stream->read((char*) &ik_num, sizeof(int));
- result->ik_frames.resize(ik_num);
- for (int i = 0; i < ik_num; i++)
- {
- result->ik_frames[i].Read(stream);
- }
- }
-
- if (stream->peek() != std::ios::traits_type::eof())
- {
- std::cerr << "vmd stream has unknown data." << std::endl;
- }
-
- return result;
- }
-
- bool SaveToFile(const std::u16string& /*filename*/)
- {
- // TODO: How to adapt u16string to string?
- /*
- std::ofstream stream(filename.c_str(), std::ios::binary);
- auto result = SaveToStream(&stream);
- stream.close();
- return result;
- */
- return false;
- }
-
- bool SaveToStream(std::ofstream *stream)
- {
- std::string magic = "Vocaloid Motion Data 0002\0";
- magic.resize(30);
-
- // magic and version
- stream->write(magic.c_str(), 30);
-
- // name
- stream->write(model_name.c_str(), 20);
-
- // bone frames
- const int bone_frame_num = static_cast<int>(bone_frames.size());
- stream->write(reinterpret_cast<const char*>(&bone_frame_num), sizeof(int));
- for (int i = 0; i < bone_frame_num; i++)
- {
- bone_frames[i].Write(stream);
- }
-
- // face frames
- const int face_frame_num = static_cast<int>(face_frames.size());
- stream->write(reinterpret_cast<const char*>(&face_frame_num), sizeof(int));
- for (int i = 0; i < face_frame_num; i++)
- {
- face_frames[i].Write(stream);
- }
-
- // camera frames
- const int camera_frame_num = static_cast<int>(camera_frames.size());
- stream->write(reinterpret_cast<const char*>(&camera_frame_num), sizeof(int));
- for (int i = 0; i < camera_frame_num; i++)
- {
- camera_frames[i].Write(stream);
- }
-
- // light frames
- const int light_frame_num = static_cast<int>(light_frames.size());
- stream->write(reinterpret_cast<const char*>(&light_frame_num), sizeof(int));
- for (int i = 0; i < light_frame_num; i++)
- {
- light_frames[i].Write(stream);
- }
-
- // self shadow datas
- const int self_shadow_num = 0;
- stream->write(reinterpret_cast<const char*>(&self_shadow_num), sizeof(int));
-
- // ik frames
- const int ik_num = static_cast<int>(ik_frames.size());
- stream->write(reinterpret_cast<const char*>(&ik_num), sizeof(int));
- for (int i = 0; i < ik_num; i++)
- {
- ik_frames[i].Write(stream);
- }
-
- return true;
- }
- };
-}
diff --git a/thirdparty/assimp/code/Material/MaterialSystem.cpp b/thirdparty/assimp/code/Material/MaterialSystem.cpp
index d0b39093b6..0be6e9f7bb 100644
--- a/thirdparty/assimp/code/Material/MaterialSystem.cpp
+++ b/thirdparty/assimp/code/Material/MaterialSystem.cpp
@@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/types.h>
#include <assimp/material.h>
#include <assimp/DefaultLogger.hpp>
-#include <assimp/Macros.h>
using namespace Assimp;
@@ -545,23 +544,7 @@ aiReturn aiMaterial::AddProperty (const aiString* pInput,
unsigned int type,
unsigned int index)
{
- // We don't want to add the whole buffer .. write a 32 bit length
- // prefix followed by the zero-terminated UTF8 string.
- // (HACK) I don't want to break the ABI now, but we definitely
- // ought to change aiString::mLength to uint32_t one day.
- if (sizeof(size_t) == 8) {
- aiString copy = *pInput;
- uint32_t* s = reinterpret_cast<uint32_t*>(&copy.length);
- s[1] = static_cast<uint32_t>(pInput->length);
-
- return AddBinaryProperty(s+1,
- static_cast<unsigned int>(pInput->length+1+4),
- pKey,
- type,
- index,
- aiPTI_String);
- }
- ai_assert(sizeof(size_t)==4);
+ ai_assert(sizeof(ai_uint32)==4);
return AddBinaryProperty(pInput,
static_cast<unsigned int>(pInput->length+1+4),
pKey,
diff --git a/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp
new file mode 100644
index 0000000000..75daeb6b59
--- /dev/null
+++ b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp
@@ -0,0 +1,268 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software 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 assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+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.
+
+----------------------------------------------------------------------
+*/
+#include "ArmaturePopulate.h"
+
+#include <assimp/BaseImporter.h>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <iostream>
+
+namespace Assimp {
+
+/// The default class constructor.
+ArmaturePopulate::ArmaturePopulate() : BaseProcess()
+{}
+
+/// The class destructor.
+ArmaturePopulate::~ArmaturePopulate()
+{}
+
+bool ArmaturePopulate::IsActive(unsigned int pFlags) const {
+ return (pFlags & aiProcess_PopulateArmatureData) != 0;
+}
+
+void ArmaturePopulate::SetupProperties(const Importer *pImp) {
+ // do nothing
+}
+
+void ArmaturePopulate::Execute(aiScene *out) {
+
+ // Now convert all bone positions to the correct mOffsetMatrix
+ std::vector<aiBone *> bones;
+ std::vector<aiNode *> nodes;
+ std::map<aiBone *, aiNode *> bone_stack;
+ BuildBoneList(out->mRootNode, out->mRootNode, out, bones);
+ BuildNodeList(out->mRootNode, nodes);
+
+ BuildBoneStack(out->mRootNode, out->mRootNode, out, bones, bone_stack, nodes);
+
+ ASSIMP_LOG_DEBUG_F("Bone stack size: ", bone_stack.size());
+
+ for (std::pair<aiBone *, aiNode *> kvp : bone_stack) {
+ aiBone *bone = kvp.first;
+ aiNode *bone_node = kvp.second;
+ ASSIMP_LOG_DEBUG_F("active node lookup: ", bone->mName.C_Str());
+ // lcl transform grab - done in generate_nodes :)
+
+ // bone->mOffsetMatrix = bone_node->mTransformation;
+ aiNode *armature = GetArmatureRoot(bone_node, bones);
+
+ ai_assert(armature);
+
+ // set up bone armature id
+ bone->mArmature = armature;
+
+ // set this bone node to be referenced properly
+ ai_assert(bone_node);
+ bone->mNode = bone_node;
+ }
+}
+
+
+/* Reprocess all nodes to calculate bone transforms properly based on the REAL
+ * mOffsetMatrix not the local. */
+/* Before this would use mesh transforms which is wrong for bone transforms */
+/* Before this would work for simple character skeletons but not complex meshes
+ * with multiple origins */
+/* Source: sketch fab log cutter fbx */
+void ArmaturePopulate::BuildBoneList(aiNode *current_node,
+ const aiNode *root_node,
+ const aiScene *scene,
+ std::vector<aiBone *> &bones) {
+ ai_assert(scene);
+ for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) {
+ aiNode *child = current_node->mChildren[nodeId];
+ ai_assert(child);
+
+ // check for bones
+ for (unsigned int meshId = 0; meshId < child->mNumMeshes; ++meshId) {
+ ai_assert(child->mMeshes);
+ unsigned int mesh_index = child->mMeshes[meshId];
+ aiMesh *mesh = scene->mMeshes[mesh_index];
+ ai_assert(mesh);
+
+ for (unsigned int boneId = 0; boneId < mesh->mNumBones; ++boneId) {
+ aiBone *bone = mesh->mBones[boneId];
+ ai_assert(bone);
+
+ // duplicate meshes exist with the same bones sometimes :)
+ // so this must be detected
+ if (std::find(bones.begin(), bones.end(), bone) == bones.end()) {
+ // add the element once
+ bones.push_back(bone);
+ }
+ }
+
+ // find mesh and get bones
+ // then do recursive lookup for bones in root node hierarchy
+ }
+
+ BuildBoneList(child, root_node, scene, bones);
+ }
+}
+
+/* Prepare flat node list which can be used for non recursive lookups later */
+void ArmaturePopulate::BuildNodeList(const aiNode *current_node,
+ std::vector<aiNode *> &nodes) {
+ ai_assert(current_node);
+
+ for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) {
+ aiNode *child = current_node->mChildren[nodeId];
+ ai_assert(child);
+
+ nodes.push_back(child);
+
+ BuildNodeList(child, nodes);
+ }
+}
+
+/* A bone stack allows us to have multiple armatures, with the same bone names
+ * A bone stack allows us also to retrieve bones true transform even with
+ * duplicate names :)
+ */
+void ArmaturePopulate::BuildBoneStack(aiNode *current_node,
+ const aiNode *root_node,
+ const aiScene *scene,
+ const std::vector<aiBone *> &bones,
+ std::map<aiBone *, aiNode *> &bone_stack,
+ std::vector<aiNode *> &node_stack) {
+ ai_assert(scene);
+ ai_assert(root_node);
+ ai_assert(!node_stack.empty());
+
+ for (aiBone *bone : bones) {
+ ai_assert(bone);
+ aiNode *node = GetNodeFromStack(bone->mName, node_stack);
+ if (node == nullptr) {
+ node_stack.clear();
+ BuildNodeList(root_node, node_stack);
+ ASSIMP_LOG_DEBUG_F("Resetting bone stack: nullptr element ", bone->mName.C_Str());
+
+ node = GetNodeFromStack(bone->mName, node_stack);
+
+ if (!node) {
+ ASSIMP_LOG_ERROR("serious import issue node for bone was not detected");
+ continue;
+ }
+ }
+
+ ASSIMP_LOG_DEBUG_F("Successfully added bone[", bone->mName.C_Str(), "] to stack and bone node is: ", node->mName.C_Str());
+
+ bone_stack.insert(std::pair<aiBone *, aiNode *>(bone, node));
+ }
+}
+
+
+/* Returns the armature root node */
+/* This is required to be detected for a bone initially, it will recurse up
+ * until it cannot find another bone and return the node No known failure
+ * points. (yet)
+ */
+aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node,
+ std::vector<aiBone *> &bone_list) {
+ while (bone_node) {
+ if (!IsBoneNode(bone_node->mName, bone_list)) {
+ ASSIMP_LOG_DEBUG_F("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str());
+ return bone_node;
+ }
+
+ bone_node = bone_node->mParent;
+ }
+
+ ASSIMP_LOG_ERROR("GetArmatureRoot() can't find armature!");
+
+ return nullptr;
+}
+
+
+
+/* Simple IsBoneNode check if this could be a bone */
+bool ArmaturePopulate::IsBoneNode(const aiString &bone_name,
+ std::vector<aiBone *> &bones) {
+ for (aiBone *bone : bones) {
+ if (bone->mName == bone_name) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Pop this node by name from the stack if found */
+/* Used in multiple armature situations with duplicate node / bone names */
+/* Known flaw: cannot have nodes with bone names, will be fixed in later release
+ */
+/* (serious to be fixed) Known flaw: nodes which have more than one bone could
+ * be prematurely dropped from stack */
+aiNode *ArmaturePopulate::GetNodeFromStack(const aiString &node_name,
+ std::vector<aiNode *> &nodes) {
+ std::vector<aiNode *>::iterator iter;
+ aiNode *found = nullptr;
+ for (iter = nodes.begin(); iter < nodes.end(); ++iter) {
+ aiNode *element = *iter;
+ ai_assert(element);
+ // node valid and node name matches
+ if (element->mName == node_name) {
+ found = element;
+ break;
+ }
+ }
+
+ if (found != nullptr) {
+ ASSIMP_LOG_INFO_F("Removed node from stack: ", found->mName.C_Str());
+ // now pop the element from the node list
+ nodes.erase(iter);
+
+ return found;
+ }
+
+ // unique names can cause this problem
+ ASSIMP_LOG_ERROR("[Serious] GetNodeFromStack() can't find node from stack!");
+
+ return nullptr;
+}
+
+
+
+
+} // Namespace Assimp
diff --git a/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h
new file mode 100644
index 0000000000..aa1ad7c80c
--- /dev/null
+++ b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h
@@ -0,0 +1,112 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software 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 assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+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 ARMATURE_POPULATE_H_
+#define ARMATURE_POPULATE_H_
+
+#include "Common/BaseProcess.h"
+#include <assimp/BaseImporter.h>
+#include <vector>
+#include <map>
+
+
+struct aiNode;
+struct aiBone;
+
+namespace Assimp {
+
+// ---------------------------------------------------------------------------
+/** Armature Populate: This is a post process designed
+ * To save you time when importing models into your game engines
+ * This was originally designed only for fbx but will work with other formats
+ * it is intended to auto populate aiBone data with armature and the aiNode
+ * This is very useful when dealing with skinned meshes
+ * or when dealing with many different skeletons
+ * It's off by default but recommend that you try it and use it
+ * It should reduce down any glue code you have in your
+ * importers
+ * You can contact RevoluPowered <gordon@gordonite.tech>
+ * For more info about this
+*/
+class ASSIMP_API ArmaturePopulate : public BaseProcess {
+public:
+ /// The default class constructor.
+ ArmaturePopulate();
+
+ /// The class destructor.
+ virtual ~ArmaturePopulate();
+
+ /// Overwritten, @see BaseProcess
+ virtual bool IsActive( unsigned int pFlags ) const;
+
+ /// Overwritten, @see BaseProcess
+ virtual void SetupProperties( const Importer* pImp );
+
+ /// Overwritten, @see BaseProcess
+ virtual void Execute( aiScene* pScene );
+
+ static aiNode *GetArmatureRoot(aiNode *bone_node,
+ std::vector<aiBone *> &bone_list);
+
+ static bool IsBoneNode(const aiString &bone_name,
+ std::vector<aiBone *> &bones);
+
+ static aiNode *GetNodeFromStack(const aiString &node_name,
+ std::vector<aiNode *> &nodes);
+
+ static void BuildNodeList(const aiNode *current_node,
+ std::vector<aiNode *> &nodes);
+
+ static void BuildBoneList(aiNode *current_node, const aiNode *root_node,
+ const aiScene *scene,
+ std::vector<aiBone *> &bones);
+
+ static void BuildBoneStack(aiNode *current_node, const aiNode *root_node,
+ const aiScene *scene,
+ const std::vector<aiBone *> &bones,
+ std::map<aiBone *, aiNode *> &bone_stack,
+ std::vector<aiNode *> &node_stack);
+};
+
+} // Namespace Assimp
+
+
+#endif // SCALE_PROCESS_H_ \ No newline at end of file
diff --git a/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp
index bb571a551b..df4d44337d 100644
--- a/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp
@@ -354,12 +354,12 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
}
else if (axis * base_axis_z >= angle_epsilon) {
FindMeshCenter(mesh, center, min, max);
- diffu = max.y - min.y;
- diffv = max.z - min.z;
+ diffu = max.x - min.x;
+ diffv = max.y - min.y;
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D& pos = mesh->mVertices[pnt];
- out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.0);
+ out[pnt].Set((pos.x - min.x) / diffu,(pos.y - min.y) / diffv,0.0);
}
}
// slower code path in case the mapping axis is not one of the coordinate system axes
diff --git a/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp
index 433f042448..016884c6e7 100644
--- a/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp
@@ -52,7 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FindInvalidDataProcess.h"
#include "ProcessHelper.h"
-#include <assimp/Macros.h>
#include <assimp/Exceptional.h>
#include <assimp/qnan.h>
diff --git a/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp
index 914ec05b46..f121fc60d3 100644
--- a/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp
@@ -431,31 +431,6 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
bone->mWeights = new aiVertexWeight[bone->mNumWeights];
memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight));
}
- else {
-
- /* NOTE:
- *
- * In the algorithm above we're assuming that there are no vertices
- * with a different bone weight setup at the same position. That wouldn't
- * make sense, but it is not absolutely impossible. SkeletonMeshBuilder
- * for example generates such input data if two skeleton points
- * share the same position. Again this doesn't make sense but is
- * reality for some model formats (MD5 for example uses these special
- * nodes as attachment tags for its weapons).
- *
- * Then it is possible that a bone has no weights anymore .... as a quick
- * workaround, we're just removing these bones. If they're animated,
- * model geometry might be modified but at least there's no risk of a crash.
- */
- delete bone;
- --pMesh->mNumBones;
- for (unsigned int n = a; n < pMesh->mNumBones; ++n) {
- pMesh->mBones[n] = pMesh->mBones[n+1];
- }
-
- --a;
- ASSIMP_LOG_WARN("Removing bone -> no weights remaining");
- }
}
return pMesh->mNumVertices;
}
diff --git a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp
index 50ff5ed93d..41f50a5ba5 100644
--- a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp
+++ b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp
@@ -224,3 +224,32 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
}
return (pcMesh->mNumVertices != iOldNumVertices);
}
+
+
+// ------------------------------------------------------------------------------------------------
+bool IsMeshInVerboseFormat(const aiMesh* mesh) {
+ // avoid slow vector<bool> specialization
+ std::vector<unsigned int> seen(mesh->mNumVertices,0);
+ for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
+ const aiFace& f = mesh->mFaces[i];
+ for(unsigned int j = 0; j < f.mNumIndices; ++j) {
+ if(++seen[f.mIndices[j]] == 2) {
+ // found a duplicate index
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+// ------------------------------------------------------------------------------------------------
+bool MakeVerboseFormatProcess::IsVerboseFormat(const aiScene* pScene) {
+ for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
+ if(!IsMeshInVerboseFormat(pScene->mMeshes[i])) {
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h
index 1adf8e2f69..8565d5933a 100644
--- a/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h
+++ b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h
@@ -94,6 +94,13 @@ public:
* @param pScene The imported data to work at. */
void Execute( aiScene* pScene);
+public:
+
+ // -------------------------------------------------------------------
+ /** Checks whether the scene is already in verbose format.
+ * @param pScene The data to check.
+ * @return true if the scene is already in verbose format. */
+ static bool IsVerboseFormat(const aiScene* pScene);
private:
diff --git a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp
index 712fd6943d..75d1b6ef78 100644
--- a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp
@@ -538,13 +538,17 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
{
Validate(&pAnimation->mName);
- // validate all materials
- if (pAnimation->mNumChannels)
+ // validate all animations
+ if (pAnimation->mNumChannels || pAnimation->mNumMorphMeshChannels)
{
- if (!pAnimation->mChannels) {
+ if (!pAnimation->mChannels && pAnimation->mNumChannels) {
ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)",
pAnimation->mNumChannels);
}
+ if (!pAnimation->mMorphMeshChannels && pAnimation->mNumMorphMeshChannels) {
+ ReportError("aiAnimation::mMorphMeshChannels is NULL (aiAnimation::mNumMorphMeshChannels is %i)",
+ pAnimation->mNumMorphMeshChannels);
+ }
for (unsigned int i = 0; i < pAnimation->mNumChannels;++i)
{
if (!pAnimation->mChannels[i])
@@ -554,6 +558,15 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
}
Validate(pAnimation, pAnimation->mChannels[i]);
}
+ for (unsigned int i = 0; i < pAnimation->mNumMorphMeshChannels;++i)
+ {
+ if (!pAnimation->mMorphMeshChannels[i])
+ {
+ ReportError("aiAnimation::mMorphMeshChannels[%i] is NULL (aiAnimation::mNumMorphMeshChannels is %i)",
+ i, pAnimation->mNumMorphMeshChannels);
+ }
+ Validate(pAnimation, pAnimation->mMorphMeshChannels[i]);
+ }
}
else {
ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
@@ -903,6 +916,48 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
}
}
+void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
+ const aiMeshMorphAnim* pMeshMorphAnim)
+{
+ Validate(&pMeshMorphAnim->mName);
+
+ if (!pMeshMorphAnim->mNumKeys) {
+ ReportError("Empty mesh morph animation channel");
+ }
+
+ // otherwise check whether one of the keys exceeds the total duration of the animation
+ if (pMeshMorphAnim->mNumKeys)
+ {
+ if (!pMeshMorphAnim->mKeys)
+ {
+ ReportError("aiMeshMorphAnim::mKeys is NULL (aiMeshMorphAnim::mNumKeys is %i)",
+ pMeshMorphAnim->mNumKeys);
+ }
+ double dLast = -10e10;
+ for (unsigned int i = 0; i < pMeshMorphAnim->mNumKeys;++i)
+ {
+ // ScenePreprocessor will compute the duration if still the default value
+ // (Aramis) Add small epsilon, comparison tended to fail if max_time == duration,
+ // seems to be due the compilers register usage/width.
+ if (pAnimation->mDuration > 0. && pMeshMorphAnim->mKeys[i].mTime > pAnimation->mDuration+0.001)
+ {
+ ReportError("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is larger "
+ "than aiAnimation::mDuration (which is %.5f)",i,
+ (float)pMeshMorphAnim->mKeys[i].mTime,
+ (float)pAnimation->mDuration);
+ }
+ if (i && pMeshMorphAnim->mKeys[i].mTime <= dLast)
+ {
+ ReportWarning("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is smaller "
+ "than aiMeshMorphAnim::mKeys[%i] (which is %.5f)",i,
+ (float)pMeshMorphAnim->mKeys[i].mTime,
+ i-1, (float)dLast);
+ }
+ dLast = pMeshMorphAnim->mKeys[i].mTime;
+ }
+ }
+}
+
// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiNode* pNode)
{
@@ -958,7 +1013,7 @@ void ValidateDSProcess::Validate( const aiString* pString)
{
if (pString->length > MAXLEN)
{
- ReportError("aiString::length is too large (%lu, maximum is %lu)",
+ ReportError("aiString::length is too large (%u, maximum is %lu)",
pString->length,MAXLEN);
}
const char* sz = pString->data;
diff --git a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h
index 0b891ef414..7b309c9251 100644
--- a/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h
+++ b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h
@@ -55,6 +55,7 @@ struct aiBone;
struct aiMesh;
struct aiAnimation;
struct aiNodeAnim;
+struct aiMeshMorphAnim;
struct aiTexture;
struct aiMaterial;
struct aiNode;
@@ -150,6 +151,13 @@ protected:
void Validate( const aiAnimation* pAnimation,
const aiNodeAnim* pBoneAnim);
+ /** Validates a mesh morph animation channel.
+ * @param pAnimation Input animation.
+ * @param pMeshMorphAnim Mesh morph animation channel.
+ * */
+ void Validate( const aiAnimation* pAnimation,
+ const aiMeshMorphAnim* pMeshMorphAnim);
+
// -------------------------------------------------------------------
/** Validates a node and all of its subnodes
* @param Node Input node*/
diff --git a/thirdparty/assimp/code/revision.h b/thirdparty/assimp/code/revision.h
index 88872aef22..66eb875303 100644
--- a/thirdparty/assimp/code/revision.h
+++ b/thirdparty/assimp/code/revision.h
@@ -1,7 +1,28 @@
#ifndef ASSIMP_REVISION_H_INC
#define ASSIMP_REVISION_H_INC
-#define GitVersion 0x00000000
+#define GitVersion 0x308db73d
#define GitBranch "master"
+#define VER_MAJOR 5
+#define VER_MINOR 0
+#define VER_PATCH 0
+#define VER_BUILD 0
+
+#define STR_HELP(x) #x
+#define STR(x) STR_HELP(x)
+
+#define VER_FILEVERSION VER_MAJOR,VER_MINOR,VER_PATCH,VER_BUILD
+#if (GitVersion == 0)
+#define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD)
+#else
+#define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) " (Commit 308db73d)"
+#endif
+
+#ifdef NDEBUG
+#define VER_ORIGINAL_FILENAME_STR "assimp.dll"
+#else
+#define VER_ORIGINAL_FILENAME_STR "assimp.dll"
+#endif // NDEBUG
+
#endif // ASSIMP_REVISION_H_INC
diff --git a/thirdparty/assimp/include/assimp/.editorconfig b/thirdparty/assimp/include/assimp/.editorconfig
new file mode 100644
index 0000000000..9ea66423ad
--- /dev/null
+++ b/thirdparty/assimp/include/assimp/.editorconfig
@@ -0,0 +1,8 @@
+# See <http://EditorConfig.org> for details
+
+[*.{h,hpp,inl}]
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_size = 4
+indent_style = space
diff --git a/thirdparty/assimp/include/assimp/BaseImporter.h b/thirdparty/assimp/include/assimp/BaseImporter.h
index 55f7fe3754..ad8a3dafd8 100644
--- a/thirdparty/assimp/include/assimp/BaseImporter.h
+++ b/thirdparty/assimp/include/assimp/BaseImporter.h
@@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Definition of the base class for all importer worker classes. */
+#pragma once
#ifndef INCLUDED_AI_BASEIMPORTER_H
#define INCLUDED_AI_BASEIMPORTER_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include "Exceptional.h"
#include <vector>
@@ -191,16 +196,13 @@ public:
/**
* Assimp Importer
* unit conversions available
- * if you need another measurment unit add it below.
- * it's currently defined in assimp that we prefer meters.
+ * NOTE: Valid options are initialised in the
+ * constructor in the implementation file to
+ * work around a VS2013 compiler bug if support
+ * for that compiler is dropped in the future
+ * initialisation can be moved back here
* */
- std::map<ImporterUnits, double> importerUnits = {
- {ImporterUnits::M, 1},
- {ImporterUnits::CM, 0.01},
- {ImporterUnits::MM, 0.001},
- {ImporterUnits::INCHES, 0.0254},
- {ImporterUnits::FEET, 0.3048}
- };
+ std::map<ImporterUnits, double> importerUnits;
virtual void SetApplicationUnits( const ImporterUnits& unit )
{
diff --git a/thirdparty/assimp/include/assimp/Bitmap.h b/thirdparty/assimp/include/assimp/Bitmap.h
index e6b5fb1327..4c3f5a437b 100644
--- a/thirdparty/assimp/include/assimp/Bitmap.h
+++ b/thirdparty/assimp/include/assimp/Bitmap.h
@@ -46,10 +46,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Used for file formats which embed their textures into the model file.
*/
-
+#pragma once
#ifndef AI_BITMAP_H_INC
#define AI_BITMAP_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include "defs.h"
#include <stdint.h>
#include <cstddef>
diff --git a/thirdparty/assimp/include/assimp/ByteSwapper.h b/thirdparty/assimp/include/assimp/ByteSwapper.h
index 20a2463fb8..3f14c471a8 100644
--- a/thirdparty/assimp/include/assimp/ByteSwapper.h
+++ b/thirdparty/assimp/include/assimp/ByteSwapper.h
@@ -42,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Helper class tp perform various byte oder swappings
(e.g. little to big endian) */
+#pragma once
#ifndef AI_BYTESWAPPER_H_INC
#define AI_BYTESWAPPER_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/ai_assert.h>
#include <assimp/types.h>
#include <stdint.h>
diff --git a/thirdparty/assimp/include/assimp/CreateAnimMesh.h b/thirdparty/assimp/include/assimp/CreateAnimMesh.h
index a60173588f..1266d1de11 100644
--- a/thirdparty/assimp/include/assimp/CreateAnimMesh.h
+++ b/thirdparty/assimp/include/assimp/CreateAnimMesh.h
@@ -43,16 +43,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file CreateAnimMesh.h
* Create AnimMesh from Mesh
*/
+#pragma once
#ifndef INCLUDED_AI_CREATE_ANIM_MESH_H
#define INCLUDED_AI_CREATE_ANIM_MESH_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/mesh.h>
-namespace Assimp {
+namespace Assimp {
-/** Create aiAnimMesh from aiMesh. */
+/**
+ * Create aiAnimMesh from aiMesh.
+ * @param mesh The input mesh to create an animated mesh from.
+ * @return The new created animated mesh.
+ */
ASSIMP_API aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh);
} // end of namespace Assimp
+
#endif // INCLUDED_AI_CREATE_ANIM_MESH_H
diff --git a/thirdparty/assimp/include/assimp/DefaultIOStream.h b/thirdparty/assimp/include/assimp/DefaultIOStream.h
index 994d728ff5..c6d382c1b5 100644
--- a/thirdparty/assimp/include/assimp/DefaultIOStream.h
+++ b/thirdparty/assimp/include/assimp/DefaultIOStream.h
@@ -41,15 +41,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Default file I/O using fXXX()-family of functions */
+#pragma once
#ifndef AI_DEFAULTIOSTREAM_H_INC
#define AI_DEFAULTIOSTREAM_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <stdio.h>
#include <assimp/IOStream.hpp>
#include <assimp/importerdesc.h>
#include <assimp/Defines.h>
-namespace Assimp {
+namespace Assimp {
// ----------------------------------------------------------------------------------
//! @class DefaultIOStream
@@ -57,8 +62,7 @@ namespace Assimp {
//! @note An instance of this class can exist without a valid file handle
//! attached to it. All calls fail, but the instance can nevertheless be
//! used with no restrictions.
-class ASSIMP_API DefaultIOStream : public IOStream
-{
+class ASSIMP_API DefaultIOStream : public IOStream {
friend class DefaultIOSystem;
#if __ANDROID__
# if __ANDROID_API__ > 9
@@ -82,7 +86,6 @@ public:
size_t pSize,
size_t pCount);
-
// -------------------------------------------------------------------
/// Write to stream
size_t Write(const void* pvBuffer,
@@ -107,16 +110,13 @@ public:
void Flush();
private:
- // File data-structure, using clib
FILE* mFile;
- // Filename
std::string mFilename;
- // Cached file size
mutable size_t mCachedSize;
};
// ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
: mFile(nullptr)
, mFilename("")
@@ -125,7 +125,7 @@ DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
}
// ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
: mFile(pFile)
, mFilename(strFilename)
@@ -137,4 +137,3 @@ DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
} // ns assimp
#endif //!!AI_DEFAULTIOSTREAM_H_INC
-
diff --git a/thirdparty/assimp/include/assimp/DefaultIOSystem.h b/thirdparty/assimp/include/assimp/DefaultIOSystem.h
index 2dd5c801b5..46f6d447c5 100644
--- a/thirdparty/assimp/include/assimp/DefaultIOSystem.h
+++ b/thirdparty/assimp/include/assimp/DefaultIOSystem.h
@@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Default implementation of IOSystem using the standard C file functions */
+#pragma once
#ifndef AI_DEFAULTIOSYSTEM_H_INC
#define AI_DEFAULTIOSYSTEM_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/IOSystem.hpp>
namespace Assimp {
diff --git a/thirdparty/assimp/include/assimp/Defines.h b/thirdparty/assimp/include/assimp/Defines.h
index 15e1d83c26..be3e2fafd6 100644
--- a/thirdparty/assimp/include/assimp/Defines.h
+++ b/thirdparty/assimp/include/assimp/Defines.h
@@ -38,6 +38,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
+#pragma once
+#ifndef AI_DEFINES_H_INC
+#define AI_DEFINES_H_INC
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
// We need those constants, workaround for any platforms where nobody defined them yet
#if (!defined SIZE_MAX)
# define SIZE_MAX (~((size_t)0))
@@ -47,3 +55,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# define UINT_MAX (~((unsigned int)0))
#endif
+#endif // AI_DEINES_H_INC
diff --git a/thirdparty/assimp/include/assimp/Exceptional.h b/thirdparty/assimp/include/assimp/Exceptional.h
index 5109b8f077..6bb6ce1e39 100644
--- a/thirdparty/assimp/include/assimp/Exceptional.h
+++ b/thirdparty/assimp/include/assimp/Exceptional.h
@@ -38,11 +38,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
-#ifndef INCLUDED_EXCEPTIONAL_H
-#define INCLUDED_EXCEPTIONAL_H
+#pragma once
+#ifndef AI_INCLUDED_EXCEPTIONAL_H
+#define AI_INCLUDED_EXCEPTIONAL_H
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
#include <stdexcept>
#include <assimp/DefaultIOStream.h>
+
using std::runtime_error;
#ifdef _MSC_VER
@@ -53,17 +59,14 @@ using std::runtime_error;
/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an
* unrecoverable error occurs while importing. Loading APIs return
* NULL instead of a valid aiScene then. */
-class DeadlyImportError
- : public runtime_error
-{
+class DeadlyImportError : public runtime_error {
public:
/** Constructor with arguments */
explicit DeadlyImportError( const std::string& errorText)
- : runtime_error(errorText)
- {
+ : runtime_error(errorText) {
+ // empty
}
-private:
};
typedef DeadlyImportError DeadlyExportError;
@@ -84,7 +87,7 @@ struct ExceptionSwallower {
template <typename T>
struct ExceptionSwallower<T*> {
T* operator ()() const {
- return NULL;
+ return nullptr;
}
};
@@ -122,4 +125,4 @@ struct ExceptionSwallower<void> {
}\
}
-#endif // INCLUDED_EXCEPTIONAL_H
+#endif // AI_INCLUDED_EXCEPTIONAL_H
diff --git a/thirdparty/assimp/include/assimp/Exporter.hpp b/thirdparty/assimp/include/assimp/Exporter.hpp
index ea0303e804..2612e1f9d2 100644
--- a/thirdparty/assimp/include/assimp/Exporter.hpp
+++ b/thirdparty/assimp/include/assimp/Exporter.hpp
@@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_EXPORT_HPP_INC
#define AI_EXPORT_HPP_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifndef ASSIMP_BUILD_NO_EXPORT
#include "cexport.h"
diff --git a/thirdparty/assimp/include/assimp/GenericProperty.h b/thirdparty/assimp/include/assimp/GenericProperty.h
index 183ecd5197..7796d595b8 100644
--- a/thirdparty/assimp/include/assimp/GenericProperty.h
+++ b/thirdparty/assimp/include/assimp/GenericProperty.h
@@ -40,12 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
+#pragma once
#ifndef AI_GENERIC_PROPERTY_H_INCLUDED
#define AI_GENERIC_PROPERTY_H_INCLUDED
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/Importer.hpp>
#include <assimp/ai_assert.h>
-#include "Hash.h"
+#include <assimp/Hash.h>
#include <map>
diff --git a/thirdparty/assimp/include/assimp/Hash.h b/thirdparty/assimp/include/assimp/Hash.h
index 30657be198..9056440789 100644
--- a/thirdparty/assimp/include/assimp/Hash.h
+++ b/thirdparty/assimp/include/assimp/Hash.h
@@ -39,10 +39,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
-
+#pragma once
#ifndef AI_HASH_H_INCLUDED
#define AI_HASH_H_INCLUDED
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <stdint.h>
#include <string.h>
diff --git a/thirdparty/assimp/include/assimp/IOStream.hpp b/thirdparty/assimp/include/assimp/IOStream.hpp
index 0623d0f70b..39932cd949 100644
--- a/thirdparty/assimp/include/assimp/IOStream.hpp
+++ b/thirdparty/assimp/include/assimp/IOStream.hpp
@@ -48,14 +48,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IOSTREAM_H_INC
#define AI_IOSTREAM_H_INC
-#include "types.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
#ifndef __cplusplus
# error This header requires C++ to be used. aiFileIO.h is the \
corresponding C interface.
#endif
-namespace Assimp {
+namespace Assimp {
// ----------------------------------------------------------------------------------
/** @brief CPP-API: Class to handle file I/O for C++
@@ -125,13 +129,13 @@ public:
}; //! class IOStream
// ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
IOStream::IOStream() AI_NO_EXCEPT {
// empty
}
// ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
IOStream::~IOStream() {
// empty
}
diff --git a/thirdparty/assimp/include/assimp/IOStreamBuffer.h b/thirdparty/assimp/include/assimp/IOStreamBuffer.h
index 58abd97a02..97c84b23e2 100644
--- a/thirdparty/assimp/include/assimp/IOStreamBuffer.h
+++ b/thirdparty/assimp/include/assimp/IOStreamBuffer.h
@@ -1,5 +1,3 @@
-#pragma once
-
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
@@ -42,10 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
+#pragma once
+#ifndef AI_IOSTREAMBUFFER_H_INC
+#define AI_IOSTREAMBUFFER_H_INC
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
#include <assimp/IOStream.hpp>
-
-#include "ParsingUtils.h"
+#include <assimp/ParsingUtils.h>
#include <vector>
@@ -124,7 +129,7 @@ private:
};
template<class T>
-inline
+AI_FORCE_INLINE
IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
: m_stream( nullptr )
, m_filesize( 0 )
@@ -138,13 +143,13 @@ IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
}
template<class T>
-inline
+AI_FORCE_INLINE
IOStreamBuffer<T>::~IOStreamBuffer() {
// empty
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::open( IOStream *stream ) {
// file still opened!
if ( nullptr != m_stream ) {
@@ -174,7 +179,7 @@ bool IOStreamBuffer<T>::open( IOStream *stream ) {
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::close() {
if ( nullptr == m_stream ) {
return false;
@@ -192,19 +197,19 @@ bool IOStreamBuffer<T>::close() {
}
template<class T>
-inline
+AI_FORCE_INLINE
size_t IOStreamBuffer<T>::size() const {
return m_filesize;
}
template<class T>
-inline
+AI_FORCE_INLINE
size_t IOStreamBuffer<T>::cacheSize() const {
return m_cacheSize;
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::readNextBlock() {
m_stream->Seek( m_filePos, aiOrigin_SET );
size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize );
@@ -222,25 +227,25 @@ bool IOStreamBuffer<T>::readNextBlock() {
}
template<class T>
-inline
+AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getNumBlocks() const {
return m_numBlocks;
}
template<class T>
-inline
+AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getCurrentBlockIndex() const {
return m_blockIdx;
}
template<class T>
-inline
+AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getFilePos() const {
return m_filePos;
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
buffer.resize( m_cacheSize );
if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) {
@@ -289,13 +294,13 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT
return true;
}
-static inline
+static AI_FORCE_INLINE
bool isEndOfCache( size_t pos, size_t cacheSize ) {
return ( pos == cacheSize );
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
buffer.resize(m_cacheSize);
if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) {
@@ -335,7 +340,7 @@ bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
// Return the last block-value if getNextLine was used before
if ( 0 != m_cachePos ) {
@@ -353,3 +358,5 @@ bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
}
} // !ns Assimp
+
+#endif // AI_IOSTREAMBUFFER_H_INC
diff --git a/thirdparty/assimp/include/assimp/IOSystem.hpp b/thirdparty/assimp/include/assimp/IOSystem.hpp
index 78139c2839..f1fb3b0c27 100644
--- a/thirdparty/assimp/include/assimp/IOSystem.hpp
+++ b/thirdparty/assimp/include/assimp/IOSystem.hpp
@@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IOSYSTEM_H_INC
#define AI_IOSYSTEM_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifndef __cplusplus
# error This header requires C++ to be used. aiFileIO.h is the \
corresponding C interface.
diff --git a/thirdparty/assimp/include/assimp/Importer.hpp b/thirdparty/assimp/include/assimp/Importer.hpp
index 4941df4122..bf449a9a25 100644
--- a/thirdparty/assimp/include/assimp/Importer.hpp
+++ b/thirdparty/assimp/include/assimp/Importer.hpp
@@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASSIMP_HPP_INC
#define AI_ASSIMP_HPP_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifndef __cplusplus
# error This header requires C++ to be used. Use assimp.h for plain C.
#endif // __cplusplus
diff --git a/thirdparty/assimp/include/assimp/LineSplitter.h b/thirdparty/assimp/include/assimp/LineSplitter.h
index 4afe45b92a..6c1097bb6d 100644
--- a/thirdparty/assimp/include/assimp/LineSplitter.h
+++ b/thirdparty/assimp/include/assimp/LineSplitter.h
@@ -48,9 +48,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_LINE_SPLITTER_H
#define INCLUDED_LINE_SPLITTER_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <stdexcept>
-#include "StreamReader.h"
-#include "ParsingUtils.h"
+#include <assimp/StreamReader.h>
+#include <assimp/ParsingUtils.h>
namespace Assimp {
@@ -140,7 +144,7 @@ private:
bool mSwallow, mSkip_empty_lines, mTrim;
};
-inline
+AI_FORCE_INLINE
LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim )
: mIdx(0)
, mCur()
@@ -153,12 +157,12 @@ LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool t
mIdx = 0;
}
-inline
+AI_FORCE_INLINE
LineSplitter::~LineSplitter() {
// empty
}
-inline
+AI_FORCE_INLINE
LineSplitter& LineSplitter::operator++() {
if (mSwallow) {
mSwallow = false;
@@ -199,12 +203,12 @@ LineSplitter& LineSplitter::operator++() {
return *this;
}
-inline
+AI_FORCE_INLINE
LineSplitter &LineSplitter::operator++(int) {
return ++(*this);
}
-inline
+AI_FORCE_INLINE
const char *LineSplitter::operator[] (size_t idx) const {
const char* s = operator->()->c_str();
@@ -222,7 +226,7 @@ const char *LineSplitter::operator[] (size_t idx) const {
}
template <size_t N>
-inline
+AI_FORCE_INLINE
void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
const char* s = operator->()->c_str();
@@ -238,44 +242,44 @@ void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
}
}
-inline
+AI_FORCE_INLINE
const std::string* LineSplitter::operator -> () const {
return &mCur;
}
-inline
+AI_FORCE_INLINE
std::string LineSplitter::operator* () const {
return mCur;
}
-inline
+AI_FORCE_INLINE
LineSplitter::operator bool() const {
return mStream.GetRemainingSize() > 0;
}
-inline
+AI_FORCE_INLINE
LineSplitter::operator line_idx() const {
return mIdx;
}
-inline
+AI_FORCE_INLINE
LineSplitter::line_idx LineSplitter::get_index() const {
return mIdx;
}
-inline
+AI_FORCE_INLINE
StreamReaderLE &LineSplitter::get_stream() {
return mStream;
}
-inline
+AI_FORCE_INLINE
bool LineSplitter::match_start(const char* check) {
const size_t len = ::strlen(check);
return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
}
-inline
+AI_FORCE_INLINE
void LineSplitter::swallow_next_increment() {
mSwallow = true;
}
diff --git a/thirdparty/assimp/include/assimp/LogAux.h b/thirdparty/assimp/include/assimp/LogAux.h
index 558485272e..bcead78dd3 100644
--- a/thirdparty/assimp/include/assimp/LogAux.h
+++ b/thirdparty/assimp/include/assimp/LogAux.h
@@ -43,9 +43,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file LogAux.h
* @brief Common logging usage patterns for importer implementations
*/
+#pragma once
#ifndef INCLUDED_AI_LOGAUX_H
#define INCLUDED_AI_LOGAUX_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/TinyFormatter.h>
#include <assimp/Exceptional.h>
#include <assimp/DefaultLogger.hpp>
diff --git a/thirdparty/assimp/include/assimp/Macros.h b/thirdparty/assimp/include/assimp/Macros.h
deleted file mode 100644
index 6515303372..0000000000
--- a/thirdparty/assimp/include/assimp/Macros.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-All rights reserved.
-
-Redistribution and use of this software 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 assimp team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the assimp team.
-
-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.
----------------------------------------------------------------------------
-*/
-
-/* Helper macro to set a pointer to NULL in debug builds
- */
-#if (defined ASSIMP_BUILD_DEBUG)
-# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
-#else
-# define AI_DEBUG_INVALIDATE_PTR(x)
-#endif
-
diff --git a/thirdparty/assimp/include/assimp/MathFunctions.h b/thirdparty/assimp/include/assimp/MathFunctions.h
index cb3b696076..b6c5872a72 100644
--- a/thirdparty/assimp/include/assimp/MathFunctions.h
+++ b/thirdparty/assimp/include/assimp/MathFunctions.h
@@ -39,22 +39,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
+#pragma once
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
/** @file MathFunctions.h
- * @brief Implementation of the math functions (gcd and lcm)
+* @brief Implementation of math utility functions.
*
- * Copied from BoostWorkaround/math
- */
+*/
+
+#include <limits>
namespace Assimp {
namespace Math {
// TODO: use binary GCD for unsigned integers ....
template < typename IntegerType >
-IntegerType gcd( IntegerType a, IntegerType b )
-{
+inline
+IntegerType gcd( IntegerType a, IntegerType b ) {
const IntegerType zero = (IntegerType)0;
- while ( true )
- {
+ while ( true ) {
if ( a == zero )
return b;
b %= a;
@@ -66,12 +72,19 @@ IntegerType gcd( IntegerType a, IntegerType b )
}
template < typename IntegerType >
-IntegerType lcm( IntegerType a, IntegerType b )
-{
+inline
+IntegerType lcm( IntegerType a, IntegerType b ) {
const IntegerType t = gcd (a,b);
- if (!t)return t;
+ if (!t)
+ return t;
return a / t * b;
}
+template<class T>
+inline
+T getEpsilon() {
+ return std::numeric_limits<T>::epsilon();
+}
+
}
}
diff --git a/thirdparty/assimp/include/assimp/MemoryIOWrapper.h b/thirdparty/assimp/include/assimp/MemoryIOWrapper.h
index c522787184..5598d4fc5f 100644
--- a/thirdparty/assimp/include/assimp/MemoryIOWrapper.h
+++ b/thirdparty/assimp/include/assimp/MemoryIOWrapper.h
@@ -42,12 +42,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file MemoryIOWrapper.h
* Handy IOStream/IOSystem implemetation to read directly from a memory buffer */
+#pragma once
#ifndef AI_MEMORYIOSTREAM_H_INC
#define AI_MEMORYIOSTREAM_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/ai_assert.h>
+
#include <stdint.h>
namespace Assimp {
diff --git a/thirdparty/assimp/include/assimp/ParsingUtils.h b/thirdparty/assimp/include/assimp/ParsingUtils.h
index 6b9574fc67..3025601246 100644
--- a/thirdparty/assimp/include/assimp/ParsingUtils.h
+++ b/thirdparty/assimp/include/assimp/ParsingUtils.h
@@ -44,11 +44,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file ParsingUtils.h
* @brief Defines helper functions for text parsing
*/
+#pragma once
#ifndef AI_PARSING_UTILS_H_INC
#define AI_PARSING_UTILS_H_INC
-#include "StringComparison.h"
-#include "StringUtils.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/StringComparison.h>
+#include <assimp/StringUtils.h>
#include <assimp/defs.h>
namespace Assimp {
diff --git a/thirdparty/assimp/include/assimp/Profiler.h b/thirdparty/assimp/include/assimp/Profiler.h
index 6ff9d41c0a..624029be99 100644
--- a/thirdparty/assimp/include/assimp/Profiler.h
+++ b/thirdparty/assimp/include/assimp/Profiler.h
@@ -43,12 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Profiler.h
* @brief Utility to measure the respective runtime of each import step
*/
-#ifndef INCLUDED_PROFILER_H
-#define INCLUDED_PROFILER_H
+#pragma once
+#ifndef AI_INCLUDED_PROFILER_H
+#define AI_INCLUDED_PROFILER_H
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
#include <chrono>
#include <assimp/DefaultLogger.hpp>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
#include <map>
@@ -67,7 +72,6 @@ public:
// empty
}
-public:
/** Start a named timer */
void BeginRegion(const std::string& region) {
@@ -95,5 +99,5 @@ private:
}
}
-#endif
+#endif // AI_INCLUDED_PROFILER_H
diff --git a/thirdparty/assimp/include/assimp/ProgressHandler.hpp b/thirdparty/assimp/include/assimp/ProgressHandler.hpp
index 4e47f1d0a6..8991a64618 100644
--- a/thirdparty/assimp/include/assimp/ProgressHandler.hpp
+++ b/thirdparty/assimp/include/assimp/ProgressHandler.hpp
@@ -47,9 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_PROGRESSHANDLER_H_INC
#define AI_PROGRESSHANDLER_H_INC
-#include "types.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
-namespace Assimp {
+namespace Assimp {
// ------------------------------------------------------------------------------------
/** @brief CPP-API: Abstract interface for custom progress report receivers.
diff --git a/thirdparty/assimp/include/assimp/RemoveComments.h b/thirdparty/assimp/include/assimp/RemoveComments.h
index 404b496719..f129420535 100644
--- a/thirdparty/assimp/include/assimp/RemoveComments.h
+++ b/thirdparty/assimp/include/assimp/RemoveComments.h
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -43,9 +42,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Declares a helper class, "CommentRemover", which can be
* used to remove comments (single and multi line) from a text file.
*/
+#pragma once
#ifndef AI_REMOVE_COMMENTS_H_INC
#define AI_REMOVE_COMMENTS_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
#include <assimp/defs.h>
@@ -58,8 +61,7 @@ namespace Assimp {
* to those in C or C++ so this code has been moved to a separate
* module.
*/
-class ASSIMP_API CommentRemover
-{
+class ASSIMP_API CommentRemover {
// class cannot be instanced
CommentRemover() {}
diff --git a/thirdparty/assimp/include/assimp/SGSpatialSort.h b/thirdparty/assimp/include/assimp/SGSpatialSort.h
index 5b4f3f41f2..fdb5ce8174 100644
--- a/thirdparty/assimp/include/assimp/SGSpatialSort.h
+++ b/thirdparty/assimp/include/assimp/SGSpatialSort.h
@@ -42,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** Small helper classes to optimize finding vertices close to a given location
*/
+#pragma once
#ifndef AI_D3DSSPATIALSORT_H_INC
#define AI_D3DSSPATIALSORT_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
#include <vector>
#include <stdint.h>
diff --git a/thirdparty/assimp/include/assimp/SceneCombiner.h b/thirdparty/assimp/include/assimp/SceneCombiner.h
index 679a2acea4..0683c1e052 100644
--- a/thirdparty/assimp/include/assimp/SceneCombiner.h
+++ b/thirdparty/assimp/include/assimp/SceneCombiner.h
@@ -43,17 +43,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Declares a helper class, "SceneCombiner" providing various
* utilities to merge scenes.
*/
+#pragma once
#ifndef AI_SCENE_COMBINER_H_INC
#define AI_SCENE_COMBINER_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/ai_assert.h>
#include <assimp/types.h>
#include <assimp/Defines.h>
+
#include <stddef.h>
#include <set>
#include <list>
#include <stdint.h>
-
#include <vector>
struct aiScene;
@@ -65,8 +70,10 @@ struct aiLight;
struct aiMetadata;
struct aiBone;
struct aiMesh;
+struct aiAnimMesh;
struct aiAnimation;
struct aiNodeAnim;
+struct aiMeshMorphAnim;
namespace Assimp {
@@ -363,6 +370,7 @@ public:
static void Copy (aiMesh** dest, const aiMesh* src);
// similar to Copy():
+ static void Copy (aiAnimMesh** dest, const aiAnimMesh* src);
static void Copy (aiMaterial** dest, const aiMaterial* src);
static void Copy (aiTexture** dest, const aiTexture* src);
static void Copy (aiAnimation** dest, const aiAnimation* src);
@@ -370,6 +378,7 @@ public:
static void Copy (aiBone** dest, const aiBone* src);
static void Copy (aiLight** dest, const aiLight* src);
static void Copy (aiNodeAnim** dest, const aiNodeAnim* src);
+ static void Copy (aiMeshMorphAnim** dest, const aiMeshMorphAnim* src);
static void Copy (aiMetadata** dest, const aiMetadata* src);
// recursive, of course
diff --git a/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h b/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h
index f9b8d9f55c..ad979a33fa 100644
--- a/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h
+++ b/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h
@@ -47,9 +47,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* for animation skeletons.
*/
+#pragma once
#ifndef AI_SKELETONMESHBUILDER_H_INC
#define AI_SKELETONMESHBUILDER_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <vector>
#include <assimp/mesh.h>
diff --git a/thirdparty/assimp/include/assimp/SmoothingGroups.h b/thirdparty/assimp/include/assimp/SmoothingGroups.h
index 92d65cea02..c1a93947f1 100644
--- a/thirdparty/assimp/include/assimp/SmoothingGroups.h
+++ b/thirdparty/assimp/include/assimp/SmoothingGroups.h
@@ -43,10 +43,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines the helper data structures for importing 3DS files.
http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */
+#pragma once
#ifndef AI_SMOOTHINGGROUPS_H_INC
#define AI_SMOOTHINGGROUPS_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/vector3.h>
+
#include <stdint.h>
#include <vector>
diff --git a/thirdparty/assimp/include/assimp/SmoothingGroups.inl b/thirdparty/assimp/include/assimp/SmoothingGroups.inl
index 84ea4a1b00..37ea083dbe 100644
--- a/thirdparty/assimp/include/assimp/SmoothingGroups.inl
+++ b/thirdparty/assimp/include/assimp/SmoothingGroups.inl
@@ -41,13 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Generation of normal vectors basing on smoothing groups */
+#pragma once
#ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED
#define AI_SMOOTHINGGROUPS_INL_INCLUDED
-// internal headers
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/SGSpatialSort.h>
-// CRT header
#include <algorithm>
using namespace Assimp;
diff --git a/thirdparty/assimp/include/assimp/SpatialSort.h b/thirdparty/assimp/include/assimp/SpatialSort.h
index 61b345bcbf..9f93543150 100644
--- a/thirdparty/assimp/include/assimp/SpatialSort.h
+++ b/thirdparty/assimp/include/assimp/SpatialSort.h
@@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** Small helper classes to optimise finding vertizes close to a given location */
+#pragma once
#ifndef AI_SPATIALSORT_H_INC
#define AI_SPATIALSORT_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <vector>
#include <assimp/types.h>
diff --git a/thirdparty/assimp/include/assimp/StandardShapes.h b/thirdparty/assimp/include/assimp/StandardShapes.h
index 3791569b83..c594cb63f4 100644
--- a/thirdparty/assimp/include/assimp/StandardShapes.h
+++ b/thirdparty/assimp/include/assimp/StandardShapes.h
@@ -41,11 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Declares a helper class, "StandardShapes" which generates
- * vertices for standard shapes, such as cylnders, cones, spheres ..
+ * vertices for standard shapes, such as cylinders, cones, spheres ..
*/
+#pragma once
#ifndef AI_STANDARD_SHAPES_H_INC
#define AI_STANDARD_SHAPES_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/vector3.h>
#include <vector>
diff --git a/thirdparty/assimp/include/assimp/StreamReader.h b/thirdparty/assimp/include/assimp/StreamReader.h
index 9116c14261..cb24f1595b 100644
--- a/thirdparty/assimp/include/assimp/StreamReader.h
+++ b/thirdparty/assimp/include/assimp/StreamReader.h
@@ -44,15 +44,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines the StreamReader class which reads data from
* a binary stream with a well-defined endianness.
*/
-
+#pragma once
#ifndef AI_STREAMREADER_H_INCLUDED
#define AI_STREAMREADER_H_INCLUDED
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/IOStream.hpp>
#include <assimp/Defines.h>
+#include <assimp/ByteSwapper.h>
+#include <assimp/Exceptional.h>
-#include "ByteSwapper.h"
-#include "Exceptional.h"
#include <memory>
namespace Assimp {
diff --git a/thirdparty/assimp/include/assimp/StreamWriter.h b/thirdparty/assimp/include/assimp/StreamWriter.h
index c7cf6c0d74..489e8adfe3 100644
--- a/thirdparty/assimp/include/assimp/StreamWriter.h
+++ b/thirdparty/assimp/include/assimp/StreamWriter.h
@@ -43,11 +43,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines the StreamWriter class which writes data to
* a binary stream with a well-defined endianness. */
-
+#pragma once
#ifndef AI_STREAMWRITER_H_INCLUDED
#define AI_STREAMWRITER_H_INCLUDED
-#include "ByteSwapper.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/ByteSwapper.h>
#include <assimp/IOStream.hpp>
#include <memory>
diff --git a/thirdparty/assimp/include/assimp/StringComparison.h b/thirdparty/assimp/include/assimp/StringComparison.h
index 8acef277b9..d3ca3e9714 100644
--- a/thirdparty/assimp/include/assimp/StringComparison.h
+++ b/thirdparty/assimp/include/assimp/StringComparison.h
@@ -49,12 +49,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
These functions are not consistently available on all platforms,
or the provided implementations behave too differently.
*/
+#pragma once
#ifndef INCLUDED_AI_STRING_WORKERS_H
#define INCLUDED_AI_STRING_WORKERS_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/ai_assert.h>
#include <assimp/defs.h>
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
#include <string.h>
#include <stdint.h>
diff --git a/thirdparty/assimp/include/assimp/StringUtils.h b/thirdparty/assimp/include/assimp/StringUtils.h
index d68b7fa479..af481f819e 100644
--- a/thirdparty/assimp/include/assimp/StringUtils.h
+++ b/thirdparty/assimp/include/assimp/StringUtils.h
@@ -39,9 +39,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
+#pragma once
#ifndef INCLUDED_AI_STRINGUTILS_H
#define INCLUDED_AI_STRINGUTILS_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/defs.h>
#include <sstream>
diff --git a/thirdparty/assimp/include/assimp/Subdivision.h b/thirdparty/assimp/include/assimp/Subdivision.h
index 43feb73b30..e9450267ec 100644
--- a/thirdparty/assimp/include/assimp/Subdivision.h
+++ b/thirdparty/assimp/include/assimp/Subdivision.h
@@ -45,7 +45,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_SUBDISIVION_H_INC
#define AI_SUBDISIVION_H_INC
-#include <cstddef>
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
struct aiMesh;
diff --git a/thirdparty/assimp/include/assimp/TinyFormatter.h b/thirdparty/assimp/include/assimp/TinyFormatter.h
index 1226b482e6..6227e42c52 100644
--- a/thirdparty/assimp/include/assimp/TinyFormatter.h
+++ b/thirdparty/assimp/include/assimp/TinyFormatter.h
@@ -45,9 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* to get rid of the boost::format dependency. Much slinker,
* basically just extends stringstream.
*/
+#pragma once
#ifndef INCLUDED_TINY_FORMATTER_H
#define INCLUDED_TINY_FORMATTER_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <sstream>
namespace Assimp {
@@ -65,24 +70,15 @@ namespace Formatter {
* @endcode */
template < typename T,
typename CharTraits = std::char_traits<T>,
- typename Allocator = std::allocator<T>
->
-class basic_formatter
-{
-
-public:
-
- typedef class std::basic_string<
- T,CharTraits,Allocator
- > string;
-
- typedef class std::basic_ostringstream<
- T,CharTraits,Allocator
- > stringstream;
-
+ typename Allocator = std::allocator<T> >
+class basic_formatter {
public:
+ typedef class std::basic_string<T,CharTraits,Allocator> string;
+ typedef class std::basic_ostringstream<T,CharTraits,Allocator> stringstream;
- basic_formatter() {}
+ basic_formatter() {
+ // empty
+ }
/* Allow basic_formatter<T>'s to be used almost interchangeably
* with std::(w)string or const (w)char* arguments because the
@@ -104,14 +100,10 @@ public:
}
#endif
-
-public:
-
operator string () const {
return underlying.str();
}
-
/* note - this is declared const because binding temporaries does only
* work for const references, so many function prototypes will
* include const basic_formatter<T>& s but might still want to
diff --git a/thirdparty/assimp/include/assimp/Vertex.h b/thirdparty/assimp/include/assimp/Vertex.h
index 2a7f0256ad..5e63db5fe4 100644
--- a/thirdparty/assimp/include/assimp/Vertex.h
+++ b/thirdparty/assimp/include/assimp/Vertex.h
@@ -47,12 +47,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
that are not currently well-defined (and would cause compile errors
due to missing operators in the math library), are commented.
*/
+#pragma once
#ifndef AI_VERTEX_H_INC
#define AI_VERTEX_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/vector3.h>
#include <assimp/mesh.h>
#include <assimp/ai_assert.h>
+
#include <functional>
namespace Assimp {
@@ -91,23 +97,14 @@ namespace Assimp {
* to *all* vertex components equally. This is useful for stuff like interpolation
* or subdivision, but won't work if special handling is required for some vertex components. */
// ------------------------------------------------------------------------------------------------
-class Vertex
-{
+class Vertex {
friend Vertex operator + (const Vertex&,const Vertex&);
friend Vertex operator - (const Vertex&,const Vertex&);
-
-// friend Vertex operator + (const Vertex&,ai_real);
-// friend Vertex operator - (const Vertex&,ai_real);
friend Vertex operator * (const Vertex&,ai_real);
friend Vertex operator / (const Vertex&,ai_real);
-
-// friend Vertex operator + (ai_real, const Vertex&);
-// friend Vertex operator - (ai_real, const Vertex&);
friend Vertex operator * (ai_real, const Vertex&);
-// friend Vertex operator / (ai_real, const Vertex&);
public:
-
Vertex() {}
// ----------------------------------------------------------------------------
@@ -158,8 +155,6 @@ public:
}
}
-public:
-
Vertex& operator += (const Vertex& v) {
*this = *this+v;
return *this;
@@ -170,18 +165,6 @@ public:
return *this;
}
-
-/*
- Vertex& operator += (ai_real v) {
- *this = *this+v;
- return *this;
- }
-
- Vertex& operator -= (ai_real v) {
- *this = *this-v;
- return *this;
- }
-*/
Vertex& operator *= (ai_real v) {
*this = *this*v;
return *this;
@@ -192,12 +175,9 @@ public:
return *this;
}
-public:
-
// ----------------------------------------------------------------------------
/** Convert back to non-interleaved storage */
void SortBack(aiMesh* out, unsigned int idx) const {
-
ai_assert(idx<out->mNumVertices);
out->mVertices[idx] = position;
@@ -291,8 +271,6 @@ public:
aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
};
-
-
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE Vertex operator + (const Vertex& v0,const Vertex& v1) {
return Vertex::BinaryOp<std::plus>(v0,v1);
@@ -302,19 +280,6 @@ AI_FORCE_INLINE Vertex operator - (const Vertex& v0,const Vertex& v1) {
return Vertex::BinaryOp<std::minus>(v0,v1);
}
-
-// ------------------------------------------------------------------------------------------------
-/*
-AI_FORCE_INLINE Vertex operator + (const Vertex& v0,ai_real f) {
- return Vertex::BinaryOp<Intern::plus>(v0,f);
-}
-
-AI_FORCE_INLINE Vertex operator - (const Vertex& v0,ai_real f) {
- return Vertex::BinaryOp<Intern::minus>(v0,f);
-}
-
-*/
-
AI_FORCE_INLINE Vertex operator * (const Vertex& v0,ai_real f) {
return Vertex::BinaryOp<Intern::multiplies>(v0,f);
}
@@ -323,26 +288,10 @@ AI_FORCE_INLINE Vertex operator / (const Vertex& v0,ai_real f) {
return Vertex::BinaryOp<Intern::multiplies>(v0,1.f/f);
}
-// ------------------------------------------------------------------------------------------------
-/*
-AI_FORCE_INLINE Vertex operator + (ai_real f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::plus>(f,v0);
-}
-
-AI_FORCE_INLINE Vertex operator - (ai_real f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::minus>(f,v0);
-}
-*/
-
AI_FORCE_INLINE Vertex operator * (ai_real f,const Vertex& v0) {
return Vertex::BinaryOp<Intern::multiplies>(f,v0);
}
-/*
-AI_FORCE_INLINE Vertex operator / (ai_real f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::divides>(f,v0);
}
-*/
-}
-#endif
+#endif // AI_VERTEX_H_INC
diff --git a/thirdparty/assimp/include/assimp/XMLTools.h b/thirdparty/assimp/include/assimp/XMLTools.h
index b0d3276873..95f12cdebf 100644
--- a/thirdparty/assimp/include/assimp/XMLTools.h
+++ b/thirdparty/assimp/include/assimp/XMLTools.h
@@ -40,9 +40,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
+#pragma once
#ifndef INCLUDED_ASSIMP_XML_TOOLS_H
#define INCLUDED_ASSIMP_XML_TOOLS_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <string>
namespace Assimp {
diff --git a/thirdparty/assimp/include/assimp/aabb.h b/thirdparty/assimp/include/assimp/aabb.h
index a20f317424..83bb62256b 100644
--- a/thirdparty/assimp/include/assimp/aabb.h
+++ b/thirdparty/assimp/include/assimp/aabb.h
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -45,6 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_AABB_H_INC
#define AI_AABB_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/vector3.h>
struct aiAABB {
@@ -69,8 +71,9 @@ struct aiAABB {
// empty
}
-#endif
+#endif // __cplusplus
+
};
-#endif
+#endif // AI_AABB_H_INC
diff --git a/thirdparty/assimp/include/assimp/ai_assert.h b/thirdparty/assimp/include/assimp/ai_assert.h
index e5de5d3f36..2b32b01d3e 100644
--- a/thirdparty/assimp/include/assimp/ai_assert.h
+++ b/thirdparty/assimp/include/assimp/ai_assert.h
@@ -44,6 +44,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASSERT_H_INC
#define AI_ASSERT_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef ASSIMP_BUILD_DEBUG
# include <assert.h>
# define ai_assert(expression) assert( expression )
diff --git a/thirdparty/assimp/include/assimp/anim.h b/thirdparty/assimp/include/assimp/anim.h
index 02e92739ec..e208b11adb 100644
--- a/thirdparty/assimp/include/assimp/anim.h
+++ b/thirdparty/assimp/include/assimp/anim.h
@@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ANIM_H_INC
#define AI_ANIM_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
#include <assimp/quaternion.h>
diff --git a/thirdparty/assimp/include/assimp/camera.h b/thirdparty/assimp/include/assimp/camera.h
index e573eea5d1..adb749ff59 100644
--- a/thirdparty/assimp/include/assimp/camera.h
+++ b/thirdparty/assimp/include/assimp/camera.h
@@ -47,6 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_CAMERA_H_INC
#define AI_CAMERA_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include "types.h"
#ifdef __cplusplus
@@ -113,7 +117,6 @@ struct aiCamera
*/
C_STRUCT aiVector3D mPosition;
-
/** 'Up' - vector of the camera coordinate system relative to
* the coordinate space defined by the corresponding node.
*
@@ -134,7 +137,6 @@ struct aiCamera
*/
C_STRUCT aiVector3D mLookAt;
-
/** Half horizontal field of view angle, in radians.
*
* The field of view angle is the angle between the center
diff --git a/thirdparty/assimp/include/assimp/cexport.h b/thirdparty/assimp/include/assimp/cexport.h
index 1d62dc26b3..cbc0253d50 100644
--- a/thirdparty/assimp/include/assimp/cexport.h
+++ b/thirdparty/assimp/include/assimp/cexport.h
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2011, assimp team
+Copyright (c) 2006-2019, assimp team
All rights reserved.
@@ -46,6 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_EXPORT_H_INC
#define AI_EXPORT_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifndef ASSIMP_BUILD_NO_EXPORT
// Public ASSIMP data structures
diff --git a/thirdparty/assimp/include/assimp/cfileio.h b/thirdparty/assimp/include/assimp/cfileio.h
index 8f7ca45469..be90999d87 100644
--- a/thirdparty/assimp/include/assimp/cfileio.h
+++ b/thirdparty/assimp/include/assimp/cfileio.h
@@ -48,10 +48,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FILEIO_H_INC
#define AI_FILEIO_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
+
#ifdef __cplusplus
extern "C" {
#endif
+
struct aiFileIO;
struct aiFile;
diff --git a/thirdparty/assimp/include/assimp/cimport.h b/thirdparty/assimp/include/assimp/cimport.h
index dbd10f1370..66b1c9a174 100644
--- a/thirdparty/assimp/include/assimp/cimport.h
+++ b/thirdparty/assimp/include/assimp/cimport.h
@@ -48,8 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASSIMP_H_INC
#define AI_ASSIMP_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
-#include "importerdesc.h"
+#include <assimp/importerdesc.h>
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/assimp/include/assimp/color4.h b/thirdparty/assimp/include/assimp/color4.h
index 3c97c8eda2..fa86128f4f 100644
--- a/thirdparty/assimp/include/assimp/color4.h
+++ b/thirdparty/assimp/include/assimp/color4.h
@@ -47,7 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_COLOR4D_H_INC
#define AI_COLOR4D_H_INC
-#include "defs.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/defs.h>
#ifdef __cplusplus
@@ -56,8 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* alpha component. Color values range from 0 to 1. */
// ----------------------------------------------------------------------------------
template <typename TReal>
-class aiColor4t
-{
+class aiColor4t {
public:
aiColor4t() AI_NO_EXCEPT : r(), g(), b(), a() {}
aiColor4t (TReal _r, TReal _g, TReal _b, TReal _a)
@@ -65,14 +68,12 @@ public:
explicit aiColor4t (TReal _r) : r(_r), g(_r), b(_r), a(_r) {}
aiColor4t (const aiColor4t& o) = default;
-public:
// combined operators
const aiColor4t& operator += (const aiColor4t& o);
const aiColor4t& operator -= (const aiColor4t& o);
const aiColor4t& operator *= (TReal f);
const aiColor4t& operator /= (TReal f);
-public:
// comparison
bool operator == (const aiColor4t& other) const;
bool operator != (const aiColor4t& other) const;
@@ -85,8 +86,6 @@ public:
/** check whether a color is (close to) black */
inline bool IsBlack() const;
-public:
-
// Red, green, blue and alpha color values
TReal r, g, b, a;
}; // !struct aiColor4D
diff --git a/thirdparty/assimp/include/assimp/color4.inl b/thirdparty/assimp/include/assimp/color4.inl
index afa53dcb5b..d4a2a98109 100644
--- a/thirdparty/assimp/include/assimp/color4.inl
+++ b/thirdparty/assimp/include/assimp/color4.inl
@@ -48,36 +48,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_COLOR4D_INL_INC
#define AI_COLOR4D_INL_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
-#include "color4.h"
+#include <assimp/color4.h>
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator += (const aiColor4t<TReal>& o) {
- r += o.r; g += o.g; b += o.b; a += o.a;
+AI_FORCE_INLINE
+const aiColor4t<TReal>& aiColor4t<TReal>::operator += (const aiColor4t<TReal>& o) {
+ r += o.r;
+ g += o.g;
+ b += o.b;
+ a += o.a;
+
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator -= (const aiColor4t<TReal>& o) {
- r -= o.r; g -= o.g; b -= o.b; a -= o.a;
+AI_FORCE_INLINE
+const aiColor4t<TReal>& aiColor4t<TReal>::operator -= (const aiColor4t<TReal>& o) {
+ r -= o.r;
+ g -= o.g;
+ b -= o.b;
+ a -= o.a;
+
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator *= (TReal f) {
- r *= f; g *= f; b *= f; a *= f;
+AI_FORCE_INLINE
+const aiColor4t<TReal>& aiColor4t<TReal>::operator *= (TReal f) {
+ r *= f;
+ g *= f;
+ b *= f;
+ a *= f;
+
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f) {
- r /= f; g /= f; b /= f; a /= f;
+AI_FORCE_INLINE
+const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f) {
+ r /= f;
+ g /= f;
+ b /= f;
+ a /= f;
+
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
+AI_FORCE_INLINE
+TReal aiColor4t<TReal>::operator[](unsigned int i) const {
switch ( i ) {
case 0:
return r;
@@ -94,7 +119,8 @@ AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
+AI_FORCE_INLINE
+TReal& aiColor4t<TReal>::operator[](unsigned int i) {
switch ( i ) {
case 0:
return r;
@@ -111,17 +137,20 @@ AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const {
+AI_FORCE_INLINE
+bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const {
return r == other.r && g == other.g && b == other.b && a == other.a;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other) const {
+AI_FORCE_INLINE
+bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other) const {
return r != other.r || g != other.g || b != other.b || a != other.a;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) const {
+AI_FORCE_INLINE
+bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) const {
return r < other.r || (
r == other.r && (
g < other.g || (
@@ -136,14 +165,17 @@ AI_FORCE_INLINE bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other)
)
);
}
+
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator - (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator - (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r - v2.r, v1.g - v2.g, v1.b - v2.b, v1.a - v2.a);
}
// ------------------------------------------------------------------------------------------------
@@ -153,53 +185,63 @@ AI_FORCE_INLINE aiColor4t<TReal> operator * (const aiColor4t<TReal>& v1, const a
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator / (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator / (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r / v2.r, v1.g / v2.g, v1.b / v2.b, v1.a / v2.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator * ( TReal f, const aiColor4t<TReal>& v) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator * ( TReal f, const aiColor4t<TReal>& v) {
return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator * ( const aiColor4t<TReal>& v, TReal f) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator * ( const aiColor4t<TReal>& v, TReal f) {
return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator / ( const aiColor4t<TReal>& v, TReal f) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator / ( const aiColor4t<TReal>& v, TReal f) {
return v * (1/f);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator / ( TReal f,const aiColor4t<TReal>& v) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator / ( TReal f,const aiColor4t<TReal>& v) {
return aiColor4t<TReal>(f,f,f,f)/v;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator + ( const aiColor4t<TReal>& v, TReal f) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator + ( const aiColor4t<TReal>& v, TReal f) {
return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator - ( const aiColor4t<TReal>& v, TReal f) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator - ( const aiColor4t<TReal>& v, TReal f) {
return aiColor4t<TReal>( v.r-f, v.g-f, v.b-f, v.a-f);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator + ( TReal f, const aiColor4t<TReal>& v) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator + ( TReal f, const aiColor4t<TReal>& v) {
return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator - ( TReal f, const aiColor4t<TReal>& v) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator - ( TReal f, const aiColor4t<TReal>& v) {
return aiColor4t<TReal>( f-v.r, f-v.g, f-v.b, f-v.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiColor4t<TReal> :: IsBlack() const {
+AI_FORCE_INLINE
+bool aiColor4t<TReal>::IsBlack() const {
// The alpha component doesn't care here. black is black.
static const TReal epsilon = 10e-3f;
return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon;
diff --git a/thirdparty/assimp/include/assimp/defs.h b/thirdparty/assimp/include/assimp/defs.h
index 05a5e3fd4b..6f2f8ae88b 100644
--- a/thirdparty/assimp/include/assimp/defs.h
+++ b/thirdparty/assimp/include/assimp/defs.h
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -50,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_DEFINES_H_INC
#define AI_DEFINES_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/config.h>
//////////////////////////////////////////////////////////////////////////
@@ -126,16 +128,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* GENBOUNDINGBOXES */
//////////////////////////////////////////////////////////////////////////
-#ifdef _MSC_VER
+#ifdef _WIN32
# undef ASSIMP_API
-
//////////////////////////////////////////////////////////////////////////
/* Define 'ASSIMP_BUILD_DLL_EXPORT' to build a DLL of the library */
//////////////////////////////////////////////////////////////////////////
# ifdef ASSIMP_BUILD_DLL_EXPORT
# define ASSIMP_API __declspec(dllexport)
# define ASSIMP_API_WINONLY __declspec(dllexport)
-# pragma warning (disable : 4251)
//////////////////////////////////////////////////////////////////////////
/* Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in
@@ -148,7 +148,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# define ASSIMP_API
# define ASSIMP_API_WINONLY
# endif
+#elif defined(SWIG)
+
+ /* Do nothing, the relevant defines are all in AssimpSwigPort.i */
+#else
+# define ASSIMP_API __attribute__ ((visibility("default")))
+# define ASSIMP_API_WINONLY
+#endif
+
+#ifdef _MSC_VER
+# ifdef ASSIMP_BUILD_DLL_EXPORT
+# pragma warning (disable : 4251)
+# endif
/* Force the compiler to inline a function, if possible
*/
# define AI_FORCE_INLINE __forceinline
@@ -156,17 +168,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/* Tells the compiler that a function never returns. Used in code analysis
* to skip dead paths (e.g. after an assertion evaluated to false). */
# define AI_WONT_RETURN __declspec(noreturn)
-
#elif defined(SWIG)
/* Do nothing, the relevant defines are all in AssimpSwigPort.i */
#else
-
# define AI_WONT_RETURN
-
-# define ASSIMP_API __attribute__ ((visibility("default")))
-# define ASSIMP_API_WINONLY
# define AI_FORCE_INLINE inline
#endif // (defined _MSC_VER)
@@ -291,9 +298,10 @@ static const ai_real ai_epsilon = (ai_real) 0.00001;
#endif
-/* To avoid running out of memory
- * This can be adjusted for specific use cases
- * It's NOT a total limit, just a limit for individual allocations
+/**
+ * To avoid running out of memory
+ * This can be adjusted for specific use cases
+ * It's NOT a total limit, just a limit for individual allocations
*/
#define AI_MAX_ALLOC(type) ((256U * 1024 * 1024) / sizeof(type))
@@ -307,4 +315,13 @@ static const ai_real ai_epsilon = (ai_real) 0.00001;
# endif
#endif // _MSC_VER
+/**
+ * Helper macro to set a pointer to NULL in debug builds
+ */
+#if (defined ASSIMP_BUILD_DEBUG)
+# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
+#else
+# define AI_DEBUG_INVALIDATE_PTR(x)
+#endif
+
#endif // !! AI_DEFINES_H_INC
diff --git a/thirdparty/assimp/include/assimp/fast_atof.h b/thirdparty/assimp/include/assimp/fast_atof.h
index 62ea969e97..6e9a1bba7a 100644
--- a/thirdparty/assimp/include/assimp/fast_atof.h
+++ b/thirdparty/assimp/include/assimp/fast_atof.h
@@ -13,10 +13,14 @@
// to ensure long numbers are handled correctly
// ------------------------------------------------------------------------------------
-
+#pragma once
#ifndef FAST_A_TO_F_H_INCLUDED
#define FAST_A_TO_F_H_INCLUDED
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <cmath>
#include <limits>
#include <stdint.h>
diff --git a/thirdparty/assimp/include/assimp/importerdesc.h b/thirdparty/assimp/include/assimp/importerdesc.h
index 36e387f011..0a6919c1ae 100644
--- a/thirdparty/assimp/include/assimp/importerdesc.h
+++ b/thirdparty/assimp/include/assimp/importerdesc.h
@@ -48,11 +48,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IMPORTER_DESC_H_INC
#define AI_IMPORTER_DESC_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
/** Mixed set of flags for #aiImporterDesc, indicating some features
* common to many importers*/
-enum aiImporterFlags
-{
+enum aiImporterFlags {
/** Indicates that there is a textual encoding of the
* file format; and that it is supported.*/
aiImporterFlags_SupportTextFlavour = 0x1,
@@ -87,8 +90,7 @@ enum aiImporterFlags
* as importers/exporters are added to Assimp, so it might be useful
* to have a common mechanism to query some rough importer
* characteristics. */
-struct aiImporterDesc
-{
+struct aiImporterDesc {
/** Full name of the importer (i.e. Blender3D importer)*/
const char* mName;
diff --git a/thirdparty/assimp/include/assimp/light.h b/thirdparty/assimp/include/assimp/light.h
index 1667cfb8c1..bdb2368c4f 100644
--- a/thirdparty/assimp/include/assimp/light.h
+++ b/thirdparty/assimp/include/assimp/light.h
@@ -49,7 +49,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_LIGHT_H_INC
#define AI_LIGHT_H_INC
-#include "types.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/assimp/include/assimp/material.h b/thirdparty/assimp/include/assimp/material.h
index 206eb2a2b0..19a7c69709 100644
--- a/thirdparty/assimp/include/assimp/material.h
+++ b/thirdparty/assimp/include/assimp/material.h
@@ -48,7 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATERIAL_H_INC
#define AI_MATERIAL_H_INC
-#include "types.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/assimp/include/assimp/material.inl b/thirdparty/assimp/include/assimp/material.inl
index b05d6af6c3..8ae6b88d3e 100644
--- a/thirdparty/assimp/include/assimp/material.inl
+++ b/thirdparty/assimp/include/assimp/material.inl
@@ -49,14 +49,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATERIAL_INL_INC
#define AI_MATERIAL_INL_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
// ---------------------------------------------------------------------------
-inline aiPropertyTypeInfo ai_real_to_property_type_info(float)
-{
+AI_FORCE_INLINE
+aiPropertyTypeInfo ai_real_to_property_type_info(float) {
return aiPTI_Float;
}
-inline aiPropertyTypeInfo ai_real_to_property_type_info(double)
-{
+AI_FORCE_INLINE
+aiPropertyTypeInfo ai_real_to_property_type_info(double) {
return aiPTI_Double;
}
// ---------------------------------------------------------------------------
@@ -64,30 +68,30 @@ inline aiPropertyTypeInfo ai_real_to_property_type_info(double)
//! @cond never
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::GetTexture( aiTextureType type,
- unsigned int index,
- C_STRUCT aiString* path,
- aiTextureMapping* mapping /*= NULL*/,
- unsigned int* uvindex /*= NULL*/,
- ai_real* blend /*= NULL*/,
- aiTextureOp* op /*= NULL*/,
- aiTextureMapMode* mapmode /*= NULL*/) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::GetTexture( aiTextureType type,
+ unsigned int index,
+ C_STRUCT aiString* path,
+ aiTextureMapping* mapping /*= NULL*/,
+ unsigned int* uvindex /*= NULL*/,
+ ai_real* blend /*= NULL*/,
+ aiTextureOp* op /*= NULL*/,
+ aiTextureMapMode* mapmode /*= NULL*/) const {
return ::aiGetMaterialTexture(this,type,index,path,mapping,uvindex,blend,op,mapmode);
}
// ---------------------------------------------------------------------------
-inline unsigned int aiMaterial::GetTextureCount(aiTextureType type) const
-{
+AI_FORCE_INLINE
+unsigned int aiMaterial::GetTextureCount(aiTextureType type) const {
return ::aiGetMaterialTextureCount(this,type);
}
// ---------------------------------------------------------------------------
template <typename Type>
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx, Type* pOut,
- unsigned int* pMax) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx, Type* pOut,
+ unsigned int* pMax) const {
unsigned int iNum = pMax ? *pMax : 1;
const aiMaterialProperty* prop;
@@ -114,9 +118,9 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
// ---------------------------------------------------------------------------
template <typename Type>
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,Type& pOut) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,Type& pOut) const {
const aiMaterialProperty* prop;
const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,
(const aiMaterialProperty**)&prop);
@@ -136,60 +140,56 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,ai_real* pOut,
- unsigned int* pMax) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,ai_real* pOut,
+ unsigned int* pMax) const {
return ::aiGetMaterialFloatArray(this,pKey,type,idx,pOut,pMax);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,int* pOut,
- unsigned int* pMax) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,int* pOut,
+ unsigned int* pMax) const {
return ::aiGetMaterialIntegerArray(this,pKey,type,idx,pOut,pMax);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,ai_real& pOut) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,ai_real& pOut) const {
return aiGetMaterialFloat(this,pKey,type,idx,&pOut);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,int& pOut) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,int& pOut) const {
return aiGetMaterialInteger(this,pKey,type,idx,&pOut);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,aiColor4D& pOut) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,aiColor4D& pOut) const {
return aiGetMaterialColor(this,pKey,type,idx,&pOut);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,aiColor3D& pOut) const
-{
+AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,aiColor3D& pOut) const {
aiColor4D c;
const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c);
pOut = aiColor3D(c.r,c.g,c.b);
return ret;
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,aiString& pOut) const
-{
+AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,aiString& pOut) const {
return aiGetMaterialString(this,pKey,type,idx,&pOut);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,aiUVTransform& pOut) const
-{
+AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,aiUVTransform& pOut) const {
return aiGetMaterialUVTransform(this,pKey,type,idx,&pOut);
}
-
// ---------------------------------------------------------------------------
template<class TYPE>
aiReturn aiMaterial::AddProperty (const TYPE* pInput,
@@ -204,84 +204,83 @@ aiReturn aiMaterial::AddProperty (const TYPE* pInput,
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const float* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE aiReturn aiMaterial::AddProperty(const float* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(float),
pKey,type,index,aiPTI_Float);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const double* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const double* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(double),
pKey,type,index,aiPTI_Double);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiUVTransform),
pKey,type,index,ai_real_to_property_type_info(pInput->mRotation));
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiColor4D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const aiColor4D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor4D),
pKey,type,index,ai_real_to_property_type_info(pInput->a));
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiColor3D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const aiColor3D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor3D),
pKey,type,index,ai_real_to_property_type_info(pInput->b));
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiVector3D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const aiVector3D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiVector3D),
pKey,type,index,ai_real_to_property_type_info(pInput->x));
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const int* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const int* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(int),
pKey,type,index,aiPTI_Integer);
@@ -296,12 +295,12 @@ inline aiReturn aiMaterial::AddProperty(const int* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<float>(const float* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<float>(const float* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(float),
pKey,type,index,aiPTI_Float);
@@ -309,12 +308,12 @@ inline aiReturn aiMaterial::AddProperty<float>(const float* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<double>(const double* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<double>(const double* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(double),
pKey,type,index,aiPTI_Double);
@@ -322,12 +321,12 @@ inline aiReturn aiMaterial::AddProperty<double>(const double* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiUVTransform),
pKey,type,index,aiPTI_Float);
@@ -335,12 +334,12 @@ inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInp
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor4D),
pKey,type,index,aiPTI_Float);
@@ -348,12 +347,12 @@ inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor3D),
pKey,type,index,aiPTI_Float);
@@ -361,12 +360,12 @@ inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiVector3D),
pKey,type,index,aiPTI_Float);
@@ -374,12 +373,12 @@ inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<int>(const int* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<int>(const int* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(int),
pKey,type,index,aiPTI_Integer);
diff --git a/thirdparty/assimp/include/assimp/matrix3x3.h b/thirdparty/assimp/include/assimp/matrix3x3.h
index 22b69561ff..2c26cf92bb 100644
--- a/thirdparty/assimp/include/assimp/matrix3x3.h
+++ b/thirdparty/assimp/include/assimp/matrix3x3.h
@@ -48,7 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATRIX3X3_H_INC
#define AI_MATRIX3X3_H_INC
-#include "defs.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/defs.h>
#ifdef __cplusplus
@@ -65,10 +69,8 @@ template <typename T> class aiVector2t;
* defined thereby.
*/
template <typename TReal>
-class aiMatrix3x3t
-{
+class aiMatrix3x3t {
public:
-
aiMatrix3x3t() AI_NO_EXCEPT :
a1(static_cast<TReal>(1.0f)), a2(), a3(),
b1(), b2(static_cast<TReal>(1.0f)), b3(),
@@ -82,8 +84,6 @@ public:
c1(_c1), c2(_c2), c3(_c3)
{}
-public:
-
// matrix multiplication.
aiMatrix3x3t& operator *= (const aiMatrix3x3t& m);
aiMatrix3x3t operator * (const aiMatrix3x3t& m) const;
@@ -101,8 +101,6 @@ public:
template <typename TOther>
operator aiMatrix3x3t<TOther> () const;
-public:
-
// -------------------------------------------------------------------
/** @brief Construction from a 4x4 matrix. The remaining parts
* of the matrix are ignored.
@@ -122,7 +120,6 @@ public:
aiMatrix3x3t& Inverse();
TReal Determinant() const;
-public:
// -------------------------------------------------------------------
/** @brief Returns a rotation matrix for a rotation around z
* @param a Rotation angle, in radians
diff --git a/thirdparty/assimp/include/assimp/matrix3x3.inl b/thirdparty/assimp/include/assimp/matrix3x3.inl
index d9d45a3e92..1ce8c9691c 100644
--- a/thirdparty/assimp/include/assimp/matrix3x3.inl
+++ b/thirdparty/assimp/include/assimp/matrix3x3.inl
@@ -48,10 +48,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATRIX3X3_INL_INC
#define AI_MATRIX3X3_INL_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
-#include "matrix3x3.h"
+#include <assimp/matrix3x3.h>
+#include <assimp/matrix4x4.h>
-#include "matrix4x4.h"
#include <algorithm>
#include <cmath>
#include <limits>
@@ -59,8 +63,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ------------------------------------------------------------------------------------------------
// Construction from a 4x4 matrix. The remaining parts of the matrix are ignored.
template <typename TReal>
-inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix) {
a1 = pMatrix.a1; a2 = pMatrix.a2; a3 = pMatrix.a3;
b1 = pMatrix.b1; b2 = pMatrix.b2; b3 = pMatrix.b3;
c1 = pMatrix.c1; c2 = pMatrix.c2; c3 = pMatrix.c3;
@@ -68,8 +72,8 @@ inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m) {
*this = aiMatrix3x3t<TReal>(m.a1 * a1 + m.b1 * a2 + m.c1 * a3,
m.a2 * a1 + m.b2 * a2 + m.c2 * a3,
m.a3 * a1 + m.b3 * a2 + m.c3 * a3,
@@ -85,8 +89,7 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t
// ------------------------------------------------------------------------------------------------
template <typename TReal>
template <typename TOther>
-aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
-{
+aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const {
return aiMatrix3x3t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),
static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),
static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3));
@@ -94,8 +97,8 @@ aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const {
aiMatrix3x3t<TReal> temp( *this);
temp *= m;
return temp;
@@ -103,7 +106,8 @@ inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TR
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
+AI_FORCE_INLINE
+TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
switch ( p_iIndex ) {
case 0:
return &a1;
@@ -119,7 +123,8 @@ inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const {
+AI_FORCE_INLINE
+const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const {
switch ( p_iIndex ) {
case 0:
return &a1;
@@ -135,8 +140,8 @@ inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) cons
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const {
return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 &&
b1 == m.b1 && b2 == m.b2 && b3 == m.b3 &&
c1 == m.c1 && c2 == m.c2 && c3 == m.c3;
@@ -144,14 +149,15 @@ inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const {
return !(*this == m);
}
// ---------------------------------------------------------------------------
template<typename TReal>
-inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
+AI_FORCE_INLINE
+bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
return
std::abs(a1 - m.a1) <= epsilon &&
std::abs(a2 - m.a2) <= epsilon &&
@@ -166,8 +172,8 @@ inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsil
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose() {
// (TReal&) don't remove, GCC complains cause of packed fields
std::swap( (TReal&)a2, (TReal&)b1);
std::swap( (TReal&)a3, (TReal&)c1);
@@ -177,15 +183,15 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline TReal aiMatrix3x3t<TReal>::Determinant() const
-{
+AI_FORCE_INLINE
+TReal aiMatrix3x3t<TReal>::Determinant() const {
return a1*b2*c3 - a1*b3*c2 + a2*b3*c1 - a2*b1*c3 + a3*b1*c2 - a3*b2*c1;
}
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse()
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse() {
// Compute the reciprocal determinant
TReal det = Determinant();
if(det == static_cast<TReal>(0.0))
@@ -219,8 +225,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse()
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out) {
out.a1 = out.b2 = std::cos(a);
out.b1 = std::sin(a);
out.a2 = - out.b1;
@@ -234,8 +240,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t
// ------------------------------------------------------------------------------------------------
// Returns a rotation matrix for a rotation around an arbitrary axis.
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out) {
TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
TReal x = axis.x, y = axis.y, z = axis.z;
@@ -249,8 +255,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVect
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out) {
out = aiMatrix3x3t<TReal>();
out.a3 = v.x;
out.b3 = v.y;
@@ -268,9 +274,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<T
*/
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
- const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx)
-{
+AI_FORCE_INLINE aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
+ const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx) {
const TReal e = from * to;
const TReal f = (e < 0)? -e:e;
@@ -352,6 +357,5 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<T
return mtx;
}
-
#endif // __cplusplus
#endif // AI_MATRIX3X3_INL_INC
diff --git a/thirdparty/assimp/include/assimp/matrix4x4.h b/thirdparty/assimp/include/assimp/matrix4x4.h
index 046bb535f2..8fc216f669 100644
--- a/thirdparty/assimp/include/assimp/matrix4x4.h
+++ b/thirdparty/assimp/include/assimp/matrix4x4.h
@@ -47,8 +47,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATRIX4X4_H_INC
#define AI_MATRIX4X4_H_INC
-#include "vector3.h"
-#include "defs.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/vector3.h>
+#include <assimp/defs.h>
#ifdef __cplusplus
@@ -66,8 +70,7 @@ template<typename TReal> class aiQuaterniont;
* defined thereby.
*/
template<typename TReal>
-class aiMatrix4x4t
-{
+class aiMatrix4x4t {
public:
/** set to identity */
@@ -91,8 +94,6 @@ public:
aiMatrix4x4t(const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation,
const aiVector3t<TReal>& position);
-public:
-
// array access operators
/** @fn TReal* operator[] (unsigned int p_iIndex)
* @param [in] p_iIndex - index of the row.
@@ -120,8 +121,6 @@ public:
template <typename TOther>
operator aiMatrix4x4t<TOther> () const;
-public:
-
// -------------------------------------------------------------------
/** @brief Transpose the matrix */
aiMatrix4x4t& Transpose();
@@ -182,7 +181,6 @@ public:
void DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
aiVector3t<TReal>& position) const;
-
// -------------------------------------------------------------------
/** @brief Creates a trafo matrix from a set of euler angles
* @param x Rotation angle for the x-axis, in radians
@@ -192,7 +190,6 @@ public:
aiMatrix4x4t& FromEulerAnglesXYZ(TReal x, TReal y, TReal z);
aiMatrix4x4t& FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb);
-public:
// -------------------------------------------------------------------
/** @brief Returns a rotation matrix for a rotation around the x axis
* @param a Rotation angle, in radians
@@ -256,7 +253,6 @@ public:
static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from,
const aiVector3t<TReal>& to, aiMatrix4x4t& out);
-public:
TReal a1, a2, a3, a4;
TReal b1, b2, b3, b4;
TReal c1, c2, c3, c4;
diff --git a/thirdparty/assimp/include/assimp/matrix4x4.inl b/thirdparty/assimp/include/assimp/matrix4x4.inl
index ebc67a06ec..84079974f7 100644
--- a/thirdparty/assimp/include/assimp/matrix4x4.inl
+++ b/thirdparty/assimp/include/assimp/matrix4x4.inl
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -53,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "matrix4x4.h"
#include "matrix3x3.h"
#include "quaternion.h"
+#include "MathFunctions.h"
#include <algorithm>
#include <limits>
@@ -61,12 +60,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ----------------------------------------------------------------------------------------
template <typename TReal>
aiMatrix4x4t<TReal>::aiMatrix4x4t() AI_NO_EXCEPT :
- a1(1.0f), a2(), a3(), a4(),
- b1(), b2(1.0f), b3(), b4(),
- c1(), c2(), c3(1.0f), c4(),
- d1(), d2(), d3(), d4(1.0f)
-{
-
+ a1(1.0f), a2(), a3(), a4(),
+ b1(), b2(1.0f), b3(), b4(),
+ c1(), c2(), c3(1.0f), c4(),
+ d1(), d2(), d3(), d4(1.0f) {
+ // empty
}
// ----------------------------------------------------------------------------------------
@@ -75,19 +73,17 @@ aiMatrix4x4t<TReal>::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4,
TReal _b1, TReal _b2, TReal _b3, TReal _b4,
TReal _c1, TReal _c2, TReal _c3, TReal _c4,
TReal _d1, TReal _d2, TReal _d3, TReal _d4) :
- a1(_a1), a2(_a2), a3(_a3), a4(_a4),
- b1(_b1), b2(_b2), b3(_b3), b4(_b4),
- c1(_c1), c2(_c2), c3(_c3), c4(_c4),
- d1(_d1), d2(_d2), d3(_d3), d4(_d4)
-{
-
+ a1(_a1), a2(_a2), a3(_a3), a4(_a4),
+ b1(_b1), b2(_b2), b3(_b3), b4(_b4),
+ c1(_c1), c2(_c2), c3(_c3), c4(_c4),
+ d1(_d1), d2(_d2), d3(_d3), d4(_d4) {
+ // empty
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
template <typename TOther>
-aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
-{
+aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const {
return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4),
static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4),
static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4),
@@ -97,8 +93,8 @@ aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m) {
a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0);
b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0);
c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0);
@@ -107,8 +103,8 @@ inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position) {
// build a 3x3 rotation matrix
aiMatrix3x3t<TReal> m = rotation.GetMatrix();
@@ -135,8 +131,8 @@ inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, cons
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m) {
*this = aiMatrix4x4t<TReal>(
m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4,
m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4,
@@ -159,8 +155,7 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const
-{
+AI_FORCE_INLINE aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const {
aiMatrix4x4t<TReal> temp(
a1 * aFloat,
a2 * aFloat,
@@ -183,8 +178,8 @@ inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat)
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const {
aiMatrix4x4t<TReal> temp(
m.a1 + a1,
m.a2 + a2,
@@ -207,18 +202,16 @@ inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TR
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const {
aiMatrix4x4t<TReal> temp( *this);
temp *= m;
return temp;
}
-
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
-{
+AI_FORCE_INLINE aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose() {
// (TReal&) don't remove, GCC complains cause of packed fields
std::swap( (TReal&)b1, (TReal&)a2);
std::swap( (TReal&)c1, (TReal&)a3);
@@ -229,11 +222,10 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
return *this;
}
-
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline TReal aiMatrix4x4t<TReal>::Determinant() const
-{
+AI_FORCE_INLINE
+TReal aiMatrix4x4t<TReal>::Determinant() const {
return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4
+ a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4
- a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3
@@ -244,8 +236,8 @@ inline TReal aiMatrix4x4t<TReal>::Determinant() const
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() {
// Compute the reciprocal determinant
const TReal det = Determinant();
if(det == static_cast<TReal>(0.0))
@@ -289,9 +281,10 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
+AI_FORCE_INLINE
+TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
if (p_iIndex > 3) {
- return NULL;
+ return nullptr;
}
switch ( p_iIndex ) {
case 0:
@@ -310,9 +303,10 @@ inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const {
+AI_FORCE_INLINE
+const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const {
if (p_iIndex > 3) {
- return NULL;
+ return nullptr;
}
switch ( p_iIndex ) {
@@ -332,8 +326,8 @@ inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const {
return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 &&
@@ -342,14 +336,15 @@ inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const {
return !(*this == m);
}
// ---------------------------------------------------------------------------
template<typename TReal>
-inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
+AI_FORCE_INLINE
+bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
return
std::abs(a1 - m.a1) <= epsilon &&
std::abs(a2 - m.a2) <= epsilon &&
@@ -401,13 +396,10 @@ inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsil
\
do {} while(false)
-
-
-
template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation,
- aiVector3t<TReal>& pPosition) const
-{
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation,
+ aiVector3t<TReal>& pPosition) const {
ASSIMP_MATRIX4_4_DECOMPOSE_PART;
// build a 3x3 rotation matrix
@@ -420,8 +412,8 @@ inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuate
}
template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const
-{
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const {
ASSIMP_MATRIX4_4_DECOMPOSE_PART;
/*
@@ -442,7 +434,7 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
*/
// Use a small epsilon to solve floating-point inaccuracies
- const TReal epsilon = 10e-3f;
+ const TReal epsilon = Assimp::Math::getEpsilon<TReal>();
pRotation.y = std::asin(-vCols[0].z);// D. Angle around oY.
@@ -475,10 +467,10 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
#undef ASSIMP_MATRIX4_4_DECOMPOSE_PART
template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle,
- aiVector3t<TReal>& pPosition) const
-{
-aiQuaterniont<TReal> pRotation;
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle,
+ aiVector3t<TReal>& pPosition) const {
+ aiQuaterniont<TReal> pRotation;
Decompose(pScaling, pRotation, pPosition);
pRotation.Normalize();
@@ -500,9 +492,9 @@ aiQuaterniont<TReal> pRotation;
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
- aiVector3t<TReal>& position) const
-{
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
+ aiVector3t<TReal>& position) const {
const aiMatrix4x4t<TReal>& _this = *this;
// extract translation
@@ -516,15 +508,15 @@ inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotat
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb) {
return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z);
}
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z) {
aiMatrix4x4t<TReal>& _this = *this;
TReal cx = std::cos(x);
@@ -552,8 +544,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TRe
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::IsIdentity() const
-{
+AI_FORCE_INLINE
+bool aiMatrix4x4t<TReal>::IsIdentity() const {
// Use a small epsilon to solve floating-point inaccuracies
const static TReal epsilon = 10e-3f;
@@ -577,8 +569,8 @@ inline bool aiMatrix4x4t<TReal>::IsIdentity() const
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out) {
/*
| 1 0 0 0 |
M = | 0 cos(A) -sin(A) 0 |
@@ -592,8 +584,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out) {
/*
| cos(A) 0 sin(A) 0 |
M = | 0 1 0 0 |
@@ -608,8 +600,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out) {
/*
| cos(A) -sin(A) 0 0 |
M = | sin(A) cos(A) 0 0 |
@@ -624,26 +616,25 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t
// ----------------------------------------------------------------------------------------
// Returns a rotation matrix for a rotation around an arbitrary axis.
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out)
-{
- TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
- TReal x = axis.x, y = axis.y, z = axis.z;
-
- // Many thanks to MathWorld and Wikipedia
- out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
- out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x;
- out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
- out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
- out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
- out.d4 = static_cast<TReal>(1.0);
-
- return out;
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out) {
+ TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
+ TReal x = axis.x, y = axis.y, z = axis.z;
+
+ // Many thanks to MathWorld and Wikipedia
+ out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
+ out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x;
+ out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
+ out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
+ out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
+ out.d4 = static_cast<TReal>(1.0);
+
+ return out;
}
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) {
out = aiMatrix4x4t<TReal>();
out.a4 = v.x;
out.b4 = v.y;
@@ -653,8 +644,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<T
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) {
out = aiMatrix4x4t<TReal>();
out.a1 = v.x;
out.b2 = v.y;
@@ -673,9 +664,9 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal
*/
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
- const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
+ const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx) {
aiMatrix3x3t<TReal> m3;
aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3);
mtx = aiMatrix4x4t<TReal>(m3);
diff --git a/thirdparty/assimp/include/assimp/mesh.h b/thirdparty/assimp/include/assimp/mesh.h
index f1628f1f54..fbf2a857ad 100644
--- a/thirdparty/assimp/include/assimp/mesh.h
+++ b/thirdparty/assimp/include/assimp/mesh.h
@@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MESH_H_INC
#define AI_MESH_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
#include <assimp/aabb.h>
@@ -248,6 +252,9 @@ struct aiVertexWeight {
};
+// Forward declare aiNode (pointer use only)
+struct aiNode;
+
// ---------------------------------------------------------------------------
/** @brief A single bone of a mesh.
*
@@ -264,6 +271,16 @@ struct aiBone {
//! The maximum value for this member is #AI_MAX_BONE_WEIGHTS.
unsigned int mNumWeights;
+#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
+ // The bone armature node - used for skeleton conversion
+ // you must enable aiProcess_PopulateArmatureData to populate this
+ C_STRUCT aiNode* mArmature;
+
+ // The bone node in the scene - used for skeleton conversion
+ // you must enable aiProcess_PopulateArmatureData to populate this
+ C_STRUCT aiNode* mNode;
+
+#endif
//! The influence weights of this bone, by vertex index.
C_STRUCT aiVertexWeight* mWeights;
@@ -418,11 +435,11 @@ struct aiAnimMesh
/**Anim Mesh name */
C_STRUCT aiString mName;
- /** Replacement for aiMesh::mVertices. If this array is non-NULL,
+ /** Replacement for aiMesh::mVertices. If this array is non-nullptr,
* it *must* contain mNumVertices entries. The corresponding
- * array in the host mesh must be non-NULL as well - animation
+ * array in the host mesh must be non-nullptr as well - animation
* meshes may neither add or nor remove vertex components (if
- * a replacement array is NULL and the corresponding source
+ * a replacement array is nullptr and the corresponding source
* array is not, the source data is taken instead)*/
C_STRUCT aiVector3D* mVertices;
@@ -596,7 +613,7 @@ struct aiMesh
C_STRUCT aiVector3D* mVertices;
/** Vertex normals.
- * The array contains normalized vectors, NULL if not present.
+ * The array contains normalized vectors, nullptr if not present.
* The array is mNumVertices in size. Normals are undefined for
* point and line primitives. A mesh consisting of points and
* lines only may not have normal vectors. Meshes with mixed
@@ -619,7 +636,7 @@ struct aiMesh
/** Vertex tangents.
* The tangent of a vertex points in the direction of the positive
- * X texture axis. The array contains normalized vectors, NULL if
+ * X texture axis. The array contains normalized vectors, nullptr if
* not present. The array is mNumVertices in size. A mesh consisting
* of points and lines only may not have normal vectors. Meshes with
* mixed primitive types (i.e. lines and triangles) may have
@@ -633,7 +650,7 @@ struct aiMesh
/** Vertex bitangents.
* The bitangent of a vertex points in the direction of the positive
- * Y texture axis. The array contains normalized vectors, NULL if not
+ * Y texture axis. The array contains normalized vectors, nullptr if not
* present. The array is mNumVertices in size.
* @note If the mesh contains tangents, it automatically also contains
* bitangents.
@@ -642,14 +659,14 @@ struct aiMesh
/** Vertex color sets.
* A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex
- * colors per vertex. NULL if not present. Each array is
+ * colors per vertex. nullptr if not present. Each array is
* mNumVertices in size if present.
*/
C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
/** Vertex texture coords, also known as UV channels.
* A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per
- * vertex. NULL if not present. The array is mNumVertices in size.
+ * vertex. nullptr if not present. The array is mNumVertices in size.
*/
C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
@@ -671,7 +688,7 @@ struct aiMesh
C_STRUCT aiFace* mFaces;
/** The number of bones this mesh contains.
- * Can be 0, in which case the mBones array is NULL.
+ * Can be 0, in which case the mBones array is nullptr.
*/
unsigned int mNumBones;
@@ -769,7 +786,10 @@ struct aiMesh
// DO NOT REMOVE THIS ADDITIONAL CHECK
if (mNumBones && mBones) {
for( unsigned int a = 0; a < mNumBones; a++) {
- delete mBones[a];
+ if(mBones[a])
+ {
+ delete mBones[a];
+ }
}
delete [] mBones;
}
diff --git a/thirdparty/assimp/include/assimp/metadata.h b/thirdparty/assimp/include/assimp/metadata.h
index 3a1dd1442a..849d90f485 100644
--- a/thirdparty/assimp/include/assimp/metadata.h
+++ b/thirdparty/assimp/include/assimp/metadata.h
@@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_METADATA_H_INC
#define AI_METADATA_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#if defined(_MSC_VER) && (_MSC_VER <= 1500)
# include "Compiler/pstdint.h"
#else
diff --git a/thirdparty/assimp/include/assimp/pbrmaterial.h b/thirdparty/assimp/include/assimp/pbrmaterial.h
index ce5f822173..892a6347f7 100644
--- a/thirdparty/assimp/include/assimp/pbrmaterial.h
+++ b/thirdparty/assimp/include/assimp/pbrmaterial.h
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -44,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file pbrmaterial.h
* @brief Defines the material system of the library
*/
+#pragma once
#ifndef AI_PBRMATERIAL_H_INC
#define AI_PBRMATERIAL_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0
diff --git a/thirdparty/assimp/include/assimp/postprocess.h b/thirdparty/assimp/include/assimp/postprocess.h
index 2a74414216..4b6732e80a 100644
--- a/thirdparty/assimp/include/assimp/postprocess.h
+++ b/thirdparty/assimp/include/assimp/postprocess.h
@@ -47,7 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_POSTPROCESS_H_INC
#define AI_POSTPROCESS_H_INC
-#include "types.h"
+#include <assimp/types.h>
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
#ifdef __cplusplus
extern "C" {
@@ -316,6 +320,19 @@ enum aiPostProcessSteps
*/
aiProcess_FixInfacingNormals = 0x2000,
+
+
+ // -------------------------------------------------------------------------
+ /**
+ * This step generically populates aiBone->mArmature and aiBone->mNode generically
+ * The point of these is it saves you later having to calculate these elements
+ * This is useful when handling rest information or skin information
+ * If you have multiple armatures on your models we strongly recommend enabling this
+ * Instead of writing your own multi-root, multi-armature lookups we have done the
+ * hard work for you :)
+ */
+ aiProcess_PopulateArmatureData = 0x4000,
+
// -------------------------------------------------------------------------
/** <hr>This step splits meshes with more than one primitive type in
* homogeneous sub-meshes.
@@ -533,6 +550,8 @@ enum aiPostProcessSteps
*/
aiProcess_Debone = 0x4000000,
+
+
// -------------------------------------------------------------------------
/** <hr>This step will perform a global scale of the model.
*
diff --git a/thirdparty/assimp/include/assimp/qnan.h b/thirdparty/assimp/include/assimp/qnan.h
index 0918bde5e7..06780da5b8 100644
--- a/thirdparty/assimp/include/assimp/qnan.h
+++ b/thirdparty/assimp/include/assimp/qnan.h
@@ -50,19 +50,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* but last time I checked compiler coverage was so bad that I decided
* to reinvent the wheel.
*/
-
+#pragma once
#ifndef AI_QNAN_H_INCLUDED
#define AI_QNAN_H_INCLUDED
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/defs.h>
+
#include <limits>
#include <stdint.h>
// ---------------------------------------------------------------------------
/** Data structure to represent the bit pattern of a 32 Bit
* IEEE 754 floating-point number. */
-union _IEEESingle
-{
+union _IEEESingle {
float Float;
struct
{
@@ -75,8 +79,7 @@ union _IEEESingle
// ---------------------------------------------------------------------------
/** Data structure to represent the bit pattern of a 64 Bit
* IEEE 754 floating-point number. */
-union _IEEEDouble
-{
+union _IEEEDouble {
double Double;
struct
{
@@ -89,8 +92,7 @@ union _IEEEDouble
// ---------------------------------------------------------------------------
/** Check whether a given float is qNaN.
* @param in Input value */
-AI_FORCE_INLINE bool is_qnan(float in)
-{
+AI_FORCE_INLINE bool is_qnan(float in) {
// the straightforward solution does not work:
// return (in != in);
// compiler generates code like this
@@ -107,8 +109,7 @@ AI_FORCE_INLINE bool is_qnan(float in)
// ---------------------------------------------------------------------------
/** Check whether a given double is qNaN.
* @param in Input value */
-AI_FORCE_INLINE bool is_qnan(double in)
-{
+AI_FORCE_INLINE bool is_qnan(double in) {
// the straightforward solution does not work:
// return (in != in);
// compiler generates code like this
@@ -127,8 +128,7 @@ AI_FORCE_INLINE bool is_qnan(double in)
*
* Denorms return false, they're treated like normal values.
* @param in Input value */
-AI_FORCE_INLINE bool is_special_float(float in)
-{
+AI_FORCE_INLINE bool is_special_float(float in) {
_IEEESingle temp;
memcpy(&temp, &in, sizeof(float));
return (temp.IEEE.Exp == (1u << 8)-1);
@@ -139,8 +139,7 @@ AI_FORCE_INLINE bool is_special_float(float in)
*
* Denorms return false, they're treated like normal values.
* @param in Input value */
-AI_FORCE_INLINE bool is_special_float(double in)
-{
+AI_FORCE_INLINE bool is_special_float(double in) {
_IEEESingle temp;
memcpy(&temp, &in, sizeof(float));
return (temp.IEEE.Exp == (1u << 11)-1);
@@ -150,15 +149,13 @@ AI_FORCE_INLINE bool is_special_float(double in)
/** Check whether a float is NOT qNaN.
* @param in Input value */
template<class TReal>
-AI_FORCE_INLINE bool is_not_qnan(TReal in)
-{
+AI_FORCE_INLINE bool is_not_qnan(TReal in) {
return !is_qnan(in);
}
// ---------------------------------------------------------------------------
/** @brief Get a fresh qnan. */
-AI_FORCE_INLINE ai_real get_qnan()
-{
+AI_FORCE_INLINE ai_real get_qnan() {
return std::numeric_limits<ai_real>::quiet_NaN();
}
diff --git a/thirdparty/assimp/include/assimp/quaternion.h b/thirdparty/assimp/include/assimp/quaternion.h
index 96574d24b9..ae45959b41 100644
--- a/thirdparty/assimp/include/assimp/quaternion.h
+++ b/thirdparty/assimp/include/assimp/quaternion.h
@@ -49,7 +49,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef __cplusplus
-#include "defs.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/defs.h>
template <typename TReal> class aiVector3t;
template <typename TReal> class aiMatrix3x3t;
diff --git a/thirdparty/assimp/include/assimp/quaternion.inl b/thirdparty/assimp/include/assimp/quaternion.inl
index c26648215e..3ce514d1bb 100644
--- a/thirdparty/assimp/include/assimp/quaternion.inl
+++ b/thirdparty/assimp/include/assimp/quaternion.inl
@@ -48,8 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_QUATERNION_INL_INC
#define AI_QUATERNION_INL_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
-#include "quaternion.h"
+#include <assimp/quaternion.h>
#include <cmath>
diff --git a/thirdparty/assimp/include/assimp/scene.h b/thirdparty/assimp/include/assimp/scene.h
index 2667db85b3..b76709eb15 100644
--- a/thirdparty/assimp/include/assimp/scene.h
+++ b/thirdparty/assimp/include/assimp/scene.h
@@ -48,14 +48,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_SCENE_H_INC
#define AI_SCENE_H_INC
-#include "types.h"
-#include "texture.h"
-#include "mesh.h"
-#include "light.h"
-#include "camera.h"
-#include "material.h"
-#include "anim.h"
-#include "metadata.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
+#include <assimp/texture.h>
+#include <assimp/mesh.h>
+#include <assimp/light.h>
+#include <assimp/camera.h>
+#include <assimp/material.h>
+#include <assimp/anim.h>
+#include <assimp/metadata.h>
#ifdef __cplusplus
# include <cstdlib>
@@ -106,13 +110,13 @@ struct ASSIMP_API aiNode
/** The transformation relative to the node's parent. */
C_STRUCT aiMatrix4x4 mTransformation;
- /** Parent node. NULL if this node is the root node. */
+ /** Parent node. nullptr if this node is the root node. */
C_STRUCT aiNode* mParent;
/** The number of child nodes of this node. */
unsigned int mNumChildren;
- /** The child nodes of this node. NULL if mNumChildren is 0. */
+ /** The child nodes of this node. nullptr if mNumChildren is 0. */
C_STRUCT aiNode** mChildren;
/** The number of meshes of this node. */
@@ -123,7 +127,7 @@ struct ASSIMP_API aiNode
*/
unsigned int* mMeshes;
- /** Metadata associated with this node or NULL if there is no metadata.
+ /** Metadata associated with this node or nullptr if there is no metadata.
* Whether any metadata is generated depends on the source file format. See the
* @link importer_notes @endlink page for more information on every source file
* format. Importers that don't document any metadata don't write any.
@@ -145,7 +149,7 @@ struct ASSIMP_API aiNode
* of the scene.
*
* @param name Name to search for
- * @return NULL or a valid Node if the search was successful.
+ * @return nullptr or a valid Node if the search was successful.
*/
inline
const aiNode* FindNode(const aiString& name) const {
@@ -340,7 +344,7 @@ struct aiScene
#ifdef __cplusplus
- //! Default constructor - set everything to 0/NULL
+ //! Default constructor - set everything to 0/nullptr
ASSIMP_API aiScene();
//! Destructor
@@ -349,33 +353,33 @@ struct aiScene
//! Check whether the scene contains meshes
//! Unless no special scene flags are set this will always be true.
inline bool HasMeshes() const {
- return mMeshes != NULL && mNumMeshes > 0;
+ return mMeshes != nullptr && mNumMeshes > 0;
}
//! Check whether the scene contains materials
//! Unless no special scene flags are set this will always be true.
inline bool HasMaterials() const {
- return mMaterials != NULL && mNumMaterials > 0;
+ return mMaterials != nullptr && mNumMaterials > 0;
}
//! Check whether the scene contains lights
inline bool HasLights() const {
- return mLights != NULL && mNumLights > 0;
+ return mLights != nullptr && mNumLights > 0;
}
//! Check whether the scene contains textures
inline bool HasTextures() const {
- return mTextures != NULL && mNumTextures > 0;
+ return mTextures != nullptr && mNumTextures > 0;
}
//! Check whether the scene contains cameras
inline bool HasCameras() const {
- return mCameras != NULL && mNumCameras > 0;
+ return mCameras != nullptr && mNumCameras > 0;
}
//! Check whether the scene contains animations
inline bool HasAnimations() const {
- return mAnimations != NULL && mNumAnimations > 0;
+ return mAnimations != nullptr && mNumAnimations > 0;
}
//! Returns a short filename from a full path
diff --git a/thirdparty/assimp/include/assimp/texture.h b/thirdparty/assimp/include/assimp/texture.h
index dc6cbef65c..0867659f46 100644
--- a/thirdparty/assimp/include/assimp/texture.h
+++ b/thirdparty/assimp/include/assimp/texture.h
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -53,13 +51,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_TEXTURE_H_INC
#define AI_TEXTURE_H_INC
-#include "types.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
#ifdef __cplusplus
extern "C" {
#endif
-
// --------------------------------------------------------------------------------
/** \def AI_EMBEDDED_TEXNAME_PREFIX
@@ -79,7 +80,6 @@ extern "C" {
# define AI_MAKE_EMBEDDED_TEXNAME(_n_) AI_EMBEDDED_TEXNAME_PREFIX # _n_
#endif
-
#include "./Compiler/pushpack1.h"
// --------------------------------------------------------------------------------
@@ -87,8 +87,7 @@ extern "C" {
*
* Used by aiTexture.
*/
-struct aiTexel
-{
+struct aiTexel {
unsigned char b,g,r,a;
#ifdef __cplusplus
diff --git a/thirdparty/assimp/include/assimp/types.h b/thirdparty/assimp/include/assimp/types.h
index 331b8cd03f..e32cae331c 100644
--- a/thirdparty/assimp/include/assimp/types.h
+++ b/thirdparty/assimp/include/assimp/types.h
@@ -48,22 +48,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_TYPES_H_INC
#define AI_TYPES_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
// Some runtime headers
#include <sys/types.h>
#include <stddef.h>
#include <string.h>
#include <limits.h>
+#include <stdint.h>
// Our compile configuration
-#include "defs.h"
+#include <assimp/defs.h>
// Some types moved to separate header due to size of operators
-#include "vector3.h"
-#include "vector2.h"
-#include "color4.h"
-#include "matrix3x3.h"
-#include "matrix4x4.h"
-#include "quaternion.h"
+#include <assimp/vector3.h>
+#include <assimp/vector2.h>
+#include <assimp/color4.h>
+#include <assimp/matrix3x3.h>
+#include <assimp/matrix4x4.h>
+#include <assimp/quaternion.h>
+
+typedef int32_t ai_int32;
+typedef uint32_t ai_uint32 ;
#ifdef __cplusplus
#include <cstring>
@@ -71,7 +79,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string> // for aiString::Set(const std::string&)
namespace Assimp {
- //! @cond never
+//! @cond never
namespace Intern {
// --------------------------------------------------------------------
/** @brief Internal helper class to utilize our internal new/delete
@@ -269,8 +277,8 @@ struct aiString
}
/** Copy constructor */
- aiString(const aiString& rOther) :
- length(rOther.length)
+ aiString(const aiString& rOther)
+ : length(rOther.length)
{
// Crop the string to the maximum length
length = length>=MAXLEN?MAXLEN-1:length;
@@ -280,7 +288,7 @@ struct aiString
/** Constructor from std::string */
explicit aiString(const std::string& pString) :
- length(pString.length())
+ length( (ai_uint32) pString.length())
{
length = length>=MAXLEN?MAXLEN-1:length;
memcpy( data, pString.c_str(), length);
@@ -292,15 +300,15 @@ struct aiString
if( pString.length() > MAXLEN - 1) {
return;
}
- length = pString.length();
+ length = (ai_uint32)pString.length();
memcpy( data, pString.c_str(), length);
data[length] = 0;
}
/** Copy a const char* to the aiString */
void Set( const char* sz) {
- const size_t len = ::strlen(sz);
- if( len > MAXLEN - 1) {
+ const ai_int32 len = (ai_uint32) ::strlen(sz);
+ if( len > (ai_int32)MAXLEN - 1) {
return;
}
length = len;
@@ -346,7 +354,7 @@ struct aiString
/** Append a string to the string */
void Append (const char* app) {
- const size_t len = ::strlen(app);
+ const ai_uint32 len = (ai_uint32) ::strlen(app);
if (!len) {
return;
}
@@ -379,7 +387,7 @@ struct aiString
/** Binary length of the string excluding the terminal 0. This is NOT the
* logical length of strings containing UTF-8 multi-byte sequences! It's
* the number of bytes from the beginning of the string to its end.*/
- size_t length;
+ ai_uint32 length;
/** String buffer. Size limit is MAXLEN */
char data[MAXLEN];
diff --git a/thirdparty/assimp/include/assimp/vector2.h b/thirdparty/assimp/include/assimp/vector2.h
index d5ef001542..c8b1ebbbc2 100644
--- a/thirdparty/assimp/include/assimp/vector2.h
+++ b/thirdparty/assimp/include/assimp/vector2.h
@@ -47,6 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_VECTOR2D_H_INC
#define AI_VECTOR2D_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
# include <cmath>
#else
diff --git a/thirdparty/assimp/include/assimp/vector2.inl b/thirdparty/assimp/include/assimp/vector2.inl
index 3b7a7beabb..4bbf432ff8 100644
--- a/thirdparty/assimp/include/assimp/vector2.inl
+++ b/thirdparty/assimp/include/assimp/vector2.inl
@@ -48,8 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_VECTOR2D_INL_INC
#define AI_VECTOR2D_INL_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
-#include "vector2.h"
+#include <assimp/vector2.h>
#include <cmath>
diff --git a/thirdparty/assimp/include/assimp/vector3.h b/thirdparty/assimp/include/assimp/vector3.h
index 7ff25cf0ad..fffeb12ad7 100644
--- a/thirdparty/assimp/include/assimp/vector3.h
+++ b/thirdparty/assimp/include/assimp/vector3.h
@@ -47,13 +47,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_VECTOR3D_H_INC
#define AI_VECTOR3D_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
# include <cmath>
#else
# include <math.h>
#endif
-#include "defs.h"
+#include <assimp/defs.h>
#ifdef __cplusplus
@@ -63,16 +67,13 @@ template<typename TReal> class aiMatrix4x4t;
// ---------------------------------------------------------------------------
/** Represents a three-dimensional vector. */
template <typename TReal>
-class aiVector3t
-{
+class aiVector3t {
public:
aiVector3t() AI_NO_EXCEPT : x(), y(), z() {}
aiVector3t(TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
explicit aiVector3t (TReal _xyz ) : x(_xyz), y(_xyz), z(_xyz) {}
aiVector3t( const aiVector3t& o ) = default;
-public:
-
// combined operators
const aiVector3t& operator += (const aiVector3t& o);
const aiVector3t& operator -= (const aiVector3t& o);
@@ -97,7 +98,6 @@ public:
template <typename TOther>
operator aiVector3t<TOther> () const;
-public:
/** @brief Set the components of a vector
* @param pX X component
* @param pY Y component
diff --git a/thirdparty/assimp/include/assimp/vector3.inl b/thirdparty/assimp/include/assimp/vector3.inl
index 2fce6eddee..6682d3b32c 100644
--- a/thirdparty/assimp/include/assimp/vector3.inl
+++ b/thirdparty/assimp/include/assimp/vector3.inl
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_VECTOR3D_INL_INC
#ifdef __cplusplus
-#include "vector3.h"
+#include <assimp/vector3.h>
#include <cmath>
diff --git a/thirdparty/assimp/include/assimp/version.h b/thirdparty/assimp/include/assimp/version.h
index c62a40e118..2fdd37a43c 100644
--- a/thirdparty/assimp/include/assimp/version.h
+++ b/thirdparty/assimp/include/assimp/version.h
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_VERSION_H_INC
#define AI_VERSION_H_INC
-#include "defs.h"
+#include <assimp/defs.h>
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/libogg/bitwise.c b/thirdparty/libogg/bitwise.c
index fa2b572029..f5ef79122e 100644
--- a/thirdparty/libogg/bitwise.c
+++ b/thirdparty/libogg/bitwise.c
@@ -11,7 +11,6 @@
********************************************************************
function: packing variable sized words into an octet stream
- last mod: $Id$
********************************************************************/
@@ -890,7 +889,7 @@ int main(void){
for(i=0;i<test2size;i++){
if(oggpack_look(&r,32)==-1)report("out of data. failed!");
if(oggpack_look(&r,32)!=large[i]){
- fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpack_look(&r,32),large[i],
+ fprintf(stderr,"%ld != %lu (%lx!=%lx):",oggpack_look(&r,32),large[i],
oggpack_look(&r,32),large[i]);
report("read incorrect value!\n");
}
@@ -1000,7 +999,7 @@ int main(void){
for(i=0;i<test2size;i++){
if(oggpackB_look(&r,32)==-1)report("out of data. failed!");
if(oggpackB_look(&r,32)!=large[i]){
- fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i],
+ fprintf(stderr,"%ld != %lu (%lx!=%lx):",oggpackB_look(&r,32),large[i],
oggpackB_look(&r,32),large[i]);
report("read incorrect value!\n");
}
diff --git a/thirdparty/libogg/crctable.h b/thirdparty/libogg/crctable.h
new file mode 100644
index 0000000000..dcc378b309
--- /dev/null
+++ b/thirdparty/libogg/crctable.h
@@ -0,0 +1,278 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2018 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
+ * *
+ ********************************************************************/
+
+#include <ogg/os_types.h>
+
+static const ogg_uint32_t crc_lookup[8][256]={
+{0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
+ 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
+ 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
+ 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
+ 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
+ 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
+ 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
+ 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
+ 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
+ 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
+ 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
+ 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
+ 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
+ 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
+ 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
+ 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
+ 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
+ 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
+ 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
+ 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
+ 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
+ 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
+ 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
+ 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
+ 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
+ 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
+ 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
+ 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
+ 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
+ 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
+ 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
+ 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4},
+
+{0x00000000,0xd219c1dc,0xa0f29e0f,0x72eb5fd3,0x452421a9,0x973de075,0xe5d6bfa6,0x37cf7e7a,
+ 0x8a484352,0x5851828e,0x2abadd5d,0xf8a31c81,0xcf6c62fb,0x1d75a327,0x6f9efcf4,0xbd873d28,
+ 0x10519b13,0xc2485acf,0xb0a3051c,0x62bac4c0,0x5575baba,0x876c7b66,0xf58724b5,0x279ee569,
+ 0x9a19d841,0x4800199d,0x3aeb464e,0xe8f28792,0xdf3df9e8,0x0d243834,0x7fcf67e7,0xadd6a63b,
+ 0x20a33626,0xf2baf7fa,0x8051a829,0x524869f5,0x6587178f,0xb79ed653,0xc5758980,0x176c485c,
+ 0xaaeb7574,0x78f2b4a8,0x0a19eb7b,0xd8002aa7,0xefcf54dd,0x3dd69501,0x4f3dcad2,0x9d240b0e,
+ 0x30f2ad35,0xe2eb6ce9,0x9000333a,0x4219f2e6,0x75d68c9c,0xa7cf4d40,0xd5241293,0x073dd34f,
+ 0xbabaee67,0x68a32fbb,0x1a487068,0xc851b1b4,0xff9ecfce,0x2d870e12,0x5f6c51c1,0x8d75901d,
+ 0x41466c4c,0x935fad90,0xe1b4f243,0x33ad339f,0x04624de5,0xd67b8c39,0xa490d3ea,0x76891236,
+ 0xcb0e2f1e,0x1917eec2,0x6bfcb111,0xb9e570cd,0x8e2a0eb7,0x5c33cf6b,0x2ed890b8,0xfcc15164,
+ 0x5117f75f,0x830e3683,0xf1e56950,0x23fca88c,0x1433d6f6,0xc62a172a,0xb4c148f9,0x66d88925,
+ 0xdb5fb40d,0x094675d1,0x7bad2a02,0xa9b4ebde,0x9e7b95a4,0x4c625478,0x3e890bab,0xec90ca77,
+ 0x61e55a6a,0xb3fc9bb6,0xc117c465,0x130e05b9,0x24c17bc3,0xf6d8ba1f,0x8433e5cc,0x562a2410,
+ 0xebad1938,0x39b4d8e4,0x4b5f8737,0x994646eb,0xae893891,0x7c90f94d,0x0e7ba69e,0xdc626742,
+ 0x71b4c179,0xa3ad00a5,0xd1465f76,0x035f9eaa,0x3490e0d0,0xe689210c,0x94627edf,0x467bbf03,
+ 0xfbfc822b,0x29e543f7,0x5b0e1c24,0x8917ddf8,0xbed8a382,0x6cc1625e,0x1e2a3d8d,0xcc33fc51,
+ 0x828cd898,0x50951944,0x227e4697,0xf067874b,0xc7a8f931,0x15b138ed,0x675a673e,0xb543a6e2,
+ 0x08c49bca,0xdadd5a16,0xa83605c5,0x7a2fc419,0x4de0ba63,0x9ff97bbf,0xed12246c,0x3f0be5b0,
+ 0x92dd438b,0x40c48257,0x322fdd84,0xe0361c58,0xd7f96222,0x05e0a3fe,0x770bfc2d,0xa5123df1,
+ 0x189500d9,0xca8cc105,0xb8679ed6,0x6a7e5f0a,0x5db12170,0x8fa8e0ac,0xfd43bf7f,0x2f5a7ea3,
+ 0xa22feebe,0x70362f62,0x02dd70b1,0xd0c4b16d,0xe70bcf17,0x35120ecb,0x47f95118,0x95e090c4,
+ 0x2867adec,0xfa7e6c30,0x889533e3,0x5a8cf23f,0x6d438c45,0xbf5a4d99,0xcdb1124a,0x1fa8d396,
+ 0xb27e75ad,0x6067b471,0x128ceba2,0xc0952a7e,0xf75a5404,0x254395d8,0x57a8ca0b,0x85b10bd7,
+ 0x383636ff,0xea2ff723,0x98c4a8f0,0x4add692c,0x7d121756,0xaf0bd68a,0xdde08959,0x0ff94885,
+ 0xc3cab4d4,0x11d37508,0x63382adb,0xb121eb07,0x86ee957d,0x54f754a1,0x261c0b72,0xf405caae,
+ 0x4982f786,0x9b9b365a,0xe9706989,0x3b69a855,0x0ca6d62f,0xdebf17f3,0xac544820,0x7e4d89fc,
+ 0xd39b2fc7,0x0182ee1b,0x7369b1c8,0xa1707014,0x96bf0e6e,0x44a6cfb2,0x364d9061,0xe45451bd,
+ 0x59d36c95,0x8bcaad49,0xf921f29a,0x2b383346,0x1cf74d3c,0xceee8ce0,0xbc05d333,0x6e1c12ef,
+ 0xe36982f2,0x3170432e,0x439b1cfd,0x9182dd21,0xa64da35b,0x74546287,0x06bf3d54,0xd4a6fc88,
+ 0x6921c1a0,0xbb38007c,0xc9d35faf,0x1bca9e73,0x2c05e009,0xfe1c21d5,0x8cf77e06,0x5eeebfda,
+ 0xf33819e1,0x2121d83d,0x53ca87ee,0x81d34632,0xb61c3848,0x6405f994,0x16eea647,0xc4f7679b,
+ 0x79705ab3,0xab699b6f,0xd982c4bc,0x0b9b0560,0x3c547b1a,0xee4dbac6,0x9ca6e515,0x4ebf24c9},
+
+{0x00000000,0x01d8ac87,0x03b1590e,0x0269f589,0x0762b21c,0x06ba1e9b,0x04d3eb12,0x050b4795,
+ 0x0ec56438,0x0f1dc8bf,0x0d743d36,0x0cac91b1,0x09a7d624,0x087f7aa3,0x0a168f2a,0x0bce23ad,
+ 0x1d8ac870,0x1c5264f7,0x1e3b917e,0x1fe33df9,0x1ae87a6c,0x1b30d6eb,0x19592362,0x18818fe5,
+ 0x134fac48,0x129700cf,0x10fef546,0x112659c1,0x142d1e54,0x15f5b2d3,0x179c475a,0x1644ebdd,
+ 0x3b1590e0,0x3acd3c67,0x38a4c9ee,0x397c6569,0x3c7722fc,0x3daf8e7b,0x3fc67bf2,0x3e1ed775,
+ 0x35d0f4d8,0x3408585f,0x3661add6,0x37b90151,0x32b246c4,0x336aea43,0x31031fca,0x30dbb34d,
+ 0x269f5890,0x2747f417,0x252e019e,0x24f6ad19,0x21fdea8c,0x2025460b,0x224cb382,0x23941f05,
+ 0x285a3ca8,0x2982902f,0x2beb65a6,0x2a33c921,0x2f388eb4,0x2ee02233,0x2c89d7ba,0x2d517b3d,
+ 0x762b21c0,0x77f38d47,0x759a78ce,0x7442d449,0x714993dc,0x70913f5b,0x72f8cad2,0x73206655,
+ 0x78ee45f8,0x7936e97f,0x7b5f1cf6,0x7a87b071,0x7f8cf7e4,0x7e545b63,0x7c3daeea,0x7de5026d,
+ 0x6ba1e9b0,0x6a794537,0x6810b0be,0x69c81c39,0x6cc35bac,0x6d1bf72b,0x6f7202a2,0x6eaaae25,
+ 0x65648d88,0x64bc210f,0x66d5d486,0x670d7801,0x62063f94,0x63de9313,0x61b7669a,0x606fca1d,
+ 0x4d3eb120,0x4ce61da7,0x4e8fe82e,0x4f5744a9,0x4a5c033c,0x4b84afbb,0x49ed5a32,0x4835f6b5,
+ 0x43fbd518,0x4223799f,0x404a8c16,0x41922091,0x44996704,0x4541cb83,0x47283e0a,0x46f0928d,
+ 0x50b47950,0x516cd5d7,0x5305205e,0x52dd8cd9,0x57d6cb4c,0x560e67cb,0x54679242,0x55bf3ec5,
+ 0x5e711d68,0x5fa9b1ef,0x5dc04466,0x5c18e8e1,0x5913af74,0x58cb03f3,0x5aa2f67a,0x5b7a5afd,
+ 0xec564380,0xed8eef07,0xefe71a8e,0xee3fb609,0xeb34f19c,0xeaec5d1b,0xe885a892,0xe95d0415,
+ 0xe29327b8,0xe34b8b3f,0xe1227eb6,0xe0fad231,0xe5f195a4,0xe4293923,0xe640ccaa,0xe798602d,
+ 0xf1dc8bf0,0xf0042777,0xf26dd2fe,0xf3b57e79,0xf6be39ec,0xf766956b,0xf50f60e2,0xf4d7cc65,
+ 0xff19efc8,0xfec1434f,0xfca8b6c6,0xfd701a41,0xf87b5dd4,0xf9a3f153,0xfbca04da,0xfa12a85d,
+ 0xd743d360,0xd69b7fe7,0xd4f28a6e,0xd52a26e9,0xd021617c,0xd1f9cdfb,0xd3903872,0xd24894f5,
+ 0xd986b758,0xd85e1bdf,0xda37ee56,0xdbef42d1,0xdee40544,0xdf3ca9c3,0xdd555c4a,0xdc8df0cd,
+ 0xcac91b10,0xcb11b797,0xc978421e,0xc8a0ee99,0xcdaba90c,0xcc73058b,0xce1af002,0xcfc25c85,
+ 0xc40c7f28,0xc5d4d3af,0xc7bd2626,0xc6658aa1,0xc36ecd34,0xc2b661b3,0xc0df943a,0xc10738bd,
+ 0x9a7d6240,0x9ba5cec7,0x99cc3b4e,0x981497c9,0x9d1fd05c,0x9cc77cdb,0x9eae8952,0x9f7625d5,
+ 0x94b80678,0x9560aaff,0x97095f76,0x96d1f3f1,0x93dab464,0x920218e3,0x906bed6a,0x91b341ed,
+ 0x87f7aa30,0x862f06b7,0x8446f33e,0x859e5fb9,0x8095182c,0x814db4ab,0x83244122,0x82fceda5,
+ 0x8932ce08,0x88ea628f,0x8a839706,0x8b5b3b81,0x8e507c14,0x8f88d093,0x8de1251a,0x8c39899d,
+ 0xa168f2a0,0xa0b05e27,0xa2d9abae,0xa3010729,0xa60a40bc,0xa7d2ec3b,0xa5bb19b2,0xa463b535,
+ 0xafad9698,0xae753a1f,0xac1ccf96,0xadc46311,0xa8cf2484,0xa9178803,0xab7e7d8a,0xaaa6d10d,
+ 0xbce23ad0,0xbd3a9657,0xbf5363de,0xbe8bcf59,0xbb8088cc,0xba58244b,0xb831d1c2,0xb9e97d45,
+ 0xb2275ee8,0xb3fff26f,0xb19607e6,0xb04eab61,0xb545ecf4,0xb49d4073,0xb6f4b5fa,0xb72c197d},
+
+{0x00000000,0xdc6d9ab7,0xbc1a28d9,0x6077b26e,0x7cf54c05,0xa098d6b2,0xc0ef64dc,0x1c82fe6b,
+ 0xf9ea980a,0x258702bd,0x45f0b0d3,0x999d2a64,0x851fd40f,0x59724eb8,0x3905fcd6,0xe5686661,
+ 0xf7142da3,0x2b79b714,0x4b0e057a,0x97639fcd,0x8be161a6,0x578cfb11,0x37fb497f,0xeb96d3c8,
+ 0x0efeb5a9,0xd2932f1e,0xb2e49d70,0x6e8907c7,0x720bf9ac,0xae66631b,0xce11d175,0x127c4bc2,
+ 0xeae946f1,0x3684dc46,0x56f36e28,0x8a9ef49f,0x961c0af4,0x4a719043,0x2a06222d,0xf66bb89a,
+ 0x1303defb,0xcf6e444c,0xaf19f622,0x73746c95,0x6ff692fe,0xb39b0849,0xd3ecba27,0x0f812090,
+ 0x1dfd6b52,0xc190f1e5,0xa1e7438b,0x7d8ad93c,0x61082757,0xbd65bde0,0xdd120f8e,0x017f9539,
+ 0xe417f358,0x387a69ef,0x580ddb81,0x84604136,0x98e2bf5d,0x448f25ea,0x24f89784,0xf8950d33,
+ 0xd1139055,0x0d7e0ae2,0x6d09b88c,0xb164223b,0xade6dc50,0x718b46e7,0x11fcf489,0xcd916e3e,
+ 0x28f9085f,0xf49492e8,0x94e32086,0x488eba31,0x540c445a,0x8861deed,0xe8166c83,0x347bf634,
+ 0x2607bdf6,0xfa6a2741,0x9a1d952f,0x46700f98,0x5af2f1f3,0x869f6b44,0xe6e8d92a,0x3a85439d,
+ 0xdfed25fc,0x0380bf4b,0x63f70d25,0xbf9a9792,0xa31869f9,0x7f75f34e,0x1f024120,0xc36fdb97,
+ 0x3bfad6a4,0xe7974c13,0x87e0fe7d,0x5b8d64ca,0x470f9aa1,0x9b620016,0xfb15b278,0x277828cf,
+ 0xc2104eae,0x1e7dd419,0x7e0a6677,0xa267fcc0,0xbee502ab,0x6288981c,0x02ff2a72,0xde92b0c5,
+ 0xcceefb07,0x108361b0,0x70f4d3de,0xac994969,0xb01bb702,0x6c762db5,0x0c019fdb,0xd06c056c,
+ 0x3504630d,0xe969f9ba,0x891e4bd4,0x5573d163,0x49f12f08,0x959cb5bf,0xf5eb07d1,0x29869d66,
+ 0xa6e63d1d,0x7a8ba7aa,0x1afc15c4,0xc6918f73,0xda137118,0x067eebaf,0x660959c1,0xba64c376,
+ 0x5f0ca517,0x83613fa0,0xe3168dce,0x3f7b1779,0x23f9e912,0xff9473a5,0x9fe3c1cb,0x438e5b7c,
+ 0x51f210be,0x8d9f8a09,0xede83867,0x3185a2d0,0x2d075cbb,0xf16ac60c,0x911d7462,0x4d70eed5,
+ 0xa81888b4,0x74751203,0x1402a06d,0xc86f3ada,0xd4edc4b1,0x08805e06,0x68f7ec68,0xb49a76df,
+ 0x4c0f7bec,0x9062e15b,0xf0155335,0x2c78c982,0x30fa37e9,0xec97ad5e,0x8ce01f30,0x508d8587,
+ 0xb5e5e3e6,0x69887951,0x09ffcb3f,0xd5925188,0xc910afe3,0x157d3554,0x750a873a,0xa9671d8d,
+ 0xbb1b564f,0x6776ccf8,0x07017e96,0xdb6ce421,0xc7ee1a4a,0x1b8380fd,0x7bf43293,0xa799a824,
+ 0x42f1ce45,0x9e9c54f2,0xfeebe69c,0x22867c2b,0x3e048240,0xe26918f7,0x821eaa99,0x5e73302e,
+ 0x77f5ad48,0xab9837ff,0xcbef8591,0x17821f26,0x0b00e14d,0xd76d7bfa,0xb71ac994,0x6b775323,
+ 0x8e1f3542,0x5272aff5,0x32051d9b,0xee68872c,0xf2ea7947,0x2e87e3f0,0x4ef0519e,0x929dcb29,
+ 0x80e180eb,0x5c8c1a5c,0x3cfba832,0xe0963285,0xfc14ccee,0x20795659,0x400ee437,0x9c637e80,
+ 0x790b18e1,0xa5668256,0xc5113038,0x197caa8f,0x05fe54e4,0xd993ce53,0xb9e47c3d,0x6589e68a,
+ 0x9d1cebb9,0x4171710e,0x2106c360,0xfd6b59d7,0xe1e9a7bc,0x3d843d0b,0x5df38f65,0x819e15d2,
+ 0x64f673b3,0xb89be904,0xd8ec5b6a,0x0481c1dd,0x18033fb6,0xc46ea501,0xa419176f,0x78748dd8,
+ 0x6a08c61a,0xb6655cad,0xd612eec3,0x0a7f7474,0x16fd8a1f,0xca9010a8,0xaae7a2c6,0x768a3871,
+ 0x93e25e10,0x4f8fc4a7,0x2ff876c9,0xf395ec7e,0xef171215,0x337a88a2,0x530d3acc,0x8f60a07b},
+
+{0x00000000,0x490d678d,0x921acf1a,0xdb17a897,0x20f48383,0x69f9e40e,0xb2ee4c99,0xfbe32b14,
+ 0x41e90706,0x08e4608b,0xd3f3c81c,0x9afeaf91,0x611d8485,0x2810e308,0xf3074b9f,0xba0a2c12,
+ 0x83d20e0c,0xcadf6981,0x11c8c116,0x58c5a69b,0xa3268d8f,0xea2bea02,0x313c4295,0x78312518,
+ 0xc23b090a,0x8b366e87,0x5021c610,0x192ca19d,0xe2cf8a89,0xabc2ed04,0x70d54593,0x39d8221e,
+ 0x036501af,0x4a686622,0x917fceb5,0xd872a938,0x2391822c,0x6a9ce5a1,0xb18b4d36,0xf8862abb,
+ 0x428c06a9,0x0b816124,0xd096c9b3,0x999bae3e,0x6278852a,0x2b75e2a7,0xf0624a30,0xb96f2dbd,
+ 0x80b70fa3,0xc9ba682e,0x12adc0b9,0x5ba0a734,0xa0438c20,0xe94eebad,0x3259433a,0x7b5424b7,
+ 0xc15e08a5,0x88536f28,0x5344c7bf,0x1a49a032,0xe1aa8b26,0xa8a7ecab,0x73b0443c,0x3abd23b1,
+ 0x06ca035e,0x4fc764d3,0x94d0cc44,0xddddabc9,0x263e80dd,0x6f33e750,0xb4244fc7,0xfd29284a,
+ 0x47230458,0x0e2e63d5,0xd539cb42,0x9c34accf,0x67d787db,0x2edae056,0xf5cd48c1,0xbcc02f4c,
+ 0x85180d52,0xcc156adf,0x1702c248,0x5e0fa5c5,0xa5ec8ed1,0xece1e95c,0x37f641cb,0x7efb2646,
+ 0xc4f10a54,0x8dfc6dd9,0x56ebc54e,0x1fe6a2c3,0xe40589d7,0xad08ee5a,0x761f46cd,0x3f122140,
+ 0x05af02f1,0x4ca2657c,0x97b5cdeb,0xdeb8aa66,0x255b8172,0x6c56e6ff,0xb7414e68,0xfe4c29e5,
+ 0x444605f7,0x0d4b627a,0xd65ccaed,0x9f51ad60,0x64b28674,0x2dbfe1f9,0xf6a8496e,0xbfa52ee3,
+ 0x867d0cfd,0xcf706b70,0x1467c3e7,0x5d6aa46a,0xa6898f7e,0xef84e8f3,0x34934064,0x7d9e27e9,
+ 0xc7940bfb,0x8e996c76,0x558ec4e1,0x1c83a36c,0xe7608878,0xae6deff5,0x757a4762,0x3c7720ef,
+ 0x0d9406bc,0x44996131,0x9f8ec9a6,0xd683ae2b,0x2d60853f,0x646de2b2,0xbf7a4a25,0xf6772da8,
+ 0x4c7d01ba,0x05706637,0xde67cea0,0x976aa92d,0x6c898239,0x2584e5b4,0xfe934d23,0xb79e2aae,
+ 0x8e4608b0,0xc74b6f3d,0x1c5cc7aa,0x5551a027,0xaeb28b33,0xe7bfecbe,0x3ca84429,0x75a523a4,
+ 0xcfaf0fb6,0x86a2683b,0x5db5c0ac,0x14b8a721,0xef5b8c35,0xa656ebb8,0x7d41432f,0x344c24a2,
+ 0x0ef10713,0x47fc609e,0x9cebc809,0xd5e6af84,0x2e058490,0x6708e31d,0xbc1f4b8a,0xf5122c07,
+ 0x4f180015,0x06156798,0xdd02cf0f,0x940fa882,0x6fec8396,0x26e1e41b,0xfdf64c8c,0xb4fb2b01,
+ 0x8d23091f,0xc42e6e92,0x1f39c605,0x5634a188,0xadd78a9c,0xe4daed11,0x3fcd4586,0x76c0220b,
+ 0xccca0e19,0x85c76994,0x5ed0c103,0x17dda68e,0xec3e8d9a,0xa533ea17,0x7e244280,0x3729250d,
+ 0x0b5e05e2,0x4253626f,0x9944caf8,0xd049ad75,0x2baa8661,0x62a7e1ec,0xb9b0497b,0xf0bd2ef6,
+ 0x4ab702e4,0x03ba6569,0xd8adcdfe,0x91a0aa73,0x6a438167,0x234ee6ea,0xf8594e7d,0xb15429f0,
+ 0x888c0bee,0xc1816c63,0x1a96c4f4,0x539ba379,0xa878886d,0xe175efe0,0x3a624777,0x736f20fa,
+ 0xc9650ce8,0x80686b65,0x5b7fc3f2,0x1272a47f,0xe9918f6b,0xa09ce8e6,0x7b8b4071,0x328627fc,
+ 0x083b044d,0x413663c0,0x9a21cb57,0xd32cacda,0x28cf87ce,0x61c2e043,0xbad548d4,0xf3d82f59,
+ 0x49d2034b,0x00df64c6,0xdbc8cc51,0x92c5abdc,0x692680c8,0x202be745,0xfb3c4fd2,0xb231285f,
+ 0x8be90a41,0xc2e46dcc,0x19f3c55b,0x50fea2d6,0xab1d89c2,0xe210ee4f,0x390746d8,0x700a2155,
+ 0xca000d47,0x830d6aca,0x581ac25d,0x1117a5d0,0xeaf48ec4,0xa3f9e949,0x78ee41de,0x31e32653},
+
+{0x00000000,0x1b280d78,0x36501af0,0x2d781788,0x6ca035e0,0x77883898,0x5af02f10,0x41d82268,
+ 0xd9406bc0,0xc26866b8,0xef107130,0xf4387c48,0xb5e05e20,0xaec85358,0x83b044d0,0x989849a8,
+ 0xb641ca37,0xad69c74f,0x8011d0c7,0x9b39ddbf,0xdae1ffd7,0xc1c9f2af,0xecb1e527,0xf799e85f,
+ 0x6f01a1f7,0x7429ac8f,0x5951bb07,0x4279b67f,0x03a19417,0x1889996f,0x35f18ee7,0x2ed9839f,
+ 0x684289d9,0x736a84a1,0x5e129329,0x453a9e51,0x04e2bc39,0x1fcab141,0x32b2a6c9,0x299aabb1,
+ 0xb102e219,0xaa2aef61,0x8752f8e9,0x9c7af591,0xdda2d7f9,0xc68ada81,0xebf2cd09,0xf0dac071,
+ 0xde0343ee,0xc52b4e96,0xe853591e,0xf37b5466,0xb2a3760e,0xa98b7b76,0x84f36cfe,0x9fdb6186,
+ 0x0743282e,0x1c6b2556,0x311332de,0x2a3b3fa6,0x6be31dce,0x70cb10b6,0x5db3073e,0x469b0a46,
+ 0xd08513b2,0xcbad1eca,0xe6d50942,0xfdfd043a,0xbc252652,0xa70d2b2a,0x8a753ca2,0x915d31da,
+ 0x09c57872,0x12ed750a,0x3f956282,0x24bd6ffa,0x65654d92,0x7e4d40ea,0x53355762,0x481d5a1a,
+ 0x66c4d985,0x7decd4fd,0x5094c375,0x4bbcce0d,0x0a64ec65,0x114ce11d,0x3c34f695,0x271cfbed,
+ 0xbf84b245,0xa4acbf3d,0x89d4a8b5,0x92fca5cd,0xd32487a5,0xc80c8add,0xe5749d55,0xfe5c902d,
+ 0xb8c79a6b,0xa3ef9713,0x8e97809b,0x95bf8de3,0xd467af8b,0xcf4fa2f3,0xe237b57b,0xf91fb803,
+ 0x6187f1ab,0x7aaffcd3,0x57d7eb5b,0x4cffe623,0x0d27c44b,0x160fc933,0x3b77debb,0x205fd3c3,
+ 0x0e86505c,0x15ae5d24,0x38d64aac,0x23fe47d4,0x622665bc,0x790e68c4,0x54767f4c,0x4f5e7234,
+ 0xd7c63b9c,0xccee36e4,0xe196216c,0xfabe2c14,0xbb660e7c,0xa04e0304,0x8d36148c,0x961e19f4,
+ 0xa5cb3ad3,0xbee337ab,0x939b2023,0x88b32d5b,0xc96b0f33,0xd243024b,0xff3b15c3,0xe41318bb,
+ 0x7c8b5113,0x67a35c6b,0x4adb4be3,0x51f3469b,0x102b64f3,0x0b03698b,0x267b7e03,0x3d53737b,
+ 0x138af0e4,0x08a2fd9c,0x25daea14,0x3ef2e76c,0x7f2ac504,0x6402c87c,0x497adff4,0x5252d28c,
+ 0xcaca9b24,0xd1e2965c,0xfc9a81d4,0xe7b28cac,0xa66aaec4,0xbd42a3bc,0x903ab434,0x8b12b94c,
+ 0xcd89b30a,0xd6a1be72,0xfbd9a9fa,0xe0f1a482,0xa12986ea,0xba018b92,0x97799c1a,0x8c519162,
+ 0x14c9d8ca,0x0fe1d5b2,0x2299c23a,0x39b1cf42,0x7869ed2a,0x6341e052,0x4e39f7da,0x5511faa2,
+ 0x7bc8793d,0x60e07445,0x4d9863cd,0x56b06eb5,0x17684cdd,0x0c4041a5,0x2138562d,0x3a105b55,
+ 0xa28812fd,0xb9a01f85,0x94d8080d,0x8ff00575,0xce28271d,0xd5002a65,0xf8783ded,0xe3503095,
+ 0x754e2961,0x6e662419,0x431e3391,0x58363ee9,0x19ee1c81,0x02c611f9,0x2fbe0671,0x34960b09,
+ 0xac0e42a1,0xb7264fd9,0x9a5e5851,0x81765529,0xc0ae7741,0xdb867a39,0xf6fe6db1,0xedd660c9,
+ 0xc30fe356,0xd827ee2e,0xf55ff9a6,0xee77f4de,0xafafd6b6,0xb487dbce,0x99ffcc46,0x82d7c13e,
+ 0x1a4f8896,0x016785ee,0x2c1f9266,0x37379f1e,0x76efbd76,0x6dc7b00e,0x40bfa786,0x5b97aafe,
+ 0x1d0ca0b8,0x0624adc0,0x2b5cba48,0x3074b730,0x71ac9558,0x6a849820,0x47fc8fa8,0x5cd482d0,
+ 0xc44ccb78,0xdf64c600,0xf21cd188,0xe934dcf0,0xa8ecfe98,0xb3c4f3e0,0x9ebce468,0x8594e910,
+ 0xab4d6a8f,0xb06567f7,0x9d1d707f,0x86357d07,0xc7ed5f6f,0xdcc55217,0xf1bd459f,0xea9548e7,
+ 0x720d014f,0x69250c37,0x445d1bbf,0x5f7516c7,0x1ead34af,0x058539d7,0x28fd2e5f,0x33d52327},
+
+{0x00000000,0x4f576811,0x9eaed022,0xd1f9b833,0x399cbdf3,0x76cbd5e2,0xa7326dd1,0xe86505c0,
+ 0x73397be6,0x3c6e13f7,0xed97abc4,0xa2c0c3d5,0x4aa5c615,0x05f2ae04,0xd40b1637,0x9b5c7e26,
+ 0xe672f7cc,0xa9259fdd,0x78dc27ee,0x378b4fff,0xdfee4a3f,0x90b9222e,0x41409a1d,0x0e17f20c,
+ 0x954b8c2a,0xda1ce43b,0x0be55c08,0x44b23419,0xacd731d9,0xe38059c8,0x3279e1fb,0x7d2e89ea,
+ 0xc824f22f,0x87739a3e,0x568a220d,0x19dd4a1c,0xf1b84fdc,0xbeef27cd,0x6f169ffe,0x2041f7ef,
+ 0xbb1d89c9,0xf44ae1d8,0x25b359eb,0x6ae431fa,0x8281343a,0xcdd65c2b,0x1c2fe418,0x53788c09,
+ 0x2e5605e3,0x61016df2,0xb0f8d5c1,0xffafbdd0,0x17cab810,0x589dd001,0x89646832,0xc6330023,
+ 0x5d6f7e05,0x12381614,0xc3c1ae27,0x8c96c636,0x64f3c3f6,0x2ba4abe7,0xfa5d13d4,0xb50a7bc5,
+ 0x9488f9e9,0xdbdf91f8,0x0a2629cb,0x457141da,0xad14441a,0xe2432c0b,0x33ba9438,0x7cedfc29,
+ 0xe7b1820f,0xa8e6ea1e,0x791f522d,0x36483a3c,0xde2d3ffc,0x917a57ed,0x4083efde,0x0fd487cf,
+ 0x72fa0e25,0x3dad6634,0xec54de07,0xa303b616,0x4b66b3d6,0x0431dbc7,0xd5c863f4,0x9a9f0be5,
+ 0x01c375c3,0x4e941dd2,0x9f6da5e1,0xd03acdf0,0x385fc830,0x7708a021,0xa6f11812,0xe9a67003,
+ 0x5cac0bc6,0x13fb63d7,0xc202dbe4,0x8d55b3f5,0x6530b635,0x2a67de24,0xfb9e6617,0xb4c90e06,
+ 0x2f957020,0x60c21831,0xb13ba002,0xfe6cc813,0x1609cdd3,0x595ea5c2,0x88a71df1,0xc7f075e0,
+ 0xbadefc0a,0xf589941b,0x24702c28,0x6b274439,0x834241f9,0xcc1529e8,0x1dec91db,0x52bbf9ca,
+ 0xc9e787ec,0x86b0effd,0x574957ce,0x181e3fdf,0xf07b3a1f,0xbf2c520e,0x6ed5ea3d,0x2182822c,
+ 0x2dd0ee65,0x62878674,0xb37e3e47,0xfc295656,0x144c5396,0x5b1b3b87,0x8ae283b4,0xc5b5eba5,
+ 0x5ee99583,0x11befd92,0xc04745a1,0x8f102db0,0x67752870,0x28224061,0xf9dbf852,0xb68c9043,
+ 0xcba219a9,0x84f571b8,0x550cc98b,0x1a5ba19a,0xf23ea45a,0xbd69cc4b,0x6c907478,0x23c71c69,
+ 0xb89b624f,0xf7cc0a5e,0x2635b26d,0x6962da7c,0x8107dfbc,0xce50b7ad,0x1fa90f9e,0x50fe678f,
+ 0xe5f41c4a,0xaaa3745b,0x7b5acc68,0x340da479,0xdc68a1b9,0x933fc9a8,0x42c6719b,0x0d91198a,
+ 0x96cd67ac,0xd99a0fbd,0x0863b78e,0x4734df9f,0xaf51da5f,0xe006b24e,0x31ff0a7d,0x7ea8626c,
+ 0x0386eb86,0x4cd18397,0x9d283ba4,0xd27f53b5,0x3a1a5675,0x754d3e64,0xa4b48657,0xebe3ee46,
+ 0x70bf9060,0x3fe8f871,0xee114042,0xa1462853,0x49232d93,0x06744582,0xd78dfdb1,0x98da95a0,
+ 0xb958178c,0xf60f7f9d,0x27f6c7ae,0x68a1afbf,0x80c4aa7f,0xcf93c26e,0x1e6a7a5d,0x513d124c,
+ 0xca616c6a,0x8536047b,0x54cfbc48,0x1b98d459,0xf3fdd199,0xbcaab988,0x6d5301bb,0x220469aa,
+ 0x5f2ae040,0x107d8851,0xc1843062,0x8ed35873,0x66b65db3,0x29e135a2,0xf8188d91,0xb74fe580,
+ 0x2c139ba6,0x6344f3b7,0xb2bd4b84,0xfdea2395,0x158f2655,0x5ad84e44,0x8b21f677,0xc4769e66,
+ 0x717ce5a3,0x3e2b8db2,0xefd23581,0xa0855d90,0x48e05850,0x07b73041,0xd64e8872,0x9919e063,
+ 0x02459e45,0x4d12f654,0x9ceb4e67,0xd3bc2676,0x3bd923b6,0x748e4ba7,0xa577f394,0xea209b85,
+ 0x970e126f,0xd8597a7e,0x09a0c24d,0x46f7aa5c,0xae92af9c,0xe1c5c78d,0x303c7fbe,0x7f6b17af,
+ 0xe4376989,0xab600198,0x7a99b9ab,0x35ced1ba,0xddabd47a,0x92fcbc6b,0x43050458,0x0c526c49},
+
+{0x00000000,0x5ba1dcca,0xb743b994,0xece2655e,0x6a466e9f,0x31e7b255,0xdd05d70b,0x86a40bc1,
+ 0xd48cdd3e,0x8f2d01f4,0x63cf64aa,0x386eb860,0xbecab3a1,0xe56b6f6b,0x09890a35,0x5228d6ff,
+ 0xadd8a7cb,0xf6797b01,0x1a9b1e5f,0x413ac295,0xc79ec954,0x9c3f159e,0x70dd70c0,0x2b7cac0a,
+ 0x79547af5,0x22f5a63f,0xce17c361,0x95b61fab,0x1312146a,0x48b3c8a0,0xa451adfe,0xfff07134,
+ 0x5f705221,0x04d18eeb,0xe833ebb5,0xb392377f,0x35363cbe,0x6e97e074,0x8275852a,0xd9d459e0,
+ 0x8bfc8f1f,0xd05d53d5,0x3cbf368b,0x671eea41,0xe1bae180,0xba1b3d4a,0x56f95814,0x0d5884de,
+ 0xf2a8f5ea,0xa9092920,0x45eb4c7e,0x1e4a90b4,0x98ee9b75,0xc34f47bf,0x2fad22e1,0x740cfe2b,
+ 0x262428d4,0x7d85f41e,0x91679140,0xcac64d8a,0x4c62464b,0x17c39a81,0xfb21ffdf,0xa0802315,
+ 0xbee0a442,0xe5417888,0x09a31dd6,0x5202c11c,0xd4a6cadd,0x8f071617,0x63e57349,0x3844af83,
+ 0x6a6c797c,0x31cda5b6,0xdd2fc0e8,0x868e1c22,0x002a17e3,0x5b8bcb29,0xb769ae77,0xecc872bd,
+ 0x13380389,0x4899df43,0xa47bba1d,0xffda66d7,0x797e6d16,0x22dfb1dc,0xce3dd482,0x959c0848,
+ 0xc7b4deb7,0x9c15027d,0x70f76723,0x2b56bbe9,0xadf2b028,0xf6536ce2,0x1ab109bc,0x4110d576,
+ 0xe190f663,0xba312aa9,0x56d34ff7,0x0d72933d,0x8bd698fc,0xd0774436,0x3c952168,0x6734fda2,
+ 0x351c2b5d,0x6ebdf797,0x825f92c9,0xd9fe4e03,0x5f5a45c2,0x04fb9908,0xe819fc56,0xb3b8209c,
+ 0x4c4851a8,0x17e98d62,0xfb0be83c,0xa0aa34f6,0x260e3f37,0x7dafe3fd,0x914d86a3,0xcaec5a69,
+ 0x98c48c96,0xc365505c,0x2f873502,0x7426e9c8,0xf282e209,0xa9233ec3,0x45c15b9d,0x1e608757,
+ 0x79005533,0x22a189f9,0xce43eca7,0x95e2306d,0x13463bac,0x48e7e766,0xa4058238,0xffa45ef2,
+ 0xad8c880d,0xf62d54c7,0x1acf3199,0x416eed53,0xc7cae692,0x9c6b3a58,0x70895f06,0x2b2883cc,
+ 0xd4d8f2f8,0x8f792e32,0x639b4b6c,0x383a97a6,0xbe9e9c67,0xe53f40ad,0x09dd25f3,0x527cf939,
+ 0x00542fc6,0x5bf5f30c,0xb7179652,0xecb64a98,0x6a124159,0x31b39d93,0xdd51f8cd,0x86f02407,
+ 0x26700712,0x7dd1dbd8,0x9133be86,0xca92624c,0x4c36698d,0x1797b547,0xfb75d019,0xa0d40cd3,
+ 0xf2fcda2c,0xa95d06e6,0x45bf63b8,0x1e1ebf72,0x98bab4b3,0xc31b6879,0x2ff90d27,0x7458d1ed,
+ 0x8ba8a0d9,0xd0097c13,0x3ceb194d,0x674ac587,0xe1eece46,0xba4f128c,0x56ad77d2,0x0d0cab18,
+ 0x5f247de7,0x0485a12d,0xe867c473,0xb3c618b9,0x35621378,0x6ec3cfb2,0x8221aaec,0xd9807626,
+ 0xc7e0f171,0x9c412dbb,0x70a348e5,0x2b02942f,0xada69fee,0xf6074324,0x1ae5267a,0x4144fab0,
+ 0x136c2c4f,0x48cdf085,0xa42f95db,0xff8e4911,0x792a42d0,0x228b9e1a,0xce69fb44,0x95c8278e,
+ 0x6a3856ba,0x31998a70,0xdd7bef2e,0x86da33e4,0x007e3825,0x5bdfe4ef,0xb73d81b1,0xec9c5d7b,
+ 0xbeb48b84,0xe515574e,0x09f73210,0x5256eeda,0xd4f2e51b,0x8f5339d1,0x63b15c8f,0x38108045,
+ 0x9890a350,0xc3317f9a,0x2fd31ac4,0x7472c60e,0xf2d6cdcf,0xa9771105,0x4595745b,0x1e34a891,
+ 0x4c1c7e6e,0x17bda2a4,0xfb5fc7fa,0xa0fe1b30,0x265a10f1,0x7dfbcc3b,0x9119a965,0xcab875af,
+ 0x3548049b,0x6ee9d851,0x820bbd0f,0xd9aa61c5,0x5f0e6a04,0x04afb6ce,0xe84dd390,0xb3ec0f5a,
+ 0xe1c4d9a5,0xba65056f,0x56876031,0x0d26bcfb,0x8b82b73a,0xd0236bf0,0x3cc10eae,0x6760d264}};
diff --git a/thirdparty/libogg/framing.c b/thirdparty/libogg/framing.c
index 79fc715c8c..83601199ad 100644
--- a/thirdparty/libogg/framing.c
+++ b/thirdparty/libogg/framing.c
@@ -5,14 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2018 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: code raw packets into framed OggSquish stream and
decode Ogg streams back into raw packets
- last mod: $Id$
note: The CRC code is directly derived from public domain code by
Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html
@@ -20,6 +19,10 @@
********************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <limits.h>
#include <string.h>
@@ -45,7 +48,7 @@ int ogg_page_eos(const ogg_page *og){
ogg_int64_t ogg_page_granulepos(const ogg_page *og){
unsigned char *page=og->header;
- ogg_int64_t granulepos=page[13]&(0xff);
+ ogg_uint64_t granulepos=page[13]&(0xff);
granulepos= (granulepos<<8)|(page[12]&0xff);
granulepos= (granulepos<<8)|(page[11]&0xff);
granulepos= (granulepos<<8)|(page[10]&0xff);
@@ -53,21 +56,21 @@ ogg_int64_t ogg_page_granulepos(const ogg_page *og){
granulepos= (granulepos<<8)|(page[8]&0xff);
granulepos= (granulepos<<8)|(page[7]&0xff);
granulepos= (granulepos<<8)|(page[6]&0xff);
- return(granulepos);
+ return((ogg_int64_t)granulepos);
}
int ogg_page_serialno(const ogg_page *og){
- return(og->header[14] |
- (og->header[15]<<8) |
- (og->header[16]<<16) |
- (og->header[17]<<24));
+ return((int)((ogg_uint32_t)og->header[14]) |
+ ((ogg_uint32_t)og->header[15]<<8) |
+ ((ogg_uint32_t)og->header[16]<<16) |
+ ((ogg_uint32_t)og->header[17]<<24));
}
long ogg_page_pageno(const ogg_page *og){
- return(og->header[18] |
- (og->header[19]<<8) |
- (og->header[20]<<16) |
- (og->header[21]<<24));
+ return((long)((ogg_uint32_t)og->header[18]) |
+ ((ogg_uint32_t)og->header[19]<<8) |
+ ((ogg_uint32_t)og->header[20]<<16) |
+ ((ogg_uint32_t)og->header[21]<<24));
}
@@ -99,90 +102,31 @@ int ogg_page_packets(const ogg_page *og){
#if 0
/* helper to initialize lookup for direct-table CRC (illustrative; we
- use the static init below) */
-
-static ogg_uint32_t _ogg_crc_entry(unsigned long index){
- int i;
- unsigned long r;
-
- r = index << 24;
- for (i=0; i<8; i++)
- if (r & 0x80000000UL)
- r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator
- polynomial, although we use an
- unreflected alg and an init/final
- of 0, not 0xffffffff */
- else
- r<<=1;
- return (r & 0xffffffffUL);
+ use the static init in crctable.h) */
+
+static void _ogg_crc_init(){
+ int i, j;
+ ogg_uint32_t polynomial, crc;
+ polynomial = 0x04c11db7; /* The same as the ethernet generator
+ polynomial, although we use an
+ unreflected alg and an init/final
+ of 0, not 0xffffffff */
+ for (i = 0; i <= 0xFF; i++){
+ crc = i << 24;
+
+ for (j = 0; j < 8; j++)
+ crc = (crc << 1) ^ (crc & (1 << 31) ? polynomial : 0);
+
+ crc_lookup[0][i] = crc;
+ }
+
+ for (i = 0; i <= 0xFF; i++)
+ for (j = 1; j < 8; j++)
+ crc_lookup[j][i] = crc_lookup[0][(crc_lookup[j - 1][i] >> 24) & 0xFF] ^ (crc_lookup[j - 1][i] << 8);
}
#endif
-static const ogg_uint32_t crc_lookup[256]={
- 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
- 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
- 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
- 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
- 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
- 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
- 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
- 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
- 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
- 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
- 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
- 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
- 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
- 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
- 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
- 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
- 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
- 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
- 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
- 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
- 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
- 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
- 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
- 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
- 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
- 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
- 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
- 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
- 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
- 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
- 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
- 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
- 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
- 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
- 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
- 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
- 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
- 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
- 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
- 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
- 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
- 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
- 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
- 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
- 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
- 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
- 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
- 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
- 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
- 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
- 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
- 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
- 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
- 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
- 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
- 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
- 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
- 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
- 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
- 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
- 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
- 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
- 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
- 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
+#include "crctable.h"
/* init the encode/decode logical stream state */
@@ -290,10 +234,27 @@ static int _os_lacing_expand(ogg_stream_state *os,long needed){
/* Direct table CRC; note that this will be faster in the future if we
perform the checksum simultaneously with other copies */
+static ogg_uint32_t _os_update_crc(ogg_uint32_t crc, unsigned char *buffer, int size){
+ while (size>=8){
+ crc^=((ogg_uint32_t)buffer[0]<<24)|((ogg_uint32_t)buffer[1]<<16)|((ogg_uint32_t)buffer[2]<<8)|((ogg_uint32_t)buffer[3]);
+
+ crc=crc_lookup[7][ crc>>24 ]^crc_lookup[6][(crc>>16)&0xFF]^
+ crc_lookup[5][(crc>> 8)&0xFF]^crc_lookup[4][ crc &0xFF]^
+ crc_lookup[3][buffer[4] ]^crc_lookup[2][buffer[5] ]^
+ crc_lookup[1][buffer[6] ]^crc_lookup[0][buffer[7] ];
+
+ buffer+=8;
+ size-=8;
+ }
+
+ while (size--)
+ crc=(crc<<8)^crc_lookup[0][((crc >> 24)&0xff)^*buffer++];
+ return crc;
+}
+
void ogg_page_checksum_set(ogg_page *og){
if(og){
ogg_uint32_t crc_reg=0;
- int i;
/* safety; needed for API behavior, but not framing code */
og->header[22]=0;
@@ -301,10 +262,8 @@ void ogg_page_checksum_set(ogg_page *og){
og->header[24]=0;
og->header[25]=0;
- for(i=0;i<og->header_len;i++)
- crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
- for(i=0;i<og->body_len;i++)
- crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
+ crc_reg=_os_update_crc(crc_reg,og->header,og->header_len);
+ crc_reg=_os_update_crc(crc_reg,og->body,og->body_len);
og->header[22]=(unsigned char)(crc_reg&0xff);
og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
@@ -414,9 +373,9 @@ static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int
}else{
/* The extra packets_done, packet_just_done logic here attempts to do two things:
- 1) Don't unneccessarily span pages.
+ 1) Don't unnecessarily span pages.
2) Unless necessary, don't flush pages if there are less than four packets on
- them; this expands page size to reduce unneccessary overhead if incoming packets
+ them; this expands page size to reduce unnecessary overhead if incoming packets
are large.
These are not necessary behaviors, just 'always better than naive flushing'
without requiring an application to explicitly request a specific optimized
@@ -723,16 +682,15 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
/* replace the computed checksum with the one actually read in */
memcpy(page+22,chksum,4);
+#ifndef DISABLE_CRC
/* Bad checksum. Lose sync */
goto sync_fail;
+#endif
}
}
/* yes, have a whole page all ready to go */
{
- unsigned char *page=oy->data+oy->returned;
- long bytes;
-
if(og){
og->header=page;
og->header_len=oy->headerbytes;
@@ -1814,6 +1772,7 @@ int main(void){
test_pack(packets,headret,0,0,0);
}
+#ifndef DISABLE_CRC
{
/* test for the libogg 1.1.1 resync in large continuation bug
found by Josh Coalson) */
@@ -1823,6 +1782,9 @@ int main(void){
fprintf(stderr,"testing continuation resync in very large packets... ");
test_pack(packets,headret,100,2,3);
}
+#else
+ fprintf(stderr,"Skipping continuation resync test due to --disable-crc\n");
+#endif
{
/* term only page. why not? */
@@ -2084,6 +2046,7 @@ int main(void){
fprintf(stderr,"ok.\n");
}
+#ifndef DISABLE_CRC
/* Test recapture: page + garbage + page */
{
ogg_page og_de;
@@ -2125,6 +2088,9 @@ int main(void){
fprintf(stderr,"ok.\n");
}
+#else
+ fprintf(stderr,"Skipping recapture test due to --disable-crc\n");
+#endif
/* Free page data that was previously copied */
{
@@ -2133,6 +2099,9 @@ int main(void){
}
}
}
+ ogg_sync_clear(&oy);
+ ogg_stream_clear(&os_en);
+ ogg_stream_clear(&os_de);
return(0);
}
diff --git a/thirdparty/libogg/ogg/config_types.h b/thirdparty/libogg/ogg/config_types.h
index e630657547..3574a8ad44 100644
--- a/thirdparty/libogg/ogg/config_types.h
+++ b/thirdparty/libogg/ogg/config_types.h
@@ -8,5 +8,6 @@ typedef uint16_t ogg_uint16_t;
typedef int32_t ogg_int32_t;
typedef uint32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
+typedef uint64_t ogg_uint64_t;
#endif
diff --git a/thirdparty/libogg/ogg/ogg.h b/thirdparty/libogg/ogg/ogg.h
index 7609fc24d6..c4325aa76d 100644
--- a/thirdparty/libogg/ogg/ogg.h
+++ b/thirdparty/libogg/ogg/ogg.h
@@ -11,7 +11,6 @@
********************************************************************
function: toplevel libogg include
- last mod: $Id$
********************************************************************/
#ifndef _OGG_H
diff --git a/thirdparty/libogg/ogg/os_types.h b/thirdparty/libogg/ogg/os_types.h
index b8f56308b5..e655a1d628 100644
--- a/thirdparty/libogg/ogg/os_types.h
+++ b/thirdparty/libogg/ogg/os_types.h
@@ -10,8 +10,7 @@
* *
********************************************************************
- function: #ifdef jail to whip a few platforms into the UNIX ideal.
- last mod: $Id$
+ function: Define a consistent set of types on each platform.
********************************************************************/
#ifndef _OS_TYPES_H
@@ -44,6 +43,7 @@
typedef unsigned long long ogg_uint64_t;
# elif defined(__MWERKS__)
typedef long long ogg_int64_t;
+ typedef unsigned long long ogg_uint64_t;
typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef short ogg_int16_t;
@@ -62,6 +62,7 @@
typedef __int64 ogg_int64_t;
typedef __int32 ogg_int32_t;
typedef unsigned __int32 ogg_uint32_t;
+ typedef unsigned __int64 ogg_uint64_t;
typedef __int16 ogg_int16_t;
typedef unsigned __int16 ogg_uint16_t;
# endif
@@ -69,12 +70,13 @@
#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
-# include <inttypes.h>
+# include <sys/types.h>
typedef int16_t ogg_int16_t;
- typedef uint16_t ogg_uint16_t;
+ typedef u_int16_t ogg_uint16_t;
typedef int32_t ogg_int32_t;
- typedef uint32_t ogg_uint32_t;
+ typedef u_int32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
+ typedef u_int64_t ogg_uint64_t;
#elif defined(__HAIKU__)
@@ -85,6 +87,7 @@
typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long ogg_int64_t;
+ typedef unsigned long long ogg_uint64_t;
#elif defined(__BEOS__)
@@ -95,6 +98,7 @@
typedef int32_t ogg_int32_t;
typedef uint32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
+ typedef uint64_t ogg_uint64_t;
#elif defined (__EMX__)
@@ -104,6 +108,8 @@
typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long ogg_int64_t;
+ typedef unsigned long long ogg_uint64_t;
+
#elif defined (DJGPP)
@@ -112,11 +118,13 @@
typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long ogg_int64_t;
+ typedef unsigned long long ogg_uint64_t;
#elif defined(R5900)
/* PS2 EE */
typedef long ogg_int64_t;
+ typedef unsigned long ogg_uint64_t;
typedef int ogg_int32_t;
typedef unsigned ogg_uint32_t;
typedef short ogg_int16_t;
@@ -129,6 +137,7 @@
typedef signed int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long int ogg_int64_t;
+ typedef unsigned long long int ogg_uint64_t;
#elif defined(__TMS320C6X__)
@@ -138,6 +147,7 @@
typedef signed int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long int ogg_int64_t;
+ typedef unsigned long long int ogg_uint64_t;
#else
diff --git a/thirdparty/zstd/common/bitstream.h b/thirdparty/zstd/common/bitstream.h
index d955bd677b..7bdb060460 100644
--- a/thirdparty/zstd/common/bitstream.h
+++ b/thirdparty/zstd/common/bitstream.h
@@ -57,6 +57,8 @@ extern "C" {
=========================================*/
#if defined(__BMI__) && defined(__GNUC__)
# include <immintrin.h> /* support for bextr (experimental) */
+#elif defined(__ICCARM__)
+# include <intrinsics.h>
#endif
#define STREAM_ACCUMULATOR_MIN_32 25
@@ -163,6 +165,8 @@ MEM_STATIC unsigned BIT_highbit32 (U32 val)
return (unsigned) r;
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
return 31 - __builtin_clz (val);
+# elif defined(__ICCARM__) /* IAR Intrinsic */
+ return 31 - __CLZ(val);
# else /* Software version */
static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
11, 14, 16, 18, 22, 25, 3, 30,
diff --git a/thirdparty/zstd/common/compiler.h b/thirdparty/zstd/common/compiler.h
index 87bf51ae8c..6686b837d6 100644
--- a/thirdparty/zstd/common/compiler.h
+++ b/thirdparty/zstd/common/compiler.h
@@ -23,7 +23,7 @@
# define INLINE_KEYWORD
#endif
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__ICCARM__)
# define FORCE_INLINE_ATTR __attribute__((always_inline))
#elif defined(_MSC_VER)
# define FORCE_INLINE_ATTR __forceinline
@@ -65,7 +65,7 @@
#ifdef _MSC_VER
# define FORCE_NOINLINE static __declspec(noinline)
#else
-# ifdef __GNUC__
+# if defined(__GNUC__) || defined(__ICCARM__)
# define FORCE_NOINLINE static __attribute__((__noinline__))
# else
# define FORCE_NOINLINE static
@@ -76,7 +76,7 @@
#ifndef __has_attribute
#define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__ICCARM__)
# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
#else
# define TARGET_ATTRIBUTE(target)
diff --git a/thirdparty/zstd/common/mem.h b/thirdparty/zstd/common/mem.h
index 5da248756f..c10d7f61e1 100644
--- a/thirdparty/zstd/common/mem.h
+++ b/thirdparty/zstd/common/mem.h
@@ -102,7 +102,7 @@ MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (size
#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
# define MEM_FORCE_MEMORY_ACCESS 2
-# elif defined(__INTEL_COMPILER) || defined(__GNUC__)
+# elif defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__)
# define MEM_FORCE_MEMORY_ACCESS 1
# endif
#endif
diff --git a/thirdparty/zstd/common/xxhash.c b/thirdparty/zstd/common/xxhash.c
index 30599aaae4..99d2459621 100644
--- a/thirdparty/zstd/common/xxhash.c
+++ b/thirdparty/zstd/common/xxhash.c
@@ -53,7 +53,8 @@
# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
# define XXH_FORCE_MEMORY_ACCESS 2
# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \
- (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
+ (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) || \
+ defined(__ICCARM__)
# define XXH_FORCE_MEMORY_ACCESS 1
# endif
#endif
@@ -120,7 +121,7 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcp
# define INLINE_KEYWORD
#endif
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__ICCARM__)
# define FORCE_INLINE_ATTR __attribute__((always_inline))
#elif defined(_MSC_VER)
# define FORCE_INLINE_ATTR __forceinline
@@ -206,7 +207,12 @@ static U64 XXH_read64(const void* memPtr)
# define XXH_rotl32(x,r) _rotl(x,r)
# define XXH_rotl64(x,r) _rotl64(x,r)
#else
+#if defined(__ICCARM__)
+# include <intrinsics.h>
+# define XXH_rotl32(x,r) __ROR(x,(32 - r))
+#else
# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
+#endif
# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
#endif
diff --git a/thirdparty/zstd/common/zstd_internal.h b/thirdparty/zstd/common/zstd_internal.h
index 81b16eac2e..585fd6b19e 100644
--- a/thirdparty/zstd/common/zstd_internal.h
+++ b/thirdparty/zstd/common/zstd_internal.h
@@ -56,9 +56,9 @@ extern "C" {
/**
* Return the specified error if the condition evaluates to true.
*
- * In debug modes, prints additional information. In order to do that
- * (particularly, printing the conditional that failed), this can't just wrap
- * RETURN_ERROR().
+ * In debug modes, prints additional information.
+ * In order to do that (particularly, printing the conditional that failed),
+ * this can't just wrap RETURN_ERROR().
*/
#define RETURN_ERROR_IF(cond, err, ...) \
if (cond) { \
@@ -324,6 +324,8 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus
return (unsigned)r;
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
return 31 - __builtin_clz(val);
+# elif defined(__ICCARM__) /* IAR Intrinsic */
+ return 31 - __CLZ(val);
# else /* Software version */
static const U32 DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
U32 v = val;
diff --git a/thirdparty/zstd/compress/zstd_compress.c b/thirdparty/zstd/compress/zstd_compress.c
index 1476512580..cd73db13be 100644
--- a/thirdparty/zstd/compress/zstd_compress.c
+++ b/thirdparty/zstd/compress/zstd_compress.c
@@ -21,6 +21,8 @@
#define HUF_STATIC_LINKING_ONLY
#include "huf.h"
#include "zstd_compress_internal.h"
+#include "zstd_compress_sequences.h"
+#include "zstd_compress_literals.h"
#include "zstd_fast.h"
#include "zstd_double_fast.h"
#include "zstd_lazy.h"
@@ -397,18 +399,6 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
}
}
-/* ZSTD_cParam_withinBounds:
- * @return 1 if value is within cParam bounds,
- * 0 otherwise */
-static int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)
-{
- ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);
- if (ZSTD_isError(bounds.error)) return 0;
- if (value < bounds.lowerBound) return 0;
- if (value > bounds.upperBound) return 0;
- return 1;
-}
-
/* ZSTD_cParam_clampBounds:
* Clamps the value into the bounded range.
*/
@@ -1903,155 +1893,6 @@ static size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* s
return ZSTD_blockHeaderSize + srcSize;
}
-static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
-{
- BYTE* const ostart = (BYTE* const)dst;
- U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
-
- RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall);
-
- switch(flSize)
- {
- case 1: /* 2 - 1 - 5 */
- ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
- break;
- case 2: /* 2 - 2 - 12 */
- MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
- break;
- case 3: /* 2 - 2 - 20 */
- MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
- break;
- default: /* not necessary : flSize is {1,2,3} */
- assert(0);
- }
-
- memcpy(ostart + flSize, src, srcSize);
- return srcSize + flSize;
-}
-
-static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
-{
- BYTE* const ostart = (BYTE* const)dst;
- U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
-
- (void)dstCapacity; /* dstCapacity already guaranteed to be >=4, hence large enough */
-
- switch(flSize)
- {
- case 1: /* 2 - 1 - 5 */
- ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
- break;
- case 2: /* 2 - 2 - 12 */
- MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
- break;
- case 3: /* 2 - 2 - 20 */
- MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
- break;
- default: /* not necessary : flSize is {1,2,3} */
- assert(0);
- }
-
- ostart[flSize] = *(const BYTE*)src;
- return flSize+1;
-}
-
-
-/* ZSTD_minGain() :
- * minimum compression required
- * to generate a compress block or a compressed literals section.
- * note : use same formula for both situations */
-static size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
-{
- U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6;
- ZSTD_STATIC_ASSERT(ZSTD_btultra == 8);
- assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
- return (srcSize >> minlog) + 2;
-}
-
-static size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
- ZSTD_hufCTables_t* nextHuf,
- ZSTD_strategy strategy, int disableLiteralCompression,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- void* workspace, size_t wkspSize,
- const int bmi2)
-{
- size_t const minGain = ZSTD_minGain(srcSize, strategy);
- size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
- BYTE* const ostart = (BYTE*)dst;
- U32 singleStream = srcSize < 256;
- symbolEncodingType_e hType = set_compressed;
- size_t cLitSize;
-
- DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i)",
- disableLiteralCompression);
-
- /* Prepare nextEntropy assuming reusing the existing table */
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
-
- if (disableLiteralCompression)
- return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
-
- /* small ? don't even attempt compression (speed opt) */
-# define COMPRESS_LITERALS_SIZE_MIN 63
- { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
- if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
- }
-
- RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, "not enough space for compression");
- { HUF_repeat repeat = prevHuf->repeatMode;
- int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
- if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
- cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
- workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2)
- : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
- workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
- if (repeat != HUF_repeat_none) {
- /* reused the existing table */
- hType = set_repeat;
- }
- }
-
- if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
- return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
- }
- if (cLitSize==1) {
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
- return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
- }
-
- if (hType == set_compressed) {
- /* using a newly constructed table */
- nextHuf->repeatMode = HUF_repeat_check;
- }
-
- /* Build header */
- switch(lhSize)
- {
- case 3: /* 2 - 2 - 10 - 10 */
- { U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
- MEM_writeLE24(ostart, lhc);
- break;
- }
- case 4: /* 2 - 2 - 14 - 14 */
- { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
- MEM_writeLE32(ostart, lhc);
- break;
- }
- case 5: /* 2 - 2 - 18 - 18 */
- { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
- MEM_writeLE32(ostart, lhc);
- ostart[4] = (BYTE)(cLitSize >> 10);
- break;
- }
- default: /* not possible : lhSize is {3,4,5} */
- assert(0);
- }
- return lhSize+cLitSize;
-}
-
-
void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
{
const seqDef* const sequences = seqStorePtr->sequencesStart;
@@ -2074,418 +1915,6 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
}
-
-/**
- * -log2(x / 256) lookup table for x in [0, 256).
- * If x == 0: Return 0
- * Else: Return floor(-log2(x / 256) * 256)
- */
-static unsigned const kInverseProbabilityLog256[256] = {
- 0, 2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162,
- 1130, 1100, 1073, 1047, 1024, 1001, 980, 960, 941, 923, 906, 889,
- 874, 859, 844, 830, 817, 804, 791, 779, 768, 756, 745, 734,
- 724, 714, 704, 694, 685, 676, 667, 658, 650, 642, 633, 626,
- 618, 610, 603, 595, 588, 581, 574, 567, 561, 554, 548, 542,
- 535, 529, 523, 517, 512, 506, 500, 495, 489, 484, 478, 473,
- 468, 463, 458, 453, 448, 443, 438, 434, 429, 424, 420, 415,
- 411, 407, 402, 398, 394, 390, 386, 382, 377, 373, 370, 366,
- 362, 358, 354, 350, 347, 343, 339, 336, 332, 329, 325, 322,
- 318, 315, 311, 308, 305, 302, 298, 295, 292, 289, 286, 282,
- 279, 276, 273, 270, 267, 264, 261, 258, 256, 253, 250, 247,
- 244, 241, 239, 236, 233, 230, 228, 225, 222, 220, 217, 215,
- 212, 209, 207, 204, 202, 199, 197, 194, 192, 190, 187, 185,
- 182, 180, 178, 175, 173, 171, 168, 166, 164, 162, 159, 157,
- 155, 153, 151, 149, 146, 144, 142, 140, 138, 136, 134, 132,
- 130, 128, 126, 123, 121, 119, 117, 115, 114, 112, 110, 108,
- 106, 104, 102, 100, 98, 96, 94, 93, 91, 89, 87, 85,
- 83, 82, 80, 78, 76, 74, 73, 71, 69, 67, 66, 64,
- 62, 61, 59, 57, 55, 54, 52, 50, 49, 47, 46, 44,
- 42, 41, 39, 37, 36, 34, 33, 31, 30, 28, 26, 25,
- 23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7,
- 5, 4, 2, 1,
-};
-
-
-/**
- * Returns the cost in bits of encoding the distribution described by count
- * using the entropy bound.
- */
-static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total)
-{
- unsigned cost = 0;
- unsigned s;
- for (s = 0; s <= max; ++s) {
- unsigned norm = (unsigned)((256 * count[s]) / total);
- if (count[s] != 0 && norm == 0)
- norm = 1;
- assert(count[s] < total);
- cost += count[s] * kInverseProbabilityLog256[norm];
- }
- return cost >> 8;
-}
-
-
-/**
- * Returns the cost in bits of encoding the distribution in count using the
- * table described by norm. The max symbol support by norm is assumed >= max.
- * norm must be valid for every symbol with non-zero probability in count.
- */
-static size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
- unsigned const* count, unsigned const max)
-{
- unsigned const shift = 8 - accuracyLog;
- size_t cost = 0;
- unsigned s;
- assert(accuracyLog <= 8);
- for (s = 0; s <= max; ++s) {
- unsigned const normAcc = norm[s] != -1 ? norm[s] : 1;
- unsigned const norm256 = normAcc << shift;
- assert(norm256 > 0);
- assert(norm256 < 256);
- cost += count[s] * kInverseProbabilityLog256[norm256];
- }
- return cost >> 8;
-}
-
-
-static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
- void const* ptr = ctable;
- U16 const* u16ptr = (U16 const*)ptr;
- U32 const maxSymbolValue = MEM_read16(u16ptr + 1);
- return maxSymbolValue;
-}
-
-
-/**
- * Returns the cost in bits of encoding the distribution in count using ctable.
- * Returns an error if ctable cannot represent all the symbols in count.
- */
-static size_t ZSTD_fseBitCost(
- FSE_CTable const* ctable,
- unsigned const* count,
- unsigned const max)
-{
- unsigned const kAccuracyLog = 8;
- size_t cost = 0;
- unsigned s;
- FSE_CState_t cstate;
- FSE_initCState(&cstate, ctable);
- RETURN_ERROR_IF(ZSTD_getFSEMaxSymbolValue(ctable) < max, GENERIC,
- "Repeat FSE_CTable has maxSymbolValue %u < %u",
- ZSTD_getFSEMaxSymbolValue(ctable), max);
- for (s = 0; s <= max; ++s) {
- unsigned const tableLog = cstate.stateLog;
- unsigned const badCost = (tableLog + 1) << kAccuracyLog;
- unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);
- if (count[s] == 0)
- continue;
- RETURN_ERROR_IF(bitCost >= badCost, GENERIC,
- "Repeat FSE_CTable has Prob[%u] == 0", s);
- cost += count[s] * bitCost;
- }
- return cost >> kAccuracyLog;
-}
-
-/**
- * Returns the cost in bytes of encoding the normalized count header.
- * Returns an error if any of the helper functions return an error.
- */
-static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
- size_t const nbSeq, unsigned const FSELog)
-{
- BYTE wksp[FSE_NCOUNTBOUND];
- S16 norm[MaxSeq + 1];
- const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
- FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max));
- return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
-}
-
-
-typedef enum {
- ZSTD_defaultDisallowed = 0,
- ZSTD_defaultAllowed = 1
-} ZSTD_defaultPolicy_e;
-
-MEM_STATIC symbolEncodingType_e
-ZSTD_selectEncodingType(
- FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
- size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
- FSE_CTable const* prevCTable,
- short const* defaultNorm, U32 defaultNormLog,
- ZSTD_defaultPolicy_e const isDefaultAllowed,
- ZSTD_strategy const strategy)
-{
- ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);
- if (mostFrequent == nbSeq) {
- *repeatMode = FSE_repeat_none;
- if (isDefaultAllowed && nbSeq <= 2) {
- /* Prefer set_basic over set_rle when there are 2 or less symbols,
- * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
- * If basic encoding isn't possible, always choose RLE.
- */
- DEBUGLOG(5, "Selected set_basic");
- return set_basic;
- }
- DEBUGLOG(5, "Selected set_rle");
- return set_rle;
- }
- if (strategy < ZSTD_lazy) {
- if (isDefaultAllowed) {
- size_t const staticFse_nbSeq_max = 1000;
- size_t const mult = 10 - strategy;
- size_t const baseLog = 3;
- size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog; /* 28-36 for offset, 56-72 for lengths */
- assert(defaultNormLog >= 5 && defaultNormLog <= 6); /* xx_DEFAULTNORMLOG */
- assert(mult <= 9 && mult >= 7);
- if ( (*repeatMode == FSE_repeat_valid)
- && (nbSeq < staticFse_nbSeq_max) ) {
- DEBUGLOG(5, "Selected set_repeat");
- return set_repeat;
- }
- if ( (nbSeq < dynamicFse_nbSeq_min)
- || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) {
- DEBUGLOG(5, "Selected set_basic");
- /* The format allows default tables to be repeated, but it isn't useful.
- * When using simple heuristics to select encoding type, we don't want
- * to confuse these tables with dictionaries. When running more careful
- * analysis, we don't need to waste time checking both repeating tables
- * and default tables.
- */
- *repeatMode = FSE_repeat_none;
- return set_basic;
- }
- }
- } else {
- size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC);
- size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC);
- size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog);
- size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq);
-
- if (isDefaultAllowed) {
- assert(!ZSTD_isError(basicCost));
- assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
- }
- assert(!ZSTD_isError(NCountCost));
- assert(compressedCost < ERROR(maxCode));
- DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
- (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost);
- if (basicCost <= repeatCost && basicCost <= compressedCost) {
- DEBUGLOG(5, "Selected set_basic");
- assert(isDefaultAllowed);
- *repeatMode = FSE_repeat_none;
- return set_basic;
- }
- if (repeatCost <= compressedCost) {
- DEBUGLOG(5, "Selected set_repeat");
- assert(!ZSTD_isError(repeatCost));
- return set_repeat;
- }
- assert(compressedCost < basicCost && compressedCost < repeatCost);
- }
- DEBUGLOG(5, "Selected set_compressed");
- *repeatMode = FSE_repeat_check;
- return set_compressed;
-}
-
-MEM_STATIC size_t
-ZSTD_buildCTable(void* dst, size_t dstCapacity,
- FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
- unsigned* count, U32 max,
- const BYTE* codeTable, size_t nbSeq,
- const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
- const FSE_CTable* prevCTable, size_t prevCTableSize,
- void* workspace, size_t workspaceSize)
-{
- BYTE* op = (BYTE*)dst;
- const BYTE* const oend = op + dstCapacity;
- DEBUGLOG(6, "ZSTD_buildCTable (dstCapacity=%u)", (unsigned)dstCapacity);
-
- switch (type) {
- case set_rle:
- FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max));
- RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall);
- *op = codeTable[0];
- return 1;
- case set_repeat:
- memcpy(nextCTable, prevCTable, prevCTableSize);
- return 0;
- case set_basic:
- FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, workspace, workspaceSize)); /* note : could be pre-calculated */
- return 0;
- case set_compressed: {
- S16 norm[MaxSeq + 1];
- size_t nbSeq_1 = nbSeq;
- const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
- if (count[codeTable[nbSeq-1]] > 1) {
- count[codeTable[nbSeq-1]]--;
- nbSeq_1--;
- }
- assert(nbSeq_1 > 1);
- FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max));
- { size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
- FORWARD_IF_ERROR(NCountSize);
- FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, workspace, workspaceSize));
- return NCountSize;
- }
- }
- default: assert(0); RETURN_ERROR(GENERIC);
- }
-}
-
-FORCE_INLINE_TEMPLATE size_t
-ZSTD_encodeSequences_body(
- void* dst, size_t dstCapacity,
- FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
- FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
- FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
- seqDef const* sequences, size_t nbSeq, int longOffsets)
-{
- BIT_CStream_t blockStream;
- FSE_CState_t stateMatchLength;
- FSE_CState_t stateOffsetBits;
- FSE_CState_t stateLitLength;
-
- RETURN_ERROR_IF(
- ERR_isError(BIT_initCStream(&blockStream, dst, dstCapacity)),
- dstSize_tooSmall, "not enough space remaining");
- DEBUGLOG(6, "available space for bitstream : %i (dstCapacity=%u)",
- (int)(blockStream.endPtr - blockStream.startPtr),
- (unsigned)dstCapacity);
-
- /* first symbols */
- FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
- FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]);
- FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]);
- BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
- if (MEM_32bits()) BIT_flushBits(&blockStream);
- BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
- if (MEM_32bits()) BIT_flushBits(&blockStream);
- if (longOffsets) {
- U32 const ofBits = ofCodeTable[nbSeq-1];
- int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
- if (extraBits) {
- BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
- BIT_flushBits(&blockStream);
- }
- BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,
- ofBits - extraBits);
- } else {
- BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
- }
- BIT_flushBits(&blockStream);
-
- { size_t n;
- for (n=nbSeq-2 ; n<nbSeq ; n--) { /* intentional underflow */
- BYTE const llCode = llCodeTable[n];
- BYTE const ofCode = ofCodeTable[n];
- BYTE const mlCode = mlCodeTable[n];
- U32 const llBits = LL_bits[llCode];
- U32 const ofBits = ofCode;
- U32 const mlBits = ML_bits[mlCode];
- DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
- (unsigned)sequences[n].litLength,
- (unsigned)sequences[n].matchLength + MINMATCH,
- (unsigned)sequences[n].offset);
- /* 32b*/ /* 64b*/
- /* (7)*/ /* (7)*/
- FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
- FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
- if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
- FSE_encodeSymbol(&blockStream, &stateLitLength, llCode); /* 16 */ /* 33 */
- if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
- BIT_flushBits(&blockStream); /* (7)*/
- BIT_addBits(&blockStream, sequences[n].litLength, llBits);
- if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
- BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
- if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream);
- if (longOffsets) {
- int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
- if (extraBits) {
- BIT_addBits(&blockStream, sequences[n].offset, extraBits);
- BIT_flushBits(&blockStream); /* (7)*/
- }
- BIT_addBits(&blockStream, sequences[n].offset >> extraBits,
- ofBits - extraBits); /* 31 */
- } else {
- BIT_addBits(&blockStream, sequences[n].offset, ofBits); /* 31 */
- }
- BIT_flushBits(&blockStream); /* (7)*/
- DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr));
- } }
-
- DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog);
- FSE_flushCState(&blockStream, &stateMatchLength);
- DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog);
- FSE_flushCState(&blockStream, &stateOffsetBits);
- DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog);
- FSE_flushCState(&blockStream, &stateLitLength);
-
- { size_t const streamSize = BIT_closeCStream(&blockStream);
- RETURN_ERROR_IF(streamSize==0, dstSize_tooSmall, "not enough space");
- return streamSize;
- }
-}
-
-static size_t
-ZSTD_encodeSequences_default(
- void* dst, size_t dstCapacity,
- FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
- FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
- FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
- seqDef const* sequences, size_t nbSeq, int longOffsets)
-{
- return ZSTD_encodeSequences_body(dst, dstCapacity,
- CTable_MatchLength, mlCodeTable,
- CTable_OffsetBits, ofCodeTable,
- CTable_LitLength, llCodeTable,
- sequences, nbSeq, longOffsets);
-}
-
-
-#if DYNAMIC_BMI2
-
-static TARGET_ATTRIBUTE("bmi2") size_t
-ZSTD_encodeSequences_bmi2(
- void* dst, size_t dstCapacity,
- FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
- FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
- FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
- seqDef const* sequences, size_t nbSeq, int longOffsets)
-{
- return ZSTD_encodeSequences_body(dst, dstCapacity,
- CTable_MatchLength, mlCodeTable,
- CTable_OffsetBits, ofCodeTable,
- CTable_LitLength, llCodeTable,
- sequences, nbSeq, longOffsets);
-}
-
-#endif
-
-static size_t ZSTD_encodeSequences(
- void* dst, size_t dstCapacity,
- FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
- FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
- FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
- seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
-{
- DEBUGLOG(5, "ZSTD_encodeSequences: dstCapacity = %u", (unsigned)dstCapacity);
-#if DYNAMIC_BMI2
- if (bmi2) {
- return ZSTD_encodeSequences_bmi2(dst, dstCapacity,
- CTable_MatchLength, mlCodeTable,
- CTable_OffsetBits, ofCodeTable,
- CTable_LitLength, llCodeTable,
- sequences, nbSeq, longOffsets);
- }
-#endif
- (void)bmi2;
- return ZSTD_encodeSequences_default(dst, dstCapacity,
- CTable_MatchLength, mlCodeTable,
- CTable_OffsetBits, ofCodeTable,
- CTable_LitLength, llCodeTable,
- sequences, nbSeq, longOffsets);
-}
-
static int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParams)
{
switch (cctxParams->literalCompressionMode) {
@@ -2526,16 +1955,16 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
BYTE* const ostart = (BYTE*)dst;
BYTE* const oend = ostart + dstCapacity;
BYTE* op = ostart;
- size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
+ size_t const nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
BYTE* seqHead;
BYTE* lastNCount = NULL;
+ DEBUGLOG(5, "ZSTD_compressSequences_internal (nbSeq=%zu)", nbSeq);
ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
- DEBUGLOG(5, "ZSTD_compressSequences_internal");
/* Compress literals */
{ const BYTE* const literals = seqStorePtr->litStart;
- size_t const litSize = seqStorePtr->lit - literals;
+ size_t const litSize = (size_t)(seqStorePtr->lit - literals);
size_t const cSize = ZSTD_compressLiterals(
&prevEntropy->huf, &nextEntropy->huf,
cctxParams->cParams.strategy,
@@ -2562,7 +1991,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
if (nbSeq==0) {
/* Copy the old tables over as if we repeated them */
memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
- return op - ostart;
+ return (size_t)(op - ostart);
}
/* seqHead : flags for FSE encoding type */
@@ -2583,7 +2012,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
ZSTD_defaultAllowed, strategy);
assert(set_basic < set_compressed && set_rle < set_compressed);
assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
- { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
+ { size_t const countSize = ZSTD_buildCTable(op, (size_t)(oend - op), CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable),
workspace, wkspSize);
@@ -2606,7 +2035,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
OF_defaultNorm, OF_defaultNormLog,
defaultPolicy, strategy);
assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
- { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
+ { size_t const countSize = ZSTD_buildCTable(op, (size_t)(oend - op), CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable),
workspace, wkspSize);
@@ -2627,7 +2056,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
ML_defaultNorm, ML_defaultNormLog,
ZSTD_defaultAllowed, strategy);
assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
- { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
+ { size_t const countSize = ZSTD_buildCTable(op, (size_t)(oend - op), CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable),
workspace, wkspSize);
@@ -2641,7 +2070,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
*seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
{ size_t const bitstreamSize = ZSTD_encodeSequences(
- op, oend - op,
+ op, (size_t)(oend - op),
CTable_MatchLength, mlCodeTable,
CTable_OffsetBits, ofCodeTable,
CTable_LitLength, llCodeTable,
@@ -2668,7 +2097,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
}
DEBUGLOG(5, "compressed block size : %u", (unsigned)(op - ostart));
- return op - ostart;
+ return (size_t)(op - ostart);
}
MEM_STATIC size_t
@@ -2841,7 +2270,8 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
{
size_t cSize;
DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
- (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, (unsigned)zc->blockState.matchState.nextToUpdate);
+ (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
+ (unsigned)zc->blockState.matchState.nextToUpdate);
{ const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
FORWARD_IF_ERROR(bss);
@@ -3109,8 +2539,9 @@ size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
{
- size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
- RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong);
+ DEBUGLOG(5, "ZSTD_compressBlock: srcSize = %u", (unsigned)srcSize);
+ { size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
+ RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong); }
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
}
@@ -3135,7 +2566,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
if (srcSize <= HASH_READ_SIZE) return 0;
while (iend - ip > HASH_READ_SIZE) {
- size_t const remaining = iend - ip;
+ size_t const remaining = (size_t)(iend - ip);
size_t const chunk = MIN(remaining, ZSTD_CHUNKSIZE_MAX);
const BYTE* const ichunk = ip + chunk;
diff --git a/thirdparty/zstd/compress/zstd_compress_internal.h b/thirdparty/zstd/compress/zstd_compress_internal.h
index 5495899be3..6d623cc6be 100644
--- a/thirdparty/zstd/compress/zstd_compress_internal.h
+++ b/thirdparty/zstd/compress/zstd_compress_internal.h
@@ -134,9 +134,15 @@ typedef struct {
typedef struct ZSTD_matchState_t ZSTD_matchState_t;
struct ZSTD_matchState_t {
ZSTD_window_t window; /* State for window round buffer management */
- U32 loadedDictEnd; /* index of end of dictionary, within context's referential. When dict referential is copied into active context (i.e. not attached), effectively same value as dictSize, since referential starts from zero */
+ U32 loadedDictEnd; /* index of end of dictionary, within context's referential.
+ * When loadedDictEnd != 0, a dictionary is in use, and still valid.
+ * This relies on a mechanism to set loadedDictEnd=0 when dictionary is no longer within distance.
+ * Such mechanism is provided within ZSTD_window_enforceMaxDist() and ZSTD_checkDictValidity().
+ * When dict referential is copied into active context (i.e. not attached),
+ * loadedDictEnd == dictSize, since referential starts from zero.
+ */
U32 nextToUpdate; /* index from which to continue table update */
- U32 hashLog3; /* dispatch table : larger == faster, more memory */
+ U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */
U32* hashTable;
U32* hashTable3;
U32* chainTable;
@@ -307,6 +313,30 @@ MEM_STATIC U32 ZSTD_MLcode(U32 mlBase)
return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase];
}
+/* ZSTD_cParam_withinBounds:
+ * @return 1 if value is within cParam bounds,
+ * 0 otherwise */
+MEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)
+{
+ ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);
+ if (ZSTD_isError(bounds.error)) return 0;
+ if (value < bounds.lowerBound) return 0;
+ if (value > bounds.upperBound) return 0;
+ return 1;
+}
+
+/* ZSTD_minGain() :
+ * minimum compression required
+ * to generate a compress block or a compressed literals section.
+ * note : use same formula for both situations */
+MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
+{
+ U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6;
+ ZSTD_STATIC_ASSERT(ZSTD_btultra == 8);
+ assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
+ return (srcSize >> minlog) + 2;
+}
+
/*! ZSTD_storeSeq() :
* Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
* `offsetCode` : distance to match + 3 (values 1-3 are repCodes).
@@ -326,7 +356,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
/* copy Literals */
assert(seqStorePtr->maxNbLit <= 128 KB);
assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit);
- ZSTD_wildcopy(seqStorePtr->lit, literals, litLength, ZSTD_no_overlap);
+ ZSTD_wildcopy(seqStorePtr->lit, literals, (ptrdiff_t)litLength, ZSTD_no_overlap);
seqStorePtr->lit += litLength;
/* literal Length */
@@ -739,24 +769,37 @@ ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
/* Similar to ZSTD_window_enforceMaxDist(),
* but only invalidates dictionary
- * when input progresses beyond window size. */
+ * when input progresses beyond window size.
+ * assumption : loadedDictEndPtr and dictMatchStatePtr are valid (non NULL)
+ * loadedDictEnd uses same referential as window->base
+ * maxDist is the window size */
MEM_STATIC void
-ZSTD_checkDictValidity(ZSTD_window_t* window,
+ZSTD_checkDictValidity(const ZSTD_window_t* window,
const void* blockEnd,
U32 maxDist,
U32* loadedDictEndPtr,
const ZSTD_matchState_t** dictMatchStatePtr)
{
- U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
- U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
- DEBUGLOG(5, "ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
- (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
-
- if (loadedDictEnd && (blockEndIdx > maxDist + loadedDictEnd)) {
- /* On reaching window size, dictionaries are invalidated */
- if (loadedDictEndPtr) *loadedDictEndPtr = 0;
- if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
- }
+ assert(loadedDictEndPtr != NULL);
+ assert(dictMatchStatePtr != NULL);
+ { U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
+ U32 const loadedDictEnd = *loadedDictEndPtr;
+ DEBUGLOG(5, "ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
+ (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
+ assert(blockEndIdx >= loadedDictEnd);
+
+ if (blockEndIdx > loadedDictEnd + maxDist) {
+ /* On reaching window size, dictionaries are invalidated.
+ * For simplification, if window size is reached anywhere within next block,
+ * the dictionary is invalidated for the full block.
+ */
+ DEBUGLOG(6, "invalidating dictionary for current block (distance > windowSize)");
+ *loadedDictEndPtr = 0;
+ *dictMatchStatePtr = NULL;
+ } else {
+ if (*loadedDictEndPtr != 0) {
+ DEBUGLOG(6, "dictionary considered valid for current block");
+ } } }
}
/**
@@ -798,6 +841,17 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
return contiguous;
}
+MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current, unsigned windowLog)
+{
+ U32 const maxDistance = 1U << windowLog;
+ U32 const lowestValid = ms->window.lowLimit;
+ U32 const withinWindow = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;
+ U32 const isDictionary = (ms->loadedDictEnd != 0);
+ U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
+ return matchLowest;
+}
+
+
/* debug functions */
#if (DEBUGLEVEL>=2)
diff --git a/thirdparty/zstd/compress/zstd_compress_literals.c b/thirdparty/zstd/compress/zstd_compress_literals.c
new file mode 100644
index 0000000000..eb3e5a44bc
--- /dev/null
+++ b/thirdparty/zstd/compress/zstd_compress_literals.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+
+ /*-*************************************
+ * Dependencies
+ ***************************************/
+#include "zstd_compress_literals.h"
+
+size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ BYTE* const ostart = (BYTE* const)dst;
+ U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
+
+ RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall);
+
+ switch(flSize)
+ {
+ case 1: /* 2 - 1 - 5 */
+ ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
+ break;
+ case 2: /* 2 - 2 - 12 */
+ MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
+ break;
+ case 3: /* 2 - 2 - 20 */
+ MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
+ break;
+ default: /* not necessary : flSize is {1,2,3} */
+ assert(0);
+ }
+
+ memcpy(ostart + flSize, src, srcSize);
+ return srcSize + flSize;
+}
+
+size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ BYTE* const ostart = (BYTE* const)dst;
+ U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
+
+ (void)dstCapacity; /* dstCapacity already guaranteed to be >=4, hence large enough */
+
+ switch(flSize)
+ {
+ case 1: /* 2 - 1 - 5 */
+ ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
+ break;
+ case 2: /* 2 - 2 - 12 */
+ MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
+ break;
+ case 3: /* 2 - 2 - 20 */
+ MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
+ break;
+ default: /* not necessary : flSize is {1,2,3} */
+ assert(0);
+ }
+
+ ostart[flSize] = *(const BYTE*)src;
+ return flSize+1;
+}
+
+size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
+ ZSTD_hufCTables_t* nextHuf,
+ ZSTD_strategy strategy, int disableLiteralCompression,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ void* workspace, size_t wkspSize,
+ const int bmi2)
+{
+ size_t const minGain = ZSTD_minGain(srcSize, strategy);
+ size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
+ BYTE* const ostart = (BYTE*)dst;
+ U32 singleStream = srcSize < 256;
+ symbolEncodingType_e hType = set_compressed;
+ size_t cLitSize;
+
+ DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i)",
+ disableLiteralCompression);
+
+ /* Prepare nextEntropy assuming reusing the existing table */
+ memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+
+ if (disableLiteralCompression)
+ return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
+
+ /* small ? don't even attempt compression (speed opt) */
+# define COMPRESS_LITERALS_SIZE_MIN 63
+ { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
+ if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
+ }
+
+ RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, "not enough space for compression");
+ { HUF_repeat repeat = prevHuf->repeatMode;
+ int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
+ if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
+ cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
+ workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2)
+ : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
+ workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
+ if (repeat != HUF_repeat_none) {
+ /* reused the existing table */
+ hType = set_repeat;
+ }
+ }
+
+ if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
+ memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+ return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
+ }
+ if (cLitSize==1) {
+ memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
+ return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
+ }
+
+ if (hType == set_compressed) {
+ /* using a newly constructed table */
+ nextHuf->repeatMode = HUF_repeat_check;
+ }
+
+ /* Build header */
+ switch(lhSize)
+ {
+ case 3: /* 2 - 2 - 10 - 10 */
+ { U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
+ MEM_writeLE24(ostart, lhc);
+ break;
+ }
+ case 4: /* 2 - 2 - 14 - 14 */
+ { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
+ MEM_writeLE32(ostart, lhc);
+ break;
+ }
+ case 5: /* 2 - 2 - 18 - 18 */
+ { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
+ MEM_writeLE32(ostart, lhc);
+ ostart[4] = (BYTE)(cLitSize >> 10);
+ break;
+ }
+ default: /* not possible : lhSize is {3,4,5} */
+ assert(0);
+ }
+ return lhSize+cLitSize;
+}
diff --git a/thirdparty/zstd/compress/zstd_compress_literals.h b/thirdparty/zstd/compress/zstd_compress_literals.h
new file mode 100644
index 0000000000..7adbecc0be
--- /dev/null
+++ b/thirdparty/zstd/compress/zstd_compress_literals.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+
+#ifndef ZSTD_COMPRESS_LITERALS_H
+#define ZSTD_COMPRESS_LITERALS_H
+
+#include "zstd_compress_internal.h" /* ZSTD_hufCTables_t, ZSTD_minGain() */
+
+
+size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+
+size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+
+size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
+ ZSTD_hufCTables_t* nextHuf,
+ ZSTD_strategy strategy, int disableLiteralCompression,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ void* workspace, size_t wkspSize,
+ const int bmi2);
+
+#endif /* ZSTD_COMPRESS_LITERALS_H */
diff --git a/thirdparty/zstd/compress/zstd_compress_sequences.c b/thirdparty/zstd/compress/zstd_compress_sequences.c
new file mode 100644
index 0000000000..3c3deae08c
--- /dev/null
+++ b/thirdparty/zstd/compress/zstd_compress_sequences.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+
+ /*-*************************************
+ * Dependencies
+ ***************************************/
+#include "zstd_compress_sequences.h"
+
+/**
+ * -log2(x / 256) lookup table for x in [0, 256).
+ * If x == 0: Return 0
+ * Else: Return floor(-log2(x / 256) * 256)
+ */
+static unsigned const kInverseProbabilityLog256[256] = {
+ 0, 2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162,
+ 1130, 1100, 1073, 1047, 1024, 1001, 980, 960, 941, 923, 906, 889,
+ 874, 859, 844, 830, 817, 804, 791, 779, 768, 756, 745, 734,
+ 724, 714, 704, 694, 685, 676, 667, 658, 650, 642, 633, 626,
+ 618, 610, 603, 595, 588, 581, 574, 567, 561, 554, 548, 542,
+ 535, 529, 523, 517, 512, 506, 500, 495, 489, 484, 478, 473,
+ 468, 463, 458, 453, 448, 443, 438, 434, 429, 424, 420, 415,
+ 411, 407, 402, 398, 394, 390, 386, 382, 377, 373, 370, 366,
+ 362, 358, 354, 350, 347, 343, 339, 336, 332, 329, 325, 322,
+ 318, 315, 311, 308, 305, 302, 298, 295, 292, 289, 286, 282,
+ 279, 276, 273, 270, 267, 264, 261, 258, 256, 253, 250, 247,
+ 244, 241, 239, 236, 233, 230, 228, 225, 222, 220, 217, 215,
+ 212, 209, 207, 204, 202, 199, 197, 194, 192, 190, 187, 185,
+ 182, 180, 178, 175, 173, 171, 168, 166, 164, 162, 159, 157,
+ 155, 153, 151, 149, 146, 144, 142, 140, 138, 136, 134, 132,
+ 130, 128, 126, 123, 121, 119, 117, 115, 114, 112, 110, 108,
+ 106, 104, 102, 100, 98, 96, 94, 93, 91, 89, 87, 85,
+ 83, 82, 80, 78, 76, 74, 73, 71, 69, 67, 66, 64,
+ 62, 61, 59, 57, 55, 54, 52, 50, 49, 47, 46, 44,
+ 42, 41, 39, 37, 36, 34, 33, 31, 30, 28, 26, 25,
+ 23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7,
+ 5, 4, 2, 1,
+};
+
+static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
+ void const* ptr = ctable;
+ U16 const* u16ptr = (U16 const*)ptr;
+ U32 const maxSymbolValue = MEM_read16(u16ptr + 1);
+ return maxSymbolValue;
+}
+
+/**
+ * Returns the cost in bytes of encoding the normalized count header.
+ * Returns an error if any of the helper functions return an error.
+ */
+static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
+ size_t const nbSeq, unsigned const FSELog)
+{
+ BYTE wksp[FSE_NCOUNTBOUND];
+ S16 norm[MaxSeq + 1];
+ const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max));
+ return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
+}
+
+/**
+ * Returns the cost in bits of encoding the distribution described by count
+ * using the entropy bound.
+ */
+static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total)
+{
+ unsigned cost = 0;
+ unsigned s;
+ for (s = 0; s <= max; ++s) {
+ unsigned norm = (unsigned)((256 * count[s]) / total);
+ if (count[s] != 0 && norm == 0)
+ norm = 1;
+ assert(count[s] < total);
+ cost += count[s] * kInverseProbabilityLog256[norm];
+ }
+ return cost >> 8;
+}
+
+/**
+ * Returns the cost in bits of encoding the distribution in count using ctable.
+ * Returns an error if ctable cannot represent all the symbols in count.
+ */
+static size_t ZSTD_fseBitCost(
+ FSE_CTable const* ctable,
+ unsigned const* count,
+ unsigned const max)
+{
+ unsigned const kAccuracyLog = 8;
+ size_t cost = 0;
+ unsigned s;
+ FSE_CState_t cstate;
+ FSE_initCState(&cstate, ctable);
+ RETURN_ERROR_IF(ZSTD_getFSEMaxSymbolValue(ctable) < max, GENERIC,
+ "Repeat FSE_CTable has maxSymbolValue %u < %u",
+ ZSTD_getFSEMaxSymbolValue(ctable), max);
+ for (s = 0; s <= max; ++s) {
+ unsigned const tableLog = cstate.stateLog;
+ unsigned const badCost = (tableLog + 1) << kAccuracyLog;
+ unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);
+ if (count[s] == 0)
+ continue;
+ RETURN_ERROR_IF(bitCost >= badCost, GENERIC,
+ "Repeat FSE_CTable has Prob[%u] == 0", s);
+ cost += count[s] * bitCost;
+ }
+ return cost >> kAccuracyLog;
+}
+
+/**
+ * Returns the cost in bits of encoding the distribution in count using the
+ * table described by norm. The max symbol support by norm is assumed >= max.
+ * norm must be valid for every symbol with non-zero probability in count.
+ */
+static size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
+ unsigned const* count, unsigned const max)
+{
+ unsigned const shift = 8 - accuracyLog;
+ size_t cost = 0;
+ unsigned s;
+ assert(accuracyLog <= 8);
+ for (s = 0; s <= max; ++s) {
+ unsigned const normAcc = norm[s] != -1 ? norm[s] : 1;
+ unsigned const norm256 = normAcc << shift;
+ assert(norm256 > 0);
+ assert(norm256 < 256);
+ cost += count[s] * kInverseProbabilityLog256[norm256];
+ }
+ return cost >> 8;
+}
+
+symbolEncodingType_e
+ZSTD_selectEncodingType(
+ FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
+ size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
+ FSE_CTable const* prevCTable,
+ short const* defaultNorm, U32 defaultNormLog,
+ ZSTD_defaultPolicy_e const isDefaultAllowed,
+ ZSTD_strategy const strategy)
+{
+ ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);
+ if (mostFrequent == nbSeq) {
+ *repeatMode = FSE_repeat_none;
+ if (isDefaultAllowed && nbSeq <= 2) {
+ /* Prefer set_basic over set_rle when there are 2 or less symbols,
+ * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
+ * If basic encoding isn't possible, always choose RLE.
+ */
+ DEBUGLOG(5, "Selected set_basic");
+ return set_basic;
+ }
+ DEBUGLOG(5, "Selected set_rle");
+ return set_rle;
+ }
+ if (strategy < ZSTD_lazy) {
+ if (isDefaultAllowed) {
+ size_t const staticFse_nbSeq_max = 1000;
+ size_t const mult = 10 - strategy;
+ size_t const baseLog = 3;
+ size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog; /* 28-36 for offset, 56-72 for lengths */
+ assert(defaultNormLog >= 5 && defaultNormLog <= 6); /* xx_DEFAULTNORMLOG */
+ assert(mult <= 9 && mult >= 7);
+ if ( (*repeatMode == FSE_repeat_valid)
+ && (nbSeq < staticFse_nbSeq_max) ) {
+ DEBUGLOG(5, "Selected set_repeat");
+ return set_repeat;
+ }
+ if ( (nbSeq < dynamicFse_nbSeq_min)
+ || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) {
+ DEBUGLOG(5, "Selected set_basic");
+ /* The format allows default tables to be repeated, but it isn't useful.
+ * When using simple heuristics to select encoding type, we don't want
+ * to confuse these tables with dictionaries. When running more careful
+ * analysis, we don't need to waste time checking both repeating tables
+ * and default tables.
+ */
+ *repeatMode = FSE_repeat_none;
+ return set_basic;
+ }
+ }
+ } else {
+ size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC);
+ size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC);
+ size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog);
+ size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq);
+
+ if (isDefaultAllowed) {
+ assert(!ZSTD_isError(basicCost));
+ assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
+ }
+ assert(!ZSTD_isError(NCountCost));
+ assert(compressedCost < ERROR(maxCode));
+ DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
+ (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost);
+ if (basicCost <= repeatCost && basicCost <= compressedCost) {
+ DEBUGLOG(5, "Selected set_basic");
+ assert(isDefaultAllowed);
+ *repeatMode = FSE_repeat_none;
+ return set_basic;
+ }
+ if (repeatCost <= compressedCost) {
+ DEBUGLOG(5, "Selected set_repeat");
+ assert(!ZSTD_isError(repeatCost));
+ return set_repeat;
+ }
+ assert(compressedCost < basicCost && compressedCost < repeatCost);
+ }
+ DEBUGLOG(5, "Selected set_compressed");
+ *repeatMode = FSE_repeat_check;
+ return set_compressed;
+}
+
+size_t
+ZSTD_buildCTable(void* dst, size_t dstCapacity,
+ FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
+ unsigned* count, U32 max,
+ const BYTE* codeTable, size_t nbSeq,
+ const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
+ const FSE_CTable* prevCTable, size_t prevCTableSize,
+ void* workspace, size_t workspaceSize)
+{
+ BYTE* op = (BYTE*)dst;
+ const BYTE* const oend = op + dstCapacity;
+ DEBUGLOG(6, "ZSTD_buildCTable (dstCapacity=%u)", (unsigned)dstCapacity);
+
+ switch (type) {
+ case set_rle:
+ FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max));
+ RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall);
+ *op = codeTable[0];
+ return 1;
+ case set_repeat:
+ memcpy(nextCTable, prevCTable, prevCTableSize);
+ return 0;
+ case set_basic:
+ FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, workspace, workspaceSize)); /* note : could be pre-calculated */
+ return 0;
+ case set_compressed: {
+ S16 norm[MaxSeq + 1];
+ size_t nbSeq_1 = nbSeq;
+ const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
+ if (count[codeTable[nbSeq-1]] > 1) {
+ count[codeTable[nbSeq-1]]--;
+ nbSeq_1--;
+ }
+ assert(nbSeq_1 > 1);
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max));
+ { size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
+ FORWARD_IF_ERROR(NCountSize);
+ FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, workspace, workspaceSize));
+ return NCountSize;
+ }
+ }
+ default: assert(0); RETURN_ERROR(GENERIC);
+ }
+}
+
+FORCE_INLINE_TEMPLATE size_t
+ZSTD_encodeSequences_body(
+ void* dst, size_t dstCapacity,
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
+ seqDef const* sequences, size_t nbSeq, int longOffsets)
+{
+ BIT_CStream_t blockStream;
+ FSE_CState_t stateMatchLength;
+ FSE_CState_t stateOffsetBits;
+ FSE_CState_t stateLitLength;
+
+ RETURN_ERROR_IF(
+ ERR_isError(BIT_initCStream(&blockStream, dst, dstCapacity)),
+ dstSize_tooSmall, "not enough space remaining");
+ DEBUGLOG(6, "available space for bitstream : %i (dstCapacity=%u)",
+ (int)(blockStream.endPtr - blockStream.startPtr),
+ (unsigned)dstCapacity);
+
+ /* first symbols */
+ FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
+ FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]);
+ FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]);
+ BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
+ if (MEM_32bits()) BIT_flushBits(&blockStream);
+ BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
+ if (MEM_32bits()) BIT_flushBits(&blockStream);
+ if (longOffsets) {
+ U32 const ofBits = ofCodeTable[nbSeq-1];
+ int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
+ if (extraBits) {
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
+ BIT_flushBits(&blockStream);
+ }
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,
+ ofBits - extraBits);
+ } else {
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
+ }
+ BIT_flushBits(&blockStream);
+
+ { size_t n;
+ for (n=nbSeq-2 ; n<nbSeq ; n--) { /* intentional underflow */
+ BYTE const llCode = llCodeTable[n];
+ BYTE const ofCode = ofCodeTable[n];
+ BYTE const mlCode = mlCodeTable[n];
+ U32 const llBits = LL_bits[llCode];
+ U32 const ofBits = ofCode;
+ U32 const mlBits = ML_bits[mlCode];
+ DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
+ (unsigned)sequences[n].litLength,
+ (unsigned)sequences[n].matchLength + MINMATCH,
+ (unsigned)sequences[n].offset);
+ /* 32b*/ /* 64b*/
+ /* (7)*/ /* (7)*/
+ FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
+ FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
+ if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
+ FSE_encodeSymbol(&blockStream, &stateLitLength, llCode); /* 16 */ /* 33 */
+ if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
+ BIT_flushBits(&blockStream); /* (7)*/
+ BIT_addBits(&blockStream, sequences[n].litLength, llBits);
+ if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
+ BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
+ if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream);
+ if (longOffsets) {
+ int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
+ if (extraBits) {
+ BIT_addBits(&blockStream, sequences[n].offset, extraBits);
+ BIT_flushBits(&blockStream); /* (7)*/
+ }
+ BIT_addBits(&blockStream, sequences[n].offset >> extraBits,
+ ofBits - extraBits); /* 31 */
+ } else {
+ BIT_addBits(&blockStream, sequences[n].offset, ofBits); /* 31 */
+ }
+ BIT_flushBits(&blockStream); /* (7)*/
+ DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr));
+ } }
+
+ DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog);
+ FSE_flushCState(&blockStream, &stateMatchLength);
+ DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog);
+ FSE_flushCState(&blockStream, &stateOffsetBits);
+ DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog);
+ FSE_flushCState(&blockStream, &stateLitLength);
+
+ { size_t const streamSize = BIT_closeCStream(&blockStream);
+ RETURN_ERROR_IF(streamSize==0, dstSize_tooSmall, "not enough space");
+ return streamSize;
+ }
+}
+
+static size_t
+ZSTD_encodeSequences_default(
+ void* dst, size_t dstCapacity,
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
+ seqDef const* sequences, size_t nbSeq, int longOffsets)
+{
+ return ZSTD_encodeSequences_body(dst, dstCapacity,
+ CTable_MatchLength, mlCodeTable,
+ CTable_OffsetBits, ofCodeTable,
+ CTable_LitLength, llCodeTable,
+ sequences, nbSeq, longOffsets);
+}
+
+
+#if DYNAMIC_BMI2
+
+static TARGET_ATTRIBUTE("bmi2") size_t
+ZSTD_encodeSequences_bmi2(
+ void* dst, size_t dstCapacity,
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
+ seqDef const* sequences, size_t nbSeq, int longOffsets)
+{
+ return ZSTD_encodeSequences_body(dst, dstCapacity,
+ CTable_MatchLength, mlCodeTable,
+ CTable_OffsetBits, ofCodeTable,
+ CTable_LitLength, llCodeTable,
+ sequences, nbSeq, longOffsets);
+}
+
+#endif
+
+size_t ZSTD_encodeSequences(
+ void* dst, size_t dstCapacity,
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
+ seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
+{
+ DEBUGLOG(5, "ZSTD_encodeSequences: dstCapacity = %u", (unsigned)dstCapacity);
+#if DYNAMIC_BMI2
+ if (bmi2) {
+ return ZSTD_encodeSequences_bmi2(dst, dstCapacity,
+ CTable_MatchLength, mlCodeTable,
+ CTable_OffsetBits, ofCodeTable,
+ CTable_LitLength, llCodeTable,
+ sequences, nbSeq, longOffsets);
+ }
+#endif
+ (void)bmi2;
+ return ZSTD_encodeSequences_default(dst, dstCapacity,
+ CTable_MatchLength, mlCodeTable,
+ CTable_OffsetBits, ofCodeTable,
+ CTable_LitLength, llCodeTable,
+ sequences, nbSeq, longOffsets);
+}
diff --git a/thirdparty/zstd/compress/zstd_compress_sequences.h b/thirdparty/zstd/compress/zstd_compress_sequences.h
new file mode 100644
index 0000000000..f5234d94c8
--- /dev/null
+++ b/thirdparty/zstd/compress/zstd_compress_sequences.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+
+#ifndef ZSTD_COMPRESS_SEQUENCES_H
+#define ZSTD_COMPRESS_SEQUENCES_H
+
+#include "fse.h" /* FSE_repeat, FSE_CTable */
+#include "zstd_internal.h" /* symbolEncodingType_e, ZSTD_strategy */
+
+typedef enum {
+ ZSTD_defaultDisallowed = 0,
+ ZSTD_defaultAllowed = 1
+} ZSTD_defaultPolicy_e;
+
+symbolEncodingType_e
+ZSTD_selectEncodingType(
+ FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
+ size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
+ FSE_CTable const* prevCTable,
+ short const* defaultNorm, U32 defaultNormLog,
+ ZSTD_defaultPolicy_e const isDefaultAllowed,
+ ZSTD_strategy const strategy);
+
+size_t
+ZSTD_buildCTable(void* dst, size_t dstCapacity,
+ FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
+ unsigned* count, U32 max,
+ const BYTE* codeTable, size_t nbSeq,
+ const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
+ const FSE_CTable* prevCTable, size_t prevCTableSize,
+ void* workspace, size_t workspaceSize);
+
+size_t ZSTD_encodeSequences(
+ void* dst, size_t dstCapacity,
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
+ seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2);
+
+#endif /* ZSTD_COMPRESS_SEQUENCES_H */
diff --git a/thirdparty/zstd/compress/zstd_double_fast.c b/thirdparty/zstd/compress/zstd_double_fast.c
index 5957255d90..54467cc31b 100644
--- a/thirdparty/zstd/compress/zstd_double_fast.c
+++ b/thirdparty/zstd/compress/zstd_double_fast.c
@@ -65,6 +65,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
const U32 lowestValid = ms->window.dictLimit;
const U32 maxDistance = 1U << cParams->windowLog;
+ /* presumes that, if there is a dictionary, it must be using Attach mode */
const U32 prefixLowestIndex = (endIndex - lowestValid > maxDistance) ? endIndex - maxDistance : lowestValid;
const BYTE* const prefixLowest = base + prefixLowestIndex;
const BYTE* const iend = istart + srcSize;
@@ -369,9 +370,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
const BYTE* const ilimit = iend - 8;
const BYTE* const base = ms->window.base;
const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
- const U32 maxDistance = 1U << cParams->windowLog;
- const U32 lowestValid = ms->window.lowLimit;
- const U32 lowLimit = (endIndex - lowestValid > maxDistance) ? endIndex - maxDistance : lowestValid;
+ const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog);
const U32 dictStartIndex = lowLimit;
const U32 dictLimit = ms->window.dictLimit;
const U32 prefixStartIndex = (dictLimit > lowLimit) ? dictLimit : lowLimit;
diff --git a/thirdparty/zstd/compress/zstd_fast.c b/thirdparty/zstd/compress/zstd_fast.c
index a05b8a47f1..59267ffbbc 100644
--- a/thirdparty/zstd/compress/zstd_fast.c
+++ b/thirdparty/zstd/compress/zstd_fast.c
@@ -71,6 +71,7 @@ size_t ZSTD_compressBlock_fast_generic(
U32 offsetSaved = 0;
/* init */
+ DEBUGLOG(5, "ZSTD_compressBlock_fast_generic");
ip0 += (ip0 == prefixStart);
ip1 = ip0 + 1;
{
@@ -239,6 +240,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
assert(prefixStartIndex >= (U32)(dictEnd - dictBase));
/* init */
+ DEBUGLOG(5, "ZSTD_compressBlock_fast_dictMatchState_generic");
ip += (dictAndPrefixLength == 0);
/* dictMatchState repCode checks don't currently handle repCode == 0
* disabling. */
@@ -379,9 +381,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
const BYTE* ip = istart;
const BYTE* anchor = istart;
const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
- const U32 maxDistance = 1U << cParams->windowLog;
- const U32 validLow = ms->window.lowLimit;
- const U32 lowLimit = (endIndex - validLow > maxDistance) ? endIndex - maxDistance : validLow;
+ const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog);
const U32 dictStartIndex = lowLimit;
const BYTE* const dictStart = dictBase + dictStartIndex;
const U32 dictLimit = ms->window.dictLimit;
@@ -392,6 +392,8 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
const BYTE* const ilimit = iend - 8;
U32 offset_1=rep[0], offset_2=rep[1];
+ DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic");
+
/* switch to "regular" variant if extDict is invalidated due to maxDistance */
if (prefixStartIndex == dictStartIndex)
return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, mls);
@@ -412,8 +414,8 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
if ( (((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > dictStartIndex))
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
- const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
- mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
+ const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
+ mLength = ZSTD_count_2segments(ip+1 +4, repMatch +4, iend, repMatchEnd, prefixStart) + 4;
ip++;
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
} else {
@@ -423,8 +425,8 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
ip += ((ip-anchor) >> kSearchStrength) + stepSize;
continue;
}
- { const BYTE* matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
- const BYTE* lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
+ { const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
+ const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
U32 offset;
mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
@@ -451,7 +453,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
- U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
+ U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
ZSTD_storeSeq(seqStore, 0, anchor, 0, repLength2-MINMATCH);
hashTable[ZSTD_hashPtr(ip, hlog, mls)] = current2;
ip += repLength2;
diff --git a/thirdparty/zstd/compress/zstd_lazy.c b/thirdparty/zstd/compress/zstd_lazy.c
index 94d906c01f..0af41724c7 100644
--- a/thirdparty/zstd/compress/zstd_lazy.c
+++ b/thirdparty/zstd/compress/zstd_lazy.c
@@ -242,9 +242,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
const BYTE* const base = ms->window.base;
U32 const current = (U32)(ip-base);
- U32 const maxDistance = 1U << cParams->windowLog;
- U32 const windowValid = ms->window.lowLimit;
- U32 const windowLow = (current - windowValid > maxDistance) ? current - maxDistance : windowValid;
+ U32 const windowLow = ZSTD_getLowestMatchIndex(ms, current, cParams->windowLog);
U32* const bt = ms->chainTable;
U32 const btLog = cParams->chainLog - 1;
@@ -497,8 +495,10 @@ size_t ZSTD_HcFindBestMatch_generic (
const BYTE* const dictEnd = dictBase + dictLimit;
const U32 current = (U32)(ip-base);
const U32 maxDistance = 1U << cParams->windowLog;
- const U32 lowValid = ms->window.lowLimit;
- const U32 lowLimit = (current - lowValid > maxDistance) ? current - maxDistance : lowValid;
+ const U32 lowestValid = ms->window.lowLimit;
+ const U32 withinMaxDistance = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;
+ const U32 isDictionary = (ms->loadedDictEnd != 0);
+ const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance;
const U32 minChain = current > chainSize ? current - chainSize : 0;
U32 nbAttempts = 1U << cParams->searchLog;
size_t ml=4-1;
@@ -619,12 +619,14 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
/* *******************************
* Common parser - lazy strategy
*********************************/
-FORCE_INLINE_TEMPLATE
-size_t ZSTD_compressBlock_lazy_generic(
+typedef enum { search_hashChain, search_binaryTree } searchMethod_e;
+
+FORCE_INLINE_TEMPLATE size_t
+ZSTD_compressBlock_lazy_generic(
ZSTD_matchState_t* ms, seqStore_t* seqStore,
U32 rep[ZSTD_REP_NUM],
const void* src, size_t srcSize,
- const U32 searchMethod, const U32 depth,
+ const searchMethod_e searchMethod, const U32 depth,
ZSTD_dictMode_e const dictMode)
{
const BYTE* const istart = (const BYTE*)src;
@@ -640,8 +642,10 @@ size_t ZSTD_compressBlock_lazy_generic(
ZSTD_matchState_t* ms,
const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
searchMax_f const searchMax = dictMode == ZSTD_dictMatchState ?
- (searchMethod ? ZSTD_BtFindBestMatch_dictMatchState_selectMLS : ZSTD_HcFindBestMatch_dictMatchState_selectMLS) :
- (searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS);
+ (searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_dictMatchState_selectMLS
+ : ZSTD_HcFindBestMatch_dictMatchState_selectMLS) :
+ (searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_selectMLS
+ : ZSTD_HcFindBestMatch_selectMLS);
U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
const ZSTD_matchState_t* const dms = ms->dictMatchState;
@@ -850,7 +854,7 @@ _storeSequence:
rep[1] = offset_2 ? offset_2 : savedOffset;
/* Return the last literals size */
- return iend - anchor;
+ return (size_t)(iend - anchor);
}
@@ -858,56 +862,56 @@ size_t ZSTD_compressBlock_btlazy2(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 1, 2, ZSTD_noDict);
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_noDict);
}
size_t ZSTD_compressBlock_lazy2(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 2, ZSTD_noDict);
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_noDict);
}
size_t ZSTD_compressBlock_lazy(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 1, ZSTD_noDict);
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_noDict);
}
size_t ZSTD_compressBlock_greedy(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 0, ZSTD_noDict);
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_noDict);
}
size_t ZSTD_compressBlock_btlazy2_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 1, 2, ZSTD_dictMatchState);
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_lazy2_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 2, ZSTD_dictMatchState);
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_lazy_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 1, ZSTD_dictMatchState);
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_greedy_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 0, ZSTD_dictMatchState);
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dictMatchState);
}
@@ -916,7 +920,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
ZSTD_matchState_t* ms, seqStore_t* seqStore,
U32 rep[ZSTD_REP_NUM],
const void* src, size_t srcSize,
- const U32 searchMethod, const U32 depth)
+ const searchMethod_e searchMethod, const U32 depth)
{
const BYTE* const istart = (const BYTE*)src;
const BYTE* ip = istart;
@@ -934,7 +938,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
typedef size_t (*searchMax_f)(
ZSTD_matchState_t* ms,
const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
- searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_extDict_selectMLS : ZSTD_HcFindBestMatch_extDict_selectMLS;
+ searchMax_f searchMax = searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_extDict_selectMLS : ZSTD_HcFindBestMatch_extDict_selectMLS;
U32 offset_1 = rep[0], offset_2 = rep[1];
@@ -1075,7 +1079,7 @@ _storeSequence:
rep[1] = offset_2;
/* Return the last literals size */
- return iend - anchor;
+ return (size_t)(iend - anchor);
}
@@ -1083,7 +1087,7 @@ size_t ZSTD_compressBlock_greedy_extDict(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 0, 0);
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0);
}
size_t ZSTD_compressBlock_lazy_extDict(
@@ -1091,7 +1095,7 @@ size_t ZSTD_compressBlock_lazy_extDict(
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 0, 1);
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1);
}
size_t ZSTD_compressBlock_lazy2_extDict(
@@ -1099,7 +1103,7 @@ size_t ZSTD_compressBlock_lazy2_extDict(
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 0, 2);
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2);
}
size_t ZSTD_compressBlock_btlazy2_extDict(
@@ -1107,5 +1111,5 @@ size_t ZSTD_compressBlock_btlazy2_extDict(
void const* src, size_t srcSize)
{
- return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 1, 2);
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2);
}
diff --git a/thirdparty/zstd/compress/zstd_opt.c b/thirdparty/zstd/compress/zstd_opt.c
index e32e542e02..2da363f93e 100644
--- a/thirdparty/zstd/compress/zstd_opt.c
+++ b/thirdparty/zstd/compress/zstd_opt.c
@@ -552,7 +552,6 @@ U32 ZSTD_insertBtAndGetAllMatches (
{
const ZSTD_compressionParameters* const cParams = &ms->cParams;
U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
- U32 const maxDistance = 1U << cParams->windowLog;
const BYTE* const base = ms->window.base;
U32 const current = (U32)(ip-base);
U32 const hashLog = cParams->hashLog;
@@ -569,8 +568,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
const BYTE* const dictEnd = dictBase + dictLimit;
const BYTE* const prefixStart = base + dictLimit;
U32 const btLow = (btMask >= current) ? 0 : current - btMask;
- U32 const windowValid = ms->window.lowLimit;
- U32 const windowLow = ((current - windowValid) > maxDistance) ? current - maxDistance : windowValid;
+ U32 const windowLow = ZSTD_getLowestMatchIndex(ms, current, cParams->windowLog);
U32 const matchLow = windowLow ? windowLow : 1;
U32* smallerPtr = bt + 2*(current&btMask);
U32* largerPtr = bt + 2*(current&btMask) + 1;
@@ -674,19 +672,21 @@ U32 ZSTD_insertBtAndGetAllMatches (
while (nbCompares-- && (matchIndex >= matchLow)) {
U32* const nextPtr = bt + 2*(matchIndex & btMask);
- size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
const BYTE* match;
+ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
assert(current > matchIndex);
if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) {
assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */
match = base + matchIndex;
+ if (matchIndex >= dictLimit) assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit);
} else {
match = dictBase + matchIndex;
+ assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
if (matchIndex+matchLength >= dictLimit)
- match = base + matchIndex; /* prepare for match[matchLength] */
+ match = base + matchIndex; /* prepare for match[matchLength] read */
}
if (matchLength > bestLength) {
diff --git a/thirdparty/zstd/decompress/zstd_decompress.c b/thirdparty/zstd/decompress/zstd_decompress.c
index e42872ad96..751060b2cd 100644
--- a/thirdparty/zstd/decompress/zstd_decompress.c
+++ b/thirdparty/zstd/decompress/zstd_decompress.c
@@ -574,9 +574,10 @@ void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
}
/** ZSTD_insertBlock() :
- insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
+ * insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
{
+ DEBUGLOG(5, "ZSTD_insertBlock: %u bytes", (unsigned)blockSize);
ZSTD_checkContinuity(dctx, blockStart);
dctx->previousDstEnd = (const char*)blockStart + blockSize;
return blockSize;
@@ -909,6 +910,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
{ blockProperties_t bp;
size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
if (ZSTD_isError(cBlockSize)) return cBlockSize;
+ RETURN_ERROR_IF(cBlockSize > dctx->fParams.blockSizeMax, corruption_detected, "Block Size Exceeds Maximum");
dctx->expected = cBlockSize;
dctx->bType = bp.blockType;
dctx->rleSize = bp.origSize;
@@ -953,6 +955,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
RETURN_ERROR(corruption_detected);
}
if (ZSTD_isError(rSize)) return rSize;
+ RETURN_ERROR_IF(rSize > dctx->fParams.blockSizeMax, corruption_detected, "Decompressed Block Size Exceeds Maximum");
DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (unsigned)rSize);
dctx->decodedSize += rSize;
if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
diff --git a/thirdparty/zstd/decompress/zstd_decompress_block.c b/thirdparty/zstd/decompress/zstd_decompress_block.c
index 24f4859c56..cbcfc08406 100644
--- a/thirdparty/zstd/decompress/zstd_decompress_block.c
+++ b/thirdparty/zstd/decompress/zstd_decompress_block.c
@@ -79,6 +79,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
{
+ DEBUGLOG(5, "ZSTD_decodeLiteralsBlock");
RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected);
{ const BYTE* const istart = (const BYTE*) src;
@@ -87,6 +88,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
switch(litEncType)
{
case set_repeat:
+ DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block");
RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted);
/* fall-through */
@@ -116,7 +118,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
/* 2 - 2 - 18 - 18 */
lhSize = 5;
litSize = (lhc >> 4) & 0x3FFFF;
- litCSize = (lhc >> 22) + (istart[4] << 10);
+ litCSize = (lhc >> 22) + ((size_t)istart[4] << 10);
break;
}
RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected);
@@ -391,7 +393,8 @@ ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
symbolNext[s] = 1;
} else {
if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
- symbolNext[s] = normalizedCounter[s];
+ assert(normalizedCounter[s]>=0);
+ symbolNext[s] = (U16)normalizedCounter[s];
} } }
memcpy(dt, &DTableH, sizeof(DTableH));
}
diff --git a/thirdparty/zstd/zstd.h b/thirdparty/zstd/zstd.h
index a1910ee223..f8e95f2283 100644
--- a/thirdparty/zstd/zstd.h
+++ b/thirdparty/zstd/zstd.h
@@ -71,7 +71,7 @@ extern "C" {
/*------ Version ------*/
#define ZSTD_VERSION_MAJOR 1
#define ZSTD_VERSION_MINOR 4
-#define ZSTD_VERSION_RELEASE 1
+#define ZSTD_VERSION_RELEASE 3
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< to check runtime library version */
@@ -1909,7 +1909,7 @@ ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
/*!
Block functions produce and decode raw zstd blocks, without frame metadata.
Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
- User will have to take in charge required information to regenerate data, such as compressed and content sizes.
+ But users will have to take in charge needed metadata to regenerate data, such as compressed and content sizes.
A few rules to respect :
- Compressing and decompressing require a context structure
@@ -1920,12 +1920,14 @@ ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
+ copyCCtx() and copyDCtx() can be used too
- Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB
+ If input is larger than a block size, it's necessary to split input data into multiple blocks
- + For inputs larger than a single block, really consider using regular ZSTD_compress() instead.
- Frame metadata is not that costly, and quickly becomes negligible as source size grows larger.
- - When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
- In which case, nothing is produced into `dst` !
- + User must test for such outcome and deal directly with uncompressed data
- + ZSTD_decompressBlock() doesn't accept uncompressed data as input !!!
+ + For inputs larger than a single block, consider using regular ZSTD_compress() instead.
+ Frame metadata is not that costly, and quickly becomes negligible as source size grows larger than a block.
+ - When a block is considered not compressible enough, ZSTD_compressBlock() result will be 0 (zero) !
+ ===> In which case, nothing is produced into `dst` !
+ + User __must__ test for such outcome and deal directly with uncompressed data
+ + A block cannot be declared incompressible if ZSTD_compressBlock() return value was != 0.
+ Doing so would mess up with statistics history, leading to potential data corruption.
+ + ZSTD_decompressBlock() _doesn't accept uncompressed data as input_ !!
+ In case of multiple successive blocks, should some of them be uncompressed,
decoder must be informed of their existence in order to follow proper history.
Use ZSTD_insertBlock() for such a case.
diff --git a/version.py b/version.py
index 45817ed69f..fee6809551 100644
--- a/version.py
+++ b/version.py
@@ -2,7 +2,7 @@ short_name = "godot"
name = "Godot Engine"
major = 3
minor = 2
-status = "alpha"
+status = "beta"
module_config = ""
year = 2019
website = "https://godotengine.org"