summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS.md3
-rw-r--r--DONORS.md65
-rw-r--r--core/io/file_access_compressed.cpp3
-rw-r--r--core/math/math_funcs.h12
-rw-r--r--core/script_debugger_remote.cpp57
-rw-r--r--core/script_debugger_remote.h6
-rw-r--r--doc/classes/GraphEdit.xml10
-rw-r--r--doc/classes/PoolIntArray.xml1
-rw-r--r--doc/classes/ProjectSettings.xml7
-rw-r--r--doc/classes/Vector2.xml2
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.h2
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp11
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h2
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp35
-rw-r--r--drivers/gles2/shaders/scene.glsl2
-rw-r--r--drivers/gles2/shaders/stdlib.glsl293
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp5
-rw-r--r--editor/animation_track_editor.cpp9
-rw-r--r--editor/animation_track_editor.h2
-rw-r--r--editor/code_editor.cpp1
-rw-r--r--editor/editor_node.cpp15
-rw-r--r--editor/icons/icon_key_animation.svg66
-rw-r--r--editor/icons/icon_key_audio.svg66
-rw-r--r--editor/icons/icon_key_bezier.svg66
-rw-r--r--editor/icons/icon_key_call.svg65
-rw-r--r--editor/icons/icon_key_selected.svg77
-rw-r--r--editor/icons/icon_key_value.svg6
-rw-r--r--editor/icons/icon_key_xform.svg65
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp33
-rw-r--r--editor/plugins/animation_player_editor_plugin.h1
-rw-r--r--editor/plugins/script_editor_plugin.cpp59
-rw-r--r--editor/plugins/script_editor_plugin.h3
-rw-r--r--editor/plugins/shader_editor_plugin.cpp10
-rw-r--r--editor/plugins/shader_editor_plugin.h4
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp96
-rw-r--r--editor/plugins/spatial_editor_plugin.h4
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp8
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp21
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp256
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h17
-rw-r--r--main/main.cpp6
-rw-r--r--modules/assimp/SCsub13
-rwxr-xr-x[-rw-r--r--]modules/assimp/godot_update_assimp.sh3
-rw-r--r--modules/gdscript/gdscript_parser.cpp1
-rw-r--r--modules/mono/glue/Managed/Files/Color.cs27
-rw-r--r--modules/mono/glue/Managed/Files/Mathf.cs8
-rw-r--r--modules/visual_script/visual_script_editor.cpp8
-rw-r--r--platform/android/SCsub7
-rw-r--r--platform/android/detect.py54
-rw-r--r--platform/osx/os_osx.mm4
-rw-r--r--platform/windows/os_windows.cpp6
-rw-r--r--platform/x11/os_x11.cpp4
-rw-r--r--scene/2d/area_2d.cpp4
-rw-r--r--scene/2d/cpu_particles_2d.cpp4
-rw-r--r--scene/2d/physics_body_2d.cpp4
-rw-r--r--scene/3d/area.cpp4
-rw-r--r--scene/3d/physics_body.cpp4
-rw-r--r--scene/gui/dialogs.cpp39
-rw-r--r--scene/gui/graph_edit.cpp30
-rw-r--r--scene/gui/line_edit.cpp1
-rw-r--r--scene/gui/progress_bar.cpp2
-rw-r--r--scene/gui/rich_text_label.cpp6
-rw-r--r--scene/main/scene_tree.cpp17
-rw-r--r--scene/resources/visual_shader_nodes.cpp2
-rw-r--r--servers/physics/collision_solver_sat.cpp4
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h6
-rw-r--r--thirdparty/README.md2
-rw-r--r--thirdparty/assimp/assimp/config.h16
-rw-r--r--thirdparty/assimp/code/CApi/AssimpCExport.cpp156
-rw-r--r--thirdparty/assimp/code/CApi/CInterfaceIOWrapper.cpp (renamed from thirdparty/assimp/code/CInterfaceIOWrapper.cpp)0
-rw-r--r--thirdparty/assimp/code/CApi/CInterfaceIOWrapper.h (renamed from thirdparty/assimp/code/CInterfaceIOWrapper.h)0
-rw-r--r--thirdparty/assimp/code/Common/Assimp.cpp695
-rw-r--r--thirdparty/assimp/code/Common/BaseImporter.cpp (renamed from thirdparty/assimp/code/BaseImporter.cpp)6
-rw-r--r--thirdparty/assimp/code/Common/BaseProcess.cpp (renamed from thirdparty/assimp/code/BaseProcess.cpp)2
-rw-r--r--thirdparty/assimp/code/Common/BaseProcess.h (renamed from thirdparty/assimp/code/BaseProcess.h)0
-rw-r--r--thirdparty/assimp/code/Common/Bitmap.cpp (renamed from thirdparty/assimp/code/Bitmap.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/CreateAnimMesh.cpp (renamed from thirdparty/assimp/code/CreateAnimMesh.cpp)4
-rw-r--r--thirdparty/assimp/code/Common/DefaultIOStream.cpp (renamed from thirdparty/assimp/code/DefaultIOStream.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/DefaultIOSystem.cpp (renamed from thirdparty/assimp/code/DefaultIOSystem.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/DefaultLogger.cpp (renamed from thirdparty/assimp/code/DefaultLogger.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/DefaultProgressHandler.h (renamed from thirdparty/assimp/code/DefaultProgressHandler.h)0
-rw-r--r--thirdparty/assimp/code/Common/Exporter.cpp (renamed from thirdparty/assimp/code/Exporter.cpp)32
-rw-r--r--thirdparty/assimp/code/Common/FileLogStream.h (renamed from thirdparty/assimp/code/FileLogStream.h)0
-rw-r--r--thirdparty/assimp/code/Common/FileSystemFilter.h (renamed from thirdparty/assimp/code/FileSystemFilter.h)0
-rw-r--r--thirdparty/assimp/code/Common/IFF.h102
-rw-r--r--thirdparty/assimp/code/Common/Importer.cpp (renamed from thirdparty/assimp/code/Importer.cpp)19
-rw-r--r--thirdparty/assimp/code/Common/Importer.h (renamed from thirdparty/assimp/code/Importer.h)0
-rw-r--r--thirdparty/assimp/code/Common/ImporterRegistry.cpp (renamed from thirdparty/assimp/code/ImporterRegistry.cpp)96
-rw-r--r--thirdparty/assimp/code/Common/PolyTools.h (renamed from thirdparty/assimp/code/PolyTools.h)0
-rw-r--r--thirdparty/assimp/code/Common/PostStepRegistry.cpp (renamed from thirdparty/assimp/code/PostStepRegistry.cpp)63
-rw-r--r--thirdparty/assimp/code/Common/RemoveComments.cpp (renamed from thirdparty/assimp/code/RemoveComments.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/SGSpatialSort.cpp (renamed from thirdparty/assimp/code/SGSpatialSort.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/SceneCombiner.cpp (renamed from thirdparty/assimp/code/SceneCombiner.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/ScenePreprocessor.cpp (renamed from thirdparty/assimp/code/ScenePreprocessor.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/ScenePreprocessor.h (renamed from thirdparty/assimp/code/ScenePreprocessor.h)0
-rw-r--r--thirdparty/assimp/code/Common/ScenePrivate.h (renamed from thirdparty/assimp/code/ScenePrivate.h)0
-rw-r--r--thirdparty/assimp/code/Common/SkeletonMeshBuilder.cpp (renamed from thirdparty/assimp/code/SkeletonMeshBuilder.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/SpatialSort.cpp (renamed from thirdparty/assimp/code/SpatialSort.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/SplitByBoneCountProcess.cpp (renamed from thirdparty/assimp/code/SplitByBoneCountProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/SplitByBoneCountProcess.h (renamed from thirdparty/assimp/code/SplitByBoneCountProcess.h)0
-rw-r--r--thirdparty/assimp/code/Common/StandardShapes.cpp (renamed from thirdparty/assimp/code/StandardShapes.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/StdOStreamLogStream.h (renamed from thirdparty/assimp/code/StdOStreamLogStream.h)0
-rw-r--r--thirdparty/assimp/code/Common/Subdivision.cpp (renamed from thirdparty/assimp/code/Subdivision.cpp)7
-rw-r--r--thirdparty/assimp/code/Common/TargetAnimation.cpp (renamed from thirdparty/assimp/code/TargetAnimation.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/TargetAnimation.h (renamed from thirdparty/assimp/code/TargetAnimation.h)0
-rw-r--r--thirdparty/assimp/code/Common/Version.cpp (renamed from thirdparty/assimp/code/Version.cpp)2
-rw-r--r--thirdparty/assimp/code/Common/VertexTriangleAdjacency.cpp (renamed from thirdparty/assimp/code/VertexTriangleAdjacency.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/VertexTriangleAdjacency.h (renamed from thirdparty/assimp/code/VertexTriangleAdjacency.h)0
-rw-r--r--thirdparty/assimp/code/Common/Win32DebugLogStream.h (renamed from thirdparty/assimp/code/Win32DebugLogStream.h)0
-rw-r--r--thirdparty/assimp/code/Common/assbin_chunks.h196
-rw-r--r--thirdparty/assimp/code/Common/scene.cpp (renamed from thirdparty/assimp/code/scene.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/simd.cpp (renamed from thirdparty/assimp/code/simd.cpp)0
-rw-r--r--thirdparty/assimp/code/Common/simd.h (renamed from thirdparty/assimp/code/simd.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXAnimation.cpp (renamed from thirdparty/assimp/code/FBXAnimation.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXBinaryTokenizer.cpp (renamed from thirdparty/assimp/code/FBXBinaryTokenizer.cpp)12
-rw-r--r--thirdparty/assimp/code/FBX/FBXCommon.h (renamed from thirdparty/assimp/code/FBXCommon.h)4
-rw-r--r--thirdparty/assimp/code/FBX/FBXCompileConfig.h (renamed from thirdparty/assimp/code/FBXCompileConfig.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXConverter.cpp (renamed from thirdparty/assimp/code/FBXConverter.cpp)268
-rw-r--r--thirdparty/assimp/code/FBX/FBXConverter.h (renamed from thirdparty/assimp/code/FBXConverter.h)37
-rw-r--r--thirdparty/assimp/code/FBX/FBXDeformer.cpp (renamed from thirdparty/assimp/code/FBXDeformer.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXDocument.cpp (renamed from thirdparty/assimp/code/FBXDocument.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXDocument.h (renamed from thirdparty/assimp/code/FBXDocument.h)4
-rw-r--r--thirdparty/assimp/code/FBX/FBXDocumentUtil.cpp (renamed from thirdparty/assimp/code/FBXDocumentUtil.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXDocumentUtil.h (renamed from thirdparty/assimp/code/FBXDocumentUtil.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXExportNode.cpp (renamed from thirdparty/assimp/code/FBXExportNode.cpp)11
-rw-r--r--thirdparty/assimp/code/FBX/FBXExportNode.h (renamed from thirdparty/assimp/code/FBXExportNode.h)12
-rw-r--r--thirdparty/assimp/code/FBX/FBXExportProperty.cpp (renamed from thirdparty/assimp/code/FBXExportProperty.cpp)257
-rw-r--r--thirdparty/assimp/code/FBX/FBXExportProperty.h (renamed from thirdparty/assimp/code/FBXExportProperty.h)48
-rw-r--r--thirdparty/assimp/code/FBX/FBXExporter.cpp (renamed from thirdparty/assimp/code/FBXExporter.cpp)115
-rw-r--r--thirdparty/assimp/code/FBX/FBXExporter.h (renamed from thirdparty/assimp/code/FBXExporter.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXImportSettings.h (renamed from thirdparty/assimp/code/FBXImportSettings.h)39
-rw-r--r--thirdparty/assimp/code/FBX/FBXImporter.cpp (renamed from thirdparty/assimp/code/FBXImporter.cpp)10
-rw-r--r--thirdparty/assimp/code/FBX/FBXImporter.h (renamed from thirdparty/assimp/code/FBXImporter.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXMaterial.cpp (renamed from thirdparty/assimp/code/FBXMaterial.cpp)44
-rw-r--r--thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp (renamed from thirdparty/assimp/code/FBXMeshGeometry.cpp)11
-rw-r--r--thirdparty/assimp/code/FBX/FBXMeshGeometry.h (renamed from thirdparty/assimp/code/FBXMeshGeometry.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXModel.cpp (renamed from thirdparty/assimp/code/FBXModel.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXNodeAttribute.cpp (renamed from thirdparty/assimp/code/FBXNodeAttribute.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXParser.cpp (renamed from thirdparty/assimp/code/FBXParser.cpp)12
-rw-r--r--thirdparty/assimp/code/FBX/FBXParser.h (renamed from thirdparty/assimp/code/FBXParser.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXProperties.cpp (renamed from thirdparty/assimp/code/FBXProperties.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXProperties.h (renamed from thirdparty/assimp/code/FBXProperties.h)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXTokenizer.cpp (renamed from thirdparty/assimp/code/FBXTokenizer.cpp)0
-rw-r--r--thirdparty/assimp/code/FBX/FBXTokenizer.h (renamed from thirdparty/assimp/code/FBXTokenizer.h)12
-rw-r--r--thirdparty/assimp/code/FBX/FBXUtil.cpp (renamed from thirdparty/assimp/code/FBXUtil.cpp)135
-rw-r--r--thirdparty/assimp/code/FBX/FBXUtil.h (renamed from thirdparty/assimp/code/FBXUtil.h)23
-rw-r--r--thirdparty/assimp/code/FIReader.cpp1834
-rw-r--r--thirdparty/assimp/code/MMD/MMDCpp14.h (renamed from thirdparty/assimp/code/MMDCpp14.h)0
-rw-r--r--thirdparty/assimp/code/MMD/MMDImporter.cpp (renamed from thirdparty/assimp/code/MMDImporter.cpp)12
-rw-r--r--thirdparty/assimp/code/MMD/MMDImporter.h (renamed from thirdparty/assimp/code/MMDImporter.h)0
-rw-r--r--thirdparty/assimp/code/MMD/MMDPmdParser.h (renamed from thirdparty/assimp/code/MMDPmdParser.h)0
-rw-r--r--thirdparty/assimp/code/MMD/MMDPmxParser.cpp (renamed from thirdparty/assimp/code/MMDPmxParser.cpp)6
-rw-r--r--thirdparty/assimp/code/MMD/MMDPmxParser.h (renamed from thirdparty/assimp/code/MMDPmxParser.h)0
-rw-r--r--thirdparty/assimp/code/MMD/MMDVmdParser.h (renamed from thirdparty/assimp/code/MMDVmdParser.h)0
-rw-r--r--thirdparty/assimp/code/Material/MaterialSystem.cpp (renamed from thirdparty/assimp/code/MaterialSystem.cpp)12
-rw-r--r--thirdparty/assimp/code/Material/MaterialSystem.h (renamed from thirdparty/assimp/code/MaterialSystem.h)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp (renamed from thirdparty/assimp/code/CalcTangentsProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.h (renamed from thirdparty/assimp/code/CalcTangentsProcess.h)4
-rw-r--r--thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp (renamed from thirdparty/assimp/code/ComputeUVMappingProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.h (renamed from thirdparty/assimp/code/ComputeUVMappingProcess.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.cpp (renamed from thirdparty/assimp/code/ConvertToLHProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.h (renamed from thirdparty/assimp/code/ConvertToLHProcess.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/DeboneProcess.cpp (renamed from thirdparty/assimp/code/DeboneProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/DeboneProcess.h (renamed from thirdparty/assimp/code/DeboneProcess.h)17
-rw-r--r--thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.cpp (renamed from thirdparty/assimp/code/DropFaceNormalsProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.h (renamed from thirdparty/assimp/code/DropFaceNormalsProcess.h)11
-rw-r--r--thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.cpp (renamed from thirdparty/assimp/code/EmbedTexturesProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.h (renamed from thirdparty/assimp/code/EmbedTexturesProcess.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindDegenerates.cpp (renamed from thirdparty/assimp/code/FindDegenerates.cpp)1
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindDegenerates.h (renamed from thirdparty/assimp/code/FindDegenerates.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindInstancesProcess.cpp (renamed from thirdparty/assimp/code/FindInstancesProcess.cpp)12
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindInstancesProcess.h (renamed from thirdparty/assimp/code/FindInstancesProcess.h)4
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp (renamed from thirdparty/assimp/code/FindInvalidDataProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.h (renamed from thirdparty/assimp/code/FindInvalidDataProcess.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/FixNormalsStep.cpp (renamed from thirdparty/assimp/code/FixNormalsStep.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/FixNormalsStep.h (renamed from thirdparty/assimp/code/FixNormalsStep.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp115
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h76
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp (renamed from thirdparty/assimp/code/GenFaceNormalsProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.h (renamed from thirdparty/assimp/code/GenFaceNormalsProcess.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp (renamed from thirdparty/assimp/code/GenVertexNormalsProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.h (renamed from thirdparty/assimp/code/GenVertexNormalsProcess.h)18
-rw-r--r--thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.cpp (renamed from thirdparty/assimp/code/ImproveCacheLocality.cpp)65
-rw-r--r--thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.h (renamed from thirdparty/assimp/code/ImproveCacheLocality.h)7
-rw-r--r--thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp (renamed from thirdparty/assimp/code/JoinVerticesProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.h (renamed from thirdparty/assimp/code/JoinVerticesProcess.h)10
-rw-r--r--thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.cpp (renamed from thirdparty/assimp/code/LimitBoneWeightsProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.h (renamed from thirdparty/assimp/code/LimitBoneWeightsProcess.h)34
-rw-r--r--thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp (renamed from thirdparty/assimp/code/MakeVerboseFormat.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h (renamed from thirdparty/assimp/code/MakeVerboseFormat.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/OptimizeGraph.cpp (renamed from thirdparty/assimp/code/OptimizeGraph.cpp)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/OptimizeGraph.h (renamed from thirdparty/assimp/code/OptimizeGraph.h)27
-rw-r--r--thirdparty/assimp/code/PostProcessing/OptimizeMeshes.cpp (renamed from thirdparty/assimp/code/OptimizeMeshes.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/OptimizeMeshes.h (renamed from thirdparty/assimp/code/OptimizeMeshes.h)10
-rw-r--r--thirdparty/assimp/code/PostProcessing/PretransformVertices.cpp (renamed from thirdparty/assimp/code/PretransformVertices.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/PretransformVertices.h (renamed from thirdparty/assimp/code/PretransformVertices.h)15
-rw-r--r--thirdparty/assimp/code/PostProcessing/ProcessHelper.cpp (renamed from thirdparty/assimp/code/ProcessHelper.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/ProcessHelper.h (renamed from thirdparty/assimp/code/ProcessHelper.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.cpp (renamed from thirdparty/assimp/code/RemoveRedundantMaterials.cpp)10
-rw-r--r--thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.h (renamed from thirdparty/assimp/code/RemoveRedundantMaterials.h)18
-rw-r--r--thirdparty/assimp/code/PostProcessing/RemoveVCProcess.cpp (renamed from thirdparty/assimp/code/RemoveVCProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/RemoveVCProcess.h (renamed from thirdparty/assimp/code/RemoveVCProcess.h)3
-rw-r--r--thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp (renamed from thirdparty/assimp/code/ScaleProcess.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/ScaleProcess.h (renamed from thirdparty/assimp/code/ScaleProcess.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.cpp (renamed from thirdparty/assimp/code/SortByPTypeProcess.cpp)18
-rw-r--r--thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.h (renamed from thirdparty/assimp/code/SortByPTypeProcess.h)11
-rw-r--r--thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.cpp (renamed from thirdparty/assimp/code/SplitLargeMeshes.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.h (renamed from thirdparty/assimp/code/SplitLargeMeshes.h)9
-rw-r--r--thirdparty/assimp/code/PostProcessing/TextureTransform.cpp (renamed from thirdparty/assimp/code/TextureTransform.cpp)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/TextureTransform.h (renamed from thirdparty/assimp/code/TextureTransform.h)2
-rw-r--r--thirdparty/assimp/code/PostProcessing/TriangulateProcess.cpp (renamed from thirdparty/assimp/code/TriangulateProcess.cpp)10
-rw-r--r--thirdparty/assimp/code/PostProcessing/TriangulateProcess.h (renamed from thirdparty/assimp/code/TriangulateProcess.h)8
-rw-r--r--thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp (renamed from thirdparty/assimp/code/ValidateDataStructure.cpp)33
-rw-r--r--thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h (renamed from thirdparty/assimp/code/ValidateDataStructure.h)3
-rw-r--r--thirdparty/assimp/code/RawLoader.cpp331
-rw-r--r--thirdparty/assimp/include/assimp/Exporter.hpp2
-rw-r--r--thirdparty/assimp/include/assimp/ParsingUtils.h3
-rw-r--r--thirdparty/assimp/include/assimp/aabb.h76
-rw-r--r--thirdparty/assimp/include/assimp/camera.h5
-rw-r--r--thirdparty/assimp/include/assimp/color4.inl4
-rw-r--r--thirdparty/assimp/include/assimp/config.h.in35
-rw-r--r--thirdparty/assimp/include/assimp/defs.h21
-rw-r--r--thirdparty/assimp/include/assimp/mesh.h11
-rw-r--r--thirdparty/assimp/include/assimp/postprocess.h13
-rw-r--r--thirdparty/assimp/include/assimp/scene.h9
-rw-r--r--thirdparty/jpeg-compressor/jpgd.cpp55
226 files changed, 3556 insertions, 3637 deletions
diff --git a/AUTHORS.md b/AUTHORS.md
index 43b4917382..430bb2dcd4 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -36,6 +36,7 @@ name is available.
Andy Moss (MillionOstrich)
Anish Bhobe (KidRigger)
Anton Yabchinskiy (a12n)
+ Anutrix
Aren Villanueva (kurikaesu)
Ariel Manzur (punto-)
Bastiaan Olij (BastiaanOlij)
@@ -68,6 +69,7 @@ name is available.
Gerrit Großkopf (Grosskopf)
Gilles Roudiere (groud)
Guilherme Felipe de C. G. da Silva (guilhermefelipecgs)
+ Hanif A (hbina)
Hein-Pieter van Braam (hpvb)
Hiroshi Ogawa (hi-ogawa)
homer666
@@ -128,6 +130,7 @@ name is available.
romulox-x
Ruslan Mustakov (endragor)
Saniko (sanikoyes)
+ santouits
SaracenOne
sersoong
Simon Wenner (swenner)
diff --git a/DONORS.md b/DONORS.md
index 947c12923b..6c4b9b0514 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -20,8 +20,8 @@ generous deed immortalized in the next stable release of Godot Engine.
## Mini sponsors
+ AD Ford
Alan Beauchamp
- Aleksandar Kordic
Anandarup Mallik
Andrew Dunai
Brandon Lamb
@@ -30,8 +30,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Christoph Woinke
Denis Malyavin
Edward Flick
+ Gamechuck
GameDev.net
GameDev.tv
+ Grady
Hein-Pieter van Braam
Jacob McKenney
Javary Co.
@@ -46,7 +48,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Patrick Aarstad
Slobodan Milnovic
Stephan Lanfermann
- Stephen Telford
Steve
VilliHaukka
Xananax
@@ -59,7 +60,6 @@ generous deed immortalized in the next stable release of Godot Engine.
David Gehrig
Ed Morley
Florian Krick
- Grady
Jakub Grzesik
K9Kraken
Manuele Finocchiaro
@@ -77,11 +77,14 @@ generous deed immortalized in the next stable release of Godot Engine.
Carlo Cabanilla
Daniel James
David Giardi
+ David Snopek
Edward E
Florian Breisch
Gero
+ GiulianoB
Javier Roman
Jay Horton
+ Jonathan Turner
Jon Smith
Jon Woodward
Justo Delgado Baudí
@@ -89,13 +92,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Kommentgames
Krzysztof Dluzniewski
Luke
+ Maciej Pendolski
Moonwards
Mored1984
- paul gruenbacher
Paul LaMotte
Péter Magyar
Rob Messick
- Ross Esmond
Ryan Badour
Scott Wadden
Sergey
@@ -103,7 +105,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Svenne Krap
Tom Langwaldt
William Wold
- Wyatt Goodin
Alex Khayrullin
Chris Goddard
@@ -115,6 +116,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Ian Richard Kunert
Ivan Trombley
Joan Fons
+ Joshua Flores
Krzysztof Jankowski
Lord Bloodhound
Lucas Ferreira Franca
@@ -135,7 +137,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Xavier PATRICELLI
Adam Neumann
- Alessandra Pereyra
Alexander J Maynard
Alexey Dyadchenko
Andrew Bowen
@@ -150,7 +151,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Daniel
Daniel Eichler
David White
- Deadly Lampshade
Eric
Eric Monson
Eugenio Hugo Salgüero Jáñez
@@ -158,7 +158,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Francisco Javier Moreno Carracedo
gavlig
GGGames.org
- Giles Montgomery
Guilherme Felipe de C. G. da Silva
Heath Hayes
Hysteria
@@ -166,14 +165,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Jared White
Jesse Nave
Jose Malheiro
- Joshua Flores
Joshua Lesperance
Juan T Chen
Juraj Móza
Kasper Jeppesen
Klaus The.
Klavdij Voncina
- Leandro Voltolino
Maarten Elings
Markus Fehr
Markus Wiesner
@@ -190,6 +187,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Paul Hocker
Paul Von Zimmerman
Pete Goodwin
+ pl
Ranoller
Samuel Judd
Scott Pilet
@@ -198,37 +196,37 @@ generous deed immortalized in the next stable release of Godot Engine.
Thomas Krampl
Tobias Bocanegra
Urho
- WytRabbit
Xavier Fumado Beltran
## Silver donors
1D_Inc
+ Abby Jones
Abraham Haskins
Adam Brunnmeier
Adam Carr
Adam Nakonieczny
Adam Smeltzer
Adisibio
+ Adrian Demetrescu
Agustinus Arya
Aidan O'Flannagain
+ Albin Jonasson Svärdsby
Alder Stefano
Alessandro Senese
- Alexander Gillberg
Alexander Koppe
Alex Davies-Moore
- Alice Robinson
Andreas Evers
Andreas Krampitz
+ Andreas Lundmark
Andreas Schüle
- Andrew Peart
+ Andrés Rodríguez
+ Andrzej Skalski
Anthony Bongiovanni
Anthony Staunton
Antony K. Jones
Arda Erol
- Artem Bashev
Arthur S. Muszynski
- Artistofdeath
Aubrey Falconer
Avencherus
B A
@@ -238,8 +236,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Benedikt
Ben Phelan
Ben Vercammen
- Ben Woodley
- Berbank
Bernd Jänichen
Black Block
Blair Allen
@@ -261,9 +257,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Collin Shooltz
Dag Sundin Söderström
Daniel Johnson
+ DanielMaximiano
Daniel Reed
- Danny Welch
- Dave Watts
+ Daniel Tebbutt
David Bullock
David Cravens
David May
@@ -330,20 +326,23 @@ generous deed immortalized in the next stable release of Godot Engine.
Josh 'Cheeseness' Bush
Juanfran
Juan Negrier
+ Juan Velandia
Judd
Jueast
Julian Murgia
+ Kamuna
Kasier Bald0
KC Chan
+ Keedong Park
kickmaniac
Kiyohiro Kawamura (kyorohiro)
+ Kjetil Haugland
Klagsam
Klassix
KR McGinley
KsyTek Games
Kuan Cheang
kycho
- Leviathan Hunter
Levi Lindsey
Linus Lind Lundgren
Lionel Gaillard
@@ -357,6 +356,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Malik Nejer
Marc Urlus
Marcus Richter
+ Markus Lohaus
Markus Michael Egger
Martin Holas
Matthew Little
@@ -365,6 +365,7 @@ generous deed immortalized in the next stable release of Godot Engine.
mhilbrunner
Michael Dürwald
Michael Gringauz
+ Michael Haney
Michael Labbe
Mikael Olsson
Mikayla Hutchinson
@@ -372,7 +373,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Mitchell J. Wagner
mlevin cantu
MoM
- Moritz Laass
MuffinManKen
Natrim
nee
@@ -382,9 +382,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Niclas Eriksen
Nicolás Montaña
Nicolas SAN AGUSTIN
+ Nima Farid
Nithin Jino
NZ
Omar Delarosa
+ omzee
Oscar Norlander
Pafka
Pan Ip
@@ -393,16 +395,19 @@ generous deed immortalized in the next stable release of Godot Engine.
Paul Gieske
Paul Mason
Paweł Kowal
- Philip O. Staiger
Pierre-Igor Berthet
Pietro Vertechi
Pitsanu Tongprasin
Point08
Poryg
+ Rafael Delboni
Rafa Laguna
Rafal Wyszomirski
+ rainerLinux
Raphael Leroux
+ Remi Rampin
Rémi Verschelde
+ Rezgi
Ricardo Alcantara
Robert Farr (Larington)
Robert Hernandez
@@ -410,6 +415,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Roger Smith
Roland Rząsa
Roman Tinkov
+ Ryan
+ Ryan Brooks
Ryan Groom
Ryan Hentz
Saad Khoudmi
@@ -418,6 +425,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Sasori Olkof
Scott D. Yelich
Sebastian Michailidis
+ sgnsajgon
Shane Sicienski
Shane Spoor
Simon Ledam
@@ -425,16 +433,14 @@ generous deed immortalized in the next stable release of Godot Engine.
SK
Sootstone
Stonepyre
- Thibault Barbaroux
+ Taylor Fahlman
thomas
Thomas Bell
Thomas Kelly
Thomas Kurz
tiansheng li
- Tim
Tim Drumheller
Tim Gudex
- Timo Schmidt
Timothy B. MacDonald
Tobbun
Tom Larrow
@@ -446,8 +452,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Tyler Stafos
UltyX
Vaiktorg
- Valeria Viana Gusmao
- Veodok
Victor
Vigilant Watch
waka nya
@@ -457,7 +461,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Will
William Hogben
Wout Standaert
- Yeung Si Xiang
+ Wyatt Goodin
+ Yegor
## Bronze donors
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index 6c4310a572..102cd9cf6c 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -208,7 +208,8 @@ void FileAccessCompressed::seek(size_t p_position) {
if (p_position == read_total) {
at_end = true;
} else {
-
+ at_end = false;
+ read_eof = false;
int block_idx = p_position / block_size;
if (block_idx != read_block) {
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index a712356ddc..af845ca01e 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -255,16 +255,16 @@ public:
static _ALWAYS_INLINE_ float round(float p_val) { return (p_val >= 0) ? Math::floor(p_val + 0.5) : -Math::floor(-p_val + 0.5); }
static _ALWAYS_INLINE_ int64_t wrapi(int64_t value, int64_t min, int64_t max) {
- int64_t rng = max - min;
- return (rng != 0) ? min + ((((value - min) % rng) + rng) % rng) : min;
+ int64_t range = max - min;
+ return range == 0 ? min : min + ((((value - min) % range) + range) % range);
}
static _ALWAYS_INLINE_ double wrapf(double value, double min, double max) {
- double rng = max - min;
- return (!is_equal_approx(rng, 0.0)) ? value - (rng * Math::floor((value - min) / rng)) : min;
+ double range = max - min;
+ return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range));
}
static _ALWAYS_INLINE_ float wrapf(float value, float min, float max) {
- float rng = max - min;
- return (!is_equal_approx(rng, 0.0f)) ? value - (rng * Math::floor((value - min) / rng)) : min;
+ float range = max - min;
+ return is_zero_approx(range) ? min : value - (range * Math::floor((value - min) / range));
}
// double only, as these functions are mainly used by the editor and not performance-critical,
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index e7ff7a3aef..5f01e043c4 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -357,10 +357,11 @@ void ScriptDebuggerRemote::_get_output() {
locking = false;
}
- if (n_errors_dropped > 0) {
+ if (n_errors_dropped == 1) {
+ // Only print one message about dropping per second
OutputError oe;
oe.error = "TOO_MANY_ERRORS";
- oe.error_descr = "Too many errors! " + String::num_int64(n_errors_dropped) + " errors were dropped.";
+ oe.error_descr = "Too many errors! Ignoring errors for up to 1 second.";
oe.warning = false;
uint64_t time = OS::get_singleton()->get_ticks_msec();
oe.hr = time / 3600000;
@@ -368,7 +369,20 @@ void ScriptDebuggerRemote::_get_output() {
oe.sec = (time / 1000) % 60;
oe.msec = time % 1000;
errors.push_back(oe);
- n_errors_dropped = 0;
+ }
+
+ if (n_warnings_dropped == 1) {
+ // Only print one message about dropping per second
+ OutputError oe;
+ oe.error = "TOO_MANY_WARNINGS";
+ oe.error_descr = "Too many warnings! Ignoring warnings for up to 1 second.";
+ oe.warning = true;
+ uint64_t time = OS::get_singleton()->get_ticks_msec();
+ oe.hr = time / 3600000;
+ oe.min = (time / 60000) % 60;
+ oe.sec = (time / 1000) % 60;
+ oe.msec = time % 1000;
+ errors.push_back(oe);
}
while (errors.size()) {
@@ -934,6 +948,19 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file
oe.msec = time % 1000;
Array cstack;
+ uint64_t ticks = OS::get_singleton()->get_ticks_usec() / 1000;
+ msec_count += ticks - last_msec;
+ last_msec = ticks;
+
+ if (msec_count > 1000) {
+ msec_count = 0;
+
+ err_count = 0;
+ n_errors_dropped = 0;
+ warn_count = 0;
+ n_warnings_dropped = 0;
+ }
+
cstack.resize(p_stack_info.size() * 3);
for (int i = 0; i < p_stack_info.size(); i++) {
cstack[i * 3 + 0] = p_stack_info[i].file;
@@ -942,15 +969,28 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file
}
oe.callstack = cstack;
+ if (oe.warning) {
+ warn_count++;
+ } else {
+ err_count++;
+ }
mutex->lock();
if (!locking && tcp_client->is_connected_to_host()) {
- if (errors.size() >= max_errors_per_frame) {
- n_errors_dropped++;
+ if (oe.warning) {
+ if (warn_count > max_warnings_per_second) {
+ n_warnings_dropped++;
+ } else {
+ errors.push_back(oe);
+ }
} else {
- errors.push_back(oe);
+ if (err_count > max_errors_per_second) {
+ n_errors_dropped++;
+ } else {
+ errors.push_back(oe);
+ }
}
}
@@ -1070,10 +1110,13 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() :
mutex(Mutex::create()),
max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")),
n_messages_dropped(0),
- max_errors_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_frame")),
+ max_errors_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_second")),
+ max_warnings_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_warnings_per_second")),
n_errors_dropped(0),
max_cps(GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second")),
char_count(0),
+ err_count(0),
+ warn_count(0),
last_msec(0),
msec_count(0),
locking(false),
diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h
index 1fc9d7c7f1..a5bfd7a32d 100644
--- a/core/script_debugger_remote.h
+++ b/core/script_debugger_remote.h
@@ -91,11 +91,15 @@ class ScriptDebuggerRemote : public ScriptDebugger {
int max_messages_per_frame;
int n_messages_dropped;
List<OutputError> errors;
- int max_errors_per_frame;
+ int max_errors_per_second;
+ int max_warnings_per_second;
int n_errors_dropped;
+ int n_warnings_dropped;
int max_cps;
int char_count;
+ int err_count;
+ int warn_count;
uint64_t last_msec;
uint64_t msec_count;
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index 111bf2109e..3cc40b7cef 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -233,6 +233,11 @@
Signal sent when user dragging connection from output port into empty space of the graph.
</description>
</signal>
+ <signal name="copy_nodes_request">
+ <description>
+ Signal sent when the user presses [code]Ctrl + C[/code].
+ </description>
+ </signal>
<signal name="delete_nodes_request">
<description>
Signal sent when a GraphNode is attempted to be removed from the GraphEdit.
@@ -263,6 +268,11 @@
Emitted when a GraphNode is selected.
</description>
</signal>
+ <signal name="paste_nodes_request">
+ <description>
+ Signal sent when the user presses [code]Ctrl + V[/code].
+ </description>
+ </signal>
<signal name="popup_request">
<argument index="0" name="position" type="Vector2">
</argument>
diff --git a/doc/classes/PoolIntArray.xml b/doc/classes/PoolIntArray.xml
index 730833b097..28a28b2bba 100644
--- a/doc/classes/PoolIntArray.xml
+++ b/doc/classes/PoolIntArray.xml
@@ -6,6 +6,7 @@
<description>
An [Array] specifically designed to hold integer values ([int]). Optimized for memory usage, does not fragment the memory.
[b]Note:[/b] This type is passed by value and not by reference.
+ [b]Note:[/b] This type is limited to signed 32-bit integers, which means it can only take values in the interval [code][-2^31, 2^31 - 1][/code], i.e. [code][-2147483648, 2147483647][/code]. Exceeding those bounds will wrap around. In comparison, [int] uses signed 64-bit integers which can hold much larger values.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 80d21e07ea..9f18eea0d4 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -650,12 +650,15 @@
<member name="network/limits/debugger_stdout/max_chars_per_second" type="int" setter="" getter="" default="2048">
Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
</member>
- <member name="network/limits/debugger_stdout/max_errors_per_frame" type="int" setter="" getter="" default="10">
- Maximum amount of errors allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
+ <member name="network/limits/debugger_stdout/max_errors_per_second" type="int" setter="" getter="" default="100">
+ Maximum number of errors allowed to be sent as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
</member>
<member name="network/limits/debugger_stdout/max_messages_per_frame" type="int" setter="" getter="" default="10">
Maximum amount of messages allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
</member>
+ <member name="network/limits/debugger_stdout/max_warnings_per_second" type="int" setter="" getter="" default="100">
+ Maximum number of warnings allowed to be sent as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
+ </member>
<member name="network/limits/packet_peer_stream/max_buffer_po2" type="int" setter="" getter="" default="16">
Default size of packet peer stream for deserializing Godot data. Over this size, data is dropped.
</member>
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 0c96c50c58..237b596fad 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -4,7 +4,7 @@
Vector used for 2D math.
</brief_description>
<description>
- 2-element structure that can be used to represent positions in 2d space or any other pair of numeric values.
+ 2-element structure that can be used to represent positions in 2D space or any other pair of numeric values.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h
index af41e91e0c..ab636dca71 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.h
+++ b/drivers/gles2/rasterizer_canvas_gles2.h
@@ -84,7 +84,7 @@ public:
Transform2D skeleton_transform;
Transform2D skeleton_transform_inverse;
- Vector2i skeleton_texture_size;
+ Size2i skeleton_texture_size;
RID current_tex;
RID current_normal;
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 23b01b4e09..453abeb853 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -1910,14 +1910,14 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
}
}
-void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform) {
+void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform, bool accum_pass) {
RasterizerStorageGLES2::Light *light_ptr = light->light_ptr;
//common parameters
float energy = light_ptr->param[VS::LIGHT_PARAM_ENERGY];
float specular = light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
- float sign = light_ptr->negative ? -1 : 1;
+ float sign = (light_ptr->negative && !accum_pass) ? -1 : 1; //inverse color for base pass lights only
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_SPECULAR, specular);
Color color = light_ptr->color * sign * energy * Math_PI;
@@ -2310,6 +2310,11 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
if (accum_pass) { //accum pass force pass
blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_ADD;
+ if (rebind_light && light && light->light_ptr->negative) {
+ glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_SUB;
+ }
}
if (prev_blend_mode != blend_mode) {
@@ -2553,7 +2558,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
}
if (rebind_light && light) {
- _setup_light(light, shadow_atlas, p_view_transform);
+ _setup_light(light, shadow_atlas, p_view_transform, accum_pass);
}
if (rebind_reflection && (refprobe_1 || refprobe_2)) {
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index c95385eb24..f60ca9675e 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -694,7 +694,7 @@ public:
_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0));
_FORCE_INLINE_ void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton);
_FORCE_INLINE_ void _setup_light_type(LightInstance *p_light, ShadowAtlas *shadow_atlas);
- _FORCE_INLINE_ void _setup_light(LightInstance *p_light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform);
+ _FORCE_INLINE_ void _setup_light(LightInstance *p_light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform, bool accum_pass);
_FORCE_INLINE_ void _setup_refprobes(ReflectionProbeInstance *p_refprobe1, ReflectionProbeInstance *p_refprobe2, const Transform &p_view_transform, Environment *p_env);
_FORCE_INLINE_ void _render_geometry(RenderList::Element *p_element);
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 630a5ed6c6..25bab0e97a 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -928,9 +928,25 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
- actions[VS::SHADER_CANVAS_ITEM].usage_defines["round"] = "#define ROUND_USED\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ // Ported from GLES3
+
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["sinh"] = "#define SINH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["cosh"] = "#define COSH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["tanh"] = "#define TANH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["asinh"] = "#define ASINH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["acosh"] = "#define ACOSH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["atanh"] = "#define ATANH_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["determinant"] = "#define DETERMINANT_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["transpose"] = "#define TRANSPOSE_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["outerProduct"] = "#define OUTER_PRODUCT_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["round"] = "#define ROUND_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["roundEven"] = "#define ROUND_EVEN_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["isinf"] = "#define IS_INF_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["isnan"] = "#define IS_NAN_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["trunc"] = "#define TRUNC_USED\n";
+
/** SPATIAL SHADER **/
actions[VS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform";
@@ -1023,6 +1039,23 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
actions[VS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
+ // Ported from GLES3
+
+ actions[VS::SHADER_SPATIAL].usage_defines["sinh"] = "#define SINH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["cosh"] = "#define COSH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["tanh"] = "#define TANH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["asinh"] = "#define ASINH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["acosh"] = "#define ACOSH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["atanh"] = "#define ATANH_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["determinant"] = "#define DETERMINANT_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["transpose"] = "#define TRANSPOSE_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["outerProduct"] = "#define OUTER_PRODUCT_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["round"] = "#define ROUND_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["roundEven"] = "#define ROUND_EVEN_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["isinf"] = "#define IS_INF_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["isnan"] = "#define IS_NAN_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["trunc"] = "#define TRUNC_USED\n";
+
actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 534c977a87..8a9387f0b3 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -10,7 +10,9 @@ precision highp float;
precision highp int;
#endif
+/* clang-format on */
#include "stdlib.glsl"
+/* clang-format off */
#define SHADER_IS_SRGB true
diff --git a/drivers/gles2/shaders/stdlib.glsl b/drivers/gles2/shaders/stdlib.glsl
index b9ecfec65e..96421fcb4a 100644
--- a/drivers/gles2/shaders/stdlib.glsl
+++ b/drivers/gles2/shaders/stdlib.glsl
@@ -35,7 +35,139 @@ highp vec4 texel2DFetch(highp sampler2D tex, ivec2 size, ivec2 coord) {
return texture2DLod(tex, vec2(x_coord, y_coord), 0.0);
}
-#ifdef ROUND_USED
+
+#if defined(SINH_USED)
+
+highp float sinh(highp float x) {
+ return 0.5 * (exp(x) - exp(-x));
+}
+
+highp vec2 sinh(highp vec2 x) {
+ return 0.5 * vec2(exp(x.x) - exp(-x.x), exp(x.y) - exp(-x.y));
+}
+
+highp vec3 sinh(highp vec3 x) {
+ return 0.5 * vec3(exp(x.x) - exp(-x.x), exp(x.y) - exp(-x.y), exp(x.z) - exp(-x.z));
+}
+
+highp vec4 sinh(highp vec4 x) {
+ return 0.5 * vec4(exp(x.x) - exp(-x.x), exp(x.y) - exp(-x.y), exp(x.z) - exp(-x.z), exp(x.w) - exp(-x.w));
+}
+
+#endif
+
+#if defined(COSH_USED)
+
+highp float cosh(highp float x) {
+ return 0.5 * (exp(x) + exp(-x));
+}
+
+highp vec2 cosh(highp vec2 x) {
+ return 0.5 * vec2(exp(x.x) + exp(-x.x), exp(x.y) + exp(-x.y));
+}
+
+highp vec3 cosh(highp vec3 x) {
+ return 0.5 * vec3(exp(x.x) + exp(-x.x), exp(x.y) + exp(-x.y), exp(x.z) + exp(-x.z));
+}
+
+highp vec4 cosh(highp vec4 x) {
+ return 0.5 * vec4(exp(x.x) + exp(-x.x), exp(x.y) + exp(-x.y), exp(x.z) + exp(-x.z), exp(x.w) + exp(-x.w));
+}
+
+#endif
+
+#if defined(TANH_USED)
+
+highp float tanh(highp float x) {
+ highp float exp2x = exp(2.0 * x);
+ return (exp2x - 1.0) / (exp2x + 1.0);
+}
+
+highp vec2 tanh(highp vec2 x) {
+ highp float exp2x = exp(2.0 * x.x);
+ highp float exp2y = exp(2.0 * x.y);
+ return vec2((exp2x - 1.0) / (exp2x + 1.0), (exp2y - 1.0) / (exp2y + 1.0));
+}
+
+highp vec3 tanh(highp vec3 x) {
+ highp float exp2x = exp(2.0 * x.x);
+ highp float exp2y = exp(2.0 * x.y);
+ highp float exp2z = exp(2.0 * x.z);
+ return vec3((exp2x - 1.0) / (exp2x + 1.0), (exp2y - 1.0) / (exp2y + 1.0), (exp2z - 1.0) / (exp2z + 1.0));
+}
+
+highp vec4 tanh(highp vec4 x) {
+ highp float exp2x = exp(2.0 * x.x);
+ highp float exp2y = exp(2.0 * x.y);
+ highp float exp2z = exp(2.0 * x.z);
+ highp float exp2w = exp(2.0 * x.w);
+ return vec4((exp2x - 1.0) / (exp2x + 1.0), (exp2y - 1.0) / (exp2y + 1.0), (exp2z - 1.0) / (exp2z + 1.0), (exp2w - 1.0) / (exp2w + 1.0));
+}
+
+#endif
+
+#if defined(ASINH_USED)
+
+highp float asinh(highp float x) {
+ return sign(x) * log(abs(x) + sqrt(1.0 + x * x));
+}
+
+highp vec2 asinh(highp vec2 x) {
+ return vec2(sign(x.x) * log(abs(x.x) + sqrt(1.0 + x.x * x.x)), sign(x.y) * log(abs(x.y) + sqrt(1.0 + x.y * x.y)));
+}
+
+highp vec3 asinh(highp vec3 x) {
+ return vec3(sign(x.x) * log(abs(x.x) + sqrt(1.0 + x.x * x.x)), sign(x.y) * log(abs(x.y) + sqrt(1.0 + x.y * x.y)), sign(x.z) * log(abs(x.z) + sqrt(1.0 + x.z * x.z)));
+}
+
+highp vec4 asinh(highp vec4 x) {
+ return vec4(sign(x.x) * log(abs(x.x) + sqrt(1.0 + x.x * x.x)), sign(x.y) * log(abs(x.y) + sqrt(1.0 + x.y * x.y)), sign(x.z) * log(abs(x.z) + sqrt(1.0 + x.z * x.z)), sign(x.w) * log(abs(x.w) + sqrt(1.0 + x.w * x.w)));
+}
+
+#endif
+
+#if defined(ACOSH_USED)
+
+highp float acosh(highp float x) {
+ return log(x + sqrt(x * x - 1.0));
+}
+
+highp vec2 acosh(highp vec2 x) {
+ return vec2(log(x.x + sqrt(x.x * x.x - 1.0)), log(x.y + sqrt(x.y * x.y - 1.0)));
+}
+
+highp vec3 acosh(highp vec3 x) {
+ return vec3(log(x.x + sqrt(x.x * x.x - 1.0)), log(x.y + sqrt(x.y * x.y - 1.0)), log(x.z + sqrt(x.z * x.z - 1.0)));
+}
+
+highp vec4 acosh(highp vec4 x) {
+ return vec4(log(x.x + sqrt(x.x * x.x - 1.0)), log(x.y + sqrt(x.y * x.y - 1.0)), log(x.z + sqrt(x.z * x.z - 1.0)), log(x.w + sqrt(x.w * x.w - 1.0)));
+}
+
+#endif
+
+#if defined(ATANH_USED)
+
+highp float atanh(highp float x) {
+ return 0.5 * log((1.0 + x) / (1.0 - x));
+}
+
+highp vec2 atanh(highp vec2 x) {
+ return 0.5 * vec2(log((1.0 + x.x) / (1.0 - x.x)), log((1.0 + x.y) / (1.0 - x.y)));
+}
+
+highp vec3 atanh(highp vec3 x) {
+ return 0.5 * vec3(log((1.0 + x.x) / (1.0 - x.x)), log((1.0 + x.y) / (1.0 - x.y)), log((1.0 + x.z) / (1.0 - x.z)));
+}
+
+highp vec4 atanh(highp vec4 x) {
+ return 0.5 * vec4(log((1.0 + x.x) / (1.0 - x.x)), log((1.0 + x.y) / (1.0 - x.y)), log((1.0 + x.z) / (1.0 - x.z)), log((1.0 + x.w) / (1.0 - x.w)));
+}
+
+#endif
+
+#if defined(ROUND_USED)
+
highp float round(highp float x) {
return floor(x + 0.5);
}
@@ -51,14 +183,163 @@ highp vec3 round(highp vec3 x) {
highp vec4 round(highp vec4 x) {
return floor(x + vec4(0.5));
}
+
+#endif
+
+#if defined(ROUND_EVEN_USED)
+
+highp float roundEven(highp float x) {
+ highp float t = x + 0.5;
+ highp float f = floor(t);
+ highp float r;
+ if (t == f) {
+ if (x > 0)
+ r = f - mod(f, 2);
+ else
+ r = f + mod(f, 2);
+ } else
+ r = f;
+ return r;
+}
+
+highp vec2 roundEven(highp vec2 x) {
+ return vec2(roundEven(x.x), roundEven(x.y));
+}
+
+highp vec3 roundEven(highp vec3 x) {
+ return vec3(roundEven(x.x), roundEven(x.y), roundEven(x.z));
+}
+
+highp vec4 roundEven(highp vec4 x) {
+ return vec4(roundEven(x.x), roundEven(x.y), roundEven(x.z), roundEven(x.w));
+}
+
+#endif
+
+#if defined(IS_INF_USED)
+
+bool isinf(highp float x) {
+ return (2 * x == x) && (x != 0);
+}
+
+bvec2 isinf(highp vec2 x) {
+ return bvec2((2 * x.x == x.x) && (x.x != 0), (2 * x.y == x.y) && (x.y != 0));
+}
+
+bvec3 isinf(highp vec3 x) {
+ return bvec3((2 * x.x == x.x) && (x.x != 0), (2 * x.y == x.y) && (x.y != 0), (2 * x.z == x.z) && (x.z != 0));
+}
+
+bvec4 isinf(highp vec4 x) {
+ return bvec4((2 * x.x == x.x) && (x.x != 0), (2 * x.y == x.y) && (x.y != 0), (2 * x.z == x.z) && (x.z != 0), (2 * x.w == x.w) && (x.w != 0));
+}
+
+#endif
+
+#if defined(IS_NAN_USED)
+
+bool isnan(highp float x) {
+ return x != x;
+}
+
+bvec2 isnan(highp vec2 x) {
+ return bvec2(x.x != x.x, x.y != x.y);
+}
+
+bvec3 isnan(highp vec3 x) {
+ return bvec3(x.x != x.x, x.y != x.y, x.z != x.z);
+}
+
+bvec4 isnan(highp vec4 x) {
+ return bvec4(x.x != x.x, x.y != x.y, x.z != x.z, x.w != x.w);
+}
+
+#endif
+
+#if defined(TRUNC_USED)
+
+highp float trunc(highp float x) {
+ return x < 0 ? -floor(-x) : floor(x);
+}
+
+highp vec2 trunc(highp vec2 x) {
+ return vec2(x.x < 0 ? -floor(-x.x) : floor(x.x), x.y < 0 ? -floor(-x.y) : floor(x.y));
+}
+
+highp vec3 trunc(highp vec3 x) {
+ return vec3(x.x < 0 ? -floor(-x.x) : floor(x.x), x.y < 0 ? -floor(-x.y) : floor(x.y), x.z < 0 ? -floor(-x.z) : floor(x.z));
+}
+
+highp vec4 trunc(highp vec4 x) {
+ return vec4(x.x < 0 ? -floor(-x.x) : floor(x.x), x.y < 0 ? -floor(-x.y) : floor(x.y), x.z < 0 ? -floor(-x.z) : floor(x.z), x.w < 0 ? -floor(-x.w) : floor(x.w));
+}
+
+#endif
+
+#if defined(DETERMINANT_USED)
+
+highp float determinant(highp mat2 m) {
+ return m[0].x * m[1].y - m[1].x * m[0].y;
+}
+
+highp float determinant(highp mat3 m) {
+ return m[0].x * (m[1].y * m[2].z - m[2].y * m[1].z) - m[1].x * (m[0].y * m[2].z - m[2].y * m[0].z) + m[2].x * (m[0].y * m[1].z - m[1].y * m[0].z);
+}
+
+highp float determinant(highp mat4 m) {
+ highp float s00 = m[2].z * m[3].w - m[3].z * m[2].w;
+ highp float s01 = m[2].y * m[3].w - m[3].y * m[2].w;
+ highp float s02 = m[2].y * m[3].z - m[3].y * m[2].z;
+ highp float s03 = m[2].x * m[3].w - m[3].x * m[2].w;
+ highp float s04 = m[2].x * m[3].z - m[3].x * m[2].z;
+ highp float s05 = m[2].x * m[3].y - m[3].x * m[2].y;
+ highp vec4 c = vec4((m[1].y * s00 - m[1].z * s01 + m[1].w * s02), -(m[1].x * s00 - m[1].z * s03 + m[1].w * s04), (m[1].x * s01 - m[1].y * s03 + m[1].w * s05), -(m[1].x * s02 - m[1].y * s04 + m[1].z * s05));
+ return m[0].x * c.x + m[0].y * c.y + m[0].z * c.z + m[0].w * c.w;
+}
+
#endif
#ifndef USE_GLES_OVER_GL
-highp mat4 transpose(highp mat4 src) {
+
+#if defined(TRANSPOSE_USED)
+
+highp mat2 transpose(highp mat2 m) {
+ return mat2(
+ vec2(m[0].x, m[1].x),
+ vec2(m[0].y, m[1].y));
+}
+
+highp mat3 transpose(highp mat3 m) {
+ return mat3(
+ vec3(m[0].x, m[1].x, m[2].x),
+ vec3(m[0].y, m[1].y, m[2].y),
+ vec3(m[0].z, m[1].z, m[2].z));
+}
+
+#endif
+
+highp mat4 transpose(highp mat4 m) {
return mat4(
- vec4(src[0].x, src[1].x, src[2].x, src[3].x),
- vec4(src[0].y, src[1].y, src[2].y, src[3].y),
- vec4(src[0].z, src[1].z, src[2].z, src[3].z),
- vec4(src[0].w, src[1].w, src[2].w, src[3].w));
+ vec4(m[0].x, m[1].x, m[2].x, m[3].x),
+ vec4(m[0].y, m[1].y, m[2].y, m[3].y),
+ vec4(m[0].z, m[1].z, m[2].z, m[3].z),
+ vec4(m[0].w, m[1].w, m[2].w, m[3].w));
}
+
+#if defined(OUTER_PRODUCT_USED)
+
+highp mat2 outerProduct(highp vec2 c, highp vec2 r) {
+ return mat2(c * r.x, c * r.y);
+}
+
+highp mat3 outerProduct(highp vec3 c, highp vec3 r) {
+ return mat3(c * r.x, c * r.y, c * r.z);
+}
+
+highp mat4 outerProduct(highp vec4 c, highp vec4 r) {
+ return mat4(c * r.x, c * r.y, c * r.z, c * r.w);
+}
+
+#endif
+
#endif
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index eb5ab53421..f4faed8736 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -1585,6 +1585,11 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.canvas_item_modulate);
state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform);
state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, Transform2D());
+ if (storage->frame.current_rt) {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0 / storage->frame.current_rt->width, 1.0 / storage->frame.current_rt->height));
+ } else {
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0, 1.0));
+ }
}
glBindBufferBase(GL_UNIFORM_BUFFER, 1, static_cast<LightInternal *>(light->light_internal.get_data())->ubo);
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 9b376ae090..014bb08144 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -31,6 +31,7 @@
#include "animation_track_editor.h"
#include "animation_track_editor_plugins.h"
+#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "editor/animation_bezier_editor.h"
#include "editor/plugins/animation_player_editor_plugin.h"
@@ -4082,6 +4083,10 @@ bool AnimationTrackEditor::is_selection_active() const {
return selection.size();
}
+bool AnimationTrackEditor::is_snap_enabled() const {
+ return snap->is_pressed() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+}
+
void AnimationTrackEditor::_update_tracks() {
int selected = _get_track_selected();
@@ -5679,7 +5684,7 @@ void AnimationTrackEditor::_selection_changed() {
float AnimationTrackEditor::snap_time(float p_value) {
- if (snap->is_pressed()) {
+ if (is_snap_enabled()) {
double snap_increment;
if (timeline->is_using_fps() && step->get_value() > 0)
@@ -5857,7 +5862,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
step = memnew(EditorSpinSlider);
step->set_min(0);
step->set_max(1000000);
- step->set_step(0.01);
+ step->set_step(0.001);
step->set_hide_slider(true);
step->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
step->set_tooltip(TTR("Animation step value."));
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 9e16f2faf7..96fd10effd 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -520,8 +520,8 @@ public:
bool is_key_selected(int p_track, int p_key) const;
bool is_selection_active() const;
bool is_moving_selection() const;
+ bool is_snap_enabled() const;
float get_moving_selection_offset() const;
- bool is_snap_enabled();
float snap_time(float p_value);
bool is_grouping_tracks();
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index e45ff3fee2..89a88dc6e7 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -152,6 +152,7 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
text_edit->cursor_set_line(line, false);
text_edit->cursor_set_column(col + text.length(), false);
text_edit->center_viewport_to_cursor();
+ text_edit->select(line, col, line, col + text.length());
}
text_edit->set_search_text(text);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ff1dd85af1..4326174a1a 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -334,6 +334,11 @@ void EditorNode::_notification(int p_what) {
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec")));
} break;
+ case MainLoop::NOTIFICATION_WM_ABOUT: {
+
+ show_about();
+ } break;
+
case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: {
_menu_option_confirm(FILE_QUIT, false);
@@ -2640,7 +2645,9 @@ void EditorNode::_discard_changes(const String &p_str) {
Node *scene = editor_data.get_edited_scene_root(tab_closing);
if (scene != NULL) {
String scene_filename = scene->get_filename();
- previous_scenes.push_back(scene_filename);
+ if (scene_filename != "") {
+ previous_scenes.push_back(scene_filename);
+ }
}
_remove_scene(tab_closing);
@@ -5955,7 +5962,7 @@ EditorNode::EditorNode() {
recent_scenes->connect("id_pressed", this, "_open_recent_scene");
p->add_separator();
- p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q);
+ p->add_shortcut(ED_SHORTCUT("editor/file_quit", TTR("Quit"), KEY_MASK_CMD + KEY_Q), FILE_QUIT, true);
project_menu = memnew(MenuButton);
project_menu->set_flat(false);
@@ -5989,9 +5996,9 @@ EditorNode::EditorNode() {
p->add_separator();
#ifdef OSX_ENABLED
- p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
+ p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q), RUN_PROJECT_MANAGER, true);
#else
- p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q);
+ p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q), RUN_PROJECT_MANAGER, true);
#endif
menu_hb->add_spacer();
diff --git a/editor/icons/icon_key_animation.svg b/editor/icons/icon_key_animation.svg
index a09567498f..6db513ca26 100644
--- a/editor/icons/icon_key_animation.svg
+++ b/editor/icons/icon_key_animation.svg
@@ -1,65 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_animation.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1852"
- inkscape:window-height="781"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="29.5"
- inkscape:cx="-10.271186"
- inkscape:cy="3.4149032"
- inkscape:window-x="68"
- inkscape:window-y="117"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#ea686c"
- id="rect2"
- style="fill:#b76ef0;fill-opacity:1" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#b76ef0" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_audio.svg b/editor/icons/icon_key_audio.svg
index 7c728bfd01..75576885ec 100644
--- a/editor/icons/icon_key_audio.svg
+++ b/editor/icons/icon_key_audio.svg
@@ -1,65 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_audio.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1053"
- inkscape:window-height="591"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="29.5"
- inkscape:cx="4"
- inkscape:cy="4"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#ea686c"
- id="rect2"
- style="fill:#eae668;fill-opacity:1" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#eae668" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_bezier.svg b/editor/icons/icon_key_bezier.svg
index 62af6fdb34..dc5800fd5a 100644
--- a/editor/icons/icon_key_bezier.svg
+++ b/editor/icons/icon_key_bezier.svg
@@ -1,65 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_bezier.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1852"
- inkscape:window-height="781"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="29.5"
- inkscape:cx="-17.152542"
- inkscape:cy="3.4149032"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#ea686c"
- id="rect2"
- style="fill:#5792f6;fill-opacity:1" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5792f6" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_call.svg b/editor/icons/icon_key_call.svg
index e702898288..6cc442c391 100644
--- a/editor/icons/icon_key_call.svg
+++ b/editor/icons/icon_key_call.svg
@@ -1,64 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_call.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="836"
- inkscape:window-height="480"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="29.5"
- inkscape:cx="4"
- inkscape:cy="4"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#adf18f"
- id="rect2"
- style="fill:#66f376;fill-opacity:1" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#66f376" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_selected.svg b/editor/icons/icon_key_selected.svg
index 2842fd93eb..6594aec6ee 100644
--- a/editor/icons/icon_key_selected.svg
+++ b/editor/icons/icon_key_selected.svg
@@ -1,76 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_selected.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1568"
- inkscape:window-height="767"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="41.7193"
- inkscape:cx="-0.48848775"
- inkscape:cy="3.5639274"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4-3" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#84c2ff"
- id="rect2" />
- </g>
- <g
- transform="translate(0,-1044.4)"
- id="g4-3">
- <rect
- style="fill:#003e7a;fill-opacity:1;stroke-width:0.56281364"
- transform="matrix(0.71728847,-0.69677633,0.71728847,0.69677633,0,0)"
- x="-751.20953"
- y="753.42743"
- width="3.4346831"
- height="3.4346831"
- ry="0.42934799"
- id="rect2-6" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#84c2ff" height="6.1027" ry=".76286" transform="matrix(.87871827 -.87871827 .87871827 .87871827 .03288 -1297.7965)" width="6.1027" x="-741.53003" y="741.08002"/><rect fill="#003e7a" height="3.434683" ry=".429348" stroke-width=".562814" transform="matrix(.89137101 -.86588067 .89137101 .86588067 -.038545 -1297.8361)" width="3.434683" x="-751.20953" y="753.42743"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_value.svg b/editor/icons/icon_key_value.svg
index 61032a1e16..8a4787d6ed 100644
--- a/editor/icons/icon_key_value.svg
+++ b/editor/icons/icon_key_value.svg
@@ -1,5 +1 @@
-<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1044.4)">
-<rect transform="rotate(-45)" x="-741.53" y="741.08" width="6.1027" height="6.1027" ry=".76286" fill="#e0e0e0"/>
-</g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#e0e0e0" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 1.002946 -1043.3636)" width="6.1027" x="-741.53003" y="741.08002"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_key_xform.svg b/editor/icons/icon_key_xform.svg
index fd22b67f52..4a567075a7 100644
--- a/editor/icons/icon_key_xform.svg
+++ b/editor/icons/icon_key_xform.svg
@@ -1,64 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
- height="8"
- version="1.1"
- viewBox="0 0 8 8"
- id="svg6"
- sodipodi:docname="icon_key_xform.svg"
- inkscape:version="0.92.3 (2405546, 2018-03-11)">
- <metadata
- id="metadata12">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <defs
- id="defs10" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="836"
- inkscape:window-height="480"
- id="namedview8"
- showgrid="false"
- inkscape:zoom="29.5"
- inkscape:cx="4"
- inkscape:cy="4"
- inkscape:window-x="67"
- inkscape:window-y="27"
- inkscape:window-maximized="0"
- inkscape:current-layer="g4" />
- <g
- transform="translate(0 -1044.4)"
- id="g4">
- <rect
- transform="rotate(-45)"
- x="-741.53"
- y="741.08"
- width="6.1027"
- height="6.1027"
- ry=".76286"
- fill="#ea686c"
- id="rect2"
- style="fill:#ea9568;fill-opacity:1" />
- </g>
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ea9568" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> \ No newline at end of file
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 5163b372b2..f42716c827 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -32,6 +32,7 @@
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
+#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "core/project_settings.h"
#include "editor/animation_track_editor.h"
@@ -293,10 +294,6 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
}
}
frame->set_max(anim->get_length());
- if (anim->get_step())
- frame->set_step(anim->get_step());
- else
- frame->set_step(0.00001);
} else {
track_editor->set_animation(Ref<Animation>());
@@ -1008,7 +1005,7 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) {
};
updating = true;
- String current = player->get_assigned_animation(); //animation->get_item_text( animation->get_selected() );
+ String current = player->get_assigned_animation();
if (current == "" || !player->has_animation(current)) {
updating = false;
current = "";
@@ -1018,14 +1015,9 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) {
Ref<Animation> anim;
anim = player->get_animation(current);
- float pos = anim->get_length() * (p_value / frame->get_max());
- float step = anim->get_step();
- if (step) {
- pos = Math::stepify(pos, step);
- if (pos < 0)
- pos = 0;
- if (pos >= anim->get_length())
- pos = anim->get_length();
+ float pos = CLAMP(anim->get_length() * (p_value / frame->get_max()), 0, anim->get_length());
+ if (track_editor->is_snap_enabled()) {
+ pos = Math::stepify(pos, anim->get_step());
}
if (player->is_valid() && !p_set) {
@@ -1063,14 +1055,6 @@ void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len)
frame->set_max(p_len);
}
-void AnimationPlayerEditor::_animation_key_editor_anim_step_changed(float p_len) {
-
- if (p_len)
- frame->set_step(p_len);
- else
- frame->set_step(0.00001);
-}
-
void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) {
if (!is_visible_in_tree())
@@ -1081,8 +1065,10 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag)
if (player->is_playing())
return;
+ Ref<Animation> anim = player->get_animation(player->get_assigned_animation());
+
updating = true;
- frame->set_value(p_pos);
+ frame->set_value(Math::stepify(p_pos, track_editor->is_snap_enabled() ? anim->get_step() : 0));
updating = false;
_seek_value_changed(p_pos, !p_drag);
@@ -1558,7 +1544,6 @@ void AnimationPlayerEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_list_changed"), &AnimationPlayerEditor::_list_changed);
ClassDB::bind_method(D_METHOD("_animation_key_editor_seek"), &AnimationPlayerEditor::_animation_key_editor_seek);
ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_len_changed"), &AnimationPlayerEditor::_animation_key_editor_anim_len_changed);
- ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_step_changed"), &AnimationPlayerEditor::_animation_key_editor_anim_step_changed);
ClassDB::bind_method(D_METHOD("_hide_anim_editors"), &AnimationPlayerEditor::_hide_anim_editors);
ClassDB::bind_method(D_METHOD("_animation_duplicate"), &AnimationPlayerEditor::_animation_duplicate);
ClassDB::bind_method(D_METHOD("_blend_editor_next_changed"), &AnimationPlayerEditor::_blend_editor_next_changed);
@@ -1621,6 +1606,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
hb->add_child(frame);
frame->set_custom_minimum_size(Size2(60, 0));
frame->set_stretch_ratio(2);
+ frame->set_step(0.0001);
frame->set_tooltip(TTR("Animation position (in seconds)."));
hb->add_child(memnew(VSeparator));
@@ -1774,7 +1760,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
track_editor->set_v_size_flags(SIZE_EXPAND_FILL);
track_editor->connect("timeline_changed", this, "_animation_key_editor_seek");
track_editor->connect("animation_len_changed", this, "_animation_key_editor_anim_len_changed");
- track_editor->connect("animation_step_changed", this, "_animation_key_editor_anim_step_changed");
_update_player();
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 398ef6ff14..22152fa8f4 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -203,7 +203,6 @@ class AnimationPlayerEditor : public VBoxContainer {
void _animation_key_editor_seek(float p_pos, bool p_drag);
void _animation_key_editor_anim_len_changed(float p_len);
- void _animation_key_editor_anim_step_changed(float p_len);
void _unhandled_key_input(const Ref<InputEvent> &p_ev);
void _animation_tool_menu(int p_option);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 9cf889c5b0..9418349d71 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -485,7 +485,7 @@ void ScriptEditor::_update_recent_scripts() {
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scripts", Array());
recent_scripts->clear();
- recent_scripts->add_shortcut(ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T));
+ recent_scripts->add_shortcut(ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent")));
recent_scripts->add_separator();
String path;
@@ -579,6 +579,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
Ref<Script> script = current->get_edited_resource();
if (script != NULL) {
+ previous_scripts.push_back(script->get_path());
notify_script_close(script);
}
}
@@ -907,7 +908,7 @@ void ScriptEditor::_file_dialog_action(String p_file) {
if (extensions.find(p_file.get_extension())) {
Ref<Script> scr = ResourceLoader::load(p_file);
if (!scr.is_valid()) {
- editor->show_warning(TTR("Error: could not load file."), TTR("Error!"));
+ editor->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!"));
file_dialog_option = -1;
return;
}
@@ -920,7 +921,7 @@ void ScriptEditor::_file_dialog_action(String p_file) {
Error error;
Ref<TextFile> text_file = _load_text_file(p_file, &error);
if (error != OK) {
- editor->show_warning(TTR("Error could not load file."), TTR("Error!"));
+ editor->show_warning(TTR("Could not load file at:") + "\n\n" + p_file, TTR("Error!"));
}
if (text_file.is_valid()) {
@@ -1012,6 +1013,52 @@ void ScriptEditor::_menu_option(int p_option) {
file_dialog->set_title(TTR("Open File"));
return;
} break;
+ case FILE_REOPEN_CLOSED: {
+
+ if (previous_scripts.empty())
+ return;
+
+ String path = previous_scripts.back()->get();
+ previous_scripts.pop_back();
+
+ List<String> extensions;
+ ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
+ bool built_in = !path.is_resource_file();
+
+ if (extensions.find(path.get_extension()) || built_in) {
+ if (built_in) {
+ String scene_path = path.get_slice("::", 0);
+ if (!EditorNode::get_singleton()->is_scene_open(scene_path)) {
+ EditorNode::get_singleton()->load_scene(scene_path);
+ script_editor->call_deferred("_menu_option", p_option);
+ previous_scripts.push_back(path); //repeat the operation
+ return;
+ }
+ }
+
+ Ref<Script> scr = ResourceLoader::load(path);
+ if (!scr.is_valid()) {
+ editor->show_warning(TTR("Could not load file at:") + "\n\n" + path, TTR("Error!"));
+ file_dialog_option = -1;
+ return;
+ }
+
+ edit(scr);
+ file_dialog_option = -1;
+ return;
+ } else {
+ Error error;
+ Ref<TextFile> text_file = _load_text_file(path, &error);
+ if (error != OK)
+ editor->show_warning(TTR("Could not load file at:") + "\n\n" + path, TTR("Error!"));
+
+ if (text_file.is_valid()) {
+ edit(text_file);
+ file_dialog_option = -1;
+ return;
+ }
+ }
+ } break;
case FILE_SAVE_ALL: {
if (_test_script_times_on_disk())
@@ -1894,6 +1941,8 @@ void ScriptEditor::_update_script_names() {
_update_members_overview_visibility();
_update_help_overview_visibility();
_update_script_colors();
+
+ file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(FILE_REOPEN_CLOSED), previous_scripts.empty());
}
void ScriptEditor::_update_script_connections() {
@@ -3172,6 +3221,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New Script...")), FILE_NEW);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New TextFile...")), FILE_NEW_TEXTFILE);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open...")), FILE_OPEN);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T), FILE_REOPEN_CLOSED);
file_menu->get_popup()->add_submenu_item(TTR("Open Recent"), "RecentScripts", FILE_OPEN_RECENT);
recent_scripts = memnew(PopupMenu);
@@ -3500,7 +3550,8 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
EDITOR_DEF("text_editor/external/exec_flags", "{file}");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "text_editor/external/exec_flags", PROPERTY_HINT_PLACEHOLDER_TEXT, "Call flags with placeholders: {project}, {file}, {col}, {line}."));
- ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T);
+ ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T);
+ ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent"));
ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Files"));
}
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 4ad2156779..0c876108a5 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -139,6 +139,7 @@ class ScriptEditor : public PanelContainer {
FILE_NEW,
FILE_NEW_TEXTFILE,
FILE_OPEN,
+ FILE_REOPEN_CLOSED,
FILE_OPEN_RECENT,
FILE_SAVE,
FILE_SAVE_AS,
@@ -265,7 +266,7 @@ class ScriptEditor : public PanelContainer {
Vector<ScriptHistory> history;
int history_pos;
- Vector<String> previous_scripts;
+ List<String> previous_scripts;
void _tab_changed(int p_which);
void _menu_option(int p_option);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 994c542187..37460c58ff 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -342,6 +342,9 @@ void ShaderEditor::_menu_option(int p_option) {
shader_editor->remove_all_bookmarks();
} break;
+ case HELP_DOCS: {
+ OS::get_singleton()->shell_open("https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/index.html");
+ } break;
}
if (p_option != SEARCH_FIND && p_option != SEARCH_REPLACE && p_option != SEARCH_GOTO_LINE) {
shader_editor->get_text_edit()->call_deferred("grab_focus");
@@ -657,11 +660,18 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
bookmarks_menu->connect("about_to_show", this, "_update_bookmark_list");
bookmarks_menu->get_popup()->connect("index_pressed", this, "_bookmark_item_pressed");
+ help_menu = memnew(MenuButton);
+ help_menu->set_text(TTR("Help"));
+ help_menu->set_switch_on_hover(true);
+ help_menu->get_popup()->add_icon_item(p_node->get_gui_base()->get_icon("Instance", "EditorIcons"), TTR("Online Docs"), HELP_DOCS);
+ help_menu->get_popup()->connect("id_pressed", this, "_menu_option");
+
add_child(main_container);
main_container->add_child(hbc);
hbc->add_child(search_menu);
hbc->add_child(edit_menu);
hbc->add_child(bookmarks_menu);
+ hbc->add_child(help_menu);
hbc->add_style_override("panel", p_node->get_gui_base()->get_stylebox("ScriptEditorPanel", "EditorStyles"));
main_container->add_child(shader_editor);
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index 8e55a1ad70..5d03c37dc4 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -94,13 +94,13 @@ class ShaderEditor : public PanelContainer {
BOOKMARK_GOTO_NEXT,
BOOKMARK_GOTO_PREV,
BOOKMARK_REMOVE_ALL,
-
+ HELP_DOCS,
};
MenuButton *edit_menu;
MenuButton *search_menu;
MenuButton *bookmarks_menu;
- MenuButton *settings_menu;
+ MenuButton *help_menu;
PopupMenu *context_menu;
uint64_t idle;
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 630f3ba9e1..d2b1cfc5af 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -250,15 +250,7 @@ Vector3 SpatialEditorViewport::_get_ray(const Vector2 &p_pos) const {
return camera->project_ray_normal(p_pos / viewport_container->get_stretch_shrink());
}
-/*
-void SpatialEditorViewport::_clear_id(Spatial *p_node) {
-
- editor_selection->remove_node(p_node);
-
-
-}
-*/
void SpatialEditorViewport::_clear_selected() {
editor_selection->clear();
@@ -2930,8 +2922,14 @@ void SpatialEditorViewport::update_transform_gizmo_view() {
if (dd == 0)
dd = 0.0001;
- float gsize = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size");
- gizmo_scale = (gsize / Math::abs(dd)) * MAX(1, EDSCALE) / viewport_container->get_stretch_shrink();
+ float gizmo_size = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size");
+ // At low viewport heights, multiply the gizmo scale based on the viewport height.
+ // This prevents the gizmo from growing very large and going outside the viewport.
+ const int viewport_base_height = 400 * MAX(1, EDSCALE);
+ gizmo_scale =
+ (gizmo_size / Math::abs(dd)) * MAX(1, EDSCALE) *
+ MIN(viewport_base_height, viewport_container->get_size().height) / viewport_base_height /
+ viewport_container->get_stretch_shrink();
Vector3 scale = Vector3(1, 1, 1) * gizmo_scale;
xform.basis.scale(scale);
@@ -4001,11 +3999,11 @@ void SpatialEditor::select_gizmo_highlight_axis(int p_axis) {
for (int i = 0; i < 3; i++) {
- move_gizmo[i]->surface_set_material(0, i == p_axis ? gizmo_hl : gizmo_color[i]);
- move_plane_gizmo[i]->surface_set_material(0, (i + 6) == p_axis ? gizmo_hl : plane_gizmo_color[i]);
- rotate_gizmo[i]->surface_set_material(0, (i + 3) == p_axis ? gizmo_hl : gizmo_color[i]);
- scale_gizmo[i]->surface_set_material(0, (i + 9) == p_axis ? gizmo_hl : gizmo_color[i]);
- scale_plane_gizmo[i]->surface_set_material(0, (i + 12) == p_axis ? gizmo_hl : plane_gizmo_color[i]);
+ move_gizmo[i]->surface_set_material(0, i == p_axis ? gizmo_color_hl[i] : gizmo_color[i]);
+ move_plane_gizmo[i]->surface_set_material(0, (i + 6) == p_axis ? plane_gizmo_color_hl[i] : plane_gizmo_color[i]);
+ rotate_gizmo[i]->surface_set_material(0, (i + 3) == p_axis ? gizmo_color_hl[i] : gizmo_color[i]);
+ scale_gizmo[i]->surface_set_material(0, (i + 9) == p_axis ? gizmo_color_hl[i] : gizmo_color[i]);
+ scale_plane_gizmo[i]->surface_set_material(0, (i + 12) == p_axis ? plane_gizmo_color_hl[i] : plane_gizmo_color[i]);
}
}
@@ -4084,6 +4082,23 @@ Object *SpatialEditor::_get_editor_data(Object *p_what) {
return si;
}
+Color SpatialEditor::_get_axis_color(int axis) {
+
+ switch (axis) {
+ case 0:
+ // X axis
+ return Color(0.96, 0.20, 0.32);
+ case 1:
+ // Y axis
+ return Color(0.53, 0.84, 0.01);
+ case 2:
+ // Z axis
+ return Color(0.16, 0.55, 0.96);
+ default:
+ return Color(0, 0, 0);
+ }
+}
+
void SpatialEditor::_generate_selection_box() {
AABB aabb(Vector3(), Vector3(1, 1, 1));
@@ -4097,11 +4112,6 @@ void SpatialEditor::_generate_selection_box() {
Vector3 a, b;
aabb.get_edge(i, a, b);
- /*Vector<Vector3> points;
- Vector<Color> colors;
- points.push_back(a);
- points.push_back(b);*/
-
st->add_color(Color(1.0, 1.0, 0.8, 0.8));
st->add_vertex(a);
st->add_color(Color(1.0, 1.0, 0.8, 0.4));
@@ -4640,12 +4650,13 @@ void SpatialEditor::_init_indicators() {
for (int i = 0; i < 3; i++) {
Vector3 axis;
axis[i] = 1;
+ Color origin_color = _get_axis_color(i);
grid_enable[i] = false;
grid_visible[i] = false;
- origin_colors.push_back(Color(axis.x, axis.y, axis.z));
- origin_colors.push_back(Color(axis.x, axis.y, axis.z));
+ origin_colors.push_back(origin_color);
+ origin_colors.push_back(origin_color);
origin_points.push_back(axis * 4096);
origin_points.push_back(axis * -4096);
}
@@ -4674,17 +4685,11 @@ void SpatialEditor::_init_indicators() {
//move gizmo
- float gizmo_alph = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_opacity");
-
- gizmo_hl = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- gizmo_hl->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- gizmo_hl->set_on_top_of_alpha();
- gizmo_hl->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- gizmo_hl->set_albedo(Color(1, 1, 1, gizmo_alph + 0.2f));
- gizmo_hl->set_cull_mode(SpatialMaterial::CULL_DISABLED);
-
for (int i = 0; i < 3; i++) {
+ Color col = _get_axis_color(i);
+ col.a = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_opacity");
+
move_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
move_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
@@ -4695,13 +4700,13 @@ void SpatialEditor::_init_indicators() {
mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
mat->set_on_top_of_alpha();
mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- Color col;
- col[i] = 1.0;
- col.a = gizmo_alph;
mat->set_albedo(col);
-
gizmo_color[i] = mat;
+ Ref<SpatialMaterial> mat_hl = mat->duplicate();
+ mat_hl->set_albedo(Color(col.r, col.g, col.b, 1.0));
+ gizmo_color_hl[i] = mat_hl;
+
Vector3 ivec;
ivec[i] = 1;
Vector3 nivec;
@@ -4791,13 +4796,14 @@ void SpatialEditor::_init_indicators() {
plane_mat->set_on_top_of_alpha();
plane_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
plane_mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- Color col2;
- col2[i] = 1.0;
- col2.a = gizmo_alph;
- plane_mat->set_albedo(col2);
+ plane_mat->set_albedo(col);
plane_gizmo_color[i] = plane_mat; // needed, so we can draw planes from both sides
surftool->set_material(plane_mat);
surftool->commit(move_plane_gizmo[i]);
+
+ Ref<SpatialMaterial> plane_mat_hl = plane_mat->duplicate();
+ plane_mat_hl->set_albedo(Color(col.r, col.g, col.b, 1.0));
+ plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides
}
// Rotate
@@ -4920,13 +4926,14 @@ void SpatialEditor::_init_indicators() {
plane_mat->set_on_top_of_alpha();
plane_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
plane_mat->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- Color col2;
- col2[i] = 1.0;
- col2.a = gizmo_alph;
- plane_mat->set_albedo(col2);
+ plane_mat->set_albedo(col);
plane_gizmo_color[i] = plane_mat; // needed, so we can draw planes from both sides
surftool->set_material(plane_mat);
surftool->commit(scale_plane_gizmo[i]);
+
+ Ref<SpatialMaterial> plane_mat_hl = plane_mat->duplicate();
+ plane_mat_hl->set_albedo(Color(col.r, col.g, col.b, 1.0));
+ plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides
}
}
}
@@ -5824,7 +5831,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
EDITOR_DEF("editors/3d/manipulator_gizmo_size", 80);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "editors/3d/manipulator_gizmo_size", PROPERTY_HINT_RANGE, "16,1024,1"));
- EDITOR_DEF("editors/3d/manipulator_gizmo_opacity", 0.2);
+ EDITOR_DEF("editors/3d/manipulator_gizmo_opacity", 0.4);
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::REAL, "editors/3d/manipulator_gizmo_opacity", PROPERTY_HINT_RANGE, "0,1,0.01"));
over_gizmo_handle = -1;
}
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index dde402c0ff..523573333b 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -528,7 +528,8 @@ private:
Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[3], scale_gizmo[3], scale_plane_gizmo[3];
Ref<SpatialMaterial> gizmo_color[3];
Ref<SpatialMaterial> plane_gizmo_color[3];
- Ref<SpatialMaterial> gizmo_hl;
+ Ref<SpatialMaterial> gizmo_color_hl[3];
+ Ref<SpatialMaterial> plane_gizmo_color_hl[3];
int over_gizmo_handle;
@@ -635,6 +636,7 @@ private:
Node *custom_camera;
Object *_get_editor_data(Object *p_what);
+ Color _get_axis_color(int axis);
Ref<Environment> viewport_environment;
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 766890242f..b2f06ca41f 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -521,7 +521,13 @@ void TileMapEditor::_update_palette() {
for (const Map<Vector2, uint32_t>::Element *E = tiles2.front(); E; E = E->next()) {
entries2.push_back(E->key());
}
- entries2.sort();
+ // Sort tiles in row-major order
+ struct SwapComparator {
+ _FORCE_INLINE_ bool operator()(const Vector2 &v_l, const Vector2 &v_r) const {
+ return v_l.y != v_r.y ? v_l.y < v_r.y : v_l.x < v_r.x;
+ }
+ };
+ entries2.sort_custom<SwapComparator>();
Ref<Texture> tex = tileset->tile_get_texture(sel_tile);
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index f135becf5f..1a27e749e2 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -924,8 +924,7 @@ void TileSetEditor::_on_workspace_draw() {
case EDITMODE_OCCLUSION:
case EDITMODE_NAVIGATION: {
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
- Vector2 coord = edited_shape_coord;
- draw_highlight_subtile(coord);
+ draw_highlight_subtile(edited_shape_coord);
}
draw_polygon_shapes();
draw_grid_snap();
@@ -1519,6 +1518,8 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
undo_redo->create_action(TTR("Edit Navigation Polygon"));
undo_redo->add_do_method(edited_navigation_shape.ptr(), "set_vertices", polygon);
undo_redo->add_undo_method(edited_navigation_shape.ptr(), "set_vertices", edited_navigation_shape->get_vertices());
+ undo_redo->add_do_method(edited_navigation_shape.ptr(), "clear_polygons");
+ undo_redo->add_undo_method(edited_navigation_shape.ptr(), "clear_polygons");
undo_redo->add_do_method(edited_navigation_shape.ptr(), "add_polygon", indices);
undo_redo->add_undo_method(edited_navigation_shape.ptr(), "add_polygon", edited_navigation_shape->get_polygon(0));
undo_redo->add_do_method(this, "_select_edited_shape_coord");
@@ -1872,7 +1873,7 @@ void TileSetEditor::_update_tile_data() {
} else {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
for (int y = 0; y < cell_count.y; y++) {
for (int x = 0; x < cell_count.x; x++) {
SubtileData data;
@@ -1974,7 +1975,7 @@ void TileSetEditor::_select_previous_tile() {
case EDITMODE_Z_INDEX: {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
cell_count -= Vector2(1, 1);
edited_shape_coord = cell_count;
_select_edited_shape_coord();
@@ -2031,7 +2032,7 @@ void TileSetEditor::_select_next_subtile() {
} else {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
if (edited_shape_coord.x >= cell_count.x - 1 && edited_shape_coord.y >= cell_count.y - 1) {
_select_next_tile();
} else {
@@ -2057,7 +2058,7 @@ void TileSetEditor::_select_previous_subtile() {
} else {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->tile_get_region(get_current_tile()).size;
- Vector2i cell_count = size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing));
+ Vector2 cell_count = (size / (tileset->autotile_get_size(get_current_tile()) + Vector2(spacing, spacing))).floor();
if (edited_shape_coord.x <= 0 && edited_shape_coord.y <= 0) {
_select_previous_tile();
} else {
@@ -2077,9 +2078,9 @@ void TileSetEditor::_select_next_shape() {
} else if (edit_mode != EDITMODE_COLLISION) {
_select_next_subtile();
} else {
- Vector2i edited_coord = Vector2();
+ Vector2i edited_coord = Vector2i();
if (tileset->tile_get_tile_mode(get_current_tile()) != TileSet::SINGLE_TILE) {
- edited_coord = edited_shape_coord;
+ edited_coord = Vector2i(edited_shape_coord);
}
SubtileData data = current_tile_data[edited_coord];
if (data.collisions.size() == 0) {
@@ -2130,9 +2131,9 @@ void TileSetEditor::_select_previous_shape() {
} else if (edit_mode != EDITMODE_COLLISION) {
_select_previous_subtile();
} else {
- Vector2i edited_coord = Vector2();
+ Vector2i edited_coord = Vector2i();
if (tileset->tile_get_tile_mode(get_current_tile()) != TileSet::SINGLE_TILE) {
- edited_coord = edited_shape_coord;
+ edited_coord = Vector2i(edited_shape_coord);
}
SubtileData data = current_tile_data[edited_coord];
if (data.collisions.size() == 0) {
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index f15354b643..c956409966 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -42,17 +42,17 @@
#include "scene/main/viewport.h"
#include "scene/resources/visual_shader_nodes.h"
-Control *VisualShaderNodePlugin::create_editor(const Ref<VisualShaderNode> &p_node) {
+Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
if (get_script_instance()) {
- return get_script_instance()->call("create_editor", p_node);
+ return get_script_instance()->call("create_editor", p_parent_resource, p_node);
}
return NULL;
}
void VisualShaderNodePlugin::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::OBJECT, "create_editor", PropertyInfo(Variant::OBJECT, "for_node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode")));
+ BIND_VMETHOD(MethodInfo(Variant::OBJECT, "create_editor", PropertyInfo(Variant::OBJECT, "parent_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::OBJECT, "for_node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode")));
}
///////////////////
@@ -438,7 +438,7 @@ void VisualShaderEditor::_update_graph() {
int port_offset = 0;
if (is_group) {
- port_offset++;
+ port_offset += 2;
}
Ref<VisualShaderNodeUniform> uniform = vsnode;
@@ -462,7 +462,7 @@ void VisualShaderEditor::_update_graph() {
}
for (int i = 0; i < plugins.size(); i++) {
- custom_editor = plugins.write[i]->create_editor(vsnode);
+ custom_editor = plugins.write[i]->create_editor(visual_shader, vsnode);
if (custom_editor) {
break;
}
@@ -477,6 +477,11 @@ void VisualShaderEditor::_update_graph() {
}
if (is_group) {
+
+ offset = memnew(Control);
+ offset->set_custom_minimum_size(Size2(0, 6 * EDSCALE));
+ node->add_child(offset);
+
HBoxContainer *hb2 = memnew(HBoxContainer);
Button *add_input_btn = memnew(Button);
@@ -524,6 +529,7 @@ void VisualShaderEditor::_update_graph() {
}
HBoxContainer *hb = memnew(HBoxContainer);
+ hb->add_constant_override("separation", 7 * EDSCALE);
Variant default_value;
@@ -559,7 +565,6 @@ void VisualShaderEditor::_update_graph() {
}
if (i == 0 && custom_editor) {
-
hb->add_child(custom_editor);
custom_editor->set_h_size_flags(SIZE_EXPAND_FILL);
} else {
@@ -567,7 +572,6 @@ void VisualShaderEditor::_update_graph() {
if (valid_left) {
if (is_group) {
-
OptionButton *type_box = memnew(OptionButton);
hb->add_child(type_box);
type_box->add_item(TTR("Scalar"));
@@ -580,9 +584,9 @@ void VisualShaderEditor::_update_graph() {
LineEdit *name_box = memnew(LineEdit);
hb->add_child(name_box);
- name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0));
+ name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
+ name_box->set_h_size_flags(SIZE_EXPAND_FILL);
name_box->set_text(name_left);
- name_box->set_expand_to_text_length(true);
name_box->connect("text_entered", this, "_change_input_port_name", varray(name_box, nodes[n_i], i));
name_box->connect("focus_exited", this, "_port_name_focus_out", varray(name_box, nodes[n_i], i, false));
@@ -600,7 +604,9 @@ void VisualShaderEditor::_update_graph() {
}
}
- hb->add_spacer();
+ if (!is_group) {
+ hb->add_spacer();
+ }
if (valid_right) {
if (is_group) {
@@ -612,9 +618,9 @@ void VisualShaderEditor::_update_graph() {
LineEdit *name_box = memnew(LineEdit);
hb->add_child(name_box);
- name_box->set_custom_minimum_size(Size2(60 * EDSCALE, 0));
+ name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0));
+ name_box->set_h_size_flags(SIZE_EXPAND_FILL);
name_box->set_text(name_right);
- name_box->set_expand_to_text_length(true);
name_box->connect("text_entered", this, "_change_output_port_name", varray(name_box, nodes[n_i], i));
name_box->connect("focus_exited", this, "_port_name_focus_out", varray(name_box, nodes[n_i], i, true));
@@ -675,7 +681,7 @@ void VisualShaderEditor::_update_graph() {
}
offset = memnew(Control);
- offset->set_custom_minimum_size(Size2(0, 5 * EDSCALE));
+ offset->set_custom_minimum_size(Size2(0, 4 * EDSCALE));
node->add_child(offset);
String error = vsnode->get_warning(visual_shader->get_mode(), type);
@@ -692,12 +698,14 @@ void VisualShaderEditor::_update_graph() {
expression_node->set_control(expression_box, 0);
node->add_child(expression_box);
+ Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
Color text_color = EDITOR_GET("text_editor/highlighting/text_color");
Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
expression_box->set_syntax_coloring(true);
+ expression_box->add_color_override("background_color", background_color);
for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) {
@@ -1010,7 +1018,7 @@ void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, in
}
undo_redo->create_action(TTR("Resize VisualShader node"), UndoRedo::MERGE_ENDS);
- undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, p_new_size / EDSCALE);
+ undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, p_new_size);
undo_redo->add_undo_method(this, "_set_node_size", p_type, p_node, node->get_size());
undo_redo->commit_action();
}
@@ -1379,6 +1387,9 @@ void VisualShaderEditor::_delete_request(int which) {
undo_redo->add_do_method(visual_shader.ptr(), "remove_node", type, which);
undo_redo->add_undo_method(visual_shader.ptr(), "add_node", type, node, visual_shader->get_node_position(type, which), which);
+ undo_redo->add_do_method(this, "_clear_buffer");
+ undo_redo->add_undo_method(this, "_clear_buffer");
+
// restore size, inputs and outputs if node is group
VisualShaderNodeGroupBase *group = Object::cast_to<VisualShaderNodeGroupBase>(node.ptr());
if (group) {
@@ -1533,12 +1544,32 @@ void VisualShaderEditor::_node_changed(int p_id) {
}
}
-void VisualShaderEditor::_duplicate_nodes() {
+void VisualShaderEditor::_dup_update_excluded(int p_type, Set<int> &r_excluded) {
+ r_excluded.clear();
+ VisualShader::Type type = (VisualShader::Type)p_type;
- VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
+ for (int i = 0; i < graph->get_child_count(); i++) {
- List<int> nodes;
- Set<int> excluded;
+ GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
+ if (gn) {
+ int id = String(gn->get_name()).to_int();
+ Ref<VisualShaderNode> node = visual_shader->get_node(type, id);
+ Ref<VisualShaderNodeOutput> output = node;
+ if (output.is_valid()) {
+ r_excluded.insert(id);
+ continue;
+ }
+ r_excluded.insert(id);
+ }
+ }
+}
+
+void VisualShaderEditor::_dup_copy_nodes(int p_type, List<int> &r_nodes, Set<int> &r_excluded) {
+
+ VisualShader::Type type = (VisualShader::Type)p_type;
+
+ selection_center.x = 0.0f;
+ selection_center.y = 0.0f;
for (int i = 0; i < graph->get_child_count(); i++) {
@@ -1548,33 +1579,37 @@ void VisualShaderEditor::_duplicate_nodes() {
Ref<VisualShaderNode> node = visual_shader->get_node(type, id);
Ref<VisualShaderNodeOutput> output = node;
if (output.is_valid()) { // can't duplicate output
- excluded.insert(id);
+ r_excluded.insert(id);
continue;
}
if (node.is_valid() && gn->is_selected()) {
- nodes.push_back(id);
+ Vector2 pos = visual_shader->get_node_position(type, id);
+ selection_center += pos;
+ r_nodes.push_back(id);
}
- excluded.insert(id);
+ r_excluded.insert(id);
}
}
- if (nodes.empty())
- return;
+ selection_center /= (float)r_nodes.size();
+}
- undo_redo->create_action(TTR("Duplicate Nodes"));
+void VisualShaderEditor::_dup_paste_nodes(int p_type, List<int> &r_nodes, Set<int> &r_excluded, const Vector2 &p_offset, bool p_select) {
+
+ VisualShader::Type type = (VisualShader::Type)p_type;
int base_id = visual_shader->get_valid_node_id(type);
int id_from = base_id;
Map<int, int> connection_remap;
- for (List<int>::Element *E = nodes.front(); E; E = E->next()) {
+ for (List<int>::Element *E = r_nodes.front(); E; E = E->next()) {
connection_remap[E->get()] = id_from;
Ref<VisualShaderNode> node = visual_shader->get_node(type, E->get());
Ref<VisualShaderNode> dupli = node->duplicate();
- undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, dupli, visual_shader->get_node_position(type, E->get()) + Vector2(10, 10) * EDSCALE, id_from);
+ undo_redo->add_do_method(visual_shader.ptr(), "add_node", type, dupli, visual_shader->get_node_position(type, E->get()) + p_offset, id_from);
undo_redo->add_undo_method(visual_shader.ptr(), "remove_node", type, id_from);
// duplicate size, inputs and outputs if node is group
@@ -1606,21 +1641,71 @@ void VisualShaderEditor::_duplicate_nodes() {
undo_redo->add_undo_method(this, "_update_graph");
undo_redo->commit_action();
- // reselect duplicated nodes by excluding the other ones
- for (int i = 0; i < graph->get_child_count(); i++) {
-
- GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
- if (gn) {
- int id = String(gn->get_name()).to_int();
- if (!excluded.has(id)) {
- gn->set_selected(true);
- } else {
- gn->set_selected(false);
+ if (p_select) {
+ // reselect duplicated nodes by excluding the other ones
+ for (int i = 0; i < graph->get_child_count(); i++) {
+
+ GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
+ if (gn) {
+ int id = String(gn->get_name()).to_int();
+ if (!r_excluded.has(id)) {
+ gn->set_selected(true);
+ } else {
+ gn->set_selected(false);
+ }
}
}
}
}
+void VisualShaderEditor::_clear_buffer() {
+
+ copy_nodes_buffer.clear();
+ copy_nodes_excluded_buffer.clear();
+}
+
+void VisualShaderEditor::_duplicate_nodes() {
+
+ int type = edit_type->get_selected();
+
+ List<int> nodes;
+ Set<int> excluded;
+
+ _dup_copy_nodes(type, nodes, excluded);
+
+ if (nodes.empty())
+ return;
+
+ undo_redo->create_action(TTR("Duplicate Nodes"));
+
+ _dup_paste_nodes(type, nodes, excluded, Vector2(10, 10) * EDSCALE, true);
+}
+
+void VisualShaderEditor::_copy_nodes() {
+
+ copy_type = edit_type->get_selected();
+
+ _clear_buffer();
+
+ _dup_copy_nodes(copy_type, copy_nodes_buffer, copy_nodes_excluded_buffer);
+}
+
+void VisualShaderEditor::_paste_nodes() {
+
+ if (copy_nodes_buffer.empty())
+ return;
+
+ int type = edit_type->get_selected();
+
+ undo_redo->create_action(TTR("Paste Nodes"));
+
+ float scale = graph->get_zoom();
+
+ _dup_paste_nodes(type, copy_nodes_buffer, copy_nodes_excluded_buffer, (graph->get_scroll_ofs() / scale + graph->get_local_mouse_position() / scale - selection_center), false);
+
+ _dup_update_excluded(type, copy_nodes_excluded_buffer); // to prevent selection of previous copies at new paste
+}
+
void VisualShaderEditor::_on_nodes_delete() {
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
@@ -1647,6 +1732,9 @@ void VisualShaderEditor::_on_nodes_delete() {
undo_redo->add_do_method(visual_shader.ptr(), "remove_node", type, F->get());
undo_redo->add_undo_method(visual_shader.ptr(), "add_node", type, node, visual_shader->get_node_position(type, F->get()), F->get());
+ undo_redo->add_do_method(this, "_clear_buffer");
+ undo_redo->add_undo_method(this, "_clear_buffer");
+
// restore size, inputs and outputs if node is group
VisualShaderNodeGroupBase *group = Object::cast_to<VisualShaderNodeGroupBase>(node.ptr());
if (group) {
@@ -1691,6 +1779,10 @@ void VisualShaderEditor::_on_nodes_delete() {
}
void VisualShaderEditor::_mode_selected(int p_id) {
+
+ copy_nodes_buffer.clear();
+ copy_nodes_excluded_buffer.clear();
+
_update_options_menu();
_update_graph();
}
@@ -1884,6 +1976,8 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_line_edit_changed", &VisualShaderEditor::_line_edit_changed);
ClassDB::bind_method("_port_name_focus_out", &VisualShaderEditor::_port_name_focus_out);
ClassDB::bind_method("_duplicate_nodes", &VisualShaderEditor::_duplicate_nodes);
+ ClassDB::bind_method("_copy_nodes", &VisualShaderEditor::_copy_nodes);
+ ClassDB::bind_method("_paste_nodes", &VisualShaderEditor::_paste_nodes);
ClassDB::bind_method("_mode_selected", &VisualShaderEditor::_mode_selected);
ClassDB::bind_method("_input_select_item", &VisualShaderEditor::_input_select_item);
ClassDB::bind_method("_preview_select_port", &VisualShaderEditor::_preview_select_port);
@@ -1898,6 +1992,7 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_remove_output_port", &VisualShaderEditor::_remove_output_port);
ClassDB::bind_method("_node_resized", &VisualShaderEditor::_node_resized);
ClassDB::bind_method("_set_node_size", &VisualShaderEditor::_set_node_size);
+ ClassDB::bind_method("_clear_buffer", &VisualShaderEditor::_clear_buffer);
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw);
@@ -1943,6 +2038,8 @@ VisualShaderEditor::VisualShaderEditor() {
graph->connect("node_selected", this, "_node_selected");
graph->connect("scroll_offset_changed", this, "_scroll_changed");
graph->connect("duplicate_nodes_request", this, "_duplicate_nodes");
+ graph->connect("copy_nodes_request", this, "_copy_nodes");
+ graph->connect("paste_nodes_request", this, "_paste_nodes");
graph->connect("delete_nodes_request", this, "_on_nodes_delete");
graph->connect("gui_input", this, "_graph_gui_input");
graph->connect("connection_to_empty", this, "_connection_to_empty");
@@ -2078,15 +2175,15 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("GreaterThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than (>)")), VisualShaderNodeCompare::FUNC_GREATER_THAN, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("GreaterThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than or Equal (>=)")), VisualShaderNodeCompare::FUNC_GREATER_THAN_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("If", "Conditional", "Functions", "VisualShaderNodeIf", TTR("Returns an associated vector if the provided scalars are equal, greater or less."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("IsInf", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF and a scalar parameter."), VisualShaderNodeIs::FUNC_IS_INF, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, -1, -1, true));
- add_options.push_back(AddOption("IsNaN", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between NaN and a scalar parameter."), VisualShaderNodeIs::FUNC_IS_NAN, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, -1, -1, true));
+ add_options.push_back(AddOption("IsInf", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF and a scalar parameter."), VisualShaderNodeIs::FUNC_IS_INF, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("IsNaN", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between NaN and a scalar parameter."), VisualShaderNodeIs::FUNC_IS_NAN, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("LessThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), VisualShaderNodeCompare::FUNC_LESS_THAN, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("LessThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("NotEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), VisualShaderNodeCompare::FUNC_NOT_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Compare", "Conditional", "Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the comparison between two parameters."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("Is", "Conditional", "Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, -1, -1, true));
+ add_options.push_back(AddOption("Is", "Conditional", "Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("BooleanConstant", "Conditional", "Variables", "VisualShaderNodeBooleanConstant", TTR("Boolean constant."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
add_options.push_back(AddOption("BooleanUniform", "Conditional", "Variables", "VisualShaderNodeBooleanUniform", TTR("Boolean uniform."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
@@ -2221,16 +2318,16 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Abs", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the absolute value of the parameter."), VisualShaderNodeScalarFunc::FUNC_ABS, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("ACos", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the arc-cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ACOS, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("ACosH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true));
+ add_options.push_back(AddOption("ACosH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("ASin", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the arc-sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ASIN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("ASinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true));
+ add_options.push_back(AddOption("ASinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("ATan", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeScalarOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true));
+ add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeScalarFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeScalarClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Cos", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true));
+ add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Degrees", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeScalarFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Exp", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Base-e Exponential."), VisualShaderNodeScalarFunc::FUNC_EXP, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Exp2", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Base-2 Exponential."), VisualShaderNodeScalarFunc::FUNC_EXP2, VisualShaderNode::PORT_TYPE_SCALAR));
@@ -2248,17 +2345,17 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Radians", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Converts a quantity in degrees to radians."), VisualShaderNodeScalarFunc::FUNC_RADIANS, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Reciprocal", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("1.0 / scalar"), VisualShaderNodeScalarFunc::FUNC_RECIPROCAL, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Round", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest integer to the parameter."), VisualShaderNodeScalarFunc::FUNC_ROUND, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("RoundEven", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest even integer to the parameter."), VisualShaderNodeScalarFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true));
+ add_options.push_back(AddOption("RoundEven", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest even integer to the parameter."), VisualShaderNodeScalarFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Saturate", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Clamps the value between 0.0 and 1.0."), VisualShaderNodeScalarFunc::FUNC_SATURATE, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Sign", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Extracts the sign of the parameter."), VisualShaderNodeScalarFunc::FUNC_SIGN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true));
+ add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeScalarFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), VisualShaderNodeScalarOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true));
- add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeScalarFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true));
+ add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeScalarFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeScalarOp", TTR("Adds scalar to scalar."), VisualShaderNodeScalarOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeScalarOp", TTR("Divides scalar by scalar."), VisualShaderNodeScalarOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR));
@@ -2282,13 +2379,13 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("TransformFunc", "Transform", "Common", "VisualShaderNodeTransformFunc", TTR("Transform function."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("OuterProduct", "Transform", "Composition", "VisualShaderNodeOuterProduct", TTR("Calculate the outer product of a pair of vectors.\n\nOuterProduct treats the first parameter 'c' as a column vector (matrix with one column) and the second parameter 'r' as a row vector (matrix with one row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix whose number of rows is the number of components in 'c' and whose number of columns is the number of components in 'r'."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, -1, -1, true));
+ add_options.push_back(AddOption("OuterProduct", "Transform", "Composition", "VisualShaderNodeOuterProduct", TTR("Calculate the outer product of a pair of vectors.\n\nOuterProduct treats the first parameter 'c' as a column vector (matrix with one column) and the second parameter 'r' as a row vector (matrix with one row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix whose number of rows is the number of components in 'c' and whose number of columns is the number of components in 'r'."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("TransformCompose", "Transform", "Composition", "VisualShaderNodeTransformCompose", TTR("Composes transform from four vectors."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("TransformDecompose", "Transform", "Composition", "VisualShaderNodeTransformDecompose", TTR("Decomposes transform to four vectors.")));
- add_options.push_back(AddOption("Determinant", "Transform", "Functions", "VisualShaderNodeDeterminant", TTR("Calculates the determinant of a transform."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true));
+ add_options.push_back(AddOption("Determinant", "Transform", "Functions", "VisualShaderNodeDeterminant", TTR("Calculates the determinant of a transform."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Inverse", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the inverse of a transform."), VisualShaderNodeTransformFunc::FUNC_INVERSE, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, -1, -1, true));
- add_options.push_back(AddOption("Transpose", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the transpose of a transform."), VisualShaderNodeTransformFunc::FUNC_TRANSPOSE, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, -1, -1, true));
+ add_options.push_back(AddOption("Transpose", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the transpose of a transform."), VisualShaderNodeTransformFunc::FUNC_TRANSPOSE, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("TransformMult", "Transform", "Operators", "VisualShaderNodeTransformMult", TTR("Multiplies transform by transform."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("TransformVectorMult", "Transform", "Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
@@ -2306,16 +2403,16 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true));
+ add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true));
+ add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true));
+ add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeVectorClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true));
+ add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Distance", "Vector", "Functions", "VisualShaderNodeVectorDistance", TTR("Returns the distance between two points."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
@@ -2341,19 +2438,19 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true));
+ add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true));
+ add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true));
- add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true));
+ add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds vector to vector."), VisualShaderNodeVectorOp::OP_ADD, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides vector by vector."), VisualShaderNodeVectorOp::OP_DIV, VisualShaderNode::PORT_TYPE_VECTOR));
@@ -2493,6 +2590,7 @@ public:
class VisualShaderNodePluginDefaultEditor : public VBoxContainer {
GDCLASS(VisualShaderNodePluginDefaultEditor, VBoxContainer);
+ Ref<Resource> parent_resource;
public:
void _property_changed(const String &prop, const Variant &p_value, const String &p_field, bool p_changing = false) {
@@ -2506,7 +2604,27 @@ public:
undo_redo->create_action(TTR("Edit Visual Property") + ": " + prop, UndoRedo::MERGE_ENDS);
undo_redo->add_do_property(node.ptr(), prop, p_value);
undo_redo->add_undo_property(node.ptr(), prop, node->get(prop));
+
+ if (p_value.get_type() == Variant::OBJECT) {
+
+ RES prev_res = node->get(prop);
+ RES curr_res = p_value;
+
+ if (curr_res.is_null()) {
+ undo_redo->add_do_method(this, "_open_inspector", (RES)parent_resource.ptr());
+ } else {
+ undo_redo->add_do_method(this, "_open_inspector", (RES)curr_res.ptr());
+ }
+ if (!prev_res.is_null()) {
+ undo_redo->add_undo_method(this, "_open_inspector", (RES)prev_res.ptr());
+ } else {
+ undo_redo->add_undo_method(this, "_open_inspector", (RES)parent_resource.ptr());
+ }
+ undo_redo->add_do_method(this, "_refresh_request");
+ undo_redo->add_undo_method(this, "_refresh_request");
+ }
undo_redo->commit_action();
+
updating = false;
}
@@ -2522,11 +2640,20 @@ public:
VisualShaderEditor::get_singleton()->call_deferred("_update_graph");
}
+ void _resource_selected(const String &p_path, RES p_resource) {
+ _open_inspector(p_resource);
+ }
+
+ void _open_inspector(RES p_resource) {
+ EditorNode::get_singleton()->get_inspector()->edit(p_resource.ptr());
+ }
+
bool updating;
Ref<VisualShaderNode> node;
Vector<EditorProperty *> properties;
- void setup(Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, Ref<VisualShaderNode> p_node) {
+ void setup(Ref<Resource> p_parent_resource, Vector<EditorProperty *> p_properties, const Vector<StringName> &p_names, Ref<VisualShaderNode> p_node) {
+ parent_resource = p_parent_resource;
updating = false;
node = p_node;
properties = p_properties;
@@ -2535,6 +2662,11 @@ public:
add_child(p_properties[i]);
+ bool res_prop = Object::cast_to<EditorPropertyResource>(p_properties[i]);
+ if (res_prop) {
+ p_properties[i]->connect("resource_selected", this, "_resource_selected");
+ }
+
properties[i]->connect("property_changed", this, "_property_changed");
properties[i]->set_object_and_property(node.ptr(), p_names[i]);
properties[i]->update_property();
@@ -2548,10 +2680,12 @@ public:
ClassDB::bind_method("_property_changed", &VisualShaderNodePluginDefaultEditor::_property_changed, DEFVAL(String()), DEFVAL(false));
ClassDB::bind_method("_node_changed", &VisualShaderNodePluginDefaultEditor::_node_changed);
ClassDB::bind_method("_refresh_request", &VisualShaderNodePluginDefaultEditor::_refresh_request);
+ ClassDB::bind_method("_resource_selected", &VisualShaderNodePluginDefaultEditor::_resource_selected);
+ ClassDB::bind_method("_open_inspector", &VisualShaderNodePluginDefaultEditor::_open_inspector);
}
};
-Control *VisualShaderNodePluginDefault::create_editor(const Ref<VisualShaderNode> &p_node) {
+Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
if (p_node->is_class("VisualShaderNodeInput")) {
//create input
@@ -2609,7 +2743,7 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<VisualShaderNode
properties.push_back(pinfo[i].name);
}
VisualShaderNodePluginDefaultEditor *editor = memnew(VisualShaderNodePluginDefaultEditor);
- editor->setup(editors, properties, p_node);
+ editor->setup(p_parent_resource, editors, properties, p_node);
return editor;
}
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index 100bc53d00..315ef1788e 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -48,7 +48,7 @@ protected:
static void _bind_methods();
public:
- virtual Control *create_editor(const Ref<VisualShaderNode> &p_node);
+ virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
};
class VisualShaderEditor : public VBoxContainer {
@@ -176,8 +176,21 @@ class VisualShaderEditor : public VBoxContainer {
void _port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output);
+ void _dup_copy_nodes(int p_type, List<int> &r_nodes, Set<int> &r_excluded);
+ void _dup_update_excluded(int p_type, Set<int> &r_excluded);
+ void _dup_paste_nodes(int p_type, List<int> &r_nodes, Set<int> &r_excluded, const Vector2 &p_offset, bool p_select);
+
void _duplicate_nodes();
+ Vector2 selection_center;
+ int copy_type; // shader type
+ List<int> copy_nodes_buffer;
+ Set<int> copy_nodes_excluded_buffer;
+
+ void _clear_buffer();
+ void _copy_nodes();
+ void _paste_nodes();
+
Vector<Ref<VisualShaderNodePlugin> > plugins;
void _mode_selected(int p_id);
@@ -259,7 +272,7 @@ class VisualShaderNodePluginDefault : public VisualShaderNodePlugin {
GDCLASS(VisualShaderNodePluginDefault, VisualShaderNodePlugin);
public:
- virtual Control *create_editor(const Ref<VisualShaderNode> &p_node);
+ virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
};
class EditorPropertyShaderMode : public EditorProperty {
diff --git a/main/main.cpp b/main/main.cpp
index 7e69864e1e..39cd2548fb 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -783,8 +783,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_chars_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_chars_per_second", PROPERTY_HINT_RANGE, "0, 4096, 1, or_greater"));
GLOBAL_DEF("network/limits/debugger_stdout/max_messages_per_frame", 10);
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_messages_per_frame", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_messages_per_frame", PROPERTY_HINT_RANGE, "0, 20, 1, or_greater"));
- GLOBAL_DEF("network/limits/debugger_stdout/max_errors_per_frame", 10);
- ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_errors_per_frame", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_errors_per_frame", PROPERTY_HINT_RANGE, "0, 20, 1, or_greater"));
+ GLOBAL_DEF("network/limits/debugger_stdout/max_errors_per_second", 100);
+ ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_errors_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_errors_per_second", PROPERTY_HINT_RANGE, "0, 200, 1, or_greater"));
+ GLOBAL_DEF("network/limits/debugger_stdout/max_warnings_per_second", 100);
+ ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_warnings_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_warnings_per_second", PROPERTY_HINT_RANGE, "0, 200, 1, or_greater"));
if (debug_mode == "remote") {
diff --git a/modules/assimp/SCsub b/modules/assimp/SCsub
index d8ef866bec..275f1ff5e9 100644
--- a/modules/assimp/SCsub
+++ b/modules/assimp/SCsub
@@ -9,6 +9,7 @@ env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/include'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code/Importer/IFC'])
env_assimp.Prepend(CPPPATH=['#thirdparty/misc'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code'])
+env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/common'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/irrXML/'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/unzip/'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code/Importer/STEPParser'])
@@ -65,11 +66,11 @@ env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_STEP_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_IFC_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_XGL_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_ASSBIN_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_C4D_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_3MF_IMPORTER'])
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'])
if(env['platform'] == 'windows'):
@@ -84,7 +85,13 @@ elif(env['platform'] == 'osx'):
env_thirdparty = env_assimp.Clone()
env_thirdparty.disable_warnings()
-env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/Common/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/PostProcessing/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/Material/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/FBX/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/MMD/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/glTF/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/glTF2/*.cpp'))
# Godot's own source files
env_assimp.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/assimp/godot_update_assimp.sh b/modules/assimp/godot_update_assimp.sh
index dcf1e6d4a2..ff8ff59e97 100644..100755
--- a/modules/assimp/godot_update_assimp.sh
+++ b/modules/assimp/godot_update_assimp.sh
@@ -254,8 +254,9 @@ rm -rf contrib/irrXML
rm -rf contrib/Open3DGC
rm -rf contrib/openddlparser
rm -rf contrib/poly2tri
-rm -rf contrib/rapidjson
+#rm -rf contrib/rapidjson
rm -rf contrib/unzip
rm -rf contrib/zip
rm -rf contrib/stb_image
rm .travis*
+
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index f006d50a83..357e9c9615 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -3487,6 +3487,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
} break;
case GDScriptTokenizer::TK_PR_CLASS_NAME: {
+ _mark_line_as_safe(tokenizer->get_token_line());
if (p_class->owner) {
_set_error("'class_name' is only valid for the main class namespace.");
return;
diff --git a/modules/mono/glue/Managed/Files/Color.cs b/modules/mono/glue/Managed/Files/Color.cs
index 84ff19fc54..da57a7f9ae 100644
--- a/modules/mono/glue/Managed/Files/Color.cs
+++ b/modules/mono/glue/Managed/Files/Color.cs
@@ -375,7 +375,7 @@ namespace Godot
return c;
}
- public string ToHtml(bool include_alpha = true)
+ public string ToHtml(bool includeAlpha = true)
{
var txt = string.Empty;
@@ -383,7 +383,7 @@ namespace Godot
txt += ToHex32(g);
txt += ToHex32(b);
- if (include_alpha)
+ if (includeAlpha)
txt = ToHex32(a) + txt;
return txt;
@@ -465,13 +465,13 @@ namespace Godot
for (int i = 0; i < 2; i++)
{
- char[] c = { (char)0, (char)0 };
+ char c;
int lv = v & 0xF;
if (lv < 10)
- c[0] = (char)('0' + lv);
+ c = (char)('0' + lv);
else
- c[0] = (char)('a' + lv - 10);
+ c = (char)('a' + lv - 10);
v >>= 4;
ret = c + ret;
@@ -490,12 +490,17 @@ namespace Godot
bool alpha;
- if (color.Length == 8)
- alpha = true;
- else if (color.Length == 6)
- alpha = false;
- else
- return false;
+ switch (color.Length)
+ {
+ case 8:
+ alpha = true;
+ break;
+ case 6:
+ alpha = false;
+ break;
+ default:
+ return false;
+ }
if (alpha)
{
diff --git a/modules/mono/glue/Managed/Files/Mathf.cs b/modules/mono/glue/Managed/Files/Mathf.cs
index 6c1a51fcf9..15adf0a13b 100644
--- a/modules/mono/glue/Managed/Files/Mathf.cs
+++ b/modules/mono/glue/Managed/Files/Mathf.cs
@@ -336,14 +336,14 @@ namespace Godot
public static int Wrap(int value, int min, int max)
{
- int rng = max - min;
- return rng != 0 ? min + ((value - min) % rng + rng) % rng : min;
+ int range = max - min;
+ return range == 0 ? min : min + ((value - min) % range + range) % range;
}
public static real_t Wrap(real_t value, real_t min, real_t max)
{
- real_t rng = max - min;
- return !IsEqualApprox(rng, default(real_t)) ? min + ((value - min) % rng + rng) % rng : min;
+ real_t range = max - min;
+ return IsZeroApprox(range) ? min : min + ((value - min) % range + range) % range;
}
}
}
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 603c5a7f3c..eef3f0f8ae 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -776,8 +776,8 @@ void VisualScriptEditor::_update_members() {
TreeItem *functions = members->create_item(root);
functions->set_selectable(0, false);
functions->set_text(0, TTR("Functions:"));
- functions->add_button(0, Control::get_icon("Override", "EditorIcons"), 1);
- functions->add_button(0, Control::get_icon("Add", "EditorIcons"), 0);
+ functions->add_button(0, Control::get_icon("Override", "EditorIcons"), 1, false, TTR("Override an existing built-in function."));
+ functions->add_button(0, Control::get_icon("Add", "EditorIcons"), 0, false, TTR("Create a new function."));
functions->set_custom_color(0, Control::get_color("mono_color", "Editor"));
List<StringName> func_names;
@@ -795,7 +795,7 @@ void VisualScriptEditor::_update_members() {
TreeItem *variables = members->create_item(root);
variables->set_selectable(0, false);
variables->set_text(0, TTR("Variables:"));
- variables->add_button(0, Control::get_icon("Add", "EditorIcons"));
+ variables->add_button(0, Control::get_icon("Add", "EditorIcons"), -1, false, TTR("Create a new variable."));
variables->set_custom_color(0, Control::get_color("mono_color", "Editor"));
Ref<Texture> type_icons[Variant::VARIANT_MAX] = {
@@ -848,7 +848,7 @@ void VisualScriptEditor::_update_members() {
TreeItem *_signals = members->create_item(root);
_signals->set_selectable(0, false);
_signals->set_text(0, TTR("Signals:"));
- _signals->add_button(0, Control::get_icon("Add", "EditorIcons"));
+ _signals->add_button(0, Control::get_icon("Add", "EditorIcons"), -1, false, TTR("Create a new signal."));
_signals->set_custom_color(0, Control::get_color("mono_color", "Editor"));
List<StringName> signal_names;
diff --git a/platform/android/SCsub b/platform/android/SCsub
index d772dc9d71..e355caf0f9 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -53,7 +53,6 @@ if lib_arch_dir != '':
out_dir = '#platform/android/java/libs/' + lib_type_dir + '/' + lib_arch_dir
env_android.Command(out_dir + '/libgodot_android.so', '#bin/libgodot' + env['SHLIBSUFFIX'], Move("$TARGET", "$SOURCE"))
- ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"])
- if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"):
- stl_lib_path = str(env['ANDROID_NDK_ROOT']) + '/sources/cxx-stl/llvm-libc++/libs/' + lib_arch_dir + '/libc++_shared.so'
- env_android.Command(out_dir + '/libc++_shared.so', stl_lib_path, Copy("$TARGET", "$SOURCE"))
+
+ stl_lib_path = str(env['ANDROID_NDK_ROOT']) + '/sources/cxx-stl/llvm-libc++/libs/' + lib_arch_dir + '/libc++_shared.so'
+ env_android.Command(out_dir + '/libc++_shared.so', stl_lib_path, Copy("$TARGET", "$SOURCE"))
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 3f179e3a65..283791f336 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -28,7 +28,6 @@ def get_opts():
('ndk_platform', 'Target platform (android-<api>, e.g. "android-18")', "android-18"),
EnumVariable('android_arch', 'Target architecture', "armv7", ('armv7', 'arm64v8', 'x86', 'x86_64')),
BoolVariable('android_neon', 'Enable NEON support (armv7 only)', True),
- BoolVariable('android_stl', 'Enable Android STL support (for modules)', True)
]
@@ -205,31 +204,29 @@ def configure(env):
common_opts = ['-fno-integrated-as', '-gcc-toolchain', gcc_toolchain_path]
- lib_sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + env['ndk_platform'] + "/" + env['ARCH']
-
## Compile flags
+
+ env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/include"])
+ env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++abi/include"])
+ env.Append(CXXFLAGS=["-std=gnu++14"])
+
# Disable exceptions and rtti on non-tools (template) builds
- if env['tools'] or env['android_stl']:
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/include"])
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++abi/include"])
- env.Append(CXXFLAGS=['-frtti', "-std=gnu++14"])
+ if env['tools']:
+ env.Append(CXXFLAGS=['-frtti'])
else:
env.Append(CXXFLAGS=['-fno-rtti', '-fno-exceptions'])
# Don't use dynamic_cast, necessary with no-rtti.
env.Append(CPPDEFINES=['NO_SAFE_CAST'])
- ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"])
- if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"):
- print("Using NDK unified headers")
- sysroot = env["ANDROID_NDK_ROOT"] + "/sysroot"
- env.Append(CPPFLAGS=["--sysroot=" + sysroot])
- env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath])
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/android/support/include"])
- # For unified headers this define has to be set manually
- env.Append(CPPDEFINES=[('__ANDROID_API__', str(get_platform(env['ndk_platform'])))])
- else:
- print("Using NDK deprecated headers")
- env.Append(CPPFLAGS=["-isystem", lib_sysroot + "/usr/include"])
+ lib_sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + env['ndk_platform'] + "/" + env['ARCH']
+
+ # Using NDK unified headers (NDK r15+)
+ sysroot = env["ANDROID_NDK_ROOT"] + "/sysroot"
+ env.Append(CPPFLAGS=["--sysroot=" + sysroot])
+ env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath])
+ env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/android/support/include"])
+ # For unified headers this define has to be set manually
+ env.Append(CPPDEFINES=[('__ANDROID_API__', str(get_platform(env['ndk_platform'])))])
env.Append(CCFLAGS='-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing'.split())
env.Append(CPPDEFINES=['NO_STATVFS', 'GLES_ENABLED'])
@@ -263,18 +260,15 @@ def configure(env):
env.Append(CCFLAGS=common_opts)
## Link flags
- if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"):
- if LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"):
- env.Append(LINKFLAGS=['-Wl,--exclude-libs,libgcc.a', '-Wl,--exclude-libs,libatomic.a', '-nostdlib++'])
- else:
- env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libandroid_support.a"])
- env.Append(LINKFLAGS=['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'])
- env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/"])
- env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] +"/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libc++_shared.so"])
+
+ ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"])
+ if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"):
+ env.Append(LINKFLAGS=['-Wl,--exclude-libs,libgcc.a', '-Wl,--exclude-libs,libatomic.a', '-nostdlib++'])
else:
- env.Append(LINKFLAGS=['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'])
- if mt_link:
- env.Append(LINKFLAGS=['-Wl,--threads'])
+ env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libandroid_support.a"])
+ env.Append(LINKFLAGS=['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'])
+ env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/"])
+ env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] +"/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libc++_shared.so"])
if env["android_arch"] == "armv7":
env.Append(LINKFLAGS='-Wl,--fix-cortex-a8'.split())
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 992aff54f1..a48f784529 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -2411,7 +2411,7 @@ Size2 OS_OSX::get_min_window_size() const {
void OS_OSX::set_min_window_size(const Size2 p_size) {
if ((p_size != Size2()) && (max_size != Size2()) && ((p_size.x > max_size.x) || (p_size.y > max_size.y))) {
- WARN_PRINT("Minimum window size can't be larger than maximum window size!");
+ ERR_PRINT("Minimum window size can't be larger than maximum window size!");
return;
}
min_size = p_size;
@@ -2427,7 +2427,7 @@ void OS_OSX::set_min_window_size(const Size2 p_size) {
void OS_OSX::set_max_window_size(const Size2 p_size) {
if ((p_size != Size2()) && ((p_size.x < min_size.x) || (p_size.y < min_size.y))) {
- WARN_PRINT("Maximum window size can't be smaller than minimum window size!");
+ ERR_PRINT("Maximum window size can't be smaller than minimum window size!");
return;
}
max_size = p_size;
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 93d4482279..db4575a0cb 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -719,7 +719,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
pressrc = 0;
}
}
- } else if (mouse_mode != MOUSE_MODE_CAPTURED) {
+ } else {
// for reasons unknown to mankind, wheel comes in screen coordinates
POINT coords;
coords.x = mb->get_position().x;
@@ -1813,7 +1813,7 @@ Size2 OS_Windows::get_min_window_size() const {
void OS_Windows::set_min_window_size(const Size2 p_size) {
if ((p_size != Size2()) && (max_size != Size2()) && ((p_size.x > max_size.x) || (p_size.y > max_size.y))) {
- WARN_PRINT("Minimum window size can't be larger than maximum window size!");
+ ERR_PRINT("Minimum window size can't be larger than maximum window size!");
return;
}
min_size = p_size;
@@ -1822,7 +1822,7 @@ void OS_Windows::set_min_window_size(const Size2 p_size) {
void OS_Windows::set_max_window_size(const Size2 p_size) {
if ((p_size != Size2()) && ((p_size.x < min_size.x) || (p_size.y < min_size.y))) {
- WARN_PRINT("Maximum window size can't be smaller than minimum window size!");
+ ERR_PRINT("Maximum window size can't be smaller than minimum window size!");
return;
}
max_size = p_size;
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 36bf51e7f9..0d1e702d04 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -1266,7 +1266,7 @@ Size2 OS_X11::get_min_window_size() const {
void OS_X11::set_min_window_size(const Size2 p_size) {
if ((p_size != Size2()) && (max_size != Size2()) && ((p_size.x > max_size.x) || (p_size.y > max_size.y))) {
- WARN_PRINT("Minimum window size can't be larger than maximum window size!");
+ ERR_PRINT("Minimum window size can't be larger than maximum window size!");
return;
}
min_size = p_size;
@@ -1295,7 +1295,7 @@ void OS_X11::set_min_window_size(const Size2 p_size) {
void OS_X11::set_max_window_size(const Size2 p_size) {
if ((p_size != Size2()) && ((p_size.x < min_size.x) || (p_size.y < min_size.y))) {
- WARN_PRINT("Maximum window size can't be smaller than minimum window size!");
+ ERR_PRINT("Maximum window size can't be smaller than minimum window size!");
return;
}
max_size = p_size;
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index b701e84a9c..e9731f1cd4 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -672,8 +672,8 @@ void Area2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_vec"), "set_gravity_vector", "get_gravity_vector");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.001"), "set_gravity", "get_gravity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_linear_damp", "get_linear_damp");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable");
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 4b309a93b5..f9f273d494 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -962,9 +962,13 @@ void CPUParticles2D::_set_redraw(bool p_redraw) {
if (redraw) {
VS::get_singleton()->connect("frame_pre_draw", this, "_update_render_thread");
VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true);
+
+ VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1);
} else {
VS::get_singleton()->disconnect("frame_pre_draw", this, "_update_render_thread");
VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false);
+
+ VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
}
#ifndef NO_THREADS
update_mutex->unlock();
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 39b3375f09..936ba777b5 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1074,10 +1074,10 @@ void RigidBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep");
ADD_GROUP("Linear", "linear_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
ADD_GROUP("Angular", "angular_");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_GROUP("Applied Forces", "applied_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "applied_torque"), "set_applied_torque", "get_applied_torque");
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index 4247266e3d..19f43dd274 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -718,8 +718,8 @@ void Area::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity_distance_scale", PROPERTY_HINT_EXP_RANGE, "0,1024,0.001,or_greater"), "set_gravity_distance_scale", "get_gravity_distance_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity_vec"), "set_gravity_vector", "get_gravity_vector");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gravity", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_gravity", "get_gravity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,1024,0.001"), "set_linear_damp", "get_linear_damp");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,1024,0.001"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_PROPERTY(PropertyInfo(Variant::INT, "priority", PROPERTY_HINT_RANGE, "0,128,1"), "set_priority", "get_priority");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable");
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 2f8b2ecc5c..fa2bb300fa 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1044,10 +1044,10 @@ void RigidBody::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer::BODY_AXIS_ANGULAR_Z);
ADD_GROUP("Linear", "linear_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
ADD_GROUP("Angular", "angular_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 4da11b671e..59bbdad97a 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -219,6 +219,14 @@ void WindowDialog::_notification(int p_what) {
close_button->set_begin(Point2(-get_constant("close_h_ofs", "WindowDialog"), -get_constant("close_v_ofs", "WindowDialog")));
} break;
+ case NOTIFICATION_TRANSLATION_CHANGED: {
+ String new_title = tr(title);
+ if (title != new_title) {
+ title = new_title;
+ update();
+ }
+ } break;
+
case NOTIFICATION_MOUSE_EXIT: {
// Reset the mouse cursor when leaving the resizable window border.
if (resizable && !drag_type) {
@@ -226,11 +234,13 @@ void WindowDialog::_notification(int p_what) {
set_default_cursor_shape(CURSOR_ARROW);
}
} break;
+
#ifdef TOOLS_ENABLED
case NOTIFICATION_POST_POPUP: {
if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton())
EditorNode::get_singleton()->dim_editor(true);
} break;
+
case NOTIFICATION_POPUP_HIDE: {
if (get_tree() && Engine::get_singleton()->is_editor_hint() && EditorNode::get_singleton())
EditorNode::get_singleton()->dim_editor(false);
@@ -272,8 +282,11 @@ int WindowDialog::_drag_hit_test(const Point2 &pos) const {
void WindowDialog::set_title(const String &p_title) {
- title = tr(p_title);
- update();
+ String new_title = tr(p_title);
+ if (title != new_title) {
+ title = new_title;
+ update();
+ }
}
String WindowDialog::get_title() const {
@@ -296,8 +309,8 @@ Size2 WindowDialog::get_minimum_size() const {
const int padding = button_width / 2;
const int button_area = button_width + padding;
- // as the title gets centered, title_width + close_button_width is not enough.
- // we want a width w, such that w / 2 - title_width / 2 >= button_area, i.e.
+ // As the title gets centered, title_width + close_button_width is not enough.
+ // We want a width w, such that w / 2 - title_width / 2 >= button_area, i.e.
// w >= 2 * button_area + title_width
return Size2(2 * button_area + title_width, 1);
@@ -324,7 +337,6 @@ void WindowDialog::_bind_methods() {
WindowDialog::WindowDialog() {
- //title="Hello!";
drag_type = DRAG_NONE;
resizable = false;
close_button = memnew(TextureButton);
@@ -340,7 +352,6 @@ WindowDialog::~WindowDialog() {
void PopupDialog::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
-
RID ci = get_canvas_item();
get_stylebox("panel", "PopupMenu")->draw(ci, Rect2(Point2(), get_size()));
}
@@ -362,15 +373,15 @@ void AcceptDialog::_post_popup() {
void AcceptDialog::_notification(int p_what) {
- if (p_what == NOTIFICATION_MODAL_CLOSE) {
-
- cancel_pressed();
- } else if (p_what == NOTIFICATION_READY) {
-
- _update_child_rects();
- } else if (p_what == NOTIFICATION_RESIZED) {
+ switch (p_what) {
+ case NOTIFICATION_MODAL_CLOSE: {
+ cancel_pressed();
+ } break;
- _update_child_rects();
+ case NOTIFICATION_READY:
+ case NOTIFICATION_RESIZED: {
+ _update_child_rects();
+ } break;
}
}
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index f238aeb392..38005f1322 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1030,14 +1030,28 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
Ref<InputEventKey> k = p_ev;
- if (k.is_valid() && k->get_scancode() == KEY_D && k->is_pressed() && k->get_command()) {
- emit_signal("duplicate_nodes_request");
- accept_event();
- }
- if (k.is_valid() && k->get_scancode() == KEY_DELETE && k->is_pressed()) {
- emit_signal("delete_nodes_request");
- accept_event();
+ if (k.is_valid()) {
+
+ if (k->get_scancode() == KEY_D && k->is_pressed() && k->get_command()) {
+ emit_signal("duplicate_nodes_request");
+ accept_event();
+ }
+
+ if (k->get_scancode() == KEY_C && k->is_pressed() && k->get_command()) {
+ emit_signal("copy_nodes_request");
+ accept_event();
+ }
+
+ if (k->get_scancode() == KEY_V && k->is_pressed() && k->get_command()) {
+ emit_signal("paste_nodes_request");
+ accept_event();
+ }
+
+ if (k->get_scancode() == KEY_DELETE && k->is_pressed()) {
+ emit_signal("delete_nodes_request");
+ accept_event();
+ }
}
Ref<InputEventMagnifyGesture> magnify_gesture = p_ev;
@@ -1297,6 +1311,8 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("disconnection_request", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot")));
ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2, "position")));
ADD_SIGNAL(MethodInfo("duplicate_nodes_request"));
+ ADD_SIGNAL(MethodInfo("copy_nodes_request"));
+ ADD_SIGNAL(MethodInfo("paste_nodes_request"));
ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index d5347edb87..ccdc95696c 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -59,6 +59,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
menu->set_scale(get_global_transform().get_scale());
menu->popup();
grab_focus();
+ accept_event();
return;
}
diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp
index 264eda4035..0154a452ad 100644
--- a/scene/gui/progress_bar.cpp
+++ b/scene/gui/progress_bar.cpp
@@ -60,7 +60,7 @@ void ProgressBar::_notification(int p_what) {
draw_style_box(bg, Rect2(Point2(), get_size()));
float r = get_as_ratio();
int mp = fg->get_minimum_size().width;
- int p = r * get_size().width - mp;
+ int p = r * (get_size().width - mp);
if (p > 0) {
draw_style_box(fg, Rect2(Point2(), Size2(p + fg->get_minimum_size().width, get_size().height)));
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index d6c0981ebc..8223ea6d1e 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -821,11 +821,7 @@ void RichTextLabel::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
- if (is_inside_tree() && use_bbcode) {
- parse_bbcode(bbcode);
- //first_invalid_line=0; //invalidate ALL
- //update();
- }
+ update();
} break;
case NOTIFICATION_DRAW: {
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index dbf3150ae0..2668acd3d5 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -37,7 +37,6 @@
#include "core/os/os.h"
#include "core/print_string.h"
#include "core/project_settings.h"
-#include "editor/editor_node.h"
#include "main/input_default.h"
#include "node.h"
#include "scene/resources/dynamic_font.h"
@@ -647,7 +646,8 @@ void SceneTree::_notification(int p_notification) {
case NOTIFICATION_WM_MOUSE_ENTER:
case NOTIFICATION_WM_MOUSE_EXIT:
case NOTIFICATION_WM_FOCUS_IN:
- case NOTIFICATION_WM_FOCUS_OUT: {
+ case NOTIFICATION_WM_FOCUS_OUT:
+ case NOTIFICATION_WM_ABOUT: {
if (p_notification == NOTIFICATION_WM_FOCUS_IN) {
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
@@ -671,19 +671,6 @@ void SceneTree::_notification(int p_notification) {
} break;
- case NOTIFICATION_WM_ABOUT: {
-
-#ifdef TOOLS_ENABLED
- if (EditorNode::get_singleton()) {
- EditorNode::get_singleton()->show_about();
- } else {
-#endif
- get_root()->propagate_notification(p_notification);
-#ifdef TOOLS_ENABLED
- }
-#endif
- } break;
-
case NOTIFICATION_CRASH: {
get_root()->propagate_notification(p_notification);
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 21ee247b02..a1a29ec950 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -2106,7 +2106,7 @@ String VisualShaderNodeOuterProduct::get_output_port_name(int p_port) const {
}
String VisualShaderNodeOuterProduct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return "\t" + p_output_vars[0] + " = outerProduct( " + p_input_vars[0] + ", " + p_input_vars[1] + " );\n";
+ return "\t" + p_output_vars[0] + " = outerProduct( vec4(" + p_input_vars[0] + ", 0.0), vec4(" + p_input_vars[1] + ", 0.0) );\n";
}
VisualShaderNodeOuterProduct::VisualShaderNodeOuterProduct() {
diff --git a/servers/physics/collision_solver_sat.cpp b/servers/physics/collision_solver_sat.cpp
index d0f8fd8aff..a13fa65009 100644
--- a/servers/physics/collision_solver_sat.cpp
+++ b/servers/physics/collision_solver_sat.cpp
@@ -274,8 +274,8 @@ static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_po
points_B = p_points_B;
}
- int version_A = (pointcount_A > 2 ? 2 : pointcount_A) - 1;
- int version_B = (pointcount_B > 2 ? 2 : pointcount_B) - 1;
+ int version_A = (pointcount_A > 3 ? 3 : pointcount_A) - 1;
+ int version_B = (pointcount_B > 3 ? 3 : pointcount_B) - 1;
GenerateContactsFunc contacts_func = generate_contacts_func_table[version_A][version_B];
ERR_FAIL_COND(!contacts_func);
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index b61e1faad2..33a184ba3f 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -327,11 +327,11 @@ public:
static Physics2DServer *init_server() {
int tm = GLOBAL_DEF("physics/2d/thread_model", 1);
- if (tm == 0) //single unsafe
+ if (tm == 0) // single unsafe
return memnew(T);
- else if (tm == 1) //single saef
+ else if (tm == 1) // single safe
return memnew(Physics2DServerWrapMT(memnew(T), false));
- else //single unsafe
+ else // multi threaded
return memnew(Physics2DServerWrapMT(memnew(T), true));
}
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 81e30c3f6b..99f917dbc1 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -4,7 +4,7 @@
## assimp
- Upstream: http://github.com/assimp/assimp
-- Version: git (d3d98a7ec0c8d38e1952b46dfe53f7e9233dc92d)
+- Version: git (1d565b0aab5a2ee00462f18c5b8a81f6a5454a48)
- License: BSD-3-Clause
diff --git a/thirdparty/assimp/assimp/config.h b/thirdparty/assimp/assimp/config.h
index 8b0634d28b..382a698268 100644
--- a/thirdparty/assimp/assimp/config.h
+++ b/thirdparty/assimp/assimp/config.h
@@ -647,6 +647,21 @@ enum aiComponent {
"AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
// ---------------------------------------------------------------------------
+/** @brief Set wether the FBX importer shall not remove empty bones.
+ *
+ *
+ * Empty bone are often used to define connections for other models.
+ */
+#define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \
+ "AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES"
+
+// ---------------------------------------------------------------------------
+/** @brief Set wether the FBX importer shall convert the unit from cm to m.
+ */
+#define AI_CONFIG_FBX_CONVERT_TO_M \
+ "AI_CONFIG_FBX_CONVERT_TO_M"
+
+// ---------------------------------------------------------------------------
/** @brief Set the vertex animation keyframe to be imported
*
* ASSIMP does not support vertex keyframes (only bone animation is supported).
@@ -978,3 +993,4 @@ enum aiComponent {
/* #cmakedefine ASSIMP_DOUBLE_PRECISION 1 */
#endif // !! AI_CONFIG_H_INC
+
diff --git a/thirdparty/assimp/code/CApi/AssimpCExport.cpp b/thirdparty/assimp/code/CApi/AssimpCExport.cpp
new file mode 100644
index 0000000000..7557edcfc6
--- /dev/null
+++ b/thirdparty/assimp/code/CApi/AssimpCExport.cpp
@@ -0,0 +1,156 @@
+/*
+---------------------------------------------------------------------------
+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.
+---------------------------------------------------------------------------
+*/
+
+/** @file AssimpCExport.cpp
+Assimp C export interface. See Exporter.cpp for some notes.
+*/
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+
+#include "CInterfaceIOWrapper.h"
+#include <assimp/SceneCombiner.h>
+#include "Common/ScenePrivate.h"
+#include <assimp/Exporter.hpp>
+
+using namespace Assimp;
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API size_t aiGetExportFormatCount(void)
+{
+ return Exporter().GetExportFormatCount();
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index)
+{
+ // Note: this is valid as the index always pertains to a built-in exporter,
+ // for which the returned structure is guaranteed to be of static storage duration.
+ Exporter exporter;
+ const aiExportFormatDesc* orig( exporter.GetExportFormatDescription( index ) );
+ if (NULL == orig) {
+ return NULL;
+ }
+
+ aiExportFormatDesc *desc = new aiExportFormatDesc;
+ desc->description = new char[ strlen( orig->description ) + 1 ]();
+ ::strncpy( (char*) desc->description, orig->description, strlen( orig->description ) );
+ desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ]();
+ ::strncpy( ( char* ) desc->fileExtension, orig->fileExtension, strlen( orig->fileExtension ) );
+ desc->id = new char[ strlen( orig->id ) + 1 ]();
+ ::strncpy( ( char* ) desc->id, orig->id, strlen( orig->id ) );
+
+ return desc;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiReleaseExportFormatDescription( const aiExportFormatDesc *desc ) {
+ if (NULL == desc) {
+ return;
+ }
+
+ delete [] desc->description;
+ delete [] desc->fileExtension;
+ delete [] desc->id;
+ delete desc;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
+{
+ if (!pOut || !pIn) {
+ return;
+ }
+
+ SceneCombiner::CopyScene(pOut,pIn,true);
+ ScenePriv(*pOut)->mIsCopy = true;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn)
+{
+ // note: aiReleaseImport() is also able to delete scene copies, but in addition
+ // it also handles scenes with import metadata.
+ delete pIn;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing )
+{
+ return ::aiExportSceneEx(pScene,pFormatId,pFileName,NULL,pPreprocessing);
+}
+
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API aiReturn aiExportSceneEx( const aiScene* pScene, const char* pFormatId, const char* pFileName, aiFileIO* pIO, unsigned int pPreprocessing )
+{
+ Exporter exp;
+
+ if (pIO) {
+ exp.SetIOHandler(new CIOSystemWrapper(pIO));
+ }
+ return exp.Export(pScene,pFormatId,pFileName,pPreprocessing);
+}
+
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing )
+{
+ Exporter exp;
+ if (!exp.ExportToBlob(pScene,pFormatId,pPreprocessing)) {
+ return NULL;
+ }
+ const aiExportDataBlob* blob = exp.GetOrphanedBlob();
+ ai_assert(blob);
+
+ return blob;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API C_STRUCT void aiReleaseExportBlob( const aiExportDataBlob* pData )
+{
+ delete pData;
+}
+
+#endif // !ASSIMP_BUILD_NO_EXPORT
diff --git a/thirdparty/assimp/code/CInterfaceIOWrapper.cpp b/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.cpp
index 5a3a49565a..5a3a49565a 100644
--- a/thirdparty/assimp/code/CInterfaceIOWrapper.cpp
+++ b/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.cpp
diff --git a/thirdparty/assimp/code/CInterfaceIOWrapper.h b/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.h
index 2162320302..2162320302 100644
--- a/thirdparty/assimp/code/CInterfaceIOWrapper.h
+++ b/thirdparty/assimp/code/CApi/CInterfaceIOWrapper.h
diff --git a/thirdparty/assimp/code/Common/Assimp.cpp b/thirdparty/assimp/code/Common/Assimp.cpp
new file mode 100644
index 0000000000..178b2c01d0
--- /dev/null
+++ b/thirdparty/assimp/code/Common/Assimp.cpp
@@ -0,0 +1,695 @@
+/*
+---------------------------------------------------------------------------
+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.
+---------------------------------------------------------------------------
+*/
+/** @file Assimp.cpp
+ * @brief Implementation of the Plain-C API
+ */
+
+#include <assimp/cimport.h>
+#include <assimp/LogStream.hpp>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/Importer.hpp>
+#include <assimp/importerdesc.h>
+#include <assimp/scene.h>
+#include <assimp/GenericProperty.h>
+#include <assimp/Exceptional.h>
+#include <assimp/BaseImporter.h>
+
+#include "CApi/CInterfaceIOWrapper.h"
+#include "Importer.h"
+#include "ScenePrivate.h"
+
+#include <list>
+
+// ------------------------------------------------------------------------------------------------
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+# include <thread>
+# include <mutex>
+#endif
+// ------------------------------------------------------------------------------------------------
+using namespace Assimp;
+
+namespace Assimp {
+ // underlying structure for aiPropertyStore
+ typedef BatchLoader::PropertyMap PropertyMap;
+
+ /** Stores the LogStream objects for all active C log streams */
+ struct mpred {
+ bool operator () (const aiLogStream& s0, const aiLogStream& s1) const {
+ return s0.callback<s1.callback&&s0.user<s1.user;
+ }
+ };
+ typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap;
+
+ /** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */
+ typedef std::list<Assimp::LogStream*> PredefLogStreamMap;
+
+ /** Local storage of all active log streams */
+ static LogStreamMap gActiveLogStreams;
+
+ /** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */
+ static PredefLogStreamMap gPredefinedStreams;
+
+ /** Error message of the last failed import process */
+ static std::string gLastErrorString;
+
+ /** Verbose logging active or not? */
+ static aiBool gVerboseLogging = false;
+
+ /** will return all registered importers. */
+ void GetImporterInstanceList(std::vector< BaseImporter* >& out);
+
+ /** will delete all registered importers. */
+ void DeleteImporterInstanceList(std::vector< BaseImporter* >& out);
+} // namespace assimp
+
+
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+/** Global mutex to manage the access to the log-stream map */
+static std::mutex gLogStreamMutex;
+#endif
+
+// ------------------------------------------------------------------------------------------------
+// Custom LogStream implementation for the C-API
+class LogToCallbackRedirector : public LogStream {
+public:
+ explicit LogToCallbackRedirector(const aiLogStream& s)
+ : stream (s) {
+ ai_assert(NULL != s.callback);
+ }
+
+ ~LogToCallbackRedirector() {
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+ std::lock_guard<std::mutex> lock(gLogStreamMutex);
+#endif
+ // (HACK) Check whether the 'stream.user' pointer points to a
+ // custom LogStream allocated by #aiGetPredefinedLogStream.
+ // In this case, we need to delete it, too. Of course, this
+ // might cause strange problems, but the chance is quite low.
+
+ PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(),
+ gPredefinedStreams.end(), (Assimp::LogStream*)stream.user);
+
+ if (it != gPredefinedStreams.end()) {
+ delete *it;
+ gPredefinedStreams.erase(it);
+ }
+ }
+
+ /** @copydoc LogStream::write */
+ void write(const char* message) {
+ stream.callback(message,stream.user);
+ }
+
+private:
+ aiLogStream stream;
+};
+
+// ------------------------------------------------------------------------------------------------
+void ReportSceneNotFoundError() {
+ ASSIMP_LOG_ERROR("Unable to find the Assimp::Importer for this aiScene. "
+ "The C-API does not accept scenes produced by the C++ API and vice versa");
+
+ ai_assert(false);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Reads the given file and returns its content.
+const aiScene* aiImportFile( const char* pFile, unsigned int pFlags) {
+ return aiImportFileEx(pFile,pFlags,NULL);
+}
+
+// ------------------------------------------------------------------------------------------------
+const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS) {
+ return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL);
+}
+
+// ------------------------------------------------------------------------------------------------
+const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
+ aiFileIO* pFS, const aiPropertyStore* props) {
+ ai_assert(NULL != pFile);
+
+ const aiScene* scene = NULL;
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // create an Importer for this file
+ Assimp::Importer* imp = new Assimp::Importer();
+
+ // copy properties
+ if(props) {
+ const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
+ ImporterPimpl* pimpl = imp->Pimpl();
+ pimpl->mIntProperties = pp->ints;
+ pimpl->mFloatProperties = pp->floats;
+ pimpl->mStringProperties = pp->strings;
+ pimpl->mMatrixProperties = pp->matrices;
+ }
+ // setup a custom IO system if necessary
+ if (pFS) {
+ imp->SetIOHandler( new CIOSystemWrapper (pFS) );
+ }
+
+ // and have it read the file
+ scene = imp->ReadFile( pFile, pFlags);
+
+ // if succeeded, store the importer in the scene and keep it alive
+ if( scene) {
+ ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
+ priv->mOrigImporter = imp;
+ } else {
+ // if failed, extract error code and destroy the import
+ gLastErrorString = imp->GetErrorString();
+ delete imp;
+ }
+
+ // return imported data. If the import failed the pointer is NULL anyways
+ ASSIMP_END_EXCEPTION_REGION(const aiScene*);
+
+ return scene;
+}
+
+// ------------------------------------------------------------------------------------------------
+const aiScene* aiImportFileFromMemory(
+ const char* pBuffer,
+ unsigned int pLength,
+ unsigned int pFlags,
+ const char* pHint)
+{
+ return aiImportFileFromMemoryWithProperties(pBuffer, pLength, pFlags, pHint, NULL);
+}
+
+// ------------------------------------------------------------------------------------------------
+const aiScene* aiImportFileFromMemoryWithProperties(
+ const char* pBuffer,
+ unsigned int pLength,
+ unsigned int pFlags,
+ const char* pHint,
+ const aiPropertyStore* props)
+{
+ ai_assert( NULL != pBuffer );
+ ai_assert( 0 != pLength );
+
+ const aiScene* scene = NULL;
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // create an Importer for this file
+ Assimp::Importer* imp = new Assimp::Importer();
+
+ // copy properties
+ if(props) {
+ const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
+ ImporterPimpl* pimpl = imp->Pimpl();
+ pimpl->mIntProperties = pp->ints;
+ pimpl->mFloatProperties = pp->floats;
+ pimpl->mStringProperties = pp->strings;
+ pimpl->mMatrixProperties = pp->matrices;
+ }
+
+ // and have it read the file from the memory buffer
+ scene = imp->ReadFileFromMemory( pBuffer, pLength, pFlags,pHint);
+
+ // if succeeded, store the importer in the scene and keep it alive
+ if( scene) {
+ ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
+ priv->mOrigImporter = imp;
+ }
+ else {
+ // if failed, extract error code and destroy the import
+ gLastErrorString = imp->GetErrorString();
+ delete imp;
+ }
+ // return imported data. If the import failed the pointer is NULL anyways
+ ASSIMP_END_EXCEPTION_REGION(const aiScene*);
+ return scene;
+}
+
+// ------------------------------------------------------------------------------------------------
+// Releases all resources associated with the given import process.
+void aiReleaseImport( const aiScene* pScene)
+{
+ if (!pScene) {
+ return;
+ }
+
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // find the importer associated with this data
+ const ScenePrivateData* priv = ScenePriv(pScene);
+ if( !priv || !priv->mOrigImporter) {
+ delete pScene;
+ }
+ else {
+ // deleting the Importer also deletes the scene
+ // Note: the reason that this is not written as 'delete priv->mOrigImporter'
+ // is a suspected bug in gcc 4.4+ (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52339)
+ Importer* importer = priv->mOrigImporter;
+ delete importer;
+ }
+
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
+ unsigned int pFlags)
+{
+ const aiScene* sc = NULL;
+
+
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // find the importer associated with this data
+ const ScenePrivateData* priv = ScenePriv(pScene);
+ if( !priv || !priv->mOrigImporter) {
+ ReportSceneNotFoundError();
+ return NULL;
+ }
+
+ sc = priv->mOrigImporter->ApplyPostProcessing(pFlags);
+
+ if (!sc) {
+ aiReleaseImport(pScene);
+ return NULL;
+ }
+
+ ASSIMP_END_EXCEPTION_REGION(const aiScene*);
+ return sc;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API const aiScene *aiApplyCustomizedPostProcessing( const aiScene *scene,
+ BaseProcess* process,
+ bool requestValidation ) {
+ const aiScene* sc( NULL );
+
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // find the importer associated with this data
+ const ScenePrivateData* priv = ScenePriv( scene );
+ if ( NULL == priv || NULL == priv->mOrigImporter ) {
+ ReportSceneNotFoundError();
+ return NULL;
+ }
+
+ sc = priv->mOrigImporter->ApplyCustomizedPostProcessing( process, requestValidation );
+
+ if ( !sc ) {
+ aiReleaseImport( scene );
+ return NULL;
+ }
+
+ ASSIMP_END_EXCEPTION_REGION( const aiScene* );
+
+ return sc;
+}
+
+// ------------------------------------------------------------------------------------------------
+void CallbackToLogRedirector (const char* msg, char* dt)
+{
+ ai_assert( NULL != msg );
+ ai_assert( NULL != dt );
+ LogStream* s = (LogStream*)dt;
+
+ s->write(msg);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file)
+{
+ aiLogStream sout;
+
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+ LogStream* stream = LogStream::createDefaultStream(pStream,file);
+ if (!stream) {
+ sout.callback = NULL;
+ sout.user = NULL;
+ }
+ else {
+ sout.callback = &CallbackToLogRedirector;
+ sout.user = (char*)stream;
+ }
+ gPredefinedStreams.push_back(stream);
+ ASSIMP_END_EXCEPTION_REGION(aiLogStream);
+ return sout;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+ std::lock_guard<std::mutex> lock(gLogStreamMutex);
+#endif
+
+ LogStream* lg = new LogToCallbackRedirector(*stream);
+ gActiveLogStreams[*stream] = lg;
+
+ if (DefaultLogger::isNullLogger()) {
+ DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
+ }
+ DefaultLogger::get()->attachStream(lg);
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+ std::lock_guard<std::mutex> lock(gLogStreamMutex);
+#endif
+ // find the log-stream associated with this data
+ LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
+ // it should be there... else the user is playing fools with us
+ if( it == gActiveLogStreams.end()) {
+ return AI_FAILURE;
+ }
+ DefaultLogger::get()->detatchStream( it->second );
+ delete it->second;
+
+ gActiveLogStreams.erase( it);
+
+ if (gActiveLogStreams.empty()) {
+ DefaultLogger::kill();
+ }
+ ASSIMP_END_EXCEPTION_REGION(aiReturn);
+ return AI_SUCCESS;
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiDetachAllLogStreams(void)
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+ std::lock_guard<std::mutex> lock(gLogStreamMutex);
+#endif
+ Logger *logger( DefaultLogger::get() );
+ if ( NULL == logger ) {
+ return;
+ }
+
+ for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
+ logger->detatchStream( it->second );
+ delete it->second;
+ }
+ gActiveLogStreams.clear();
+ DefaultLogger::kill();
+
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiEnableVerboseLogging(aiBool d)
+{
+ if (!DefaultLogger::isNullLogger()) {
+ DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
+ }
+ gVerboseLogging = d;
+}
+
+// ------------------------------------------------------------------------------------------------
+// Returns the error text of the last failed import process.
+const char* aiGetErrorString()
+{
+ return gLastErrorString.c_str();
+}
+
+// -----------------------------------------------------------------------------------------------
+// Return the description of a importer given its index
+const aiImporterDesc* aiGetImportFormatDescription( size_t pIndex)
+{
+ return Importer().GetImporterInfo(pIndex);
+}
+
+// -----------------------------------------------------------------------------------------------
+// Return the number of importers
+size_t aiGetImportFormatCount(void)
+{
+ return Importer().GetImporterCount();
+}
+
+// ------------------------------------------------------------------------------------------------
+// Returns the error text of the last failed import process.
+aiBool aiIsExtensionSupported(const char* szExtension)
+{
+ ai_assert(NULL != szExtension);
+ aiBool candoit=AI_FALSE;
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // FIXME: no need to create a temporary Importer instance just for that ..
+ Assimp::Importer tmp;
+ candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE;
+
+ ASSIMP_END_EXCEPTION_REGION(aiBool);
+ return candoit;
+}
+
+// ------------------------------------------------------------------------------------------------
+// Get a list of all file extensions supported by ASSIMP
+void aiGetExtensionList(aiString* szOut)
+{
+ ai_assert(NULL != szOut);
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // FIXME: no need to create a temporary Importer instance just for that ..
+ Assimp::Importer tmp;
+ tmp.GetExtensionList(*szOut);
+
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Get the memory requirements for a particular import.
+void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
+ C_STRUCT aiMemoryInfo* in)
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+
+ // find the importer associated with this data
+ const ScenePrivateData* priv = ScenePriv(pIn);
+ if( !priv || !priv->mOrigImporter) {
+ ReportSceneNotFoundError();
+ return;
+ }
+
+ return priv->mOrigImporter->GetMemoryRequirements(*in);
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void)
+{
+ return reinterpret_cast<aiPropertyStore*>( new PropertyMap() );
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p)
+{
+ delete reinterpret_cast<PropertyMap*>(p);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyInteger
+ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore* p, const char* szName, int value)
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+ PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
+ SetGenericProperty<int>(pp->ints,szName,value);
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyFloat
+ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, ai_real value)
+{
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+ PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
+ SetGenericProperty<ai_real>(pp->floats,szName,value);
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyString
+ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName,
+ const C_STRUCT aiString* st)
+{
+ if (!st) {
+ return;
+ }
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+ PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
+ SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str()));
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Importer::SetPropertyMatrix
+ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName,
+ const C_STRUCT aiMatrix4x4* mat)
+{
+ if (!mat) {
+ return;
+ }
+ ASSIMP_BEGIN_EXCEPTION_REGION();
+ PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
+ SetGenericProperty<aiMatrix4x4>(pp->matrices,szName,*mat);
+ ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Rotation matrix to quaternion
+ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
+{
+ ai_assert( NULL != quat );
+ ai_assert( NULL != mat );
+ *quat = aiQuaternion(*mat);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Matrix decomposition
+ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
+ aiQuaternion* rotation,
+ aiVector3D* position)
+{
+ ai_assert( NULL != rotation );
+ ai_assert( NULL != position );
+ ai_assert( NULL != scaling );
+ ai_assert( NULL != mat );
+ mat->Decompose(*scaling,*rotation,*position);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Matrix transpose
+ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3* mat)
+{
+ ai_assert(NULL != mat);
+ mat->Transpose();
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat)
+{
+ ai_assert(NULL != mat);
+ mat->Transpose();
+}
+
+// ------------------------------------------------------------------------------------------------
+// Vector transformation
+ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
+ const aiMatrix3x3* mat)
+{
+ ai_assert( NULL != mat );
+ ai_assert( NULL != vec);
+ *vec *= (*mat);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec,
+ const aiMatrix4x4* mat)
+{
+ ai_assert( NULL != mat );
+ ai_assert( NULL != vec );
+
+ *vec *= (*mat);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Matrix multiplication
+ASSIMP_API void aiMultiplyMatrix4(
+ aiMatrix4x4* dst,
+ const aiMatrix4x4* src)
+{
+ ai_assert( NULL != dst );
+ ai_assert( NULL != src );
+ *dst = (*dst) * (*src);
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiMultiplyMatrix3(
+ aiMatrix3x3* dst,
+ const aiMatrix3x3* src)
+{
+ ai_assert( NULL != dst );
+ ai_assert( NULL != src );
+ *dst = (*dst) * (*src);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Matrix identity
+ASSIMP_API void aiIdentityMatrix3(
+ aiMatrix3x3* mat)
+{
+ ai_assert(NULL != mat);
+ *mat = aiMatrix3x3();
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API void aiIdentityMatrix4(
+ aiMatrix4x4* mat)
+{
+ ai_assert(NULL != mat);
+ *mat = aiMatrix4x4();
+}
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API C_STRUCT const aiImporterDesc* aiGetImporterDesc( const char *extension ) {
+ if( NULL == extension ) {
+ return NULL;
+ }
+ const aiImporterDesc *desc( NULL );
+ std::vector< BaseImporter* > out;
+ GetImporterInstanceList( out );
+ for( size_t i = 0; i < out.size(); ++i ) {
+ if( 0 == strncmp( out[ i ]->GetInfo()->mFileExtensions, extension, strlen( extension ) ) ) {
+ desc = out[ i ]->GetInfo();
+ break;
+ }
+ }
+
+ DeleteImporterInstanceList(out);
+
+ return desc;
+}
+
+// ------------------------------------------------------------------------------------------------
diff --git a/thirdparty/assimp/code/BaseImporter.cpp b/thirdparty/assimp/code/Common/BaseImporter.cpp
index 4803c6d6f2..0a5694aa0e 100644
--- a/thirdparty/assimp/code/BaseImporter.cpp
+++ b/thirdparty/assimp/code/Common/BaseImporter.cpp
@@ -320,7 +320,11 @@ std::string BaseImporter::GetExtension( const std::string& file ) {
return false;
}
-#include "../contrib/utf8cpp/source/utf8.h"
+#ifdef ASSIMP_USE_HUNTER
+# include <utf8/utf8.h>
+#else
+# include "../contrib/utf8cpp/source/utf8.h"
+#endif
// ------------------------------------------------------------------------------------------------
// Convert to UTF8 data
diff --git a/thirdparty/assimp/code/BaseProcess.cpp b/thirdparty/assimp/code/Common/BaseProcess.cpp
index 18872c3693..e247be418d 100644
--- a/thirdparty/assimp/code/BaseProcess.cpp
+++ b/thirdparty/assimp/code/Common/BaseProcess.cpp
@@ -89,7 +89,7 @@ void BaseProcess::ExecuteOnScene( Importer* pImp)
// and kill the partially imported data
delete pImp->Pimpl()->mScene;
- pImp->Pimpl()->mScene = NULL;
+ pImp->Pimpl()->mScene = nullptr;
}
}
diff --git a/thirdparty/assimp/code/BaseProcess.h b/thirdparty/assimp/code/Common/BaseProcess.h
index 4d5c7a76be..4d5c7a76be 100644
--- a/thirdparty/assimp/code/BaseProcess.h
+++ b/thirdparty/assimp/code/Common/BaseProcess.h
diff --git a/thirdparty/assimp/code/Bitmap.cpp b/thirdparty/assimp/code/Common/Bitmap.cpp
index b22b71ea9e..b22b71ea9e 100644
--- a/thirdparty/assimp/code/Bitmap.cpp
+++ b/thirdparty/assimp/code/Common/Bitmap.cpp
diff --git a/thirdparty/assimp/code/CreateAnimMesh.cpp b/thirdparty/assimp/code/Common/CreateAnimMesh.cpp
index 1a052849bb..98b60e5319 100644
--- a/thirdparty/assimp/code/CreateAnimMesh.cpp
+++ b/thirdparty/assimp/code/Common/CreateAnimMesh.cpp
@@ -47,10 +47,6 @@ namespace Assimp {
aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh)
{
aiAnimMesh *animesh = new aiAnimMesh;
- animesh->mVertices = NULL;
- animesh->mNormals = NULL;
- animesh->mTangents = NULL;
- animesh->mBitangents = NULL;
animesh->mNumVertices = mesh->mNumVertices;
if (mesh->mVertices) {
animesh->mVertices = new aiVector3D[animesh->mNumVertices];
diff --git a/thirdparty/assimp/code/DefaultIOStream.cpp b/thirdparty/assimp/code/Common/DefaultIOStream.cpp
index 1c100b6189..1c100b6189 100644
--- a/thirdparty/assimp/code/DefaultIOStream.cpp
+++ b/thirdparty/assimp/code/Common/DefaultIOStream.cpp
diff --git a/thirdparty/assimp/code/DefaultIOSystem.cpp b/thirdparty/assimp/code/Common/DefaultIOSystem.cpp
index d40b67de32..d40b67de32 100644
--- a/thirdparty/assimp/code/DefaultIOSystem.cpp
+++ b/thirdparty/assimp/code/Common/DefaultIOSystem.cpp
diff --git a/thirdparty/assimp/code/DefaultLogger.cpp b/thirdparty/assimp/code/Common/DefaultLogger.cpp
index de3528d2b4..de3528d2b4 100644
--- a/thirdparty/assimp/code/DefaultLogger.cpp
+++ b/thirdparty/assimp/code/Common/DefaultLogger.cpp
diff --git a/thirdparty/assimp/code/DefaultProgressHandler.h b/thirdparty/assimp/code/Common/DefaultProgressHandler.h
index bd2cce00be..bd2cce00be 100644
--- a/thirdparty/assimp/code/DefaultProgressHandler.h
+++ b/thirdparty/assimp/code/Common/DefaultProgressHandler.h
diff --git a/thirdparty/assimp/code/Exporter.cpp b/thirdparty/assimp/code/Common/Exporter.cpp
index 8848e87f5b..090b561ae0 100644
--- a/thirdparty/assimp/code/Exporter.cpp
+++ b/thirdparty/assimp/code/Common/Exporter.cpp
@@ -61,15 +61,16 @@ Here we implement only the C++ interface (Assimp::Exporter).
#include <assimp/mesh.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
-
-#include "DefaultProgressHandler.h"
-#include "BaseProcess.h"
-#include "JoinVerticesProcess.h"
-#include "MakeVerboseFormat.h"
-#include "ConvertToLHProcess.h"
-#include "PretransformVertices.h"
#include <assimp/Exceptional.h>
-#include "ScenePrivate.h"
+
+#include "Common/DefaultProgressHandler.h"
+#include "Common/BaseProcess.h"
+#include "Common/ScenePrivate.h"
+#include "PostProcessing/CalcTangentsProcess.h"
+#include "PostProcessing/MakeVerboseFormat.h"
+#include "PostProcessing/JoinVerticesProcess.h"
+#include "PostProcessing/ConvertToLHProcess.h"
+#include "PostProcessing/PretransformVertices.h"
#include <memory>
@@ -101,6 +102,7 @@ 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 ExportAssimp2Json(const char* , IOSystem*, const aiScene* , const Assimp::ExportProperties*);
// ------------------------------------------------------------------------------------------------
// global array of all export formats which Assimp supports in its current build
@@ -161,11 +163,11 @@ Exporter::ExportFormatEntry gExporters[] =
#endif
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
- Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0 ),
+ Exporter::ExportFormatEntry( "assbin", "Assimp Binary File", "assbin" , &ExportSceneAssbin, 0 ),
#endif
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
- Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0 ),
+ Exporter::ExportFormatEntry( "assxml", "Assimp XML Document", "assxml" , &ExportSceneAssxml, 0 ),
#endif
#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
@@ -178,7 +180,11 @@ Exporter::ExportFormatEntry gExporters[] =
#endif
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
- Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 )
+ Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 ),
+#endif
+
+#ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
+ Exporter::ExportFormatEntry( "assjson", "Assimp JSON Document", "json", &ExportAssimp2Json, 0)
#endif
};
@@ -288,7 +294,7 @@ void Exporter::SetProgressHandler(ProgressHandler* pHandler) {
// ------------------------------------------------------------------------------------------------
const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
- unsigned int, const ExportProperties* /*pProperties*/ ) {
+ unsigned int pPreprocessing, const ExportProperties* pProperties) {
if (pimpl->blob) {
delete pimpl->blob;
pimpl->blob = nullptr;
@@ -298,7 +304,7 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
BlobIOSystem* blobio = new BlobIOSystem();
pimpl->mIOSystem = std::shared_ptr<IOSystem>( blobio );
- if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
+ if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName(), pPreprocessing, pProperties)) {
pimpl->mIOSystem = old;
return nullptr;
}
diff --git a/thirdparty/assimp/code/FileLogStream.h b/thirdparty/assimp/code/Common/FileLogStream.h
index 740c503192..740c503192 100644
--- a/thirdparty/assimp/code/FileLogStream.h
+++ b/thirdparty/assimp/code/Common/FileLogStream.h
diff --git a/thirdparty/assimp/code/FileSystemFilter.h b/thirdparty/assimp/code/Common/FileSystemFilter.h
index 9923cdbdd3..9923cdbdd3 100644
--- a/thirdparty/assimp/code/FileSystemFilter.h
+++ b/thirdparty/assimp/code/Common/FileSystemFilter.h
diff --git a/thirdparty/assimp/code/Common/IFF.h b/thirdparty/assimp/code/Common/IFF.h
new file mode 100644
index 0000000000..91d7d48289
--- /dev/null
+++ b/thirdparty/assimp/code/Common/IFF.h
@@ -0,0 +1,102 @@
+// Definitions for the Interchange File Format (IFF)
+// Alexander Gessler, 2006
+// Adapted to Assimp August 2008
+
+#ifndef AI_IFF_H_INCLUDED
+#define AI_IFF_H_INCLUDED
+
+#include <assimp/ByteSwapper.h>
+
+namespace Assimp {
+namespace IFF {
+
+/////////////////////////////////////////////////////////////////////////////////
+//! Describes an IFF chunk header
+/////////////////////////////////////////////////////////////////////////////////
+struct ChunkHeader
+{
+ //! Type of the chunk header - FourCC
+ uint32_t type;
+
+ //! Length of the chunk data, in bytes
+ uint32_t length;
+};
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//! Describes an IFF sub chunk header
+/////////////////////////////////////////////////////////////////////////////////
+struct SubChunkHeader
+{
+ //! Type of the chunk header - FourCC
+ uint32_t type;
+
+ //! Length of the chunk data, in bytes
+ uint16_t length;
+};
+
+
+#define AI_IFF_FOURCC(a,b,c,d) ((uint32_t) (((uint8_t)a << 24u) | \
+ ((uint8_t)b << 16u) | ((uint8_t)c << 8u) | ((uint8_t)d)))
+
+
+#define AI_IFF_FOURCC_FORM AI_IFF_FOURCC('F','O','R','M')
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//! Load a chunk header
+//! @param outFile Pointer to the file data - points to the chunk data afterwards
+//! @return Copy of the chunk header
+/////////////////////////////////////////////////////////////////////////////////
+inline ChunkHeader LoadChunk(uint8_t*& outFile)
+{
+ ChunkHeader head;
+ ::memcpy(&head.type, outFile, 4);
+ outFile += 4;
+ ::memcpy(&head.length, outFile, 4);
+ outFile += 4;
+ AI_LSWAP4(head.length);
+ AI_LSWAP4(head.type);
+ return head;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+//! Load a sub chunk header
+//! @param outFile Pointer to the file data - points to the chunk data afterwards
+//! @return Copy of the sub chunk header
+/////////////////////////////////////////////////////////////////////////////////
+inline SubChunkHeader LoadSubChunk(uint8_t*& outFile)
+{
+ SubChunkHeader head;
+ ::memcpy(&head.type, outFile, 4);
+ outFile += 4;
+ ::memcpy(&head.length, outFile, 2);
+ outFile += 2;
+ AI_LSWAP2(head.length);
+ AI_LSWAP4(head.type);
+ return head;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+//! Read the file header and return the type of the file and its size
+//! @param outFile Pointer to the file data. The buffer must at
+//! least be 12 bytes large.
+//! @param fileType Receives the type of the file
+//! @return 0 if everything was OK, otherwise an error message
+/////////////////////////////////////////////////////////////////////////////////
+inline const char* ReadHeader(uint8_t* outFile, uint32_t& fileType)
+{
+ ChunkHeader head = LoadChunk(outFile);
+ if(AI_IFF_FOURCC_FORM != head.type)
+ {
+ return "The file is not an IFF file: FORM chunk is missing";
+ }
+ ::memcpy(&fileType, outFile, 4);
+ AI_LSWAP4(fileType);
+ return 0;
+}
+
+
+}}
+
+#endif // !! AI_IFF_H_INCLUDED
diff --git a/thirdparty/assimp/code/Importer.cpp b/thirdparty/assimp/code/Common/Importer.cpp
index 65b16471cc..91b50859a0 100644
--- a/thirdparty/assimp/code/Importer.cpp
+++ b/thirdparty/assimp/code/Common/Importer.cpp
@@ -64,15 +64,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ------------------------------------------------------------------------------------------------
// Internal headers
// ------------------------------------------------------------------------------------------------
-#include "Importer.h"
-#include <assimp/BaseImporter.h>
-#include "BaseProcess.h"
+#include "Common/Importer.h"
+#include "Common/BaseProcess.h"
+#include "Common/DefaultProgressHandler.h"
+#include "PostProcessing/ProcessHelper.h"
+#include "Common/ScenePreprocessor.h"
+#include "Common/ScenePrivate.h"
-#include "DefaultProgressHandler.h"
+#include <assimp/BaseImporter.h>
#include <assimp/GenericProperty.h>
-#include "ProcessHelper.h"
-#include "ScenePreprocessor.h"
-#include "ScenePrivate.h"
#include <assimp/MemoryIOWrapper.h>
#include <assimp/Profiler.h>
#include <assimp/TinyFormatter.h>
@@ -86,7 +86,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultIOSystem.h>
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
-# include "ValidateDataStructure.h"
+# include "PostProcessing/ValidateDataStructure.h"
#endif
using namespace Assimp::Profiling;
@@ -590,10 +590,12 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
// Find an worker class which can handle the file
BaseImporter* imp = NULL;
+ SetPropertyInteger("importerIndex", -1);
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {
imp = pimpl->mImporter[a];
+ SetPropertyInteger("importerIndex", a);
break;
}
}
@@ -606,6 +608,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
imp = pimpl->mImporter[a];
+ SetPropertyInteger("importerIndex", a);
break;
}
}
diff --git a/thirdparty/assimp/code/Importer.h b/thirdparty/assimp/code/Common/Importer.h
index a439d99c2f..a439d99c2f 100644
--- a/thirdparty/assimp/code/Importer.h
+++ b/thirdparty/assimp/code/Common/Importer.h
diff --git a/thirdparty/assimp/code/ImporterRegistry.cpp b/thirdparty/assimp/code/Common/ImporterRegistry.cpp
index 747815fa6f..32ac3b4168 100644
--- a/thirdparty/assimp/code/ImporterRegistry.cpp
+++ b/thirdparty/assimp/code/Common/ImporterRegistry.cpp
@@ -56,146 +56,146 @@ corresponding preprocessor flag to selectively disable formats.
// (include_new_importers_here)
// ------------------------------------------------------------------------------------------------
#ifndef ASSIMP_BUILD_NO_X_IMPORTER
-# include "XFileImporter.h"
+# include "X/XFileImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
-# include "AMFImporter.hpp"
+# include "AMF/AMFImporter.hpp"
#endif
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-# include "3DSLoader.h"
+# include "3DS/3DSLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
-# include "MD3Loader.h"
+# include "MD3/MD3Loader.h"
#endif
#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
-# include "MDLLoader.h"
+# include "MDL/MDLLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
-# include "MD2Loader.h"
+# include "MD2/MD2Loader.h"
#endif
#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
-# include "PlyLoader.h"
+# include "Ply/PlyLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
-# include "ASELoader.h"
+# include "ASE/ASELoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
-# include "ObjFileImporter.h"
+# include "Obj/ObjFileImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
-# include "HMPLoader.h"
+# include "HMP/HMPLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER
-# include "SMDLoader.h"
+# include "SMD/SMDLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
-# include "MDCLoader.h"
+# include "MDC/MDCLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
-# include "MD5Loader.h"
+# include "MD5/MD5Loader.h"
#endif
#ifndef ASSIMP_BUILD_NO_STL_IMPORTER
-# include "STLLoader.h"
+# include "STL/STLLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-# include "LWOLoader.h"
+# include "LWO/LWOLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
-# include "DXFLoader.h"
+# include "DXF/DXFLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER
-# include "NFFLoader.h"
+# include "NFF/NFFLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
-# include "RawLoader.h"
+# include "Raw/RawLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_SIB_IMPORTER
-# include "SIBImporter.h"
+# include "SIB/SIBImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
-# include "OFFLoader.h"
+# include "OFF/OFFLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
-# include "ACLoader.h"
+# include "AC/ACLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
-# include "BVHLoader.h"
+# include "BVH/BVHLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
-# include "IRRMeshLoader.h"
+# include "Irr/IRRMeshLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
-# include "IRRLoader.h"
+# include "Irr/IRRLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
-# include "Q3DLoader.h"
+# include "Q3D/Q3DLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
-# include "B3DImporter.h"
+# include "B3D/B3DImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
-# include "ColladaLoader.h"
+# include "Collada/ColladaLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
-# include "TerragenLoader.h"
+# include "Terragen/TerragenLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
-# include "CSMLoader.h"
+# include "CSM/CSMLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
-# include "UnrealLoader.h"
+# include "Unreal/UnrealLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
-# include "LWSLoader.h"
+# include "LWS/LWSLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-# include "OgreImporter.h"
+# include "Ogre/OgreImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
-# include "OpenGEXImporter.h"
+# include "OpenGEX/OpenGEXImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
-# include "MS3DLoader.h"
+# include "MS3D/MS3DLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
-# include "COBLoader.h"
+# include "COB/COBLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-# include "BlenderLoader.h"
+# include "Blender/BlenderLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
-# include "Q3BSPFileImporter.h"
+# include "Q3BSP/Q3BSPFileImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
-# include "NDOLoader.h"
+# include "NDO/NDOLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
# include "Importer/IFC/IFCLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
-# include "XGLLoader.h"
+# include "XGL/XGLLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-# include "FBXImporter.h"
+# include "FBX/FBXImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
-# include "AssbinLoader.h"
+# include "Assbin/AssbinLoader.h"
#endif
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
-# include "glTFImporter.h"
-# include "glTF2Importer.h"
+# include "glTF/glTFImporter.h"
+# include "glTF2/glTF2Importer.h"
#endif
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
-# include "C4DImporter.h"
+# include "C4D/C4DImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
-# include "D3MFImporter.h"
+# include "3MF/D3MFImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-# include "X3DImporter.hpp"
+# include "X3D/X3DImporter.hpp"
#endif
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
-# include "MMDImporter.h"
+# include "MMD/MMDImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
# include "Importer/StepFile/StepFileImporter.h"
@@ -364,7 +364,7 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
void DeleteImporterInstanceList(std::vector< BaseImporter* >& deleteList){
for(size_t i= 0; i<deleteList.size();++i){
delete deleteList[i];
- deleteList[i]=NULL;
+ deleteList[i]=nullptr;
}//for
}
diff --git a/thirdparty/assimp/code/PolyTools.h b/thirdparty/assimp/code/Common/PolyTools.h
index fbbda0e7d1..fbbda0e7d1 100644
--- a/thirdparty/assimp/code/PolyTools.h
+++ b/thirdparty/assimp/code/Common/PolyTools.h
diff --git a/thirdparty/assimp/code/PostStepRegistry.cpp b/thirdparty/assimp/code/Common/PostStepRegistry.cpp
index 15b4a28843..ef58f8ddfd 100644
--- a/thirdparty/assimp/code/PostStepRegistry.cpp
+++ b/thirdparty/assimp/code/Common/PostStepRegistry.cpp
@@ -48,89 +48,93 @@ directly (unless you are adding new steps), instead use the
corresponding preprocessor flag to selectively disable steps.
*/
-#include "ProcessHelper.h"
+#include "PostProcessing/ProcessHelper.h"
#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
-# include "CalcTangentsProcess.h"
+# include "PostProcessing/CalcTangentsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
-# include "JoinVerticesProcess.h"
+# include "PostProcessing/JoinVerticesProcess.h"
#endif
#if !(defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS && defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS && defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
-# include "ConvertToLHProcess.h"
+# include "PostProcessing/ConvertToLHProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
-# include "TriangulateProcess.h"
+# include "PostProcessing/TriangulateProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_DROPFACENORMALS_PROCESS
-# include "DropFaceNormalsProcess.h"
+# include "PostProcessing/DropFaceNormalsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS
-# include "GenFaceNormalsProcess.h"
+# include "PostProcessing/GenFaceNormalsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS
-# include "GenVertexNormalsProcess.h"
+# include "PostProcessing/GenVertexNormalsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_REMOVEVC_PROCESS
-# include "RemoveVCProcess.h"
+# include "PostProcessing/RemoveVCProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS
-# include "SplitLargeMeshes.h"
+# include "PostProcessing/SplitLargeMeshes.h"
#endif
#ifndef ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS
-# include "PretransformVertices.h"
+# include "PostProcessing/PretransformVertices.h"
#endif
#ifndef ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS
-# include "LimitBoneWeightsProcess.h"
+# include "PostProcessing/LimitBoneWeightsProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
-# include "ValidateDataStructure.h"
+# include "PostProcessing/ValidateDataStructure.h"
#endif
#ifndef ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS
-# include "ImproveCacheLocality.h"
+# include "PostProcessing/ImproveCacheLocality.h"
#endif
#ifndef ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS
-# include "FixNormalsStep.h"
+# include "PostProcessing/FixNormalsStep.h"
#endif
#ifndef ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS
-# include "RemoveRedundantMaterials.h"
+# include "PostProcessing/RemoveRedundantMaterials.h"
#endif
#if (!defined ASSIMP_BUILD_NO_EMBEDTEXTURES_PROCESS)
-# include "EmbedTexturesProcess.h"
+# include "PostProcessing/EmbedTexturesProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
-# include "FindInvalidDataProcess.h"
+# include "PostProcessing/FindInvalidDataProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS
-# include "FindDegenerates.h"
+# include "PostProcessing/FindDegenerates.h"
#endif
#ifndef ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS
-# include "SortByPTypeProcess.h"
+# include "PostProcessing/SortByPTypeProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
-# include "ComputeUVMappingProcess.h"
+# include "PostProcessing/ComputeUVMappingProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
-# include "TextureTransform.h"
+# include "PostProcessing/TextureTransform.h"
#endif
#ifndef ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS
-# include "FindInstancesProcess.h"
+# include "PostProcessing/FindInstancesProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
-# include "OptimizeMeshes.h"
+# include "PostProcessing/OptimizeMeshes.h"
#endif
#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
-# include "OptimizeGraph.h"
+# include "PostProcessing/OptimizeGraph.h"
#endif
#ifndef ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS
-# include "SplitByBoneCountProcess.h"
+# include "Common/SplitByBoneCountProcess.h"
#endif
#ifndef ASSIMP_BUILD_NO_DEBONE_PROCESS
-# include "DeboneProcess.h"
+# include "PostProcessing/DeboneProcess.h"
#endif
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
-# include "ScaleProcess.h"
+# include "PostProcessing/ScaleProcess.h"
#endif
+#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
+# include "PostProcessing/GenBoundingBoxesProcess.h"
+#endif
+
namespace Assimp {
@@ -246,6 +250,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
#if (!defined ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
out.push_back( new ImproveCacheLocalityProcess());
#endif
+#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
+ out.push_back(new GenBoundingBoxesProcess);
+#endif
}
}
diff --git a/thirdparty/assimp/code/RemoveComments.cpp b/thirdparty/assimp/code/Common/RemoveComments.cpp
index 91700a7699..91700a7699 100644
--- a/thirdparty/assimp/code/RemoveComments.cpp
+++ b/thirdparty/assimp/code/Common/RemoveComments.cpp
diff --git a/thirdparty/assimp/code/SGSpatialSort.cpp b/thirdparty/assimp/code/Common/SGSpatialSort.cpp
index 120070b0aa..120070b0aa 100644
--- a/thirdparty/assimp/code/SGSpatialSort.cpp
+++ b/thirdparty/assimp/code/Common/SGSpatialSort.cpp
diff --git a/thirdparty/assimp/code/SceneCombiner.cpp b/thirdparty/assimp/code/Common/SceneCombiner.cpp
index e445bd7434..e445bd7434 100644
--- a/thirdparty/assimp/code/SceneCombiner.cpp
+++ b/thirdparty/assimp/code/Common/SceneCombiner.cpp
diff --git a/thirdparty/assimp/code/ScenePreprocessor.cpp b/thirdparty/assimp/code/Common/ScenePreprocessor.cpp
index 432a3d7666..432a3d7666 100644
--- a/thirdparty/assimp/code/ScenePreprocessor.cpp
+++ b/thirdparty/assimp/code/Common/ScenePreprocessor.cpp
diff --git a/thirdparty/assimp/code/ScenePreprocessor.h b/thirdparty/assimp/code/Common/ScenePreprocessor.h
index 3f4c8d7c3f..3f4c8d7c3f 100644
--- a/thirdparty/assimp/code/ScenePreprocessor.h
+++ b/thirdparty/assimp/code/Common/ScenePreprocessor.h
diff --git a/thirdparty/assimp/code/ScenePrivate.h b/thirdparty/assimp/code/Common/ScenePrivate.h
index f336aafc9a..f336aafc9a 100644
--- a/thirdparty/assimp/code/ScenePrivate.h
+++ b/thirdparty/assimp/code/Common/ScenePrivate.h
diff --git a/thirdparty/assimp/code/SkeletonMeshBuilder.cpp b/thirdparty/assimp/code/Common/SkeletonMeshBuilder.cpp
index 06cfe034e9..06cfe034e9 100644
--- a/thirdparty/assimp/code/SkeletonMeshBuilder.cpp
+++ b/thirdparty/assimp/code/Common/SkeletonMeshBuilder.cpp
diff --git a/thirdparty/assimp/code/SpatialSort.cpp b/thirdparty/assimp/code/Common/SpatialSort.cpp
index a4f3a4e4b8..a4f3a4e4b8 100644
--- a/thirdparty/assimp/code/SpatialSort.cpp
+++ b/thirdparty/assimp/code/Common/SpatialSort.cpp
diff --git a/thirdparty/assimp/code/SplitByBoneCountProcess.cpp b/thirdparty/assimp/code/Common/SplitByBoneCountProcess.cpp
index 2ef66a9afc..2ef66a9afc 100644
--- a/thirdparty/assimp/code/SplitByBoneCountProcess.cpp
+++ b/thirdparty/assimp/code/Common/SplitByBoneCountProcess.cpp
diff --git a/thirdparty/assimp/code/SplitByBoneCountProcess.h b/thirdparty/assimp/code/Common/SplitByBoneCountProcess.h
index 6c904a9df4..6c904a9df4 100644
--- a/thirdparty/assimp/code/SplitByBoneCountProcess.h
+++ b/thirdparty/assimp/code/Common/SplitByBoneCountProcess.h
diff --git a/thirdparty/assimp/code/StandardShapes.cpp b/thirdparty/assimp/code/Common/StandardShapes.cpp
index 2e5100130f..2e5100130f 100644
--- a/thirdparty/assimp/code/StandardShapes.cpp
+++ b/thirdparty/assimp/code/Common/StandardShapes.cpp
diff --git a/thirdparty/assimp/code/StdOStreamLogStream.h b/thirdparty/assimp/code/Common/StdOStreamLogStream.h
index 893e261a2b..893e261a2b 100644
--- a/thirdparty/assimp/code/StdOStreamLogStream.h
+++ b/thirdparty/assimp/code/Common/StdOStreamLogStream.h
diff --git a/thirdparty/assimp/code/Subdivision.cpp b/thirdparty/assimp/code/Common/Subdivision.cpp
index 19db223a55..60c54939f5 100644
--- a/thirdparty/assimp/code/Subdivision.cpp
+++ b/thirdparty/assimp/code/Common/Subdivision.cpp
@@ -43,9 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Subdivision.h>
#include <assimp/SceneCombiner.h>
#include <assimp/SpatialSort.h>
-#include "ProcessHelper.h"
#include <assimp/Vertex.h>
#include <assimp/ai_assert.h>
+
+#include "PostProcessing/ProcessHelper.h"
+
#include <stdio.h>
using namespace Assimp;
@@ -56,8 +58,7 @@ void mydummy() {}
* implementation is basing on recursive refinement. Directly evaluating the result is also
* possible and much quicker, but it depends on lengthy matrix lookup tables. */
// ------------------------------------------------------------------------------------------------
-class CatmullClarkSubdivider : public Subdivider
-{
+class CatmullClarkSubdivider : public Subdivider {
public:
void Subdivide (aiMesh* mesh, aiMesh*& out, unsigned int num, bool discard_input);
void Subdivide (aiMesh** smesh, size_t nmesh,
diff --git a/thirdparty/assimp/code/TargetAnimation.cpp b/thirdparty/assimp/code/Common/TargetAnimation.cpp
index b8062499ff..b8062499ff 100644
--- a/thirdparty/assimp/code/TargetAnimation.cpp
+++ b/thirdparty/assimp/code/Common/TargetAnimation.cpp
diff --git a/thirdparty/assimp/code/TargetAnimation.h b/thirdparty/assimp/code/Common/TargetAnimation.h
index 91634ab5aa..91634ab5aa 100644
--- a/thirdparty/assimp/code/TargetAnimation.h
+++ b/thirdparty/assimp/code/Common/TargetAnimation.h
diff --git a/thirdparty/assimp/code/Version.cpp b/thirdparty/assimp/code/Common/Version.cpp
index 0381037ff1..cc94340ac8 100644
--- a/thirdparty/assimp/code/Version.cpp
+++ b/thirdparty/assimp/code/Common/Version.cpp
@@ -134,7 +134,7 @@ ASSIMP_API aiScene::aiScene()
, mCameras(nullptr)
, mMetaData(nullptr)
, mPrivate(new Assimp::ScenePrivateData()) {
- // empty
+ // empty
}
// ------------------------------------------------------------------------------------------------
diff --git a/thirdparty/assimp/code/VertexTriangleAdjacency.cpp b/thirdparty/assimp/code/Common/VertexTriangleAdjacency.cpp
index 7cfd1a3505..7cfd1a3505 100644
--- a/thirdparty/assimp/code/VertexTriangleAdjacency.cpp
+++ b/thirdparty/assimp/code/Common/VertexTriangleAdjacency.cpp
diff --git a/thirdparty/assimp/code/VertexTriangleAdjacency.h b/thirdparty/assimp/code/Common/VertexTriangleAdjacency.h
index f3be47612d..f3be47612d 100644
--- a/thirdparty/assimp/code/VertexTriangleAdjacency.h
+++ b/thirdparty/assimp/code/Common/VertexTriangleAdjacency.h
diff --git a/thirdparty/assimp/code/Win32DebugLogStream.h b/thirdparty/assimp/code/Common/Win32DebugLogStream.h
index a6063a261e..a6063a261e 100644
--- a/thirdparty/assimp/code/Win32DebugLogStream.h
+++ b/thirdparty/assimp/code/Common/Win32DebugLogStream.h
diff --git a/thirdparty/assimp/code/Common/assbin_chunks.h b/thirdparty/assimp/code/Common/assbin_chunks.h
new file mode 100644
index 0000000000..15e4af5e7d
--- /dev/null
+++ b/thirdparty/assimp/code/Common/assbin_chunks.h
@@ -0,0 +1,196 @@
+#ifndef INCLUDED_ASSBIN_CHUNKS_H
+#define INCLUDED_ASSBIN_CHUNKS_H
+
+#define ASSBIN_VERSION_MAJOR 1
+#define ASSBIN_VERSION_MINOR 0
+
+/**
+@page assfile .ASS File formats
+
+@section over Overview
+Assimp provides its own interchange format, which is intended to applications which need
+to serialize 3D-models and to reload them quickly. Assimp's file formats are designed to
+be read by Assimp itself. They encode additional information needed by Assimp to optimize
+its postprocessing pipeline. If you once apply specific steps to a scene, then save it
+and reread it from an ASS format using the same post processing settings, they won't
+be executed again.
+
+The format comes in two flavours: XML and binary - both of them hold a complete dump of
+the 'aiScene' data structure returned by the APIs. The focus for the binary format
+(<tt>.assbin</tt>) is fast loading. Optional deflate compression helps reduce file size. The XML
+flavour, <tt>.assxml</tt> or simply .xml, is just a plain-to-xml conversion of aiScene.
+
+ASSBIN is Assimp's binary interchange format. assimp_cmd (<tt>&lt;root&gt;/tools/assimp_cmd</tt>) is able to
+write it and the core library provides a loader for it.
+
+@section assxml XML File format
+
+The format is pretty much self-explanatory due to its similarity to the in-memory aiScene structure.
+With few exceptions, C structures are wrapped in XML elements.
+
+The DTD for ASSXML can be found in <tt>&lt;root&gt;/doc/AssXML_Scheme.xml</tt>. Or have look
+at the output files generated by assimp_cmd.
+
+@section assbin Binary file format
+
+The ASSBIN file format is composed of chunks to represent the hierarchical aiScene data structure.
+This makes the format extensible and allows backward-compatibility with future data structure
+versions. The <tt>&lt;root&gt;/code/assbin_chunks.h</tt> header contains some magic constants
+for use by stand-alone ASSBIN loaders. Also, Assimp's own file writer can be found
+in <tt>&lt;root&gt;/tools/assimp_cmd/WriteDumb.cpp</tt> (yes, the 'b' is no typo ...).
+
+@verbatim
+
+-------------------------------------------------------------------------------
+1. File structure:
+-------------------------------------------------------------------------------
+
+----------------------
+| Header (512 bytes) |
+----------------------
+| Variable chunks |
+----------------------
+
+-------------------------------------------------------------------------------
+2. Definitions:
+-------------------------------------------------------------------------------
+
+integer is four bytes wide, stored in little-endian byte order.
+short is two bytes wide, stored in little-endian byte order.
+byte is a single byte.
+string is an integer n followed by n UTF-8 characters, not terminated by zero
+float is an IEEE 754 single-precision floating-point value
+double is an IEEE 754 double-precision floating-point value
+t[n] is an array of n elements of type t
+
+-------------------------------------------------------------------------------
+2. Header:
+-------------------------------------------------------------------------------
+
+byte[44] Magic identification string for ASSBIN files.
+ 'ASSIMP.binary'
+
+integer Major version of the Assimp library which wrote the file
+integer Minor version of the Assimp library which wrote the file
+ match these against ASSBIN_VERSION_MAJOR and ASSBIN_VERSION_MINOR
+
+integer SVN revision of the Assimp library (intended for our internal
+ debugging - if you write Ass files from your own APPs, set this value to 0.
+integer Assimp compile flags
+
+short 0 for normal files, 1 for shortened dumps for regression tests
+ these should have the file extension assbin.regress
+
+short 1 if the data after the header is compressed with the DEFLATE algorithm,
+ 0 for uncompressed files.
+ For compressed files, the first integer after the header is
+ always the uncompressed data size
+
+byte[256] Zero-terminated source file name, UTF-8
+byte[128] Zero-terminated command line parameters passed to assimp_cmd, UTF-8
+
+byte[64] Reserved for future use
+---> Total length: 512 bytes
+
+-------------------------------------------------------------------------------
+3. Chunks:
+-------------------------------------------------------------------------------
+
+integer Magic chunk ID (ASSBIN_CHUNK_XXX)
+integer Chunk data length, in bytes
+ (unknown chunks are possible, a good reader skips over them)
+ (chunk-data-length does not include the first two integers)
+
+byte[n] chunk-data-length bytes of data, depending on the chunk type
+
+Chunks can contain nested chunks. Nested chunks are ALWAYS at the end of the chunk,
+their size is included in chunk-data-length.
+
+The chunk layout for all ASSIMP data structures is derived from their C declarations.
+The general 'rule' to get from Assimp headers to the serialized layout is:
+
+ 1. POD members (i.e. aiMesh::mPrimitiveTypes, aiMesh::mNumVertices),
+ in order of declaration.
+
+ 2. Array-members (aiMesh::mFaces, aiMesh::mVertices, aiBone::mWeights),
+ in order of declaration.
+
+ 2. Object array members (i.e aiMesh::mBones, aiScene::mMeshes) are stored in
+ subchunks directly following the data written in 1.) and 2.)
+
+
+ Of course, there are some exceptions to this general order:
+
+[[aiScene]]
+
+ - The root node holding the scene structure is naturally stored in
+ a ASSBIN_CHUNK_AINODE subchunk following 1.) and 2.) (which is
+ empty for aiScene).
+
+[[aiMesh]]
+
+ - mTextureCoords and mNumUVComponents are serialized as follows:
+
+ [number of used uv channels times]
+ integer mNumUVComponents[n]
+ float mTextureCoords[n][3]
+
+ -> more than AI_MAX_TEXCOORD_CHANNELS can be stored. This allows Assimp
+ builds with different settings for AI_MAX_TEXCOORD_CHANNELS to exchange
+ data.
+ -> the on-disk format always uses 3 floats to write UV coordinates.
+ If mNumUVComponents[0] is 1, the corresponding mTextureCoords array
+ consists of 3 floats.
+
+ - The array member block of aiMesh is prefixed with an integer that specifies
+ the kinds of vertex components actually present in the mesh. This is a
+ bitwise combination of the ASSBIN_MESH_HAS_xxx constants.
+
+[[aiFace]]
+
+ - mNumIndices is stored as short
+ - mIndices are written as short, if aiMesh::mNumVertices<65536
+
+[[aiNode]]
+
+ - mParent is omitted
+
+[[aiLight]]
+
+ - mAttenuationXXX not written if aiLight::mType == aiLightSource_DIRECTIONAL
+ - mAngleXXX not written if aiLight::mType != aiLightSource_SPOT
+
+[[aiMaterial]]
+
+ - mNumAllocated is omitted, for obvious reasons :-)
+
+
+ @endverbatim*/
+
+
+#define ASSBIN_HEADER_LENGTH 512
+
+// these are the magic chunk identifiers for the binary ASS file format
+#define ASSBIN_CHUNK_AICAMERA 0x1234
+#define ASSBIN_CHUNK_AILIGHT 0x1235
+#define ASSBIN_CHUNK_AITEXTURE 0x1236
+#define ASSBIN_CHUNK_AIMESH 0x1237
+#define ASSBIN_CHUNK_AINODEANIM 0x1238
+#define ASSBIN_CHUNK_AISCENE 0x1239
+#define ASSBIN_CHUNK_AIBONE 0x123a
+#define ASSBIN_CHUNK_AIANIMATION 0x123b
+#define ASSBIN_CHUNK_AINODE 0x123c
+#define ASSBIN_CHUNK_AIMATERIAL 0x123d
+#define ASSBIN_CHUNK_AIMATERIALPROPERTY 0x123e
+
+#define ASSBIN_MESH_HAS_POSITIONS 0x1
+#define ASSBIN_MESH_HAS_NORMALS 0x2
+#define ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS 0x4
+#define ASSBIN_MESH_HAS_TEXCOORD_BASE 0x100
+#define ASSBIN_MESH_HAS_COLOR_BASE 0x10000
+
+#define ASSBIN_MESH_HAS_TEXCOORD(n) (ASSBIN_MESH_HAS_TEXCOORD_BASE << n)
+#define ASSBIN_MESH_HAS_COLOR(n) (ASSBIN_MESH_HAS_COLOR_BASE << n)
+
+
+#endif // INCLUDED_ASSBIN_CHUNKS_H
diff --git a/thirdparty/assimp/code/scene.cpp b/thirdparty/assimp/code/Common/scene.cpp
index 2acb348d81..2acb348d81 100644
--- a/thirdparty/assimp/code/scene.cpp
+++ b/thirdparty/assimp/code/Common/scene.cpp
diff --git a/thirdparty/assimp/code/simd.cpp b/thirdparty/assimp/code/Common/simd.cpp
index 04615f408e..04615f408e 100644
--- a/thirdparty/assimp/code/simd.cpp
+++ b/thirdparty/assimp/code/Common/simd.cpp
diff --git a/thirdparty/assimp/code/simd.h b/thirdparty/assimp/code/Common/simd.h
index 3eecdd4581..3eecdd4581 100644
--- a/thirdparty/assimp/code/simd.h
+++ b/thirdparty/assimp/code/Common/simd.h
diff --git a/thirdparty/assimp/code/FBXAnimation.cpp b/thirdparty/assimp/code/FBX/FBXAnimation.cpp
index 874914431b..874914431b 100644
--- a/thirdparty/assimp/code/FBXAnimation.cpp
+++ b/thirdparty/assimp/code/FBX/FBXAnimation.cpp
diff --git a/thirdparty/assimp/code/FBXBinaryTokenizer.cpp b/thirdparty/assimp/code/FBX/FBXBinaryTokenizer.cpp
index 7138df4315..a4a2bc8e79 100644
--- a/thirdparty/assimp/code/FBXBinaryTokenizer.cpp
+++ b/thirdparty/assimp/code/FBX/FBXBinaryTokenizer.cpp
@@ -98,7 +98,7 @@ namespace FBX {
// return (flags & to_check) != 0;
//}
// ------------------------------------------------------------------------------------------------
-Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
+Token::Token(const char* sbegin, const char* send, TokenType type, size_t offset)
:
#ifdef DEBUG
contents(sbegin, static_cast<size_t>(send-sbegin)),
@@ -122,18 +122,18 @@ namespace {
// ------------------------------------------------------------------------------------------------
// signal tokenization error, this is always unrecoverable. Throws DeadlyImportError.
-AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset) AI_WONT_RETURN_SUFFIX;
-AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset)
+AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset) AI_WONT_RETURN_SUFFIX;
+AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset)
{
throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset));
}
// ------------------------------------------------------------------------------------------------
-uint32_t Offset(const char* begin, const char* cursor) {
+size_t Offset(const char* begin, const char* cursor) {
ai_assert(begin <= cursor);
- return static_cast<unsigned int>(cursor - begin);
+ return cursor - begin;
}
// ------------------------------------------------------------------------------------------------
@@ -424,7 +424,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
// ------------------------------------------------------------------------------------------------
// TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
-void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length)
+void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
{
ai_assert(input);
diff --git a/thirdparty/assimp/code/FBXCommon.h b/thirdparty/assimp/code/FBX/FBXCommon.h
index fcb20a5cad..e516449130 100644
--- a/thirdparty/assimp/code/FBXCommon.h
+++ b/thirdparty/assimp/code/FBX/FBXCommon.h
@@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
-
+namespace Assimp {
namespace FBX
{
const std::string NULL_RECORD = { // 13 null bytes
@@ -80,7 +80,7 @@ namespace FBX
TransformInheritance_MAX // end-of-enum sentinel
};
}
-
+}
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // AI_FBXCOMMON_H_INC
diff --git a/thirdparty/assimp/code/FBXCompileConfig.h b/thirdparty/assimp/code/FBX/FBXCompileConfig.h
index 3a3841fa5b..3a3841fa5b 100644
--- a/thirdparty/assimp/code/FBXCompileConfig.h
+++ b/thirdparty/assimp/code/FBX/FBXCompileConfig.h
diff --git a/thirdparty/assimp/code/FBXConverter.cpp b/thirdparty/assimp/code/FBX/FBXConverter.cpp
index 09ae06a64f..9f940d3226 100644
--- a/thirdparty/assimp/code/FBXConverter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXConverter.cpp
@@ -67,6 +67,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <iomanip>
+
namespace Assimp {
namespace FBX {
@@ -76,20 +77,21 @@ namespace Assimp {
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
- FBXConverter::FBXConverter(aiScene* out, const Document& doc)
- : defaultMaterialIndex()
- , lights()
- , cameras()
- , textures()
- , materials_converted()
- , textures_converted()
- , meshes_converted()
- , node_anim_chain_bits()
- , mNodeNameInstances()
- , mNodeNames()
- , anim_fps()
- , out(out)
- , doc(doc) {
+ FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit )
+ : defaultMaterialIndex()
+ , lights()
+ , cameras()
+ , textures()
+ , materials_converted()
+ , textures_converted()
+ , meshes_converted()
+ , node_anim_chain_bits()
+ , mNodeNames()
+ , anim_fps()
+ , out(out)
+ , doc(doc)
+ , mRemoveEmptyBones( removeEmptyBones )
+ , mCurrentUnit(FbxUnit::cm) {
// animations need to be converted first since this will
// populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated.
@@ -117,6 +119,7 @@ namespace Assimp {
ConvertGlobalSettings();
TransferDataToScene();
+ ConvertToUnitScale(unit);
// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
// to make sure the scene passes assimp's validation. FBX files
@@ -138,12 +141,46 @@ namespace Assimp {
void FBXConverter::ConvertRootNode() {
out->mRootNode = new aiNode();
- out->mRootNode->mName.Set("RootNode");
+ std::string unique_name;
+ GetUniqueName("RootNode", unique_name);
+ out->mRootNode->mName.Set(unique_name);
// root has ID 0
ConvertNodes(0L, *out->mRootNode);
}
+ static std::string getAncestorBaseName(const aiNode* node)
+ {
+ const char* nodeName = nullptr;
+ size_t length = 0;
+ while (node && (!nodeName || length == 0))
+ {
+ nodeName = node->mName.C_Str();
+ length = node->mName.length;
+ node = node->mParent;
+ }
+
+ if (!nodeName || length == 0)
+ {
+ return {};
+ }
+ // could be std::string_view if c++17 available
+ return std::string(nodeName, length);
+ }
+
+ // Make unique name
+ std::string FBXConverter::MakeUniqueNodeName(const Model* const model, const aiNode& parent)
+ {
+ std::string original_name = FixNodeName(model->Name());
+ if (original_name.empty())
+ {
+ original_name = getAncestorBaseName(&parent);
+ }
+ std::string unique_name;
+ GetUniqueName(original_name, unique_name);
+ return unique_name;
+ }
+
void FBXConverter::ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
@@ -175,35 +212,18 @@ namespace Assimp {
aiMatrix4x4 new_abs_transform = parent_transform;
+ std::string unique_name = MakeUniqueNodeName(model, parent);
+
// 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.
- GenerateTransformationNodeChain(*model, nodes_chain, post_nodes_chain);
+ const bool need_additional_node = GenerateTransformationNodeChain(*model, unique_name, nodes_chain, post_nodes_chain);
ai_assert(nodes_chain.size());
- std::string original_name = FixNodeName(model->Name());
-
- // check if any of the nodes in the chain has the name the fbx node
- // is supposed to have. If there is none, add another node to
- // preserve the name - people might have scripts etc. that rely
- // on specific node names.
- aiNode* name_carrier = NULL;
- for (aiNode* prenode : nodes_chain) {
- if (!strcmp(prenode->mName.C_Str(), original_name.c_str())) {
- name_carrier = prenode;
- break;
- }
- }
-
- if (!name_carrier) {
- std::string old_original_name = original_name;
- GetUniqueName(old_original_name, original_name);
- nodes_chain.push_back(new aiNode(original_name));
- }
- else {
- original_name = nodes_chain.back()->mName.C_Str();
+ if (need_additional_node) {
+ nodes_chain.push_back(new aiNode(unique_name));
}
//setup metadata on newest node
@@ -265,11 +285,11 @@ namespace Assimp {
ConvertNodes(model->ID(), *last_parent, new_abs_transform);
if (doc.Settings().readLights) {
- ConvertLights(*model, original_name);
+ ConvertLights(*model, unique_name);
}
if (doc.Settings().readCameras) {
- ConvertCameras(*model, original_name);
+ ConvertCameras(*model, unique_name);
}
nodes.push_back(nodes_chain.front());
@@ -387,6 +407,7 @@ namespace Assimp {
break;
default:
ai_assert(false);
+ break;
}
}
@@ -399,11 +420,6 @@ namespace Assimp {
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
- //cameras are defined along positive x direction
- /*out_camera->mPosition = cam.Position();
- out_camera->mLookAt = (cam.InterestPosition() - out_camera->mPosition).Normalize();
- out_camera->mUp = cam.UpVector();*/
-
out_camera->mPosition = aiVector3D(0.0f);
out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
@@ -421,21 +437,16 @@ namespace Assimp {
void FBXConverter::GetUniqueName(const std::string &name, std::string &uniqueName)
{
uniqueName = name;
- int i = 0;
- auto it = mNodeNameInstances.find(name); // duplicate node name instance count
- if (it != mNodeNameInstances.end())
+ auto it_pair = mNodeNames.insert({ name, 0 }); // duplicate node name instance count
+ unsigned int& i = it_pair.first->second;
+ while (!it_pair.second)
{
- i = it->second;
- while (mNodeNames.find(uniqueName) != mNodeNames.end())
- {
- i++;
- std::stringstream ext;
- ext << name << std::setfill('0') << std::setw(3) << i;
- uniqueName = ext.str();
- }
+ i++;
+ std::ostringstream ext;
+ ext << name << std::setfill('0') << std::setw(3) << i;
+ uniqueName = ext.str();
+ it_pair = mNodeNames.insert({ uniqueName, 0 });
}
- mNodeNameInstances[name] = i;
- mNodeNames.insert(uniqueName);
}
const char* FBXConverter::NameTransformationComp(TransformationComp comp) {
@@ -651,8 +662,7 @@ namespace Assimp {
if ((v - all_ones).SquareLength() > zero_epsilon) {
return true;
}
- }
- else if (ok) {
+ } else if (ok) {
if (v.SquareLength() > zero_epsilon) {
return true;
}
@@ -667,7 +677,7 @@ namespace Assimp {
return name + std::string(MAGIC_NODE_TAG) + "_" + NameTransformationComp(comp);
}
- void FBXConverter::GenerateTransformationNodeChain(const Model& model, std::vector<aiNode*>& output_nodes,
+ bool FBXConverter::GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<aiNode*>& output_nodes,
std::vector<aiNode*>& post_output_nodes) {
const PropertyTable& props = model.Props();
const Model::RotOrder rot = model.RotationOrder();
@@ -782,8 +792,6 @@ namespace Assimp {
// not be guaranteed.
ai_assert(NeedsComplexTransformationChain(model) == is_complex);
- std::string name = FixNodeName(model.Name());
-
// now, if we have more than just Translation, Scaling and Rotation,
// we need to generate a full node chain to accommodate for assimp's
// lack to express pivots and offsets.
@@ -825,20 +833,20 @@ namespace Assimp {
}
ai_assert(output_nodes.size());
- return;
+ return true;
}
// else, we can just multiply the matrices together
aiNode* nd = new aiNode();
output_nodes.push_back(nd);
- std::string uniqueName;
- GetUniqueName(name, uniqueName);
- nd->mName.Set(uniqueName);
+ // name passed to the method is already unique
+ nd->mName.Set(name);
for (const auto &transform : chain) {
nd->mTransformation = nd->mTransformation * transform;
}
+ return false;
}
void FBXConverter::SetupNodeMetadata(const Model& model, aiNode& nd)
@@ -977,7 +985,9 @@ namespace Assimp {
unsigned int epcount = 0;
for (unsigned i = 0; i < indices.size(); i++)
{
- if (indices[i] < 0) epcount++;
+ if (indices[i] < 0) {
+ epcount++;
+ }
}
unsigned int pcount = static_cast<unsigned int>( indices.size() );
unsigned int scount = out_mesh->mNumFaces = pcount - epcount;
@@ -1237,10 +1247,10 @@ namespace Assimp {
ai_assert(count_faces);
ai_assert(count_vertices);
- // mapping from output indices to DOM indexing, needed to resolve weights
+ // mapping from output indices to DOM indexing, needed to resolve weights or blendshapes
std::vector<unsigned int> reverseMapping;
-
- if (process_weights) {
+ std::map<unsigned int, unsigned int> translateIndexMap;
+ if (process_weights || mesh.GetBlendShapes().size() > 0) {
reverseMapping.resize(count_vertices);
}
@@ -1347,6 +1357,7 @@ namespace Assimp {
if (reverseMapping.size()) {
reverseMapping[cursor] = in_cursor;
+ translateIndexMap[in_cursor] = cursor;
}
out_mesh->mVertices[cursor] = vertices[in_cursor];
@@ -1378,6 +1389,50 @@ namespace Assimp {
ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping);
}
+ std::vector<aiAnimMesh*> animMeshes;
+ for (const BlendShape* blendShape : mesh.GetBlendShapes()) {
+ for (const BlendShapeChannel* blendShapeChannel : blendShape->BlendShapeChannels()) {
+ const std::vector<const ShapeGeometry*>& shapeGeometries = blendShapeChannel->GetShapeGeometries();
+ for (size_t i = 0; i < shapeGeometries.size(); i++) {
+ aiAnimMesh* animMesh = aiCreateAnimMesh(out_mesh);
+ const ShapeGeometry* shapeGeometry = shapeGeometries.at(i);
+ const std::vector<aiVector3D>& vertices = shapeGeometry->GetVertices();
+ const std::vector<aiVector3D>& normals = shapeGeometry->GetNormals();
+ const std::vector<unsigned int>& indices = shapeGeometry->GetIndices();
+ animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
+ for (size_t j = 0; j < indices.size(); j++) {
+ unsigned int index = indices.at(j);
+ aiVector3D vertex = vertices.at(j);
+ aiVector3D normal = normals.at(j);
+ unsigned int count = 0;
+ const unsigned int* outIndices = mesh.ToOutputVertexIndex(index, count);
+ for (unsigned int k = 0; k < count; k++) {
+ unsigned int outIndex = outIndices[k];
+ if (translateIndexMap.find(outIndex) == translateIndexMap.end())
+ continue;
+ unsigned int index = translateIndexMap[outIndex];
+ animMesh->mVertices[index] += vertex;
+ if (animMesh->mNormals != nullptr) {
+ animMesh->mNormals[index] += normal;
+ animMesh->mNormals[index].NormalizeSafe();
+ }
+ }
+ }
+ animMesh->mWeight = shapeGeometries.size() > 1 ? blendShapeChannel->DeformPercent() / 100.0f : 1.0f;
+ animMeshes.push_back(animMesh);
+ }
+ }
+ }
+
+ const size_t numAnimMeshes = animMeshes.size();
+ if (numAnimMeshes > 0) {
+ out_mesh->mNumAnimMeshes = static_cast<unsigned int>(numAnimMeshes);
+ out_mesh->mAnimMeshes = new aiAnimMesh*[numAnimMeshes];
+ for (size_t i = 0; i < numAnimMeshes; i++) {
+ out_mesh->mAnimMeshes[i] = animMeshes.at(i);
+ }
+ }
+
return static_cast<unsigned int>(meshes.size() - 1);
}
@@ -1407,7 +1462,7 @@ namespace Assimp {
const WeightIndexArray& indices = cluster->GetIndices();
- if (indices.empty()) {
+ if (indices.empty() && mRemoveEmptyBones ) {
continue;
}
@@ -1439,13 +1494,11 @@ namespace Assimp {
if (index_out_indices.back() == no_index_sentinel) {
index_out_indices.back() = out_indices.size();
-
}
if (no_mat_check) {
out_indices.push_back(out_idx[i]);
- }
- else {
+ } else {
// this extra lookup is in O(logn), so the entire algorithm becomes O(nlogn)
const std::vector<unsigned int>::iterator it = std::lower_bound(
outputVertStartIndices->begin(),
@@ -1461,11 +1514,11 @@ 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.
- if (ok) {
+ if (ok && mRemoveEmptyBones) {
ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
count_out_indices, node_global_transform);
}
@@ -1596,6 +1649,13 @@ namespace Assimp {
out_mat->AddProperty(&str, AI_MATKEY_NAME);
}
+ // Set the shading mode as best we can: The FBX specification only mentions Lambert and Phong, and only Phong is mentioned in Assimp's aiShadingMode enum.
+ if (material.GetShadingModel() == "phong")
+ {
+ aiShadingMode shadingMode = aiShadingMode_Phong;
+ out_mat->AddProperty<aiShadingMode>(&shadingMode, 1, AI_MATKEY_SHADING_MODEL);
+ }
+
// shading stuff and colors
SetShadingPropertiesCommon(out_mat, props);
SetShadingPropertiesRaw( out_mat, props, material.Textures(), mesh );
@@ -1621,7 +1681,7 @@ namespace Assimp {
out_tex->pcData = reinterpret_cast<aiTexel*>(const_cast<Video&>(video).RelinquishContent());
// try to extract a hint from the file extension
- const std::string& filename = video.FileName().empty() ? video.RelativeFilename() : video.FileName();
+ const std::string& filename = video.RelativeFilename().empty() ? video.FileName() : video.RelativeFilename();
std::string ext = BaseImporter::GetExtension(filename);
if (ext == "jpeg") {
@@ -1632,7 +1692,7 @@ namespace Assimp {
memcpy(out_tex->achFormatHint, ext.c_str(), ext.size());
}
- out_tex->mFilename.Set(video.FileName().c_str());
+ out_tex->mFilename.Set(filename.c_str());
return static_cast<unsigned int>(textures.size() - 1);
}
@@ -1678,9 +1738,8 @@ namespace Assimp {
}
void FBXConverter::TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures,
- const std::string& propName,
- aiTextureType target, const MeshGeometry* const mesh)
- {
+ const std::string& propName,
+ aiTextureType target, const MeshGeometry* const mesh) {
TextureMap::const_iterator it = textures.find(propName);
if (it == textures.end()) {
return;
@@ -3407,8 +3466,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
na->mScalingKeys = new aiVectorKey[keys.size()];
- if (keys.size() > 0)
+ if (keys.size() > 0) {
InterpolateKeys(na->mScalingKeys, keys, inputs, aiVector3D(1.0f, 1.0f, 1.0f), maxTime, minTime);
+ }
}
void FBXConverter::ConvertTranslationKeys(aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
@@ -3472,6 +3532,46 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
out->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
}
+ void FBXConverter::ConvertToUnitScale( FbxUnit unit ) {
+ if (mCurrentUnit == unit) {
+ return;
+ }
+
+ ai_real scale = 1.0;
+ if (mCurrentUnit == FbxUnit::cm) {
+ if (unit == FbxUnit::m) {
+ scale = (ai_real)0.01;
+ } else if (unit == FbxUnit::km) {
+ scale = (ai_real)0.00001;
+ }
+ } else if (mCurrentUnit == FbxUnit::m) {
+ if (unit == FbxUnit::cm) {
+ scale = (ai_real)100.0;
+ } else if (unit == FbxUnit::km) {
+ scale = (ai_real)0.001;
+ }
+ } else if (mCurrentUnit == FbxUnit::km) {
+ if (unit == FbxUnit::cm) {
+ scale = (ai_real)100000.0;
+ } else if (unit == FbxUnit::m) {
+ scale = (ai_real)1000.0;
+ }
+ }
+
+ for (auto mesh : meshes) {
+ if (nullptr == mesh) {
+ continue;
+ }
+
+ if (mesh->HasPositions()) {
+ for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
+ aiVector3D &pos = mesh->mVertices[i];
+ pos *= scale;
+ }
+ }
+ }
+ }
+
void FBXConverter::TransferDataToScene()
{
ai_assert(!out->mMeshes);
@@ -3525,9 +3625,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
}
// ------------------------------------------------------------------------------------------------
- void ConvertToAssimpScene(aiScene* out, const Document& doc)
+ void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit)
{
- FBXConverter converter(out, doc);
+ FBXConverter converter(out, doc, removeEmptyBones, unit);
}
} // !FBX
diff --git a/thirdparty/assimp/code/FBXConverter.h b/thirdparty/assimp/code/FBX/FBXConverter.h
index 50637468b9..17a7bc56b7 100644
--- a/thirdparty/assimp/code/FBXConverter.h
+++ b/thirdparty/assimp/code/FBX/FBXConverter.h
@@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXUtil.h"
#include "FBXProperties.h"
#include "FBXImporter.h"
+
#include <assimp/anim.h>
#include <assimp/material.h>
#include <assimp/light.h>
@@ -76,12 +77,22 @@ 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
- * @param doc Parsed FBX document
+ * @param doc Parsed FBX document
+ * @param removeEmptyBones Will remove bones, which do not have any references to vertices.
*/
-void ConvertToAssimpScene(aiScene* out, const Document& doc);
+void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit);
/** Dummy class to encapsulate the conversion process */
class FBXConverter {
@@ -112,7 +123,7 @@ public:
};
public:
- FBXConverter(aiScene* out, const Document& doc);
+ FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit);
~FBXConverter();
private:
@@ -145,6 +156,11 @@ private:
const char* NameTransformationComp(TransformationComp comp);
// ------------------------------------------------------------------------------------------------
+ // Returns an unique name for a node or traverses up a hierarchy until a non-empty name is found and
+ // then makes this name unique
+ std::string MakeUniqueNodeName(const Model* const model, const aiNode& parent);
+
+ // ------------------------------------------------------------------------------------------------
// note: this returns the REAL fbx property names
const char* NameTransformationCompProperty(TransformationComp comp);
@@ -167,7 +183,7 @@ private:
/**
* note: memory for output_nodes will be managed by the caller
*/
- void GenerateTransformationNodeChain(const Model& model, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes);
+ bool GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes);
// ------------------------------------------------------------------------------------------------
void SetupNodeMetadata(const Model& model, aiNode& nd);
@@ -415,6 +431,10 @@ private:
void ConvertGlobalSettings();
// ------------------------------------------------------------------------------------------------
+ // Will perform the conversion from a given unit to the requested unit.
+ void ConvertToUnitScale(FbxUnit unit);
+
+ // ------------------------------------------------------------------------------------------------
// copy generated meshes, animations, lights, cameras and textures to the output scene
void TransferDataToScene();
@@ -443,16 +463,17 @@ private:
NodeAnimBitMap node_anim_chain_bits;
// number of nodes with the same name
- using NodeAnimNameMap = std::unordered_map<std::string, unsigned int>;
- NodeAnimNameMap mNodeNameInstances;
-
- using NodeNameCache = std::unordered_set<std::string>;
+ using NodeNameCache = std::unordered_map<std::string, unsigned int>;
NodeNameCache mNodeNames;
double anim_fps;
aiScene* const out;
const FBX::Document& doc;
+
+ bool mRemoveEmptyBones;
+
+ FbxUnit mCurrentUnit;
};
}
diff --git a/thirdparty/assimp/code/FBXDeformer.cpp b/thirdparty/assimp/code/FBX/FBXDeformer.cpp
index 6927553450..6927553450 100644
--- a/thirdparty/assimp/code/FBXDeformer.cpp
+++ b/thirdparty/assimp/code/FBX/FBXDeformer.cpp
diff --git a/thirdparty/assimp/code/FBXDocument.cpp b/thirdparty/assimp/code/FBX/FBXDocument.cpp
index 1af08fe6d8..1af08fe6d8 100644
--- a/thirdparty/assimp/code/FBXDocument.cpp
+++ b/thirdparty/assimp/code/FBX/FBXDocument.cpp
diff --git a/thirdparty/assimp/code/FBXDocument.h b/thirdparty/assimp/code/FBX/FBXDocument.h
index c849defdcd..18e5c38f13 100644
--- a/thirdparty/assimp/code/FBXDocument.h
+++ b/thirdparty/assimp/code/FBX/FBXDocument.h
@@ -627,7 +627,7 @@ public:
return content;
}
- uint32_t ContentLength() const {
+ uint64_t ContentLength() const {
return contentLength;
}
@@ -643,7 +643,7 @@ private:
std::string fileName;
std::shared_ptr<const PropertyTable> props;
- uint32_t contentLength;
+ uint64_t contentLength;
uint8_t* content;
};
diff --git a/thirdparty/assimp/code/FBXDocumentUtil.cpp b/thirdparty/assimp/code/FBX/FBXDocumentUtil.cpp
index f84691479a..f84691479a 100644
--- a/thirdparty/assimp/code/FBXDocumentUtil.cpp
+++ b/thirdparty/assimp/code/FBX/FBXDocumentUtil.cpp
diff --git a/thirdparty/assimp/code/FBXDocumentUtil.h b/thirdparty/assimp/code/FBX/FBXDocumentUtil.h
index 2450109e59..2450109e59 100644
--- a/thirdparty/assimp/code/FBXDocumentUtil.h
+++ b/thirdparty/assimp/code/FBX/FBXDocumentUtil.h
diff --git a/thirdparty/assimp/code/FBXExportNode.cpp b/thirdparty/assimp/code/FBX/FBXExportNode.cpp
index e5215466a1..06c89cee46 100644
--- a/thirdparty/assimp/code/FBXExportNode.cpp
+++ b/thirdparty/assimp/code/FBX/FBXExportNode.cpp
@@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream> // ostringstream
#include <memory> // shared_ptr
+namespace Assimp {
// AddP70<type> helpers... there's no usable pattern here,
// so all are defined as separate functions.
// Even "animatable" properties are often completely different
@@ -252,7 +253,8 @@ void FBX::Node::DumpChildren(
} else {
std::ostringstream ss;
DumpChildrenAscii(ss, indent);
- s.PutString(ss.str());
+ if (ss.tellp() > 0)
+ s.PutString(ss.str());
}
}
@@ -266,7 +268,8 @@ void FBX::Node::End(
} else {
std::ostringstream ss;
EndAscii(ss, indent, has_children);
- s.PutString(ss.str());
+ if (ss.tellp() > 0)
+ s.PutString(ss.str());
}
}
@@ -367,7 +370,7 @@ void FBX::Node::EndBinary(
bool has_children
) {
// if there were children, add a null record
- if (has_children) { s.PutString(FBX::NULL_RECORD); }
+ if (has_children) { s.PutString(Assimp::FBX::NULL_RECORD); }
// now go back and write initial pos
this->end_pos = s.Tell();
@@ -563,6 +566,6 @@ void FBX::Node::WritePropertyNode(
FBX::Node::WritePropertyNodeAscii(name, v, s, indent);
}
}
-
+}
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/thirdparty/assimp/code/FBXExportNode.h b/thirdparty/assimp/code/FBX/FBXExportNode.h
index e1ebc36969..ef3bc781a4 100644
--- a/thirdparty/assimp/code/FBXExportNode.h
+++ b/thirdparty/assimp/code/FBX/FBXExportNode.h
@@ -54,16 +54,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
+namespace Assimp {
namespace FBX {
class Node;
}
-class FBX::Node
-{
-public: // public data members
+class FBX::Node {
+public:
// TODO: accessors
std::string name; // node name
- std::vector<FBX::Property> properties; // node properties
+ std::vector<FBX::FBXExportProperty> properties; // node properties
std::vector<FBX::Node> children; // child nodes
// some nodes always pretend they have children...
@@ -214,7 +214,7 @@ public: // static member functions
Assimp::StreamWriterLE& s,
bool binary, int indent
) {
- FBX::Property p(value);
+ FBX::FBXExportProperty p(value);
FBX::Node node(name, p);
node.Dump(s, binary, indent);
}
@@ -264,7 +264,7 @@ private: // static helper functions
);
};
-
+}
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
diff --git a/thirdparty/assimp/code/FBXExportProperty.cpp b/thirdparty/assimp/code/FBX/FBXExportProperty.cpp
index 9981d6b1c6..f8593e6295 100644
--- a/thirdparty/assimp/code/FBXExportProperty.cpp
+++ b/thirdparty/assimp/code/FBX/FBXExportProperty.cpp
@@ -52,187 +52,210 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <locale>
#include <sstream> // ostringstream
+namespace Assimp {
+namespace FBX {
// constructors for single element properties
-FBX::Property::Property(bool v)
- : type('C'), data(1)
-{
- data = {uint8_t(v)};
+FBXExportProperty::FBXExportProperty(bool v)
+: type('C')
+, data(1) {
+ data = {
+ uint8_t(v)
+ };
}
-FBX::Property::Property(int16_t v) : type('Y'), data(2)
-{
+FBXExportProperty::FBXExportProperty(int16_t v)
+: type('Y')
+, data(2) {
uint8_t* d = data.data();
(reinterpret_cast<int16_t*>(d))[0] = v;
}
-FBX::Property::Property(int32_t v) : type('I'), data(4)
-{
+FBXExportProperty::FBXExportProperty(int32_t v)
+: type('I')
+, data(4) {
uint8_t* d = data.data();
(reinterpret_cast<int32_t*>(d))[0] = v;
}
-FBX::Property::Property(float v) : type('F'), data(4)
-{
+FBXExportProperty::FBXExportProperty(float v)
+: type('F')
+, data(4) {
uint8_t* d = data.data();
(reinterpret_cast<float*>(d))[0] = v;
}
-FBX::Property::Property(double v) : type('D'), data(8)
-{
+FBXExportProperty::FBXExportProperty(double v)
+: type('D')
+, data(8) {
uint8_t* d = data.data();
(reinterpret_cast<double*>(d))[0] = v;
}
-FBX::Property::Property(int64_t v) : type('L'), data(8)
-{
+FBXExportProperty::FBXExportProperty(int64_t v)
+: type('L')
+, data(8) {
uint8_t* d = data.data();
(reinterpret_cast<int64_t*>(d))[0] = v;
}
-
// constructors for array-type properties
-FBX::Property::Property(const char* c, bool raw)
- : Property(std::string(c), raw)
-{}
+FBXExportProperty::FBXExportProperty(const char* c, bool raw)
+: FBXExportProperty(std::string(c), raw) {
+ // empty
+}
// strings can either be saved as "raw" (R) data, or "string" (S) data
-FBX::Property::Property(const std::string& s, bool raw)
- : type(raw ? 'R' : 'S'), data(s.size())
-{
+FBXExportProperty::FBXExportProperty(const std::string& s, bool raw)
+: type(raw ? 'R' : 'S')
+, data(s.size()) {
for (size_t i = 0; i < s.size(); ++i) {
data[i] = uint8_t(s[i]);
}
}
-FBX::Property::Property(const std::vector<uint8_t>& r)
- : type('R'), data(r)
-{}
+FBXExportProperty::FBXExportProperty(const std::vector<uint8_t>& r)
+: type('R')
+, data(r) {
+ // empty
+}
-FBX::Property::Property(const std::vector<int32_t>& va)
- : type('i'), data(4*va.size())
-{
+FBXExportProperty::FBXExportProperty(const std::vector<int32_t>& va)
+: type('i')
+, data(4 * va.size() ) {
int32_t* d = reinterpret_cast<int32_t*>(data.data());
- for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
+ for (size_t i = 0; i < va.size(); ++i) {
+ d[i] = va[i];
+ }
}
-FBX::Property::Property(const std::vector<int64_t>& va)
- : type('l'), data(8*va.size())
-{
+FBXExportProperty::FBXExportProperty(const std::vector<int64_t>& va)
+: type('l')
+, data(8 * va.size()) {
int64_t* d = reinterpret_cast<int64_t*>(data.data());
- for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
+ for (size_t i = 0; i < va.size(); ++i) {
+ d[i] = va[i];
+ }
}
-FBX::Property::Property(const std::vector<float>& va)
- : type('f'), data(4*va.size())
-{
+FBXExportProperty::FBXExportProperty(const std::vector<float>& va)
+: type('f')
+, data(4 * va.size()) {
float* d = reinterpret_cast<float*>(data.data());
- for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
+ for (size_t i = 0; i < va.size(); ++i) {
+ d[i] = va[i];
+ }
}
-FBX::Property::Property(const std::vector<double>& va)
- : type('d'), data(8*va.size())
-{
+FBXExportProperty::FBXExportProperty(const std::vector<double>& va)
+: type('d')
+, data(8 * va.size()) {
double* d = reinterpret_cast<double*>(data.data());
- for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
+ for (size_t i = 0; i < va.size(); ++i) {
+ d[i] = va[i];
+ }
}
-FBX::Property::Property(const aiMatrix4x4& vm)
- : type('d'), data(8*16)
-{
+FBXExportProperty::FBXExportProperty(const aiMatrix4x4& vm)
+: type('d')
+, data(8 * 16) {
double* d = reinterpret_cast<double*>(data.data());
for (unsigned int c = 0; c < 4; ++c) {
for (unsigned int r = 0; r < 4; ++r) {
- d[4*c+r] = vm[r][c];
+ d[4 * c + r] = vm[r][c];
}
}
}
// public member functions
-size_t FBX::Property::size()
-{
+size_t FBXExportProperty::size() {
switch (type) {
- case 'C': case 'Y': case 'I': case 'F': case 'D': case 'L':
- return data.size() + 1;
- case 'S': case 'R':
- return data.size() + 5;
- case 'i': case 'd':
- return data.size() + 13;
- default:
- throw DeadlyExportError("Requested size on property of unknown type");
+ case 'C':
+ case 'Y':
+ case 'I':
+ case 'F':
+ case 'D':
+ case 'L':
+ return data.size() + 1;
+ case 'S':
+ case 'R':
+ return data.size() + 5;
+ case 'i':
+ case 'd':
+ return data.size() + 13;
+ default:
+ throw DeadlyExportError("Requested size on property of unknown type");
}
}
-void FBX::Property::DumpBinary(Assimp::StreamWriterLE &s)
-{
+void FBXExportProperty::DumpBinary(Assimp::StreamWriterLE& s) {
s.PutU1(type);
uint8_t* d = data.data();
size_t N;
switch (type) {
- case 'C': s.PutU1(*(reinterpret_cast<uint8_t*>(d))); return;
- case 'Y': s.PutI2(*(reinterpret_cast<int16_t*>(d))); return;
- case 'I': s.PutI4(*(reinterpret_cast<int32_t*>(d))); return;
- case 'F': s.PutF4(*(reinterpret_cast<float*>(d))); return;
- case 'D': s.PutF8(*(reinterpret_cast<double*>(d))); return;
- case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(d))); return;
- case 'S':
- case 'R':
- s.PutU4(uint32_t(data.size()));
- for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); }
- return;
- case 'i':
- N = data.size() / 4;
- s.PutU4(uint32_t(N)); // number of elements
- s.PutU4(0); // no encoding (1 would be zip-compressed)
- // TODO: compress if large?
- s.PutU4(uint32_t(data.size())); // data size
- for (size_t i = 0; i < N; ++i) {
- s.PutI4((reinterpret_cast<int32_t*>(d))[i]);
- }
- return;
- case 'l':
- N = data.size() / 8;
- s.PutU4(uint32_t(N)); // number of elements
- s.PutU4(0); // no encoding (1 would be zip-compressed)
- // TODO: compress if large?
- s.PutU4(uint32_t(data.size())); // data size
- for (size_t i = 0; i < N; ++i) {
- s.PutI8((reinterpret_cast<int64_t*>(d))[i]);
- }
- return;
- case 'f':
- N = data.size() / 4;
- s.PutU4(uint32_t(N)); // number of elements
- s.PutU4(0); // no encoding (1 would be zip-compressed)
- // TODO: compress if large?
- s.PutU4(uint32_t(data.size())); // data size
- for (size_t i = 0; i < N; ++i) {
- s.PutF4((reinterpret_cast<float*>(d))[i]);
- }
- return;
- case 'd':
- N = data.size() / 8;
- s.PutU4(uint32_t(N)); // number of elements
- s.PutU4(0); // no encoding (1 would be zip-compressed)
- // TODO: compress if large?
- s.PutU4(uint32_t(data.size())); // data size
- for (size_t i = 0; i < N; ++i) {
- s.PutF8((reinterpret_cast<double*>(d))[i]);
- }
- return;
- default:
- std::ostringstream err;
- err << "Tried to dump property with invalid type '";
- err << type << "'!";
- throw DeadlyExportError(err.str());
+ case 'C': s.PutU1(*(reinterpret_cast<uint8_t*>(d))); return;
+ case 'Y': s.PutI2(*(reinterpret_cast<int16_t*>(d))); return;
+ case 'I': s.PutI4(*(reinterpret_cast<int32_t*>(d))); return;
+ case 'F': s.PutF4(*(reinterpret_cast<float*>(d))); return;
+ case 'D': s.PutF8(*(reinterpret_cast<double*>(d))); return;
+ case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(d))); return;
+ case 'S':
+ case 'R':
+ s.PutU4(uint32_t(data.size()));
+ for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); }
+ return;
+ case 'i':
+ N = data.size() / 4;
+ s.PutU4(uint32_t(N)); // number of elements
+ s.PutU4(0); // no encoding (1 would be zip-compressed)
+ // TODO: compress if large?
+ s.PutU4(uint32_t(data.size())); // data size
+ for (size_t i = 0; i < N; ++i) {
+ s.PutI4((reinterpret_cast<int32_t*>(d))[i]);
+ }
+ return;
+ case 'l':
+ N = data.size() / 8;
+ s.PutU4(uint32_t(N)); // number of elements
+ s.PutU4(0); // no encoding (1 would be zip-compressed)
+ // TODO: compress if large?
+ s.PutU4(uint32_t(data.size())); // data size
+ for (size_t i = 0; i < N; ++i) {
+ s.PutI8((reinterpret_cast<int64_t*>(d))[i]);
+ }
+ return;
+ case 'f':
+ N = data.size() / 4;
+ s.PutU4(uint32_t(N)); // number of elements
+ s.PutU4(0); // no encoding (1 would be zip-compressed)
+ // TODO: compress if large?
+ s.PutU4(uint32_t(data.size())); // data size
+ for (size_t i = 0; i < N; ++i) {
+ s.PutF4((reinterpret_cast<float*>(d))[i]);
+ }
+ return;
+ case 'd':
+ N = data.size() / 8;
+ s.PutU4(uint32_t(N)); // number of elements
+ s.PutU4(0); // no encoding (1 would be zip-compressed)
+ // TODO: compress if large?
+ s.PutU4(uint32_t(data.size())); // data size
+ for (size_t i = 0; i < N; ++i) {
+ s.PutF8((reinterpret_cast<double*>(d))[i]);
+ }
+ return;
+ default:
+ std::ostringstream err;
+ err << "Tried to dump property with invalid type '";
+ err << type << "'!";
+ throw DeadlyExportError(err.str());
}
}
-void FBX::Property::DumpAscii(Assimp::StreamWriterLE &outstream, int indent)
-{
+void FBXExportProperty::DumpAscii(Assimp::StreamWriterLE& outstream, int indent) {
std::ostringstream ss;
ss.imbue(std::locale::classic());
ss.precision(15); // this seems to match official FBX SDK exports
@@ -240,8 +263,7 @@ void FBX::Property::DumpAscii(Assimp::StreamWriterLE &outstream, int indent)
outstream.PutString(ss.str());
}
-void FBX::Property::DumpAscii(std::ostream& s, int indent)
-{
+void FBXExportProperty::DumpAscii(std::ostream& s, int indent) {
// no writing type... or anything. just shove it into the stream.
uint8_t* d = data.data();
size_t N;
@@ -360,5 +382,8 @@ void FBX::Property::DumpAscii(std::ostream& s, int indent)
}
}
+} // Namespace FBX
+} // Namespace Assimp
+
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/thirdparty/assimp/code/FBXExportProperty.h b/thirdparty/assimp/code/FBX/FBXExportProperty.h
index 9c9d37c362..d692fe6ee3 100644
--- a/thirdparty/assimp/code/FBXExportProperty.h
+++ b/thirdparty/assimp/code/FBX/FBXExportProperty.h
@@ -47,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
-
#include <assimp/types.h> // aiMatrix4x4
#include <assimp/StreamWriter.h> // StreamWriterLE
@@ -56,11 +55,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <ostream>
#include <type_traits> // is_void
+namespace Assimp {
namespace FBX {
- class Property;
-}
-/** FBX::Property
+/** @brief FBX::Property
*
* Holds a value of any of FBX's recognized types,
* each represented by a particular one-character code.
@@ -78,35 +76,34 @@ namespace FBX {
* S : string (array of 1-byte char)
* R : raw data (array of bytes)
*/
-class FBX::Property
-{
+class FBXExportProperty {
public:
// constructors for basic types.
// all explicit to avoid accidental typecasting
- explicit Property(bool v);
+ explicit FBXExportProperty(bool v);
// TODO: determine if there is actually a byte type,
// or if this always means <bool>. 'C' seems to imply <char>,
// so possibly the above was intended to represent both.
- explicit Property(int16_t v);
- explicit Property(int32_t v);
- explicit Property(float v);
- explicit Property(double v);
- explicit Property(int64_t v);
+ explicit FBXExportProperty(int16_t v);
+ explicit FBXExportProperty(int32_t v);
+ explicit FBXExportProperty(float v);
+ explicit FBXExportProperty(double v);
+ explicit FBXExportProperty(int64_t v);
// strings can either be stored as 'R' (raw) or 'S' (string) type
- explicit Property(const char* c, bool raw=false);
- explicit Property(const std::string& s, bool raw=false);
- explicit Property(const std::vector<uint8_t>& r);
- explicit Property(const std::vector<int32_t>& va);
- explicit Property(const std::vector<int64_t>& va);
- explicit Property(const std::vector<double>& va);
- explicit Property(const std::vector<float>& va);
- explicit Property(const aiMatrix4x4& vm);
+ explicit FBXExportProperty(const char* c, bool raw = false);
+ explicit FBXExportProperty(const std::string& s, bool raw = false);
+ explicit FBXExportProperty(const std::vector<uint8_t>& r);
+ explicit FBXExportProperty(const std::vector<int32_t>& va);
+ explicit FBXExportProperty(const std::vector<int64_t>& va);
+ explicit FBXExportProperty(const std::vector<double>& va);
+ explicit FBXExportProperty(const std::vector<float>& va);
+ explicit FBXExportProperty(const aiMatrix4x4& vm);
// this will catch any type not defined above,
// so that we don't accidentally convert something we don't want.
// for example (const char*) --> (bool)... seriously wtf C++
template <class T>
- explicit Property(T v) : type('X') {
+ explicit FBXExportProperty(T v) : type('X') {
static_assert(std::is_void<T>::value, "TRIED TO CREATE FBX PROPERTY WITH UNSUPPORTED TYPE, CHECK YOUR PROPERTY INSTANTIATION");
} // note: no line wrap so it appears verbatim on the compiler error
@@ -114,9 +111,9 @@ public:
size_t size();
// write this property node as binary data to the given stream
- void DumpBinary(Assimp::StreamWriterLE &s);
- void DumpAscii(Assimp::StreamWriterLE &s, int indent=0);
- void DumpAscii(std::ostream &s, int indent=0);
+ void DumpBinary(Assimp::StreamWriterLE& s);
+ void DumpAscii(Assimp::StreamWriterLE& s, int indent = 0);
+ void DumpAscii(std::ostream& s, int indent = 0);
// note: make sure the ostream is in classic "C" locale
private:
@@ -124,6 +121,9 @@ private:
std::vector<uint8_t> data;
};
+} // Namespace FBX
+} // Namespace Assimp
+
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // AI_FBXEXPORTPROPERTY_H_INC
diff --git a/thirdparty/assimp/code/FBXExporter.cpp b/thirdparty/assimp/code/FBX/FBXExporter.cpp
index acb1227144..153e676506 100644
--- a/thirdparty/assimp/code/FBXExporter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXExporter.cpp
@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXExportNode.h"
#include "FBXExportProperty.h"
#include "FBXCommon.h"
+#include "FBXUtil.h"
#include <assimp/version.h> // aiGetVersion
#include <assimp/IOSystem.hpp>
@@ -73,7 +74,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
const ai_real DEG = ai_real( 57.29577951308232087679815481 ); // degrees per radian
+using namespace Assimp;
+using namespace Assimp::FBX;
+
// some constants that we'll use for writing metadata
+namespace Assimp {
namespace FBX {
const std::string EXPORT_VERSION_STR = "7.4.0";
const uint32_t EXPORT_VERSION_INT = 7400; // 7.4 == 2014/2015
@@ -92,11 +97,6 @@ namespace FBX {
";------------------------------------------------------------------";
}
-using namespace Assimp;
-using namespace FBX;
-
-namespace Assimp {
-
// ---------------------------------------------------------------------
// Worker function for exporting a scene to binary FBX.
// Prototyped and registered in Exporter.cpp
@@ -121,6 +121,7 @@ namespace Assimp {
IOSystem* pIOSystem,
const aiScene* pScene,
const ExportProperties* pProperties
+
){
// initialize the exporter
FBXExporter exporter(pScene, pProperties);
@@ -1218,6 +1219,16 @@ void FBXExporter::WriteObjects ()
layer.AddChild(le);
layer.Dump(outstream, binary, indent);
+ for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr)
+ {
+ FBX::Node layerExtra("Layer", int32_t(1));
+ layerExtra.AddChild("Version", int32_t(100));
+ FBX::Node leExtra("LayerElement");
+ leExtra.AddChild("Type", "LayerElementUV");
+ leExtra.AddChild("TypedIndex", int32_t(lr));
+ layerExtra.AddChild(leExtra);
+ layerExtra.Dump(outstream, binary, indent);
+ }
// finish the node record
indent = 1;
n.End(outstream, binary, indent, true);
@@ -1393,10 +1404,6 @@ void FBXExporter::WriteObjects ()
// FbxVideo - stores images used by textures.
for (const auto &it : uid_by_image) {
- if (it.first.compare(0, 1, "*") == 0) {
- // TODO: embedded textures
- continue;
- }
FBX::Node n("Video");
const int64_t& uid = it.second;
const std::string name = ""; // TODO: ... name???
@@ -1406,7 +1413,33 @@ void FBXExporter::WriteObjects ()
// TODO: get full path... relative path... etc... ugh...
// for now just use the same path for everything,
// and hopefully one of them will work out.
- const std::string& path = it.first;
+ std::string path = it.first;
+ // try get embedded texture
+ const aiTexture* embedded_texture = mScene->GetEmbeddedTexture(it.first.c_str());
+ if (embedded_texture != nullptr) {
+ // change the path (use original filename, if available. If name is empty, concatenate texture index with file extension)
+ std::stringstream newPath;
+ if (embedded_texture->mFilename.length > 0) {
+ newPath << embedded_texture->mFilename.C_Str();
+ } else if (embedded_texture->achFormatHint[0]) {
+ int texture_index = std::stoi(path.substr(1, path.size() - 1));
+ newPath << texture_index << "." << embedded_texture->achFormatHint;
+ }
+ path = newPath.str();
+ // embed the texture
+ size_t texture_size = static_cast<size_t>(embedded_texture->mWidth * std::max(embedded_texture->mHeight, 1u));
+ if (binary) {
+ // embed texture as binary data
+ std::vector<uint8_t> tex_data;
+ tex_data.resize(texture_size);
+ memcpy(&tex_data[0], (char*)embedded_texture->pcData, texture_size);
+ n.AddChild("Content", tex_data);
+ } else {
+ // embed texture in base64 encoding
+ std::string encoded_texture = FBX::Util::EncodeBase64((char*)embedded_texture->pcData, texture_size);
+ n.AddChild("Content", encoded_texture);
+ }
+ }
p.AddP70("Path", "KString", "XRefUrl", "", path);
n.AddChild(p);
n.AddChild("UseMipMap", int32_t(0));
@@ -1419,17 +1452,17 @@ void FBXExporter::WriteObjects ()
// referenced by material_index/texture_type pairs.
std::map<std::pair<size_t,size_t>,int64_t> texture_uids;
const std::map<aiTextureType,std::string> prop_name_by_tt = {
- {aiTextureType_DIFFUSE, "DiffuseColor"},
- {aiTextureType_SPECULAR, "SpecularColor"},
- {aiTextureType_AMBIENT, "AmbientColor"},
- {aiTextureType_EMISSIVE, "EmissiveColor"},
- {aiTextureType_HEIGHT, "Bump"},
- {aiTextureType_NORMALS, "NormalMap"},
- {aiTextureType_SHININESS, "ShininessExponent"},
- {aiTextureType_OPACITY, "TransparentColor"},
+ {aiTextureType_DIFFUSE, "DiffuseColor"},
+ {aiTextureType_SPECULAR, "SpecularColor"},
+ {aiTextureType_AMBIENT, "AmbientColor"},
+ {aiTextureType_EMISSIVE, "EmissiveColor"},
+ {aiTextureType_HEIGHT, "Bump"},
+ {aiTextureType_NORMALS, "NormalMap"},
+ {aiTextureType_SHININESS, "ShininessExponent"},
+ {aiTextureType_OPACITY, "TransparentColor"},
{aiTextureType_DISPLACEMENT, "DisplacementColor"},
//{aiTextureType_LIGHTMAP, "???"},
- {aiTextureType_REFLECTION, "ReflectionColor"}
+ {aiTextureType_REFLECTION, "ReflectionColor"}
//{aiTextureType_UNKNOWN, ""}
};
for (size_t i = 0; i < mScene->mNumMaterials; ++i) {
@@ -1575,19 +1608,41 @@ void FBXExporter::WriteObjects ()
// one sticky point is that the number of vertices may not match,
// because assimp splits vertices by normal, uv, etc.
+ // functor for aiNode sorting
+ struct SortNodeByName
+ {
+ bool operator()(const aiNode *lhs, const aiNode *rhs) const
+ {
+ return strcmp(lhs->mName.C_Str(), rhs->mName.C_Str()) < 0;
+ }
+ };
+
// first we should mark the skeleton for each mesh.
// the skeleton must include not only the aiBones,
// but also all their parent nodes.
// anything that affects the position of any bone node must be included.
- std::vector<std::set<const aiNode*>> skeleton_by_mesh(mScene->mNumMeshes);
+ // Use SorNodeByName to make sure the exported result will be the same across all systems
+ // Otherwise the aiNodes of the skeleton would be sorted based on the pointer address, which isn't consistent
+ std::vector<std::set<const aiNode*, SortNodeByName>> skeleton_by_mesh(mScene->mNumMeshes);
// at the same time we can build a list of all the skeleton nodes,
// which will be used later to mark them as type "limbNode".
std::unordered_set<const aiNode*> limbnodes;
+
+ //actual bone nodes in fbx, without parenting-up
+ std::unordered_set<std::string> setAllBoneNamesInScene;
+ for(unsigned int m = 0; m < mScene->mNumMeshes; ++ m)
+ {
+ aiMesh* pMesh = mScene->mMeshes[m];
+ for(unsigned int b = 0; b < pMesh->mNumBones; ++ b)
+ setAllBoneNamesInScene.insert(pMesh->mBones[b]->mName.data);
+ }
+ aiMatrix4x4 mxTransIdentity;
+
// and a map of nodes by bone name, as finding them is annoying.
std::map<std::string,aiNode*> node_by_bone;
for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
const aiMesh* m = mScene->mMeshes[mi];
- std::set<const aiNode*> skeleton;
+ std::set<const aiNode*, SortNodeByName> skeleton;
for (size_t bi =0; bi < m->mNumBones; ++bi) {
const aiBone* b = m->mBones[bi];
const std::string name(b->mName.C_Str());
@@ -1626,6 +1681,11 @@ void FBXExporter::WriteObjects ()
if (node_name.find(MAGIC_NODE_TAG) != std::string::npos) {
continue;
}
+ //not a bone in scene && no effect in transform
+ if(setAllBoneNamesInScene.find(node_name)==setAllBoneNamesInScene.end()
+ && parent->mTransformation == mxTransIdentity) {
+ continue;
+ }
// otherwise check if this is the root of the skeleton
bool end = false;
// is the mesh part of this node?
@@ -1728,7 +1788,7 @@ void FBXExporter::WriteObjects ()
aiMatrix4x4 mesh_xform = get_world_transform(mesh_node, mScene);
// now make a subdeformer for each bone in the skeleton
- const std::set<const aiNode*> &skeleton = skeleton_by_mesh[mi];
+ const std::set<const aiNode*, SortNodeByName> skeleton= skeleton_by_mesh[mi];
for (const aiNode* bone_node : skeleton) {
// if there's a bone for this node, find it
const aiBone* b = nullptr;
@@ -1790,7 +1850,10 @@ void FBXExporter::WriteObjects ()
// this should be the same as the bone's mOffsetMatrix.
// if it's not the same, the skeleton isn't in the bind pose.
- const float epsilon = 1e-4f; // some error is to be expected
+ float epsilon = 1e-4f; // some error is to be expected
+ float epsilon_custom = mProperties->GetPropertyFloat("BINDPOSE_EPSILON", -1);
+ if(epsilon_custom > 0)
+ epsilon = epsilon_custom;
bool bone_xform_okay = true;
if (b && ! tr.Equal(b->mOffsetMatrix, epsilon)) {
not_in_bind_pose.insert(b);
@@ -2237,8 +2300,8 @@ void FBXExporter::WriteModelNode(
// not sure what these are for,
// but they seem to be omnipresent
- m.AddChild("Shading", Property(true));
- m.AddChild("Culling", Property("CullingOff"));
+ m.AddChild("Shading", FBXExportProperty(true));
+ m.AddChild("Culling", FBXExportProperty("CullingOff"));
m.Dump(outstream, binary, 1);
}
@@ -2351,7 +2414,7 @@ void FBXExporter::WriteModelNodes(
na.AddProperties(
node_attribute_uid, FBX::SEPARATOR + "NodeAttribute", "LimbNode"
);
- na.AddChild("TypeFlags", Property("Skeleton"));
+ na.AddChild("TypeFlags", FBXExportProperty("Skeleton"));
na.Dump(outstream, binary, 1);
// and connect them
connections.emplace_back("C", "OO", node_attribute_uid, node_uid);
diff --git a/thirdparty/assimp/code/FBXExporter.h b/thirdparty/assimp/code/FBX/FBXExporter.h
index 71fb55c57f..71fb55c57f 100644
--- a/thirdparty/assimp/code/FBXExporter.h
+++ b/thirdparty/assimp/code/FBX/FBXExporter.h
diff --git a/thirdparty/assimp/code/FBXImportSettings.h b/thirdparty/assimp/code/FBX/FBXImportSettings.h
index d5e1c20608..1a4c80f8b2 100644
--- a/thirdparty/assimp/code/FBXImportSettings.h
+++ b/thirdparty/assimp/code/FBX/FBXImportSettings.h
@@ -53,19 +53,22 @@ namespace FBX {
struct ImportSettings
{
ImportSettings()
- : strictMode(true)
- , readAllLayers(true)
- , readAllMaterials(false)
- , readMaterials(true)
- , readTextures(true)
- , readCameras(true)
- , readLights(true)
- , readAnimations(true)
- , readWeights(true)
- , preservePivots(true)
- , optimizeEmptyAnimationCurves(true)
- , useLegacyEmbeddedTextureNaming(false)
- {}
+ : strictMode(true)
+ , readAllLayers(true)
+ , readAllMaterials(false)
+ , readMaterials(true)
+ , readTextures(true)
+ , readCameras(true)
+ , readLights(true)
+ , readAnimations(true)
+ , readWeights(true)
+ , preservePivots(true)
+ , optimizeEmptyAnimationCurves(true)
+ , useLegacyEmbeddedTextureNaming(false)
+ , removeEmptyBones( true )
+ , convertToMeters( false ) {
+ // empty
+ }
/** enable strict mode:
@@ -141,8 +144,16 @@ struct ImportSettings
bool optimizeEmptyAnimationCurves;
/** use legacy naming for embedded textures eg: (*0, *1, *2)
- **/
+ */
bool useLegacyEmbeddedTextureNaming;
+
+ /** Empty bones shall be removed
+ */
+ bool removeEmptyBones;
+
+ /** Set to true to perform a conversion from cm to meter after the import
+ */
+ bool convertToMeters;
};
diff --git a/thirdparty/assimp/code/FBXImporter.cpp b/thirdparty/assimp/code/FBX/FBXImporter.cpp
index 2cc8bffc29..ec8bbd2b47 100644
--- a/thirdparty/assimp/code/FBXImporter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXImporter.cpp
@@ -140,6 +140,8 @@ void FBXImporter::SetupProperties(const Importer* pImp)
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);
}
// ------------------------------------------------------------------------------------------------
@@ -170,7 +172,7 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
bool is_binary = false;
if (!strncmp(begin,"Kaydara FBX Binary",18)) {
is_binary = true;
- TokenizeBinary(tokens,begin,static_cast<unsigned int>(contents.size()));
+ TokenizeBinary(tokens,begin,contents.size());
}
else {
Tokenize(tokens,begin);
@@ -183,8 +185,12 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// 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);
+ ConvertToAssimpScene(pScene,doc, settings.removeEmptyBones, unit);
std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
}
diff --git a/thirdparty/assimp/code/FBXImporter.h b/thirdparty/assimp/code/FBX/FBXImporter.h
index c365b2cddf..c365b2cddf 100644
--- a/thirdparty/assimp/code/FBXImporter.h
+++ b/thirdparty/assimp/code/FBX/FBXImporter.h
diff --git a/thirdparty/assimp/code/FBXMaterial.cpp b/thirdparty/assimp/code/FBX/FBXMaterial.cpp
index f16f134404..f43a8b84b0 100644
--- a/thirdparty/assimp/code/FBXMaterial.cpp
+++ b/thirdparty/assimp/code/FBX/FBXMaterial.cpp
@@ -316,7 +316,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0));
}
- if(Content) {
+ if(Content && !Content->Tokens().empty()) {
//this field is omitted when the embedded texture is already loaded, let's ignore if it's not found
try {
const Token& token = GetRequiredToken(*Content, 0);
@@ -326,16 +326,40 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
DOMError("embedded content is not surrounded by quotation marks", &element);
}
else {
- const char* encodedData = data + 1;
- size_t encodedDataLen = static_cast<size_t>(token.end() - token.begin());
- // search for last quotation mark
- while (encodedDataLen > 1 && encodedData[encodedDataLen] != '"')
- encodedDataLen--;
- if (encodedDataLen % 4 != 0) {
- DOMError("embedded content is invalid, needs to be in base64", &element);
+ size_t targetLength = 0;
+ auto numTokens = Content->Tokens().size();
+ // First time compute size (it could be large like 64Gb and it is good to allocate it once)
+ for (uint32_t tokenIdx = 0; tokenIdx < numTokens; ++tokenIdx)
+ {
+ const Token& dataToken = GetRequiredToken(*Content, tokenIdx);
+ size_t tokenLength = dataToken.end() - dataToken.begin() - 2; // ignore double quotes
+ const char* base64data = dataToken.begin() + 1;
+ const size_t outLength = Util::ComputeDecodedSizeBase64(base64data, tokenLength);
+ if (outLength == 0)
+ {
+ DOMError("Corrupted embedded content found", &element);
+ }
+ targetLength += outLength;
}
- else {
- contentLength = Util::DecodeBase64(encodedData, encodedDataLen, content);
+ if (targetLength == 0)
+ {
+ DOMError("Corrupted embedded content found", &element);
+ }
+ content = new uint8_t[targetLength];
+ contentLength = static_cast<uint64_t>(targetLength);
+ size_t dst_offset = 0;
+ for (uint32_t tokenIdx = 0; tokenIdx < numTokens; ++tokenIdx)
+ {
+ const Token& dataToken = GetRequiredToken(*Content, tokenIdx);
+ size_t tokenLength = dataToken.end() - dataToken.begin() - 2; // ignore double quotes
+ const char* base64data = dataToken.begin() + 1;
+ dst_offset += Util::DecodeBase64(base64data, tokenLength, content + dst_offset, targetLength - dst_offset);
+ }
+ if (targetLength != dst_offset)
+ {
+ delete[] content;
+ contentLength = 0;
+ DOMError("Corrupted embedded content found", &element);
}
}
}
diff --git a/thirdparty/assimp/code/FBXMeshGeometry.cpp b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp
index d75476b826..44a0264ca0 100644
--- a/thirdparty/assimp/code/FBXMeshGeometry.cpp
+++ b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp
@@ -568,15 +568,15 @@ void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D>& colors_out, cons
}
// ------------------------------------------------------------------------------------------------
-static const std::string TangentIndexToken = "TangentIndex";
-static const std::string TangentsIndexToken = "TangentsIndex";
+static const char *TangentIndexToken = "TangentIndex";
+static const char *TangentsIndexToken = "TangentsIndex";
void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source,
const std::string& MappingInformationType,
const std::string& ReferenceInformationType)
{
const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent";
- const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken.c_str() : TangentIndexToken.c_str();
+ const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken : TangentIndexToken;
ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
str,
strIdx,
@@ -630,10 +630,11 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
materials_out.clear();
}
- m_materials.assign(m_vertices.size(),materials_out[0]);
+ materials_out.resize(m_vertices.size());
+ std::fill(materials_out.begin(), materials_out.end(), materials_out.at(0));
}
else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
- m_materials.resize(face_count);
+ materials_out.resize(face_count);
if(materials_out.size() != face_count) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
diff --git a/thirdparty/assimp/code/FBXMeshGeometry.h b/thirdparty/assimp/code/FBX/FBXMeshGeometry.h
index d6d4512177..d6d4512177 100644
--- a/thirdparty/assimp/code/FBXMeshGeometry.h
+++ b/thirdparty/assimp/code/FBX/FBXMeshGeometry.h
diff --git a/thirdparty/assimp/code/FBXModel.cpp b/thirdparty/assimp/code/FBX/FBXModel.cpp
index 589af36ac7..589af36ac7 100644
--- a/thirdparty/assimp/code/FBXModel.cpp
+++ b/thirdparty/assimp/code/FBX/FBXModel.cpp
diff --git a/thirdparty/assimp/code/FBXNodeAttribute.cpp b/thirdparty/assimp/code/FBX/FBXNodeAttribute.cpp
index b72e5637ee..b72e5637ee 100644
--- a/thirdparty/assimp/code/FBXNodeAttribute.cpp
+++ b/thirdparty/assimp/code/FBX/FBXNodeAttribute.cpp
diff --git a/thirdparty/assimp/code/FBXParser.cpp b/thirdparty/assimp/code/FBX/FBXParser.cpp
index b255c47347..4a9346040d 100644
--- a/thirdparty/assimp/code/FBXParser.cpp
+++ b/thirdparty/assimp/code/FBX/FBXParser.cpp
@@ -117,7 +117,7 @@ namespace FBX {
Element::Element(const Token& key_token, Parser& parser)
: key_token(key_token)
{
- TokenPtr n = NULL;
+ TokenPtr n = nullptr;
do {
n = parser.AdvanceToNextToken();
if(!n) {
@@ -643,9 +643,9 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
if (type == 'd') {
const double* d = reinterpret_cast<const double*>(&buff[0]);
for (unsigned int i = 0; i < count3; ++i, d += 3) {
- out.push_back(aiVector3D(static_cast<float>(d[0]),
- static_cast<float>(d[1]),
- static_cast<float>(d[2])));
+ out.push_back(aiVector3D(static_cast<ai_real>(d[0]),
+ static_cast<ai_real>(d[1]),
+ static_cast<ai_real>(d[2])));
}
// for debugging
/*for ( size_t i = 0; i < out.size(); i++ ) {
@@ -963,7 +963,6 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
}
}
-
// ------------------------------------------------------------------------------------------------
// read an array of uints
void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
@@ -1280,7 +1279,6 @@ float ParseTokenAsFloat(const Token& t)
return i;
}
-
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsInt() with ParseError handling
int ParseTokenAsInt(const Token& t)
@@ -1293,8 +1291,6 @@ int ParseTokenAsInt(const Token& t)
return i;
}
-
-
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsInt64() with ParseError handling
int64_t ParseTokenAsInt64(const Token& t)
diff --git a/thirdparty/assimp/code/FBXParser.h b/thirdparty/assimp/code/FBX/FBXParser.h
index 7b0cf72039..7b0cf72039 100644
--- a/thirdparty/assimp/code/FBXParser.h
+++ b/thirdparty/assimp/code/FBX/FBXParser.h
diff --git a/thirdparty/assimp/code/FBXProperties.cpp b/thirdparty/assimp/code/FBX/FBXProperties.cpp
index 8d7036b6a9..8d7036b6a9 100644
--- a/thirdparty/assimp/code/FBXProperties.cpp
+++ b/thirdparty/assimp/code/FBX/FBXProperties.cpp
diff --git a/thirdparty/assimp/code/FBXProperties.h b/thirdparty/assimp/code/FBX/FBXProperties.h
index 58755542fc..58755542fc 100644
--- a/thirdparty/assimp/code/FBXProperties.h
+++ b/thirdparty/assimp/code/FBX/FBXProperties.h
diff --git a/thirdparty/assimp/code/FBXTokenizer.cpp b/thirdparty/assimp/code/FBX/FBXTokenizer.cpp
index 252cce3557..252cce3557 100644
--- a/thirdparty/assimp/code/FBXTokenizer.cpp
+++ b/thirdparty/assimp/code/FBX/FBXTokenizer.cpp
diff --git a/thirdparty/assimp/code/FBXTokenizer.h b/thirdparty/assimp/code/FBX/FBXTokenizer.h
index 2af29743f4..afa588a470 100644
--- a/thirdparty/assimp/code/FBXTokenizer.h
+++ b/thirdparty/assimp/code/FBX/FBXTokenizer.h
@@ -93,7 +93,7 @@ public:
Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column);
/** construct a binary token */
- Token(const char* sbegin, const char* send, TokenType type, unsigned int offset);
+ Token(const char* sbegin, const char* send, TokenType type, size_t offset);
~Token();
@@ -118,14 +118,14 @@ public:
return type;
}
- unsigned int Offset() const {
+ size_t Offset() const {
ai_assert(IsBinary());
return offset;
}
unsigned int Line() const {
ai_assert(!IsBinary());
- return line;
+ return static_cast<unsigned int>(line);
}
unsigned int Column() const {
@@ -147,8 +147,8 @@ private:
const TokenType type;
union {
- const unsigned int line;
- unsigned int offset;
+ size_t line;
+ size_t offset;
};
const unsigned int column;
};
@@ -178,7 +178,7 @@ void Tokenize(TokenList& output_tokens, const char* input);
* @param input_buffer Binary input buffer to be processed.
* @param length Length of input buffer, in bytes. There is no 0-terminal.
* @throw DeadlyImportError if something goes wrong */
-void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length);
+void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length);
} // ! FBX
diff --git a/thirdparty/assimp/code/FBXUtil.cpp b/thirdparty/assimp/code/FBX/FBXUtil.cpp
index fb483161b2..c10e057c8c 100644
--- a/thirdparty/assimp/code/FBXUtil.cpp
+++ b/thirdparty/assimp/code/FBX/FBXUtil.cpp
@@ -86,7 +86,7 @@ const char* TokenTypeString(TokenType t)
// ------------------------------------------------------------------------------------------------
-std::string AddOffset(const std::string& prefix, const std::string& text, unsigned int offset)
+std::string AddOffset(const std::string& prefix, const std::string& text, size_t offset)
{
return static_cast<std::string>( (Formatter::format() << prefix << " (offset 0x" << std::hex << offset << ") " << text) );
}
@@ -114,47 +114,126 @@ std::string AddTokenText(const std::string& prefix, const std::string& text, con
text) );
}
+// Generated by this formula: T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
static const uint8_t base64DecodeTable[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
- 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
- 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 255, 255, 255,
+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255
};
uint8_t DecodeBase64(char ch)
{
- return base64DecodeTable[size_t(ch)];
+ const auto idx = static_cast<uint8_t>(ch);
+ if (idx > 127)
+ return 255;
+ return base64DecodeTable[idx];
}
-size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
+size_t ComputeDecodedSizeBase64(const char* in, size_t inLength)
{
- if (inLength < 4) {
- out = 0;
+ if (inLength < 2)
+ {
+ return 0;
+ }
+ const size_t equals = size_t(in[inLength - 1] == '=') + size_t(in[inLength - 2] == '=');
+ const size_t full_length = (inLength * 3) >> 2; // div by 4
+ if (full_length < equals)
+ {
+ return 0;
+ }
+ return full_length - equals;
+}
+
+size_t DecodeBase64(const char* in, size_t inLength, uint8_t* out, size_t maxOutLength)
+{
+ if (maxOutLength == 0 || inLength < 2) {
return 0;
}
+ const size_t realLength = inLength - size_t(in[inLength - 1] == '=') - size_t(in[inLength - 2] == '=');
+ size_t dst_offset = 0;
+ int val = 0, valb = -8;
+ for (size_t src_offset = 0; src_offset < realLength; ++src_offset)
+ {
+ const uint8_t table_value = Util::DecodeBase64(in[src_offset]);
+ if (table_value == 255)
+ {
+ return 0;
+ }
+ val = (val << 6) + table_value;
+ valb += 6;
+ if (valb >= 0)
+ {
+ out[dst_offset++] = static_cast<uint8_t>((val >> valb) & 0xFF);
+ valb -= 8;
+ val &= 0xFFF;
+ }
+ }
+ return dst_offset;
+}
- const size_t outLength = (inLength * 3) / 4;
- out = new uint8_t[outLength];
- memset(out, 0, outLength);
+static const char to_base64_string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+char EncodeBase64(char byte)
+{
+ return to_base64_string[(size_t)byte];
+}
- size_t i = 0;
- size_t j = 0;
- for (i = 0; i < inLength - 4; i += 4)
+/** Encodes a block of 4 bytes to base64 encoding
+*
+* @param bytes Bytes to encode.
+* @param out_string String to write encoded values to.
+* @param string_pos Position in out_string.*/
+void EncodeByteBlock(const char* bytes, std::string& out_string, size_t string_pos)
+{
+ char b0 = (bytes[0] & 0xFC) >> 2;
+ char b1 = (bytes[0] & 0x03) << 4 | ((bytes[1] & 0xF0) >> 4);
+ char b2 = (bytes[1] & 0x0F) << 2 | ((bytes[2] & 0xC0) >> 6);
+ char b3 = (bytes[2] & 0x3F);
+
+ out_string[string_pos + 0] = EncodeBase64(b0);
+ out_string[string_pos + 1] = EncodeBase64(b1);
+ out_string[string_pos + 2] = EncodeBase64(b2);
+ out_string[string_pos + 3] = EncodeBase64(b3);
+}
+
+std::string EncodeBase64(const char* data, size_t length)
+{
+ // calculate extra bytes needed to get a multiple of 3
+ size_t extraBytes = 3 - length % 3;
+
+ // number of base64 bytes
+ size_t encodedBytes = 4 * (length + extraBytes) / 3;
+
+ std::string encoded_string(encodedBytes, '=');
+
+ // read blocks of 3 bytes
+ for (size_t ib3 = 0; ib3 < length / 3; ib3++)
{
- uint8_t b0 = Util::DecodeBase64(in[i]);
- uint8_t b1 = Util::DecodeBase64(in[i + 1]);
- uint8_t b2 = Util::DecodeBase64(in[i + 2]);
- uint8_t b3 = Util::DecodeBase64(in[i + 3]);
-
- out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
- out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
- out[j++] = (uint8_t)((b2 << 6) | b3);
+ const size_t iByte = ib3 * 3;
+ const size_t iEncodedByte = ib3 * 4;
+ const char* currData = &data[iByte];
+
+ EncodeByteBlock(currData, encoded_string, iEncodedByte);
+ }
+
+ // if size of data is not a multiple of 3, also encode the final bytes (and add zeros where needed)
+ if (extraBytes > 0)
+ {
+ char finalBytes[4] = { 0,0,0,0 };
+ memcpy(&finalBytes[0], &data[length - length % 3], length % 3);
+
+ const size_t iEncodedByte = encodedBytes - 4;
+ EncodeByteBlock(&finalBytes[0], encoded_string, iEncodedByte);
+
+ // add '=' at the end
+ for (size_t i = 0; i < 4 * extraBytes / 3; i++)
+ encoded_string[encodedBytes - i - 1] = '=';
}
- return outLength;
+ return encoded_string;
}
} // !Util
diff --git a/thirdparty/assimp/code/FBXUtil.h b/thirdparty/assimp/code/FBX/FBXUtil.h
index 6890e015ba..b634418858 100644
--- a/thirdparty/assimp/code/FBXUtil.h
+++ b/thirdparty/assimp/code/FBX/FBXUtil.h
@@ -78,7 +78,7 @@ const char* TokenTypeString(TokenType t);
* @param line Line index, 1-based
* @param column Column index, 1-based
* @return A string of the following format: {prefix} (offset 0x{offset}) {text}*/
-std::string AddOffset(const std::string& prefix, const std::string& text, unsigned int offset);
+std::string AddOffset(const std::string& prefix, const std::string& text, size_t offset);
/** Format log/error messages using a given line location in the source file.
@@ -105,13 +105,30 @@ std::string AddTokenText(const std::string& prefix, const std::string& text, con
* @return decoded byte value*/
uint8_t DecodeBase64(char ch);
+/** Compute decoded size of a Base64-encoded string
+*
+* @param in Characters to decode.
+* @param inLength Number of characters to decode.
+* @return size of the decoded data (number of bytes)*/
+size_t ComputeDecodedSizeBase64(const char* in, size_t inLength);
+
/** Decode a Base64-encoded string
*
* @param in Characters to decode.
* @param inLength Number of characters to decode.
-* @param out Reference to pointer where we will store the decoded data.
+* @param out Pointer where we will store the decoded data.
+* @param maxOutLength Size of output buffer.
* @return size of the decoded data (number of bytes)*/
-size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
+size_t DecodeBase64(const char* in, size_t inLength, uint8_t* out, size_t maxOutLength);
+
+char EncodeBase64(char byte);
+
+/** Encode bytes in base64-encoding
+*
+* @param data Binary data to encode.
+* @param inLength Number of bytes to encode.
+* @return base64-encoded string*/
+std::string EncodeBase64(const char* data, size_t length);
}
}
diff --git a/thirdparty/assimp/code/FIReader.cpp b/thirdparty/assimp/code/FIReader.cpp
deleted file mode 100644
index 2116316ca3..0000000000
--- a/thirdparty/assimp/code/FIReader.cpp
+++ /dev/null
@@ -1,1834 +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.
-
-----------------------------------------------------------------------
-*/
-/// \file FIReader.cpp
-/// \brief Reader for Fast Infoset encoded binary XML files.
-/// \date 2017
-/// \author Patrick Daehne
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "FIReader.hpp"
-#include <assimp/StringUtils.h>
-
-// Workaround for issue #1361
-// https://github.com/assimp/assimp/issues/1361
-#ifdef __ANDROID__
-# define _GLIBCXX_USE_C99 1
-#endif
-
-#include <assimp/Exceptional.h>
-#include <assimp/IOStream.hpp>
-#include <assimp/types.h>
-#include <assimp/MemoryIOWrapper.h>
-#include <assimp/irrXMLWrapper.h>
-#include "../contrib/utf8cpp/source/utf8.h"
-#include <assimp/fast_atof.h>
-#include <stack>
-#include <map>
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-
-namespace Assimp {
-
-static const std::string parseErrorMessage = "Fast Infoset parse error";
-
-static const char *xmlDeclarations[] = {
- "<?xml encoding='finf'?>",
- "<?xml encoding='finf' standalone='yes'?>",
- "<?xml encoding='finf' standalone='no'?>",
- "<?xml version='1.0' encoding='finf'?>",
- "<?xml version='1.0' encoding='finf' standalone='yes'?>",
- "<?xml version='1.0' encoding='finf' standalone='no'?>",
- "<?xml version='1.1' encoding='finf'?>",
- "<?xml version='1.1' encoding='finf' standalone='yes'?>",
- "<?xml version='1.1' encoding='finf' standalone='no'?>"
-};
-
-static size_t parseMagic(const uint8_t *data, const uint8_t *dataEnd) {
- if (dataEnd - data < 4) {
- return 0;
- }
- uint32_t magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- switch (magic) {
- case 0xe0000001:
- return 4;
- case 0x3c3f786d: // "<?xm"
- {
- size_t xmlDeclarationsLength = sizeof(xmlDeclarations) / sizeof(xmlDeclarations[0]);
- for (size_t i = 0; i < xmlDeclarationsLength; ++i) {
- auto xmlDeclaration = xmlDeclarations[i];
- ptrdiff_t xmlDeclarationLength = strlen(xmlDeclaration);
- if ((dataEnd - data >= xmlDeclarationLength) && (memcmp(xmlDeclaration, data, xmlDeclarationLength) == 0)) {
- data += xmlDeclarationLength;
- if (dataEnd - data < 4) {
- return 0;
- }
- magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- return magic == 0xe0000001 ? xmlDeclarationLength + 4 : 0;
- }
- }
- return 0;
- }
- default:
- return 0;
- }
-}
-
-static std::string parseUTF8String(const uint8_t *data, size_t len) {
- return std::string((char*)data, len);
-}
-
-static std::string parseUTF16String(const uint8_t *data, size_t len) {
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t numShorts = len / 2;
- std::vector<short> utf16;
- utf16.reserve(numShorts);
- for (size_t i = 0; i < numShorts; ++i) {
- short v = (data[0] << 8) | data[1];
- utf16.push_back(v);
- data += 2;
- }
- std::string result;
- utf8::utf16to8(utf16.begin(), utf16.end(), back_inserter(result));
- return result;
-}
-
-struct FIStringValueImpl: public FIStringValue {
- inline FIStringValueImpl(std::string &&value_) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ { return value; }
-};
-
-std::shared_ptr<FIStringValue> FIStringValue::create(std::string &&value) {
- return std::make_shared<FIStringValueImpl>(std::move(value));
-}
-
-struct FIHexValueImpl: public FIHexValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIHexValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::hex << std::uppercase << std::setfill('0');
- std::for_each(value.begin(), value.end(), [&](uint8_t c) { os << std::setw(2) << static_cast<int>(c); });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIHexValue> FIHexValue::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIHexValueImpl>(std::move(value));
-}
-
-struct FIBase64ValueImpl: public FIBase64Value {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIBase64ValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- uint8_t c1 = 0, c2;
- int imod3 = 0;
- std::vector<uint8_t>::size_type valueSize = value.size();
- for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
- c2 = value[i];
- switch (imod3) {
- case 0:
- os << basis_64[c2 >> 2];
- imod3 = 1;
- break;
- case 1:
- os << basis_64[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)];
- imod3 = 2;
- break;
- case 2:
- os << basis_64[((c1 & 0x0f) << 2) | ((c2 & 0xc0) >> 6)] << basis_64[c2 & 0x3f];
- imod3 = 0;
- break;
- }
- c1 = c2;
- }
- switch (imod3) {
- case 1:
- os << basis_64[(c1 & 0x03) << 4] << "==";
- break;
- case 2:
- os << basis_64[(c1 & 0x0f) << 2] << '=';
- break;
- }
- strValue = os.str();
- }
- return strValue;
- };
- static const char basis_64[];
-};
-
-const char FIBase64ValueImpl::basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-std::shared_ptr<FIBase64Value> FIBase64Value::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIBase64ValueImpl>(std::move(value));
-}
-
-struct FIShortValueImpl: public FIShortValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIShortValueImpl(std::vector<int16_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int16_t s) { if (++n > 1) os << ' '; os << s; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIShortValue> FIShortValue::create(std::vector<int16_t> &&value) {
- return std::make_shared<FIShortValueImpl>(std::move(value));
-}
-
-struct FIIntValueImpl: public FIIntValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIIntValueImpl(std::vector<int32_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int32_t i) { if (++n > 1) os << ' '; os << i; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIIntValue> FIIntValue::create(std::vector<int32_t> &&value) {
- return std::make_shared<FIIntValueImpl>(std::move(value));
-}
-
-struct FILongValueImpl: public FILongValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FILongValueImpl(std::vector<int64_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int64_t l) { if (++n > 1) os << ' '; os << l; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FILongValue> FILongValue::create(std::vector<int64_t> &&value) {
- return std::make_shared<FILongValueImpl>(std::move(value));
-}
-
-struct FIBoolValueImpl: public FIBoolValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIBoolValueImpl(std::vector<bool> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::boolalpha;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](bool b) { if (++n > 1) os << ' '; os << b; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIBoolValue> FIBoolValue::create(std::vector<bool> &&value) {
- return std::make_shared<FIBoolValueImpl>(std::move(value));
-}
-
-struct FIFloatValueImpl: public FIFloatValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIFloatValueImpl(std::vector<float> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](float f) { if (++n > 1) os << ' '; os << f; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIFloatValue> FIFloatValue::create(std::vector<float> &&value) {
- return std::make_shared<FIFloatValueImpl>(std::move(value));
-}
-
-struct FIDoubleValueImpl: public FIDoubleValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIDoubleValueImpl(std::vector<double> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](double d) { if (++n > 1) os << ' '; os << d; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIDoubleValue> FIDoubleValue::create(std::vector<double> &&value) {
- return std::make_shared<FIDoubleValueImpl>(std::move(value));
-}
-
-struct FIUUIDValueImpl: public FIUUIDValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIUUIDValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::hex << std::uppercase << std::setfill('0');
- std::vector<uint8_t>::size_type valueSize = value.size();
- for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
- switch (i & 15) {
- case 0:
- if (i > 0) {
- os << ' ';
- }
- os << std::setw(2) << static_cast<int>(value[i]);
- break;
- case 4:
- case 6:
- case 8:
- case 10:
- os << '-';
- // intentionally fall through!
- case 1:
- case 2:
- case 3:
- case 5:
- case 7:
- case 9:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- os << std::setw(2) << static_cast<int>(value[i]);
- break;
- }
- }
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIUUIDValue> FIUUIDValue::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIUUIDValueImpl>(std::move(value));
-}
-
-struct FICDATAValueImpl: public FICDATAValue {
- inline FICDATAValueImpl(std::string &&value_) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ { return value; }
-};
-
-std::shared_ptr<FICDATAValue> FICDATAValue::create(std::string &&value) {
- return std::make_shared<FICDATAValueImpl>(std::move(value));
-}
-
-struct FIHexDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FIHexValue::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FIBase64Decoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FIBase64Value::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FIShortDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int16_t> value;
- size_t numShorts = len / 2;
- value.reserve(numShorts);
- for (size_t i = 0; i < numShorts; ++i) {
- int16_t v = (data[0] << 8) | data[1];
- value.push_back(v);
- data += 2;
- }
- return FIShortValue::create(std::move(value));
- }
-};
-
-struct FIIntDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 3) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int32_t> value;
- size_t numInts = len / 4;
- value.reserve(numInts);
- for (size_t i = 0; i < numInts; ++i) {
- int32_t v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- value.push_back(v);
- data += 4;
- }
- return FIIntValue::create(std::move(value));
- }
-};
-
-struct FILongDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 7) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int64_t> value;
- size_t numLongs = len / 8;
- value.reserve(numLongs);
- for (size_t i = 0; i < numLongs; ++i) {
- int64_t b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
- int64_t v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
- value.push_back(v);
- data += 8;
- }
- return FILongValue::create(std::move(value));
- }
-};
-
-struct FIBoolDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<bool> value;
- uint8_t b = *data++;
- size_t unusedBits = b >> 4;
- size_t numBools = (len * 8) - 4 - unusedBits;
- value.reserve(numBools);
- uint8_t mask = 1 << 3;
- for (size_t i = 0; i < numBools; ++i) {
- if (!mask) {
- mask = 1 << 7;
- b = *data++;
- }
- value.push_back((b & mask) != 0);
- }
- return FIBoolValue::create(std::move(value));
- }
-};
-
-struct FIFloatDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 3) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<float> value;
- size_t numFloats = len / 4;
- value.reserve(numFloats);
- for (size_t i = 0; i < numFloats; ++i) {
- int v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- float f;
- memcpy(&f, &v, 4);
- value.push_back(f);
- data += 4;
- }
- return FIFloatValue::create(std::move(value));
- }
-};
-
-struct FIDoubleDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 7) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<double> value;
- size_t numDoubles = len / 8;
- value.reserve(numDoubles);
- for (size_t i = 0; i < numDoubles; ++i) {
- long long b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
- long long v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
- double f;
- memcpy(&f, &v, 8);
- value.push_back(f);
- data += 8;
- }
- return FIDoubleValue::create(std::move(value));
- }
-};
-
-struct FIUUIDDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 15) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return FIUUIDValue::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FICDATADecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FICDATAValue::create(parseUTF8String(data, len));
- }
-};
-
-class CFIReaderImpl: public FIReader {
-public:
-
- CFIReaderImpl(std::unique_ptr<uint8_t[]> data_, size_t size):
- data(std::move(data_)), dataP(data.get()), dataEnd(data.get() + size), currentNodeType(irr::io::EXN_NONE),
- emptyElement(false), headerPending(true), terminatorPending(false)
- {}
-
- virtual ~CFIReaderImpl() {}
-
- virtual bool read() /*override*/ {
- if (headerPending) {
- headerPending = false;
- parseHeader();
- }
- if (terminatorPending) {
- terminatorPending = false;
- if (elementStack.empty()) {
- return false;
- }
- else {
- nodeName = elementStack.top();
- elementStack.pop();
- currentNodeType = nodeName.empty() ? irr::io::EXN_UNKNOWN : irr::io::EXN_ELEMENT_END;
- return true;
- }
- }
- if (dataP >= dataEnd) {
- return false;
- }
- uint8_t b = *dataP;
- if (b < 0x80) { // Element (C.2.11.2, C.3.7.2)
- // C.3
- parseElement();
- return true;
- }
- else if (b < 0xc0) { // Characters (C.3.7.5)
- // C.7
- auto chars = parseNonIdentifyingStringOrIndex3(vocabulary.charactersTable);
- nodeName = chars->toString();
- currentNodeType = irr::io::EXN_TEXT;
- return true;
- }
- else if (b < 0xe0) {
- if ((b & 0xfc) == 0xc4) { // DTD (C.2.11.5)
- // C.9
- ++dataP;
- if (b & 0x02) {
- /*const std::string &systemID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b & 0x01) {
- /*const std::string &publicID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- elementStack.push(EmptyString);
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- else if ((b & 0xfc) == 0xc8) { // Unexpanded entity reference (C.3.7.4)
- // C.6
- ++dataP;
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (b & 0x02) {
- /*const std::string &systemID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b & 0x01) {
- /*const std::string &publicID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- }
- else if (b < 0xf0) {
- if (b == 0xe1) { // Processing instruction (C.2.11.3, C.3.7.3)
- // C.5
- ++dataP;
- /*const std::string &target =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::shared_ptr<const FIValue> data =*/ parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- else if (b == 0xe2) { // Comment (C.2.11.4, C.3.7.6)
- // C.8
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::shared_ptr<const FIValue> comment = parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- nodeName = comment->toString();
- currentNodeType = irr::io::EXN_COMMENT;
- return true;
- }
- }
- else { // Terminator (C.2.12, C.3.8)
- ++dataP;
- if (b == 0xff) {
- terminatorPending = true;
- }
- if (elementStack.empty()) {
- return false;
- }
- else {
- nodeName = elementStack.top();
- elementStack.pop();
- currentNodeType = nodeName.empty() ? irr::io::EXN_UNKNOWN : irr::io::EXN_ELEMENT_END;
- return true;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- virtual irr::io::EXML_NODE getNodeType() const /*override*/ {
- return currentNodeType;
- }
-
- virtual int getAttributeCount() const /*override*/ {
- return static_cast<int>(attributes.size());
- }
-
- virtual const char* getAttributeName(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].name.c_str();
- }
-
- virtual const char* getAttributeValue(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].value->toString().c_str();
- }
-
- virtual const char* getAttributeValue(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return nullptr;
- }
- return attr->value->toString().c_str();
- }
-
- virtual const char* getAttributeValueSafe(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return EmptyString.c_str();
- }
- return attr->value->toString().c_str();
- }
-
- virtual int getAttributeValueAsInt(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return 0;
- }
- std::shared_ptr<const FIIntValue> intValue = std::dynamic_pointer_cast<const FIIntValue>(attr->value);
- if (intValue) {
- return intValue->value.size() == 1 ? intValue->value.front() : 0;
- }
- return atoi(attr->value->toString().c_str());
- }
-
- virtual int getAttributeValueAsInt(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return 0;
- }
- std::shared_ptr<const FIIntValue> intValue = std::dynamic_pointer_cast<const FIIntValue>(attributes[idx].value);
- if (intValue) {
- return intValue->value.size() == 1 ? intValue->value.front() : 0;
- }
- return atoi(attributes[idx].value->toString().c_str());
- }
-
- virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return 0;
- }
- std::shared_ptr<const FIFloatValue> floatValue = std::dynamic_pointer_cast<const FIFloatValue>(attr->value);
- if (floatValue) {
- return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
- }
-
- return fast_atof(attr->value->toString().c_str());
- }
-
- virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return 0;
- }
- std::shared_ptr<const FIFloatValue> floatValue = std::dynamic_pointer_cast<const FIFloatValue>(attributes[idx].value);
- if (floatValue) {
- return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
- }
- return fast_atof(attributes[idx].value->toString().c_str());
- }
-
- virtual const char* getNodeName() const /*override*/ {
- return nodeName.c_str();
- }
-
- virtual const char* getNodeData() const /*override*/ {
- return nodeName.c_str();
- }
-
- virtual bool isEmptyElement() const /*override*/ {
- return emptyElement;
- }
-
- virtual irr::io::ETEXT_FORMAT getSourceFormat() const /*override*/ {
- return irr::io::ETF_UTF8;
- }
-
- virtual irr::io::ETEXT_FORMAT getParserFormat() const /*override*/ {
- return irr::io::ETF_UTF8;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].value;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return nullptr;
- }
- return attr->value;
- }
-
- virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr<FIDecoder> decoder) /*override*/ {
- decoderMap[algorithmUri] = std::move(decoder);
- }
-
- virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) /*override*/ {
- vocabularyMap[vocabularyUri] = vocabulary;
- }
-
-private:
-
- struct QName {
- std::string prefix;
- std::string uri;
- std::string name;
- inline QName() {}
- inline QName(const FIQName &qname): prefix(qname.prefix ? qname.prefix : ""), uri(qname.uri ? qname.uri : ""), name(qname.name) {}
- };
-
- struct Attribute {
- QName qname;
- std::string name;
- std::shared_ptr<const FIValue> value;
- };
-
- struct Vocabulary {
- std::vector<std::string> restrictedAlphabetTable;
- std::vector<std::string> encodingAlgorithmTable;
- std::vector<std::string> prefixTable;
- std::vector<std::string> namespaceNameTable;
- std::vector<std::string> localNameTable;
- std::vector<std::string> otherNCNameTable;
- std::vector<std::string> otherURITable;
- std::vector<std::shared_ptr<const FIValue>> attributeValueTable;
- std::vector<std::shared_ptr<const FIValue>> charactersTable;
- std::vector<std::shared_ptr<const FIValue>> otherStringTable;
- std::vector<QName> elementNameTable;
- std::vector<QName> attributeNameTable;
- Vocabulary() {
- prefixTable.push_back("xml");
- namespaceNameTable.push_back("http://www.w3.org/XML/1998/namespace");
- }
- };
-
- const Attribute* getAttributeByName(const char* name) const {
- if (!name) {
- return 0;
- }
- std::string n = name;
- for (int i=0; i<(int)attributes.size(); ++i) {
- if (attributes[i].name == n) {
- return &attributes[i];
- }
- }
- return 0;
- }
-
- size_t parseInt2() { // C.25
- uint8_t b = *dataP++;
- if (!(b & 0x40)) { // x0...... (C.25.2)
- return b & 0x3f;
- }
- else if ((b & 0x60) == 0x40) { // x10..... ........ (C.25.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x1f) << 8) | *dataP++) + 0x40;
- }
- }
- else if ((b & 0x70) == 0x60) { // x110.... ........ ........ (C.25.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x0f) << 16) | (dataP[0] << 8) | dataP[1]) + 0x2040;
- dataP += 2;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseInt3() { // C.27
- uint8_t b = *dataP++;
- if (!(b & 0x20)) { // xx0..... (C.27.2)
- return b & 0x1f;
- }
- else if ((b & 0x38) == 0x20) { // xx100... ........ (C.27.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x07) << 8) | *dataP++) + 0x20;
- }
- }
- else if ((b & 0x38) == 0x28) { // xx101... ........ ........ (C.27.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x07) << 16) | (dataP[0] << 8) | dataP[1]) + 0x820;
- dataP += 2;
- return result;
- }
- }
- else if ((b & 0x3f) == 0x30) { // xx110000 0000.... ........ ........ (C.27.5)
- if ((dataEnd - dataP > 2) && !(dataP[0] & 0xf0)) {
- size_t result = (((dataP[0] & 0x0f) << 16) | (dataP[1] << 8) | dataP[2]) + 0x80820;
- dataP += 3;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseInt4() { // C.28
- uint8_t b = *dataP++;
- if (!(b & 0x10)) { // xxx0.... (C.28.2)
- return b & 0x0f;
- }
- else if ((b & 0x1c) == 0x10) { // xxx100.. ........ (C.28.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x03) << 8) | *dataP++) + 0x10;
- }
- }
- else if ((b & 0x1c) == 0x14) { // xxx101.. ........ ........ (C.28.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x03) << 16) | (dataP[0] << 8) | dataP[1]) + 0x410;
- dataP += 2;
- return result;
- }
- }
- else if ((b & 0x1f) == 0x18) { // xxx11000 0000.... ........ ........ (C.28.5)
- if ((dataEnd - dataP > 2) && !(dataP[0] & 0xf0)) {
- size_t result = (((dataP[0] & 0x0f) << 16) | (dataP[1] << 8) | dataP[2]) + 0x40410;
- dataP += 3;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseSequenceLen() { // C.21
- if (dataEnd - dataP > 0) {
- uint8_t b = *dataP++;
- if (b < 0x80) { // 0....... (C.21.2)
- return b;
- }
- else if ((b & 0xf0) == 0x80) { // 1000.... ........ ........ (C.21.3)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x0f) << 16) | (dataP[0] << 8) | dataP[1]) + 0x80;
- dataP += 2;
- return result;
- }
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- std::string parseNonEmptyOctetString2() { // C.22
- // Parse the length of the string
- uint8_t b = *dataP++ & 0x7f;
- size_t len;
- if (!(b & 0x40)) { // x0...... (C.22.3.1)
- len = b + 1;
- }
- else if (b == 0x40) { // x1000000 ........ (C.22.3.2)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- len = *dataP++ + 0x41;
- }
- else if (b == 0x60) { // x1100000 ........ ........ ........ ........ (C.22.3.3)
- if (dataEnd - dataP < 4) {
- throw DeadlyImportError(parseErrorMessage);
- }
- len = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x141;
- dataP += 4;
- }
- else {
- throw DeadlyImportError(parseErrorMessage);
- }
-
- // Parse the string (C.22.4)
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::string s = parseUTF8String(dataP, len);
- dataP += len;
-
- return s;
- }
-
- size_t parseNonEmptyOctetString5Length() { // C.23
- // Parse the length of the string
- size_t b = *dataP++ & 0x0f;
- if (!(b & 0x08)) { // xxxx0... (C.23.3.1)
- return b + 1;
- }
- else if (b == 0x08) { // xxxx1000 ........ (C.23.3.2)
- if (dataEnd - dataP > 0) {
- return *dataP++ + 0x09;
- }
- }
- else if (b == 0x0c) { // xxxx1100 ........ ........ ........ ........ (C.23.3.3)
- if (dataEnd - dataP > 3) {
- size_t result = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x109;
- dataP += 4;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseNonEmptyOctetString7Length() { // C.24
- // Parse the length of the string
- size_t b = *dataP++ & 0x03;
- if (!(b & 0x02)) { // xxxxxx0. (C.24.3.1)
- return b + 1;
- }
- else if (b == 0x02) { // xxxxxx10 ........ (C.24.3.2)
- if (dataEnd - dataP > 0) {
- return *dataP++ + 0x3;
- }
- }
- else if (b == 0x03) { // xxxxxx11 ........ ........ ........ ........ (C.24.3.3)
- if (dataEnd - dataP > 3) {
- size_t result = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x103;
- dataP += 4;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- std::shared_ptr<const FIValue> parseEncodedData(size_t index, size_t len) {
- if (index < 32) {
- FIDecoder *decoder = defaultDecoder[index];
- if (!decoder) {
- throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
- }
- return decoder->decode(dataP, len);
- }
- else {
- if (index - 32 >= vocabulary.encodingAlgorithmTable.size()) {
- throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
- }
- std::string uri = vocabulary.encodingAlgorithmTable[index - 32];
- auto it = decoderMap.find(uri);
- if (it == decoderMap.end()) {
- throw DeadlyImportError("Unsupported encoding algorithm " + uri);
- }
- else {
- return it->second->decode(dataP, len);
- }
- }
- }
-
- std::shared_ptr<const FIValue> parseRestrictedAlphabet(size_t index, size_t len) {
- std::string alphabet;
- if (index < 16) {
- switch (index) {
- case 0: // numeric
- alphabet = "0123456789-+.e ";
- break;
- case 1: // date and time
- alphabet = "0123456789-:TZ ";
- break;
- default:
- throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
- }
- }
- else {
- if (index - 16 >= vocabulary.restrictedAlphabetTable.size()) {
- throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
- }
- alphabet = vocabulary.restrictedAlphabetTable[index - 16];
- }
- std::vector<uint32_t> alphabetUTF32;
- utf8::utf8to32(alphabet.begin(), alphabet.end(), back_inserter(alphabetUTF32));
- std::string::size_type alphabetLength = alphabetUTF32.size();
- if (alphabetLength < 2) {
- throw DeadlyImportError("Invalid restricted alphabet length " + to_string(alphabetLength));
- }
- std::string::size_type bitsPerCharacter = 1;
- while ((1ull << bitsPerCharacter) <= alphabetLength) {
- ++bitsPerCharacter;
- }
- size_t bitsAvail = 0;
- uint8_t mask = (1 << bitsPerCharacter) - 1;
- uint32_t bits = 0;
- std::string s;
- for (size_t i = 0; i < len; ++i) {
- bits = (bits << 8) | dataP[i];
- bitsAvail += 8;
- while (bitsAvail >= bitsPerCharacter) {
- bitsAvail -= bitsPerCharacter;
- size_t charIndex = (bits >> bitsAvail) & mask;
- if (charIndex < alphabetLength) {
- s.push_back(alphabetUTF32[charIndex]);
- }
- else if (charIndex != mask) {
- throw DeadlyImportError(parseErrorMessage);
- }
- }
- }
- return FIStringValue::create(std::move(s));
- }
-
- std::shared_ptr<const FIValue> parseEncodedCharacterString3() { // C.19
- std::shared_ptr<const FIValue> result;
- size_t len;
- uint8_t b = *dataP;
- if (b & 0x20) {
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t index = ((b & 0x0f) << 4) | ((*dataP & 0xf0) >> 4); // C.29
- len = parseNonEmptyOctetString5Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x10) {
- // encoding algorithm (C.19.3.4)
- result = parseEncodedData(index, len);
- }
- else {
- // Restricted alphabet (C.19.3.3)
- result = parseRestrictedAlphabet(index, len);
- }
- }
- else {
- len = parseNonEmptyOctetString5Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x10) {
- // UTF-16 (C.19.3.2)
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result = FIStringValue::create(parseUTF16String(dataP, len));
- }
- else {
- // UTF-8 (C.19.3.1)
- result = FIStringValue::create(parseUTF8String(dataP, len));
- }
- }
- dataP += len;
- return result;
- }
-
- std::shared_ptr<const FIValue> parseEncodedCharacterString5() { // C.20
- std::shared_ptr<const FIValue> result;
- size_t len;
- uint8_t b = *dataP;
- if (b & 0x08) {
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t index = ((b & 0x03) << 6) | ((*dataP & 0xfc) >> 2); /* C.29 */
- len = parseNonEmptyOctetString7Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x04) {
- // encoding algorithm (C.20.3.4)
- result = parseEncodedData(index, len);
- }
- else {
- // Restricted alphabet (C.20.3.3)
- result = parseRestrictedAlphabet(index, len);
- }
- }
- else {
- len = parseNonEmptyOctetString7Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x04) {
- // UTF-16 (C.20.3.2)
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result = FIStringValue::create(parseUTF16String(dataP, len));
- }
- else {
- // UTF-8 (C.20.3.1)
- result = FIStringValue::create(parseUTF8String(dataP, len));
- }
- }
- dataP += len;
- return result;
- }
-
- const std::string &parseIdentifyingStringOrIndex(std::vector<std::string> &stringTable) { // C.13
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP;
- if (b & 0x80) {
- // We have an index (C.13.4)
- size_t index = parseInt2();
- if (index >= stringTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return stringTable[index];
- }
- else {
- // We have a string (C.13.3)
- stringTable.push_back(parseNonEmptyOctetString2());
- return stringTable.back();
- }
- }
-
- QName parseNameSurrogate() { // C.16
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP++;
- if (b & 0xfc) { // Padding '000000' C.2.5.5
- throw DeadlyImportError(parseErrorMessage);
- }
- QName result;
- size_t index;
- if (b & 0x02) { // prefix (C.16.3)
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.prefixTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.prefix = vocabulary.prefixTable[index];
- }
- if (b & 0x01) { // namespace-name (C.16.4)
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.namespaceNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.uri = vocabulary.namespaceNameTable[index];
- }
- // local-name
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.localNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.name = vocabulary.localNameTable[index];
- return result;
- }
-
- const QName &parseQualifiedNameOrIndex2(std::vector<QName> &qNameTable) { // C.17
- uint8_t b = *dataP;
- if ((b & 0x7c) == 0x78) { // x11110..
- // We have a literal (C.17.3)
- ++dataP;
- QName result;
- // prefix (C.17.3.1)
- result.prefix = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- // namespace-name (C.17.3.1)
- result.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- // local-name
- result.name = parseIdentifyingStringOrIndex(vocabulary.localNameTable);
- qNameTable.push_back(result);
- return qNameTable.back();
- }
- else {
- // We have an index (C.17.4)
- size_t index = parseInt2();
- if (index >= qNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return qNameTable[index];
- }
- }
-
- const QName &parseQualifiedNameOrIndex3(std::vector<QName> &qNameTable) { // C.18
- uint8_t b = *dataP;
- if ((b & 0x3c) == 0x3c) { // xx1111..
- // We have a literal (C.18.3)
- ++dataP;
- QName result;
- // prefix (C.18.3.1)
- result.prefix = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- // namespace-name (C.18.3.1)
- result.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- // local-name
- result.name = parseIdentifyingStringOrIndex(vocabulary.localNameTable);
- qNameTable.push_back(result);
- return qNameTable.back();
- }
- else {
- // We have an index (C.18.4)
- size_t index = parseInt3();
- if (index >= qNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return qNameTable[index];
- }
- }
-
- std::shared_ptr<const FIValue> parseNonIdentifyingStringOrIndex1(std::vector<std::shared_ptr<const FIValue>> &valueTable) { // C.14
- uint8_t b = *dataP;
- if (b == 0xff) { // C.26.2
- // empty string
- ++dataP;
- return EmptyFIString;
- }
- else if (b & 0x80) { // C.14.4
- // We have an index
- size_t index = parseInt2();
- if (index >= valueTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return valueTable[index];
- }
- else { // C.14.3
- // We have a literal
- std::shared_ptr<const FIValue> result = parseEncodedCharacterString3();
- if (b & 0x40) { // C.14.3.1
- valueTable.push_back(result);
- }
- return result;
- }
- }
-
- std::shared_ptr<const FIValue> parseNonIdentifyingStringOrIndex3(std::vector<std::shared_ptr<const FIValue>> &valueTable) { // C.15
- uint8_t b = *dataP;
- if (b & 0x20) { // C.15.4
- // We have an index
- size_t index = parseInt4();
- if (index >= valueTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return valueTable[index];
- }
- else { // C.15.3
- // We have a literal
- std::shared_ptr<const FIValue> result = parseEncodedCharacterString5();
- if (b & 0x10) { // C.15.3.1
- valueTable.push_back(result);
- }
- return result;
- }
- }
-
- void parseElement() {
- // C.3
-
- attributes.clear();
-
- uint8_t b = *dataP;
- bool hasAttributes = (b & 0x40) != 0; // C.3.3
- if ((b & 0x3f) == 0x38) { // C.3.4.1
- // Parse namespaces
- ++dataP;
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP++;
- if (b == 0xf0) { // C.3.4.3
- break;
- }
- if ((b & 0xfc) != 0xcc) { // C.3.4.2
- throw DeadlyImportError(parseErrorMessage);
- }
- // C.12
- Attribute attr;
- attr.qname.prefix = "xmlns";
- attr.qname.name = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- attr.qname.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- attr.name = attr.qname.name.empty() ? "xmlns" : "xmlns:" + attr.qname.name;
- attr.value = FIStringValue::create(std::string(attr.qname.uri));
- attributes.push_back(attr);
- }
- if ((dataEnd - dataP < 1) || (*dataP & 0xc0)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- }
-
- // Parse Element name (C.3.5)
- const QName &elemName = parseQualifiedNameOrIndex3(vocabulary.elementNameTable);
- nodeName = elemName.prefix.empty() ? elemName.name : elemName.prefix + ':' + elemName.name;
-
- if (hasAttributes) {
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP;
- if (b < 0x80) { // C.3.6.1
- // C.4
- Attribute attr;
- attr.qname = parseQualifiedNameOrIndex2(vocabulary.attributeNameTable);
- attr.name = attr.qname.prefix.empty() ? attr.qname.name : attr.qname.prefix + ':' + attr.qname.name;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- attr.value = parseNonIdentifyingStringOrIndex1(vocabulary.attributeValueTable);
- attributes.push_back(attr);
- }
- else {
- if ((b & 0xf0) != 0xf0) { // C.3.6.2
- throw DeadlyImportError(parseErrorMessage);
- }
- emptyElement = b == 0xff; // C.3.6.2, C.3.8
- ++dataP;
- break;
- }
- }
- }
- else {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP;
- switch (b) {
- case 0xff:
- terminatorPending = true;
- // Intentionally fall through
- case 0xf0:
- emptyElement = true;
- ++dataP;
- break;
- default:
- emptyElement = false;
- }
- }
- if (!emptyElement) {
- elementStack.push(nodeName);
- }
-
- currentNodeType = irr::io::EXN_ELEMENT;
- }
-
- void parseHeader() {
- // Parse header (C.1.3)
- size_t magicSize = parseMagic(dataP, dataEnd);
- if (!magicSize) {
- throw DeadlyImportError(parseErrorMessage);
- }
- dataP += magicSize;
- // C.2.3
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP++;
- if (b & 0x40) {
- // Parse additional data (C.2.4)
- size_t len = parseSequenceLen();
- for (size_t i = 0; i < len; ++i) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string id =*/ parseNonEmptyOctetString2();
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string data =*/ parseNonEmptyOctetString2();
- }
- }
- if (b & 0x20) {
- // Parse initial vocabulary (C.2.5)
- if (dataEnd - dataP < 2) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint16_t b1 = (dataP[0] << 8) | dataP[1];
- dataP += 2;
- if (b1 & 0x1000) {
- // External vocabulary (C.2.5.2)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::string uri = parseNonEmptyOctetString2();
- auto it = vocabularyMap.find(uri);
- if (it == vocabularyMap.end()) {
- throw DeadlyImportError("Unknown vocabulary " + uri);
- }
- const FIVocabulary *externalVocabulary = it->second;
- if (externalVocabulary->restrictedAlphabetTable) {
- std::copy(externalVocabulary->restrictedAlphabetTable, externalVocabulary->restrictedAlphabetTable + externalVocabulary->restrictedAlphabetTableSize, std::back_inserter(vocabulary.restrictedAlphabetTable));
- }
- if (externalVocabulary->encodingAlgorithmTable) {
- std::copy(externalVocabulary->encodingAlgorithmTable, externalVocabulary->encodingAlgorithmTable + externalVocabulary->encodingAlgorithmTableSize, std::back_inserter(vocabulary.encodingAlgorithmTable));
- }
- if (externalVocabulary->prefixTable) {
- std::copy(externalVocabulary->prefixTable, externalVocabulary->prefixTable + externalVocabulary->prefixTableSize, std::back_inserter(vocabulary.prefixTable));
- }
- if (externalVocabulary->namespaceNameTable) {
- std::copy(externalVocabulary->namespaceNameTable, externalVocabulary->namespaceNameTable + externalVocabulary->namespaceNameTableSize, std::back_inserter(vocabulary.namespaceNameTable));
- }
- if (externalVocabulary->localNameTable) {
- std::copy(externalVocabulary->localNameTable, externalVocabulary->localNameTable + externalVocabulary->localNameTableSize, std::back_inserter(vocabulary.localNameTable));
- }
- if (externalVocabulary->otherNCNameTable) {
- std::copy(externalVocabulary->otherNCNameTable, externalVocabulary->otherNCNameTable + externalVocabulary->otherNCNameTableSize, std::back_inserter(vocabulary.otherNCNameTable));
- }
- if (externalVocabulary->otherURITable) {
- std::copy(externalVocabulary->otherURITable, externalVocabulary->otherURITable + externalVocabulary->otherURITableSize, std::back_inserter(vocabulary.otherURITable));
- }
- if (externalVocabulary->attributeValueTable) {
- std::copy(externalVocabulary->attributeValueTable, externalVocabulary->attributeValueTable + externalVocabulary->attributeValueTableSize, std::back_inserter(vocabulary.attributeValueTable));
- }
- if (externalVocabulary->charactersTable) {
- std::copy(externalVocabulary->charactersTable, externalVocabulary->charactersTable + externalVocabulary->charactersTableSize, std::back_inserter(vocabulary.charactersTable));
- }
- if (externalVocabulary->otherStringTable) {
- std::copy(externalVocabulary->otherStringTable, externalVocabulary->otherStringTable + externalVocabulary->otherStringTableSize, std::back_inserter(vocabulary.otherStringTable));
- }
- if (externalVocabulary->elementNameTable) {
- std::copy(externalVocabulary->elementNameTable, externalVocabulary->elementNameTable + externalVocabulary->elementNameTableSize, std::back_inserter(vocabulary.elementNameTable));
- }
- if (externalVocabulary->attributeNameTable) {
- std::copy(externalVocabulary->attributeNameTable, externalVocabulary->attributeNameTable + externalVocabulary->attributeNameTableSize, std::back_inserter(vocabulary.attributeNameTable));
- }
- }
- if (b1 & 0x0800) {
- // Parse restricted alphabets (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.restrictedAlphabetTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0400) {
- // Parse encoding algorithms (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.encodingAlgorithmTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0200) {
- // Parse prefixes (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.prefixTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0100) {
- // Parse namespace names (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.namespaceNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0080) {
- // Parse local names (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.localNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0040) {
- // Parse other ncnames (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherNCNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0020) {
- // Parse other uris (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherURITable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0010) {
- // Parse attribute values (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.attributeValueTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0008) {
- // Parse content character chunks (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.charactersTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0004) {
- // Parse other strings (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherStringTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0002) {
- // Parse element name surrogates (C.2.5.5)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- vocabulary.elementNameTable.push_back(parseNameSurrogate());
- }
- }
- if (b1 & 0x0001) {
- // Parse attribute name surrogates (C.2.5.5)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- vocabulary.attributeNameTable.push_back(parseNameSurrogate());
- }
- }
- }
- if (b & 0x10) {
- // Parse notations (C.2.6)
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 == 0xf0) {
- break;
- }
- if ((b1 & 0xfc) != 0xc0) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /* C.11 */
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (b1 & 0x02) {
- /*const std::string &systemId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b1 & 0x01) {
- /*const std::string &publicId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- }
- }
- if (b & 0x08) {
- // Parse unparsed entities (C.2.7)
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 == 0xf0) {
- break;
- }
- if ((b1 & 0xfe) != 0xd0) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /* C.10 */
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- /*const std::string &systemId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- if (b1 & 0x01) {
- /*const std::string &publicId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- /*const std::string &notationName =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- }
- }
- if (b & 0x04) {
- // Parse character encoding scheme (C.2.8)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string characterEncodingScheme =*/ parseNonEmptyOctetString2();
- }
- if (b & 0x02) {
- // Parse standalone flag (C.2.9)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 & 0xfe) {
- throw DeadlyImportError(parseErrorMessage);
- }
- //bool standalone = b1 & 0x01;
- }
- if (b & 0x01) {
- // Parse version (C.2.10)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::shared_ptr<const FIValue> version =*/ parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- }
- }
-
- std::unique_ptr<uint8_t[]> data;
- uint8_t *dataP, *dataEnd;
- irr::io::EXML_NODE currentNodeType;
- bool emptyElement;
- bool headerPending;
- bool terminatorPending;
- Vocabulary vocabulary;
- std::vector<Attribute> attributes;
- std::stack<std::string> elementStack;
- std::string nodeName;
- std::map<std::string, std::unique_ptr<FIDecoder>> decoderMap;
- std::map<std::string, const FIVocabulary*> vocabularyMap;
-
- static const std::string EmptyString;
- static std::shared_ptr<const FIValue> EmptyFIString;
-
- static FIHexDecoder hexDecoder;
- static FIBase64Decoder base64Decoder;
- static FIShortDecoder shortDecoder;
- static FIIntDecoder intDecoder;
- static FILongDecoder longDecoder;
- static FIBoolDecoder boolDecoder;
- static FIFloatDecoder floatDecoder;
- static FIDoubleDecoder doubleDecoder;
- static FIUUIDDecoder uuidDecoder;
- static FICDATADecoder cdataDecoder;
- static FIDecoder *defaultDecoder[32];
-};
-
-const std::string CFIReaderImpl::EmptyString;
-std::shared_ptr<const FIValue> CFIReaderImpl::EmptyFIString = FIStringValue::create(std::string());
-
-FIHexDecoder CFIReaderImpl::hexDecoder;
-FIBase64Decoder CFIReaderImpl::base64Decoder;
-FIShortDecoder CFIReaderImpl::shortDecoder;
-FIIntDecoder CFIReaderImpl::intDecoder;
-FILongDecoder CFIReaderImpl::longDecoder;
-FIBoolDecoder CFIReaderImpl::boolDecoder;
-FIFloatDecoder CFIReaderImpl::floatDecoder;
-FIDoubleDecoder CFIReaderImpl::doubleDecoder;
-FIUUIDDecoder CFIReaderImpl::uuidDecoder;
-FICDATADecoder CFIReaderImpl::cdataDecoder;
-
-FIDecoder *CFIReaderImpl::defaultDecoder[32] = {
- &hexDecoder,
- &base64Decoder,
- &shortDecoder,
- &intDecoder,
- &longDecoder,
- &boolDecoder,
- &floatDecoder,
- &doubleDecoder,
- &uuidDecoder,
- &cdataDecoder
-};
-
-class CXMLReaderImpl : public FIReader
-{
-public:
-
- //! Constructor
- CXMLReaderImpl(std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>> reader_)
- : reader(std::move(reader_))
- {}
-
- virtual ~CXMLReaderImpl() {}
-
- virtual bool read() /*override*/ {
- return reader->read();
- }
-
- virtual irr::io::EXML_NODE getNodeType() const /*override*/ {
- return reader->getNodeType();
- }
-
- virtual int getAttributeCount() const /*override*/ {
- return reader->getAttributeCount();
- }
-
- virtual const char* getAttributeName(int idx) const /*override*/ {
- return reader->getAttributeName(idx);
- }
-
- virtual const char* getAttributeValue(int idx) const /*override*/ {
- return reader->getAttributeValue(idx);
- }
-
- virtual const char* getAttributeValue(const char* name) const /*override*/ {
- return reader->getAttributeValue(name);
- }
-
- virtual const char* getAttributeValueSafe(const char* name) const /*override*/ {
- return reader->getAttributeValueSafe(name);
- }
-
- virtual int getAttributeValueAsInt(const char* name) const /*override*/ {
- return reader->getAttributeValueAsInt(name);
- }
-
- virtual int getAttributeValueAsInt(int idx) const /*override*/ {
- return reader->getAttributeValueAsInt(idx);
- }
-
- virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
- return reader->getAttributeValueAsFloat(name);
- }
-
- virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
- return reader->getAttributeValueAsFloat(idx);
- }
-
- virtual const char* getNodeName() const /*override*/ {
- return reader->getNodeName();
- }
-
- virtual const char* getNodeData() const /*override*/ {
- return reader->getNodeData();
- }
-
- virtual bool isEmptyElement() const /*override*/ {
- return reader->isEmptyElement();
- }
-
- virtual irr::io::ETEXT_FORMAT getSourceFormat() const /*override*/ {
- return reader->getSourceFormat();
- }
-
- virtual irr::io::ETEXT_FORMAT getParserFormat() const /*override*/ {
- return reader->getParserFormat();
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int /*idx*/) const /*override*/ {
- return nullptr;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* /*name*/) const /*override*/ {
- return nullptr;
- }
-
- virtual void registerDecoder(const std::string & /*algorithmUri*/, std::unique_ptr<FIDecoder> /*decoder*/) /*override*/ {}
-
-
- virtual void registerVocabulary(const std::string &/*vocabularyUri*/, const FIVocabulary * /*vocabulary*/) /*override*/ {}
-
-private:
-
- std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>> reader;
-};
-
-static std::unique_ptr<uint8_t[]> readFile(IOStream *stream, size_t &size, bool &isFI) {
- size = stream->FileSize();
- std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(new uint8_t[size]);
- if (stream->Read(data.get(), size, 1) != 1) {
- size = 0;
- data.reset();
- }
- isFI = parseMagic(data.get(), data.get() + size) > 0;
- return data;
-}
-
-std::unique_ptr<FIReader> FIReader::create(IOStream *stream)
-{
- size_t size;
- bool isFI;
- auto data = readFile(stream, size, isFI);
- if (isFI) {
- return std::unique_ptr<FIReader>(new CFIReaderImpl(std::move(data), size));
- }
- else {
- auto memios = std::unique_ptr<MemoryIOStream>(new MemoryIOStream(data.release(), size, true));
- auto callback = std::unique_ptr<CIrrXML_IOStreamReader>(new CIrrXML_IOStreamReader(memios.get()));
- return std::unique_ptr<FIReader>(new CXMLReaderImpl(std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>>(createIrrXMLReader(callback.get()))));
- }
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/thirdparty/assimp/code/MMDCpp14.h b/thirdparty/assimp/code/MMD/MMDCpp14.h
index 638b0bfd2f..638b0bfd2f 100644
--- a/thirdparty/assimp/code/MMDCpp14.h
+++ b/thirdparty/assimp/code/MMD/MMDCpp14.h
diff --git a/thirdparty/assimp/code/MMDImporter.cpp b/thirdparty/assimp/code/MMD/MMDImporter.cpp
index 84b9e35a6b..e7744e4cd0 100644
--- a/thirdparty/assimp/code/MMDImporter.cpp
+++ b/thirdparty/assimp/code/MMD/MMDImporter.cpp
@@ -41,15 +41,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
-#include "MMDImporter.h"
-#include "MMDPmdParser.h"
-#include "MMDPmxParser.h"
-#include "MMDVmdParser.h"
-#include "ConvertToLHProcess.h"
+#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>
diff --git a/thirdparty/assimp/code/MMDImporter.h b/thirdparty/assimp/code/MMD/MMDImporter.h
index 4ee94eeb00..4ee94eeb00 100644
--- a/thirdparty/assimp/code/MMDImporter.h
+++ b/thirdparty/assimp/code/MMD/MMDImporter.h
diff --git a/thirdparty/assimp/code/MMDPmdParser.h b/thirdparty/assimp/code/MMD/MMDPmdParser.h
index d2f2224aa1..d2f2224aa1 100644
--- a/thirdparty/assimp/code/MMDPmdParser.h
+++ b/thirdparty/assimp/code/MMD/MMDPmdParser.h
diff --git a/thirdparty/assimp/code/MMDPmxParser.cpp b/thirdparty/assimp/code/MMD/MMDPmxParser.cpp
index 7425ceac22..80f0986dd7 100644
--- a/thirdparty/assimp/code/MMDPmxParser.cpp
+++ b/thirdparty/assimp/code/MMD/MMDPmxParser.cpp
@@ -42,7 +42,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <utility>
#include "MMDPmxParser.h"
#include <assimp/StringUtils.h>
-#include "../contrib/utf8cpp/source/utf8.h"
+#ifdef ASSIMP_USE_HUNTER
+# include <utf8/utf8.h>
+#else
+# include "../contrib/utf8cpp/source/utf8.h"
+#endif
#include <assimp/Exceptional.h>
namespace pmx
diff --git a/thirdparty/assimp/code/MMDPmxParser.h b/thirdparty/assimp/code/MMD/MMDPmxParser.h
index cf523a1298..cf523a1298 100644
--- a/thirdparty/assimp/code/MMDPmxParser.h
+++ b/thirdparty/assimp/code/MMD/MMDPmxParser.h
diff --git a/thirdparty/assimp/code/MMDVmdParser.h b/thirdparty/assimp/code/MMD/MMDVmdParser.h
index 947c3a2422..947c3a2422 100644
--- a/thirdparty/assimp/code/MMDVmdParser.h
+++ b/thirdparty/assimp/code/MMD/MMDVmdParser.h
diff --git a/thirdparty/assimp/code/MaterialSystem.cpp b/thirdparty/assimp/code/Material/MaterialSystem.cpp
index 03d5a18a34..d0b39093b6 100644
--- a/thirdparty/assimp/code/MaterialSystem.cpp
+++ b/thirdparty/assimp/code/Material/MaterialSystem.cpp
@@ -96,12 +96,12 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
ai_real* pOut,
unsigned int* pMax)
{
- ai_assert( pOut != NULL );
- ai_assert( pMat != NULL );
+ ai_assert( pOut != nullptr );
+ ai_assert( pMat != nullptr );
const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
- if (!prop) {
+ if ( nullptr == prop) {
return AI_FAILURE;
}
@@ -112,9 +112,11 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
if (pMax) {
iWrite = std::min(*pMax,iWrite); ;
}
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<ai_real> ( reinterpret_cast<float*>(prop->mData)[a] );
+
+ for (unsigned int a = 0; a < iWrite; ++a) {
+ pOut[ a ] = static_cast<ai_real> ( reinterpret_cast<float*>(prop->mData)[a] );
}
+
if (pMax) {
*pMax = iWrite;
}
diff --git a/thirdparty/assimp/code/MaterialSystem.h b/thirdparty/assimp/code/Material/MaterialSystem.h
index 67d53578cb..67d53578cb 100644
--- a/thirdparty/assimp/code/MaterialSystem.h
+++ b/thirdparty/assimp/code/Material/MaterialSystem.h
diff --git a/thirdparty/assimp/code/CalcTangentsProcess.cpp b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp
index b30f39c274..b30f39c274 100644
--- a/thirdparty/assimp/code/CalcTangentsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp
diff --git a/thirdparty/assimp/code/CalcTangentsProcess.h b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.h
index 18775abcc7..3568a624f8 100644
--- a/thirdparty/assimp/code/CalcTangentsProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.h
@@ -42,11 +42,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines a post processing step to calculate tangents and
- bitangents on all imported meshes.*/
+ bi-tangents on all imported meshes.*/
#ifndef AI_CALCTANGENTSPROCESS_H_INC
#define AI_CALCTANGENTSPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
struct aiMesh;
diff --git a/thirdparty/assimp/code/ComputeUVMappingProcess.cpp b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp
index bb571a551b..bb571a551b 100644
--- a/thirdparty/assimp/code/ComputeUVMappingProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp
diff --git a/thirdparty/assimp/code/ComputeUVMappingProcess.h b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.h
index 24f6bb7218..a6d36e06ea 100644
--- a/thirdparty/assimp/code/ComputeUVMappingProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.h
@@ -45,7 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_COMPUTEUVMAPPING_H_INC
#define AI_COMPUTEUVMAPPING_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
#include <assimp/material.h>
#include <assimp/types.h>
diff --git a/thirdparty/assimp/code/ConvertToLHProcess.cpp b/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.cpp
index b7cd4f0bc6..b7cd4f0bc6 100644
--- a/thirdparty/assimp/code/ConvertToLHProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.cpp
diff --git a/thirdparty/assimp/code/ConvertToLHProcess.h b/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.h
index 63351568d0..f32b91fc39 100644
--- a/thirdparty/assimp/code/ConvertToLHProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/ConvertToLHProcess.h
@@ -52,7 +52,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONVERTTOLHPROCESS_H_INC
#include <assimp/types.h>
-#include "BaseProcess.h"
+
+#include "Common/BaseProcess.h"
struct aiMesh;
struct aiNodeAnim;
diff --git a/thirdparty/assimp/code/DeboneProcess.cpp b/thirdparty/assimp/code/PostProcessing/DeboneProcess.cpp
index 83b8336bc9..83b8336bc9 100644
--- a/thirdparty/assimp/code/DeboneProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/DeboneProcess.cpp
diff --git a/thirdparty/assimp/code/DeboneProcess.h b/thirdparty/assimp/code/PostProcessing/DeboneProcess.h
index ba77aba70e..8b64c2acc6 100644
--- a/thirdparty/assimp/code/DeboneProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/DeboneProcess.h
@@ -44,17 +44,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_DEBONEPROCESS_H_INC
#define AI_DEBONEPROCESS_H_INC
-#include <vector>
-#include <utility>
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
#include <assimp/scene.h>
+#include <vector>
+#include <utility>
+
+#// Forward declarations
class DeboneTest;
-namespace Assimp
-{
+namespace Assimp {
#if (!defined AI_DEBONE_THRESHOLD)
# define AI_DEBONE_THRESHOLD 1.0f
@@ -66,14 +67,11 @@ namespace Assimp
* the bone are split from the mesh. The split off (new) mesh is boneless. At any
* point in time, bones without affect upon a given mesh are to be removed.
*/
-class DeboneProcess : public BaseProcess
-{
+class DeboneProcess : public BaseProcess {
public:
-
DeboneProcess();
~DeboneProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with.
@@ -91,7 +89,6 @@ public:
void SetupProperties(const Importer* pImp);
protected:
-
// -------------------------------------------------------------------
/** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail.
diff --git a/thirdparty/assimp/code/DropFaceNormalsProcess.cpp b/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.cpp
index b11615bb82..b11615bb82 100644
--- a/thirdparty/assimp/code/DropFaceNormalsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.cpp
diff --git a/thirdparty/assimp/code/DropFaceNormalsProcess.h b/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.h
index 0d116663b7..c710c5a5ee 100644
--- a/thirdparty/assimp/code/DropFaceNormalsProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/DropFaceNormalsProcess.h
@@ -44,23 +44,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_DROPFACENORMALPROCESS_H_INC
#define AI_DROPFACENORMALPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
-namespace Assimp
-{
+namespace Assimp {
// ---------------------------------------------------------------------------
/** The DropFaceNormalsProcess computes face normals for all faces of all meshes
*/
-class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess
-{
+class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess {
public:
-
DropFaceNormalsProcess();
~DropFaceNormalsProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise
diff --git a/thirdparty/assimp/code/EmbedTexturesProcess.cpp b/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.cpp
index 739382a057..739382a057 100644
--- a/thirdparty/assimp/code/EmbedTexturesProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.cpp
diff --git a/thirdparty/assimp/code/EmbedTexturesProcess.h b/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.h
index cdf40bef74..3c4b2eab4e 100644
--- a/thirdparty/assimp/code/EmbedTexturesProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/EmbedTexturesProcess.h
@@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <string>
diff --git a/thirdparty/assimp/code/FindDegenerates.cpp b/thirdparty/assimp/code/PostProcessing/FindDegenerates.cpp
index 365f5d7447..50fac46dba 100644
--- a/thirdparty/assimp/code/FindDegenerates.cpp
+++ b/thirdparty/assimp/code/PostProcessing/FindDegenerates.cpp
@@ -228,6 +228,7 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
if ( area < 1e-6 ) {
if ( mConfigRemoveDegenerates ) {
remove_me[ a ] = true;
+ ++deg;
goto evil_jump_outside;
}
diff --git a/thirdparty/assimp/code/FindDegenerates.h b/thirdparty/assimp/code/PostProcessing/FindDegenerates.h
index 880f5f16a2..7a15e77cf1 100644
--- a/thirdparty/assimp/code/FindDegenerates.h
+++ b/thirdparty/assimp/code/PostProcessing/FindDegenerates.h
@@ -45,7 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FINDDEGENERATESPROCESS_H_INC
#define AI_FINDDEGENERATESPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
class FindDegeneratesProcessTest;
diff --git a/thirdparty/assimp/code/FindInstancesProcess.cpp b/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.cpp
index be1138116e..64907458a1 100644
--- a/thirdparty/assimp/code/FindInstancesProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.cpp
@@ -137,6 +137,11 @@ void FindInstancesProcess::Execute( aiScene* pScene)
aiMesh* inst = pScene->mMeshes[i];
hashes[i] = GetMeshHash(inst);
+ // Find an appropriate epsilon
+ // to compare position differences against
+ float epsilon = ComputePositionEpsilon(inst);
+ epsilon *= epsilon;
+
for (int a = i-1; a >= 0; --a) {
if (hashes[i] == hashes[a])
{
@@ -154,12 +159,7 @@ void FindInstancesProcess::Execute( aiScene* pScene)
orig->mPrimitiveTypes != inst->mPrimitiveTypes)
continue;
- // up to now the meshes are equal. find an appropriate
- // epsilon to compare position differences against
- float epsilon = ComputePositionEpsilon(inst);
- epsilon *= epsilon;
-
- // now compare vertex positions, normals,
+ // up to now the meshes are equal. Now compare vertex positions, normals,
// tangents and bitangents using this epsilon.
if (orig->HasPositions()) {
if(!CompareArrays(orig->mVertices,inst->mVertices,orig->mNumVertices,epsilon))
diff --git a/thirdparty/assimp/code/FindInstancesProcess.h b/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.h
index ab4a371c71..64b838d7cc 100644
--- a/thirdparty/assimp/code/FindInstancesProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/FindInstancesProcess.h
@@ -46,8 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FINDINSTANCES_H_INC
#define AI_FINDINSTANCES_H_INC
-#include "BaseProcess.h"
-#include "ProcessHelper.h"
+#include "Common/BaseProcess.h"
+#include "PostProcessing/ProcessHelper.h"
class FindInstancesProcessTest;
namespace Assimp {
diff --git a/thirdparty/assimp/code/FindInvalidDataProcess.cpp b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp
index 433f042448..433f042448 100644
--- a/thirdparty/assimp/code/FindInvalidDataProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp
diff --git a/thirdparty/assimp/code/FindInvalidDataProcess.h b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.h
index 8504fb7b1f..ce7375f34f 100644
--- a/thirdparty/assimp/code/FindInvalidDataProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.h
@@ -46,7 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FINDINVALIDDATA_H_INC
#define AI_FINDINVALIDDATA_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/types.h>
#include <assimp/anim.h>
diff --git a/thirdparty/assimp/code/FixNormalsStep.cpp b/thirdparty/assimp/code/PostProcessing/FixNormalsStep.cpp
index bbbe6899b4..bbbe6899b4 100644
--- a/thirdparty/assimp/code/FixNormalsStep.cpp
+++ b/thirdparty/assimp/code/PostProcessing/FixNormalsStep.cpp
diff --git a/thirdparty/assimp/code/FixNormalsStep.h b/thirdparty/assimp/code/PostProcessing/FixNormalsStep.h
index 6be27faef6..f60ce596a4 100644
--- a/thirdparty/assimp/code/FixNormalsStep.h
+++ b/thirdparty/assimp/code/PostProcessing/FixNormalsStep.h
@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FIXNORMALSPROCESS_H_INC
#define AI_FIXNORMALSPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
struct aiMesh;
diff --git a/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp
new file mode 100644
index 0000000000..c013454fc3
--- /dev/null
+++ b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.cpp
@@ -0,0 +1,115 @@
+/*
+---------------------------------------------------------------------------
+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 ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS
+
+#include "PostProcessing/GenBoundingBoxesProcess.h"
+
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+
+namespace Assimp {
+
+GenBoundingBoxesProcess::GenBoundingBoxesProcess()
+: BaseProcess() {
+
+}
+
+GenBoundingBoxesProcess::~GenBoundingBoxesProcess() {
+ // empty
+}
+
+bool GenBoundingBoxesProcess::IsActive(unsigned int pFlags) const {
+ return 0 != ( pFlags & aiProcess_GenBoundingBoxes );
+}
+
+void checkMesh(aiMesh* mesh, aiVector3D& min, aiVector3D& max) {
+ ai_assert(nullptr != mesh);
+
+ if (0 == mesh->mNumVertices) {
+ return;
+ }
+
+ for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
+ const aiVector3D &pos = mesh->mVertices[i];
+ if (pos.x < min.x) {
+ min.x = pos.x;
+ }
+ if (pos.y < min.y) {
+ min.y = pos.y;
+ }
+ if (pos.z < min.z) {
+ min.z = pos.z;
+ }
+
+ if (pos.x > max.x) {
+ max.x = pos.x;
+ }
+ if (pos.y > max.y) {
+ max.y = pos.y;
+ }
+ if (pos.z > max.z) {
+ max.z = pos.z;
+ }
+ }
+}
+
+void GenBoundingBoxesProcess::Execute(aiScene* pScene) {
+ if (nullptr == pScene) {
+ return;
+ }
+
+ for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
+ aiMesh* mesh = pScene->mMeshes[i];
+ if (nullptr == mesh) {
+ continue;
+ }
+
+ aiVector3D min(999999, 999999, 999999), max(-999999, -999999, -999999);
+ checkMesh(mesh, min, max);
+ mesh->mAABB.mMin = min;
+ mesh->mAABB.mMax = max;
+ }
+}
+
+} // Namespace Assimp
+
+#endif // ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS
diff --git a/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h
new file mode 100644
index 0000000000..4b43c82a42
--- /dev/null
+++ b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h
@@ -0,0 +1,76 @@
+/*
+---------------------------------------------------------------------------
+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.
+---------------------------------------------------------------------------
+*/
+
+/** @file Defines a post-processing step to generate Axis-aligned bounding
+ * volumes for all meshes.
+ */
+
+#pragma once
+
+#ifndef AI_GENBOUNDINGBOXESPROCESS_H_INC
+#define AI_GENBOUNDINGBOXESPROCESS_H_INC
+
+#ifndef ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS
+
+#include "Common/BaseProcess.h"
+
+namespace Assimp {
+
+/** Post-processing process to find axis-aligned bounding volumes for amm meshes
+ * used in a scene
+ */
+class ASSIMP_API GenBoundingBoxesProcess : public BaseProcess {
+public:
+ /// The class constructor.
+ GenBoundingBoxesProcess();
+ /// The class destructor.
+ ~GenBoundingBoxesProcess();
+ /// Will return true, if aiProcess_GenBoundingBoxes is defined.
+ bool IsActive(unsigned int pFlags) const override;
+ /// The execution callback.
+ void Execute(aiScene* pScene) override;
+};
+
+} // Namespace Assimp
+
+#endif // #ifndef ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS
+
+#endif // AI_GENBOUNDINGBOXESPROCESS_H_INC
diff --git a/thirdparty/assimp/code/GenFaceNormalsProcess.cpp b/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp
index 028334dec7..028334dec7 100644
--- a/thirdparty/assimp/code/GenFaceNormalsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.cpp
diff --git a/thirdparty/assimp/code/GenFaceNormalsProcess.h b/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.h
index c80ec9fddc..c641fd6353 100644
--- a/thirdparty/assimp/code/GenFaceNormalsProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/GenFaceNormalsProcess.h
@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_GENFACENORMALPROCESS_H_INC
#define AI_GENFACENORMALPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
namespace Assimp
diff --git a/thirdparty/assimp/code/GenVertexNormalsProcess.cpp b/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp
index 3f6c2f86bd..3f6c2f86bd 100644
--- a/thirdparty/assimp/code/GenVertexNormalsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.cpp
diff --git a/thirdparty/assimp/code/GenVertexNormalsProcess.h b/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.h
index 9142ad26f5..2ceee17e85 100644
--- a/thirdparty/assimp/code/GenVertexNormalsProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/GenVertexNormalsProcess.h
@@ -45,24 +45,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_GENVERTEXNORMALPROCESS_H_INC
#define AI_GENVERTEXNORMALPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/assbin_chunks.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
+// Forward declarations
class GenNormalsTest;
namespace Assimp {
// ---------------------------------------------------------------------------
-/** The GenFaceNormalsProcess computes vertex normals for all vertizes
+/** The GenFaceNormalsProcess computes vertex normals for all vertices
*/
-class ASSIMP_API GenVertexNormalsProcess : public BaseProcess
-{
+class ASSIMP_API GenVertexNormalsProcess : public BaseProcess {
public:
-
GenVertexNormalsProcess();
~GenVertexNormalsProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with.
@@ -88,13 +88,10 @@ public:
// setter for configMaxAngle
- inline void SetMaxSmoothAngle(ai_real f)
- {
+ inline void SetMaxSmoothAngle(ai_real f) {
configMaxAngle =f;
}
-public:
-
// -------------------------------------------------------------------
/** Computes normals for a specific mesh
* @param pcMesh Mesh
@@ -104,7 +101,6 @@ public:
bool GenMeshVertexNormals (aiMesh* pcMesh, unsigned int meshIndex);
private:
-
/** Configuration option: maximum smoothing angle, in radians*/
ai_real configMaxAngle;
mutable bool force_ = false;
diff --git a/thirdparty/assimp/code/ImproveCacheLocality.cpp b/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.cpp
index ace9d95ff8..d0a016fa42 100644
--- a/thirdparty/assimp/code/ImproveCacheLocality.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.cpp
@@ -45,14 +45,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* <br>
* The algorithm is roughly basing on this paper:
* http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf
- * .. although overdraw rduction isn't implemented yet ...
+ * .. although overdraw reduction isn't implemented yet ...
*/
-
-
// internal headers
-#include "ImproveCacheLocality.h"
-#include "VertexTriangleAdjacency.h"
+#include "PostProcessing/ImproveCacheLocality.h"
+#include "Common/VertexTriangleAdjacency.h"
+
#include <assimp/StringUtils.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
@@ -64,36 +63,33 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
-ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() {
- configCacheDepth = PP_ICL_PTCACHE_SIZE;
+ImproveCacheLocalityProcess::ImproveCacheLocalityProcess()
+: mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
+ // empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
-ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess()
-{
+ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
-bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const
-{
+bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const {
return (pFlags & aiProcess_ImproveCacheLocality) != 0;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration
-void ImproveCacheLocalityProcess::SetupProperties(const Importer* pImp)
-{
+void ImproveCacheLocalityProcess::SetupProperties(const Importer* pImp) {
// AI_CONFIG_PP_ICL_PTCACHE_SIZE controls the target cache size for the optimizer
- configCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE,PP_ICL_PTCACHE_SIZE);
+ mConfigCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE,PP_ICL_PTCACHE_SIZE);
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
-void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
-{
+void ImproveCacheLocalityProcess::Execute( aiScene* pScene) {
if (!pScene->mNumMeshes) {
ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess skipped; there are no meshes");
return;
@@ -103,7 +99,7 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
float out = 0.f;
unsigned int numf = 0, numm = 0;
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++){
+ for( unsigned int a = 0; a < pScene->mNumMeshes; ++a ){
const float res = ProcessMesh( pScene->mMeshes[a],a);
if (res) {
numf += pScene->mMeshes[a]->mNumFaces;
@@ -121,44 +117,41 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
// ------------------------------------------------------------------------------------------------
// Improves the cache coherency of a specific mesh
-float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshNum)
-{
+ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshNum) {
// TODO: rewrite this to use std::vector or boost::shared_array
- ai_assert(NULL != pMesh);
+ ai_assert(nullptr != pMesh);
// Check whether the input data is valid
// - there must be vertices and faces
// - all faces must be triangulated or we can't operate on them
if (!pMesh->HasFaces() || !pMesh->HasPositions())
- return 0.f;
+ return static_cast<ai_real>(0.f);
if (pMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) {
ASSIMP_LOG_ERROR("This algorithm works on triangle meshes only");
- return 0.f;
+ return static_cast<ai_real>(0.f);
}
- if(pMesh->mNumVertices <= configCacheDepth) {
- return 0.f;
+ if(pMesh->mNumVertices <= mConfigCacheDepth) {
+ return static_cast<ai_real>(0.f);
}
- float fACMR = 3.f;
+ ai_real fACMR = 3.f;
const aiFace* const pcEnd = pMesh->mFaces+pMesh->mNumFaces;
// Input ACMR is for logging purposes only
if (!DefaultLogger::isNullLogger()) {
- unsigned int* piFIFOStack = new unsigned int[configCacheDepth];
- memset(piFIFOStack,0xff,configCacheDepth*sizeof(unsigned int));
+ unsigned int* piFIFOStack = new unsigned int[mConfigCacheDepth];
+ memset(piFIFOStack,0xff,mConfigCacheDepth*sizeof(unsigned int));
unsigned int* piCur = piFIFOStack;
- const unsigned int* const piCurEnd = piFIFOStack + configCacheDepth;
+ const unsigned int* const piCurEnd = piFIFOStack + mConfigCacheDepth;
// count the number of cache misses
unsigned int iCacheMisses = 0;
for (const aiFace* pcFace = pMesh->mFaces;pcFace != pcEnd;++pcFace) {
-
for (unsigned int qq = 0; qq < 3;++qq) {
bool bInCache = false;
-
for (unsigned int* pp = piFIFOStack;pp < piCurEnd;++pp) {
if (*pp == pcFace->mIndices[qq]) {
// the vertex is in cache
@@ -176,7 +169,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
}
}
delete[] piFIFOStack;
- fACMR = (float)iCacheMisses / pMesh->mNumFaces;
+ fACMR = (ai_real) iCacheMisses / pMesh->mNumFaces;
if (3.0 == fACMR) {
char szBuff[128]; // should be sufficiently large in every case
@@ -185,7 +178,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
// smaller than 3.0 ...
ai_snprintf(szBuff,128,"Mesh %u: Not suitable for vcache optimization",meshNum);
ASSIMP_LOG_WARN(szBuff);
- return 0.f;
+ return static_cast<ai_real>(0.f);
}
}
@@ -258,7 +251,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
int ivdx = 0;
int ics = 1;
- int iStampCnt = configCacheDepth+1;
+ int iStampCnt = mConfigCacheDepth+1;
while (ivdx >= 0) {
unsigned int icnt = piNumTriPtrNoModify[ivdx];
@@ -294,7 +287,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
*piCSIter++ = dp;
// if the vertex is not yet in cache, set its cache count
- if (iStampCnt-piCachingStamps[dp] > configCacheDepth) {
+ if (iStampCnt-piCachingStamps[dp] > mConfigCacheDepth) {
piCachingStamps[dp] = iStampCnt++;
++iCacheMisses;
}
@@ -319,7 +312,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
// will the vertex be in cache, even after fanning occurs?
unsigned int tmp;
- if ((tmp = iStampCnt-piCachingStamps[dp]) + 2*piNumTriPtr[dp] <= configCacheDepth) {
+ if ((tmp = iStampCnt-piCachingStamps[dp]) + 2*piNumTriPtr[dp] <= mConfigCacheDepth) {
priority = tmp;
}
@@ -356,7 +349,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
}
}
}
- float fACMR2 = 0.0f;
+ ai_real fACMR2 = 0.0f;
if (!DefaultLogger::isNullLogger()) {
fACMR2 = (float)iCacheMisses / pMesh->mNumFaces;
diff --git a/thirdparty/assimp/code/ImproveCacheLocality.h b/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.h
index 1b29ee0d6e..de25ecd9fb 100644
--- a/thirdparty/assimp/code/ImproveCacheLocality.h
+++ b/thirdparty/assimp/code/PostProcessing/ImproveCacheLocality.h
@@ -45,7 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IMPROVECACHELOCALITY_H_INC
#define AI_IMPROVECACHELOCALITY_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/types.h>
struct aiMesh;
@@ -87,12 +88,12 @@ protected:
* @param pMesh The mesh to process.
* @param meshNum Index of the mesh to process
*/
- float ProcessMesh( aiMesh* pMesh, unsigned int meshNum);
+ ai_real ProcessMesh( aiMesh* pMesh, unsigned int meshNum);
private:
//! Configuration parameter: specifies the size of the cache to
//! optimize the vertex data for.
- unsigned int configCacheDepth;
+ unsigned int mConfigCacheDepth;
};
} // end of namespace Assimp
diff --git a/thirdparty/assimp/code/JoinVerticesProcess.cpp b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp
index 914ec05b46..914ec05b46 100644
--- a/thirdparty/assimp/code/JoinVerticesProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp
diff --git a/thirdparty/assimp/code/JoinVerticesProcess.h b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.h
index 66fa362de2..e017ae62db 100644
--- a/thirdparty/assimp/code/JoinVerticesProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.h
@@ -45,7 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_JOINVERTICESPROCESS_H_INC
#define AI_JOINVERTICESPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/types.h>
struct aiMesh;
@@ -61,13 +62,11 @@ namespace Assimp
* erases all but one of the copies. This usually reduces the number of vertices
* in a mesh by a serious amount and is the standard form to render a mesh.
*/
-class ASSIMP_API JoinVerticesProcess : public BaseProcess
-{
+class ASSIMP_API JoinVerticesProcess : public BaseProcess {
public:
JoinVerticesProcess();
~JoinVerticesProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise
@@ -83,15 +82,12 @@ public:
*/
void Execute( aiScene* pScene);
-public:
// -------------------------------------------------------------------
/** Unites identical vertices in the given mesh.
* @param pMesh The mesh to process.
* @param meshIndex Index of the mesh to process
*/
int ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
-
-private:
};
} // end of namespace Assimp
diff --git a/thirdparty/assimp/code/LimitBoneWeightsProcess.cpp b/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.cpp
index d560f19287..d560f19287 100644
--- a/thirdparty/assimp/code/LimitBoneWeightsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.cpp
diff --git a/thirdparty/assimp/code/LimitBoneWeightsProcess.h b/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.h
index 3602fd8edf..73c2a68d53 100644
--- a/thirdparty/assimp/code/LimitBoneWeightsProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/LimitBoneWeightsProcess.h
@@ -44,14 +44,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_LIMITBONEWEIGHTSPROCESS_H_INC
#define AI_LIMITBONEWEIGHTSPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+// Forward declarations
struct aiMesh;
class LimitBoneWeightsTest;
-namespace Assimp
-{
+namespace Assimp {
// NOTE: If you change these limits, don't forget to change the
// corresponding values in all Assimp ports
@@ -72,14 +72,11 @@ namespace Assimp
* The other weights on this bone are then renormalized to assure the sum weight
* to be 1.
*/
-class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess
-{
+class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess {
public:
-
LimitBoneWeightsProcess();
~LimitBoneWeightsProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with.
@@ -96,8 +93,6 @@ public:
*/
void SetupProperties(const Importer* pImp);
-public:
-
// -------------------------------------------------------------------
/** Limits the bone weight count for all vertices in the given mesh.
* @param pMesh The mesh to process.
@@ -111,34 +106,29 @@ public:
*/
void Execute( aiScene* pScene);
-
-public:
-
// -------------------------------------------------------------------
/** Describes a bone weight on a vertex */
- struct Weight
- {
+ struct Weight {
unsigned int mBone; ///< Index of the bone
float mWeight; ///< Weight of that bone on this vertex
Weight() AI_NO_EXCEPT
: mBone(0)
- , mWeight(0.0f)
- { }
+ , mWeight(0.0f) {
+ // empty
+ }
Weight( unsigned int pBone, float pWeight)
- {
- mBone = pBone;
- mWeight = pWeight;
+ : mBone(pBone)
+ , mWeight(pWeight) {
+ // empty
}
/** Comparison operator to sort bone weights by descending weight */
- bool operator < (const Weight& pWeight) const
- {
+ bool operator < (const Weight& pWeight) const {
return mWeight > pWeight.mWeight;
}
};
-public:
/** Maximum number of bones influencing any single vertex. */
unsigned int mMaxWeights;
};
diff --git a/thirdparty/assimp/code/MakeVerboseFormat.cpp b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp
index 50ff5ed93d..50ff5ed93d 100644
--- a/thirdparty/assimp/code/MakeVerboseFormat.cpp
+++ b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp
diff --git a/thirdparty/assimp/code/MakeVerboseFormat.h b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h
index d12db63ae1..1adf8e2f69 100644
--- a/thirdparty/assimp/code/MakeVerboseFormat.h
+++ b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h
@@ -46,7 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MAKEVERBOSEFORMAT_H_INC
#define AI_MAKEVERBOSEFORMAT_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
struct aiMesh;
namespace Assimp {
diff --git a/thirdparty/assimp/code/OptimizeGraph.cpp b/thirdparty/assimp/code/PostProcessing/OptimizeGraph.cpp
index add9ab79e1..5db51f58b6 100644
--- a/thirdparty/assimp/code/OptimizeGraph.cpp
+++ b/thirdparty/assimp/code/PostProcessing/OptimizeGraph.cpp
@@ -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,
diff --git a/thirdparty/assimp/code/OptimizeGraph.h b/thirdparty/assimp/code/PostProcessing/OptimizeGraph.h
index e5bbed7679..82cc5db3fe 100644
--- a/thirdparty/assimp/code/OptimizeGraph.h
+++ b/thirdparty/assimp/code/PostProcessing/OptimizeGraph.h
@@ -46,13 +46,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_OPTIMIZEGRAPHPROCESS_H_INC
#define AI_OPTIMIZEGRAPHPROCESS_H_INC
-#include "BaseProcess.h"
-#include "ProcessHelper.h"
+#include "Common/BaseProcess.h"
+#include "PostProcessing/ProcessHelper.h"
+
#include <assimp/types.h>
+
#include <set>
+// Forward declarations
struct aiMesh;
+
class OptimizeGraphProcessTest;
+
namespace Assimp {
// -----------------------------------------------------------------------------
@@ -64,14 +69,11 @@ namespace Assimp {
* @see aiProcess_OptimizeGraph for a detailed description of the
* algorithm being applied.
*/
-class OptimizeGraphProcess : public BaseProcess
-{
+class OptimizeGraphProcess : public BaseProcess {
public:
-
OptimizeGraphProcess();
~OptimizeGraphProcess();
-public:
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
@@ -81,14 +83,12 @@ public:
// -------------------------------------------------------------------
void SetupProperties(const Importer* pImp);
-
// -------------------------------------------------------------------
/** @brief Add a list of node names to be locked and not modified.
* @param in List of nodes. See #AI_CONFIG_PP_OG_EXCLUDE_LIST for
* format explanations.
*/
- inline void AddLockedNodeList(std::string& in)
- {
+ inline void AddLockedNodeList(std::string& in) {
ConvertListToStrings (in,locked_nodes);
}
@@ -96,8 +96,7 @@ public:
/** @brief Add another node to be locked and not modified.
* @param name Name to be locked
*/
- inline void AddLockedNode(std::string& name)
- {
+ inline void AddLockedNode(std::string& name) {
locked_nodes.push_back(name);
}
@@ -105,25 +104,21 @@ public:
/** @brief Remove a node from the list of locked nodes.
* @param name Name to be unlocked
*/
- inline void RemoveLockedNode(std::string& name)
- {
+ inline void RemoveLockedNode(std::string& name) {
locked_nodes.remove(name);
}
protected:
-
void CollectNewChildren(aiNode* nd, std::list<aiNode*>& nodes);
void FindInstancedMeshes (aiNode* pNode);
private:
-
#ifdef AI_OG_USE_HASHING
typedef std::set<unsigned int> LockedSetType;
#else
typedef std::set<std::string> LockedSetType;
#endif
-
//! Scene we're working with
aiScene* mScene;
diff --git a/thirdparty/assimp/code/OptimizeMeshes.cpp b/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.cpp
index 3f6765f6ca..3f6765f6ca 100644
--- a/thirdparty/assimp/code/OptimizeMeshes.cpp
+++ b/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.cpp
diff --git a/thirdparty/assimp/code/OptimizeMeshes.h b/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.h
index 9f46f349b4..dec4ab52de 100644
--- a/thirdparty/assimp/code/OptimizeMeshes.h
+++ b/thirdparty/assimp/code/PostProcessing/OptimizeMeshes.h
@@ -46,8 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_OPTIMIZEMESHESPROCESS_H_INC
#define AI_OPTIMIZEMESHESPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/types.h>
+
#include <vector>
struct aiMesh;
@@ -64,16 +66,14 @@ namespace Assimp {
*
* @note Instanced meshes are currently not processed.
*/
-class OptimizeMeshesProcess : public BaseProcess
-{
+class OptimizeMeshesProcess : public BaseProcess {
public:
/// @brief The class constructor.
OptimizeMeshesProcess();
- /// @brief The class destcructor,
+ /// @brief The class destructor.
~OptimizeMeshesProcess();
-
/** @brief Internal utility to store additional mesh info
*/
struct MeshInfo {
diff --git a/thirdparty/assimp/code/PretransformVertices.cpp b/thirdparty/assimp/code/PostProcessing/PretransformVertices.cpp
index 52001a0578..52001a0578 100644
--- a/thirdparty/assimp/code/PretransformVertices.cpp
+++ b/thirdparty/assimp/code/PostProcessing/PretransformVertices.cpp
diff --git a/thirdparty/assimp/code/PretransformVertices.h b/thirdparty/assimp/code/PostProcessing/PretransformVertices.h
index b7329af130..b2982951e0 100644
--- a/thirdparty/assimp/code/PretransformVertices.h
+++ b/thirdparty/assimp/code/PostProcessing/PretransformVertices.h
@@ -47,13 +47,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_PRETRANSFORMVERTICES_H_INC
#define AI_PRETRANSFORMVERTICES_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
+
#include <list>
#include <vector>
+// Forward declarations
struct aiNode;
+
class PretransformVerticesTest;
+
namespace Assimp {
// ---------------------------------------------------------------------------
@@ -80,10 +85,10 @@ public:
// -------------------------------------------------------------------
/** @brief Toggle the 'keep hierarchy' option
- * @param d hm ... difficult to guess what this means, hu!?
+ * @param keep true for keep configuration.
*/
- void KeepHierarchy(bool d) {
- configKeepHierarchy = d;
+ void KeepHierarchy(bool keep) {
+ configKeepHierarchy = keep;
}
// -------------------------------------------------------------------
@@ -148,8 +153,6 @@ private:
// Build reference counters for all meshes
void BuildMeshRefCountArray(aiNode* nd, unsigned int * refs);
-
-
//! Configuration option: keep scene hierarchy as long as possible
bool configKeepHierarchy;
bool configNormalize;
diff --git a/thirdparty/assimp/code/ProcessHelper.cpp b/thirdparty/assimp/code/PostProcessing/ProcessHelper.cpp
index 59869fdff7..59869fdff7 100644
--- a/thirdparty/assimp/code/ProcessHelper.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ProcessHelper.cpp
diff --git a/thirdparty/assimp/code/ProcessHelper.h b/thirdparty/assimp/code/PostProcessing/ProcessHelper.h
index c59f3217bf..0afcc41420 100644
--- a/thirdparty/assimp/code/ProcessHelper.h
+++ b/thirdparty/assimp/code/PostProcessing/ProcessHelper.h
@@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <assimp/SpatialSort.h>
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/ParsingUtils.h>
#include <list>
diff --git a/thirdparty/assimp/code/RemoveRedundantMaterials.cpp b/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.cpp
index 632bdca3fe..49ec8f5c47 100644
--- a/thirdparty/assimp/code/RemoveRedundantMaterials.cpp
+++ b/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.cpp
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "RemoveRedundantMaterials.h"
#include <assimp/ParsingUtils.h>
#include "ProcessHelper.h"
-#include "MaterialSystem.h"
+#include "Material/MaterialSystem.h"
#include <stdio.h>
using namespace Assimp;
@@ -57,7 +57,7 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
-: configFixedMaterials() {
+: mConfigFixedMaterials() {
// nothing to do here
}
@@ -80,7 +80,7 @@ bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const
void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp)
{
// Get value of AI_CONFIG_PP_RRM_EXCLUDE_LIST
- configFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
+ mConfigFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
}
// ------------------------------------------------------------------------------------------------
@@ -100,10 +100,10 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
// If a list of materials to be excluded was given, match the list with
// our imported materials and 'salt' all positive matches to ensure that
// we get unique hashes later.
- if (configFixedMaterials.length()) {
+ if (mConfigFixedMaterials.length()) {
std::list<std::string> strings;
- ConvertListToStrings(configFixedMaterials,strings);
+ ConvertListToStrings(mConfigFixedMaterials,strings);
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
aiMaterial* mat = pScene->mMaterials[i];
diff --git a/thirdparty/assimp/code/RemoveRedundantMaterials.h b/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.h
index dbd4d44cc0..1f32a0abfb 100644
--- a/thirdparty/assimp/code/RemoveRedundantMaterials.h
+++ b/thirdparty/assimp/code/PostProcessing/RemoveRedundantMaterials.h
@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_REMOVEREDUNDANTMATERIALS_H_INC
#define AI_REMOVEREDUNDANTMATERIALS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
class RemoveRedundantMatsTest;
@@ -57,8 +57,7 @@ namespace Assimp {
/** RemoveRedundantMatsProcess: Post-processing step to remove redundant
* materials from the imported scene.
*/
-class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess
-{
+class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess {
public:
/// The default class constructor.
RemoveRedundantMatsProcess();
@@ -66,7 +65,6 @@ public:
/// The class destructor.
~RemoveRedundantMatsProcess();
-public:
// -------------------------------------------------------------------
// Check whether step is active
bool IsActive( unsigned int pFlags) const;
@@ -79,27 +77,25 @@ public:
// Setup import settings
void SetupProperties(const Importer* pImp);
-
// -------------------------------------------------------------------
- /** @brief Set list of fixed (unmutable) materials
+ /** @brief Set list of fixed (inmutable) materials
* @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
*/
void SetFixedMaterialsString(const std::string& fixed = "") {
- configFixedMaterials = fixed;
+ mConfigFixedMaterials = fixed;
}
// -------------------------------------------------------------------
- /** @brief Get list of fixed (unmutable) materials
+ /** @brief Get list of fixed (inmutable) materials
* @return See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
*/
const std::string& GetFixedMaterialsString() const {
- return configFixedMaterials;
+ return mConfigFixedMaterials;
}
private:
-
//! Configuration option: list of all fixed materials
- std::string configFixedMaterials;
+ std::string mConfigFixedMaterials;
};
} // end of namespace Assimp
diff --git a/thirdparty/assimp/code/RemoveVCProcess.cpp b/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.cpp
index 99fd47a3aa..99fd47a3aa 100644
--- a/thirdparty/assimp/code/RemoveVCProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.cpp
diff --git a/thirdparty/assimp/code/RemoveVCProcess.h b/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.h
index 617d7b9b20..7bb21a8330 100644
--- a/thirdparty/assimp/code/RemoveVCProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/RemoveVCProcess.h
@@ -44,7 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_REMOVEVCPROCESS_H_INCLUDED
#define AI_REMOVEVCPROCESS_H_INCLUDED
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
+
#include <assimp/mesh.h>
class RemoveVCProcessTest;
diff --git a/thirdparty/assimp/code/ScaleProcess.cpp b/thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp
index 6d458c4b11..6d458c4b11 100644
--- a/thirdparty/assimp/code/ScaleProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp
diff --git a/thirdparty/assimp/code/ScaleProcess.h b/thirdparty/assimp/code/PostProcessing/ScaleProcess.h
index 55146ae064..2567378759 100644
--- a/thirdparty/assimp/code/ScaleProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/ScaleProcess.h
@@ -41,7 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
struct aiNode;
diff --git a/thirdparty/assimp/code/SortByPTypeProcess.cpp b/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.cpp
index 2e0cc54004..be8405a17b 100644
--- a/thirdparty/assimp/code/SortByPTypeProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.cpp
@@ -57,8 +57,8 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
SortByPTypeProcess::SortByPTypeProcess()
-{
- configRemoveMeshes = 0;
+: mConfigRemoveMeshes( 0 ) {
+ // empty
}
// ------------------------------------------------------------------------------------------------
@@ -78,7 +78,7 @@ bool SortByPTypeProcess::IsActive( unsigned int pFlags) const
// ------------------------------------------------------------------------------------------------
void SortByPTypeProcess::SetupProperties(const Importer* pImp)
{
- configRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,0);
+ mConfigRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,0);
}
// ------------------------------------------------------------------------------------------------
@@ -172,7 +172,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene) {
}
if (1 == num) {
- if (!(configRemoveMeshes & mesh->mPrimitiveTypes)) {
+ if (!(mConfigRemoveMeshes & mesh->mPrimitiveTypes)) {
*meshIdx = static_cast<unsigned int>( outMeshes.size() );
outMeshes.push_back(mesh);
} else {
@@ -206,7 +206,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene) {
VertexWeightTable* avw = ComputeVertexBoneWeightTable(mesh);
for (unsigned int real = 0; real < 4; ++real,++meshIdx)
{
- if ( !aiNumPerPType[real] || configRemoveMeshes & (1u << real))
+ if ( !aiNumPerPType[real] || mConfigRemoveMeshes & (1u << real))
{
continue;
}
@@ -392,10 +392,10 @@ void SortByPTypeProcess::Execute( aiScene* pScene) {
{
char buffer[1024];
::ai_snprintf(buffer,1024,"Points: %u%s, Lines: %u%s, Triangles: %u%s, Polygons: %u%s (Meshes, X = removed)",
- aiNumMeshesPerPType[0], ((configRemoveMeshes & aiPrimitiveType_POINT) ? "X" : ""),
- aiNumMeshesPerPType[1], ((configRemoveMeshes & aiPrimitiveType_LINE) ? "X" : ""),
- aiNumMeshesPerPType[2], ((configRemoveMeshes & aiPrimitiveType_TRIANGLE) ? "X" : ""),
- aiNumMeshesPerPType[3], ((configRemoveMeshes & aiPrimitiveType_POLYGON) ? "X" : ""));
+ aiNumMeshesPerPType[0], ((mConfigRemoveMeshes & aiPrimitiveType_POINT) ? "X" : ""),
+ aiNumMeshesPerPType[1], ((mConfigRemoveMeshes & aiPrimitiveType_LINE) ? "X" : ""),
+ aiNumMeshesPerPType[2], ((mConfigRemoveMeshes & aiPrimitiveType_TRIANGLE) ? "X" : ""),
+ aiNumMeshesPerPType[3], ((mConfigRemoveMeshes & aiPrimitiveType_POLYGON) ? "X" : ""));
ASSIMP_LOG_INFO(buffer);
ASSIMP_LOG_DEBUG("SortByPTypeProcess finished");
}
diff --git a/thirdparty/assimp/code/SortByPTypeProcess.h b/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.h
index c9d9924d8f..1d7ccfc152 100644
--- a/thirdparty/assimp/code/SortByPTypeProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/SortByPTypeProcess.h
@@ -45,10 +45,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_SORTBYPTYPEPROCESS_H_INC
#define AI_SORTBYPTYPEPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
class SortByPTypeProcessTest;
+
namespace Assimp {
@@ -57,14 +58,11 @@ namespace Assimp {
* A mesh with 5 lines, 3 points and 145 triangles would be split in 3
* submeshes.
*/
-class ASSIMP_API SortByPTypeProcess : public BaseProcess
-{
+class ASSIMP_API SortByPTypeProcess : public BaseProcess {
public:
-
SortByPTypeProcess();
~SortByPTypeProcess();
-public:
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
@@ -75,8 +73,7 @@ public:
void SetupProperties(const Importer* pImp);
private:
-
- int configRemoveMeshes;
+ int mConfigRemoveMeshes;
};
diff --git a/thirdparty/assimp/code/SplitLargeMeshes.cpp b/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.cpp
index 1797b28d5a..1797b28d5a 100644
--- a/thirdparty/assimp/code/SplitLargeMeshes.cpp
+++ b/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.cpp
diff --git a/thirdparty/assimp/code/SplitLargeMeshes.h b/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.h
index 77f089ce7e..3f90576ea9 100644
--- a/thirdparty/assimp/code/SplitLargeMeshes.h
+++ b/thirdparty/assimp/code/PostProcessing/SplitLargeMeshes.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,
@@ -40,21 +39,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
-/** @file Defines a post processing step to split large meshes into submeshes
+/** @file Defines a post processing step to split large meshes into sub-meshes
*/
#ifndef AI_SPLITLARGEMESHES_H_INC
#define AI_SPLITLARGEMESHES_H_INC
#include <vector>
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/mesh.h>
#include <assimp/scene.h>
+// Forward declarations
class SplitLargeMeshesTest;
-namespace Assimp
-{
+namespace Assimp {
class SplitLargeMeshesProcess_Triangle;
class SplitLargeMeshesProcess_Vertex;
diff --git a/thirdparty/assimp/code/TextureTransform.cpp b/thirdparty/assimp/code/PostProcessing/TextureTransform.cpp
index 8ae2ba7218..8ae2ba7218 100644
--- a/thirdparty/assimp/code/TextureTransform.cpp
+++ b/thirdparty/assimp/code/PostProcessing/TextureTransform.cpp
diff --git a/thirdparty/assimp/code/TextureTransform.h b/thirdparty/assimp/code/PostProcessing/TextureTransform.h
index c556ff5d8c..2a5d623d7f 100644
--- a/thirdparty/assimp/code/TextureTransform.h
+++ b/thirdparty/assimp/code/PostProcessing/TextureTransform.h
@@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_TEXTURE_TRANSFORM_H_INCLUDED
#include <assimp/BaseImporter.h>
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
#include <assimp/material.h>
#include <list>
diff --git a/thirdparty/assimp/code/TriangulateProcess.cpp b/thirdparty/assimp/code/PostProcessing/TriangulateProcess.cpp
index 0f68f47ddb..1040836bbe 100644
--- a/thirdparty/assimp/code/TriangulateProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/TriangulateProcess.cpp
@@ -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,
@@ -60,9 +58,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* a file
*/
#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
-#include "TriangulateProcess.h"
-#include "ProcessHelper.h"
-#include "PolyTools.h"
+
+#include "PostProcessing/TriangulateProcess.h"
+#include "PostProcessing/ProcessHelper.h"
+#include "Common/PolyTools.h"
+
#include <memory>
//#define AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
diff --git a/thirdparty/assimp/code/TriangulateProcess.h b/thirdparty/assimp/code/PostProcessing/TriangulateProcess.h
index 47bd2115ad..916b5103dd 100644
--- a/thirdparty/assimp/code/TriangulateProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/TriangulateProcess.h
@@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_TRIANGULATEPROCESS_H_INC
#define AI_TRIANGULATEPROCESS_H_INC
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
struct aiMesh;
@@ -59,14 +59,11 @@ namespace Assimp {
* into triangles. You usually want this to happen because the graphics cards
* need their data as triangles.
*/
-class ASSIMP_API TriangulateProcess : public BaseProcess
-{
+class ASSIMP_API TriangulateProcess : public BaseProcess {
public:
-
TriangulateProcess();
~TriangulateProcess();
-public:
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise
@@ -82,7 +79,6 @@ public:
*/
void Execute( aiScene* pScene);
-public:
// -------------------------------------------------------------------
/** Triangulates the given mesh.
* @param pMesh The mesh to triangulate.
diff --git a/thirdparty/assimp/code/ValidateDataStructure.cpp b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp
index 657b0361b7..712fd6943d 100644
--- a/thirdparty/assimp/code/ValidateDataStructure.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp
@@ -46,8 +46,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* the data structure returned by Assimp.
*/
-
-
// internal headers
#include "ValidateDataStructure.h"
#include <assimp/BaseImporter.h>
@@ -110,8 +108,8 @@ void ValidateDSProcess::ReportWarning(const char* msg,...)
}
// ------------------------------------------------------------------------------------------------
-inline int HasNameMatch(const aiString& in, aiNode* node)
-{
+inline
+int HasNameMatch(const aiString& in, aiNode* node) {
int result = (node->mName == in ? 1 : 0 );
for (unsigned int i = 0; i < node->mNumChildren;++i) {
result += HasNameMatch(in,node->mChildren[i]);
@@ -121,9 +119,8 @@ inline int HasNameMatch(const aiString& in, aiNode* node)
// ------------------------------------------------------------------------------------------------
template <typename T>
-inline void ValidateDSProcess::DoValidation(T** parray, unsigned int size,
- const char* firstName, const char* secondName)
-{
+inline
+void ValidateDSProcess::DoValidation(T** parray, unsigned int size, const char* firstName, const char* secondName) {
// validate all entries
if (size)
{
@@ -181,7 +178,8 @@ inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size,
// ------------------------------------------------------------------------------------------------
template <typename T>
inline
-void ValidateDSProcess::DoValidationWithNameCheck(T** array, unsigned int size, const char* firstName, const char* secondName) {
+void ValidateDSProcess::DoValidationWithNameCheck(T** array, unsigned int size, const char* firstName,
+ const char* secondName) {
// validate all entries
DoValidationEx(array,size,firstName,secondName);
@@ -201,9 +199,8 @@ void ValidateDSProcess::DoValidationWithNameCheck(T** array, unsigned int size,
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
-void ValidateDSProcess::Execute( aiScene* pScene)
-{
- this->mScene = pScene;
+void ValidateDSProcess::Execute( aiScene* pScene) {
+ mScene = pScene;
ASSIMP_LOG_DEBUG("ValidateDataStructureProcess begin");
// validate the node graph of the scene
@@ -516,13 +513,11 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
}
// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiMesh* pMesh,
- const aiBone* pBone,float* afSum)
-{
+void ValidateDSProcess::Validate( const aiMesh* pMesh, const aiBone* pBone,float* afSum) {
this->Validate(&pBone->mName);
if (!pBone->mNumWeights) {
- ReportError("aiBone::mNumWeights is zero");
+ //ReportError("aiBone::mNumWeights is zero");
}
// check whether all vertices affected by this bone are valid
@@ -563,9 +558,6 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
else {
ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
}
-
- // Animation duration is allowed to be zero in cases where the anim contains only a single key frame.
- // if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
}
// ------------------------------------------------------------------------------------------------
@@ -746,8 +738,9 @@ void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
"AI_MATKEY_SHININESS_STRENGTH key is 0.0");
}
break;
- default: ;
- };
+ default:
+ break;
+ }
}
if (AI_SUCCESS == aiGetMaterialFloat( pMaterial,AI_MATKEY_OPACITY,&fTemp) && (!fTemp || fTemp > 1.01)) {
diff --git a/thirdparty/assimp/code/ValidateDataStructure.h b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h
index bd21e88545..0b891ef414 100644
--- a/thirdparty/assimp/code/ValidateDataStructure.h
+++ b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h
@@ -48,7 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/types.h>
#include <assimp/material.h>
-#include "BaseProcess.h"
+
+#include "Common/BaseProcess.h"
struct aiBone;
struct aiMesh;
diff --git a/thirdparty/assimp/code/RawLoader.cpp b/thirdparty/assimp/code/RawLoader.cpp
deleted file mode 100644
index d0da247e47..0000000000
--- a/thirdparty/assimp/code/RawLoader.cpp
+++ /dev/null
@@ -1,331 +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.
----------------------------------------------------------------------------
-*/
-
-/** @file RawLoader.cpp
- * @brief Implementation of the RAW importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
-
-// internal headers
-#include "RawLoader.h"
-#include <assimp/ParsingUtils.h>
-#include <assimp/fast_atof.h>
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Raw Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "raw"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-RAWImporter::RAWImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-RAWImporter::~RAWImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool RAWImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
- return SimpleExtensionCheck(pFile,"raw");
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* RAWImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void RAWImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open RAW file " + pFile + ".");
- }
-
- // allocate storage and copy the contents of the file to a memory buffer
- // (terminate it with zero)
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- // list of groups loaded from the file
- std::vector< GroupInformation > outGroups(1,GroupInformation("<default>"));
- std::vector< GroupInformation >::iterator curGroup = outGroups.begin();
-
- // now read all lines
- char line[4096];
- while (GetNextLine(buffer,line))
- {
- // if the line starts with a non-numeric identifier, it marks
- // the beginning of a new group
- const char* sz = line;SkipSpaces(&sz);
- if (IsLineEnd(*sz))continue;
- if (!IsNumeric(*sz))
- {
- const char* sz2 = sz;
- while (!IsSpaceOrNewLine(*sz2))++sz2;
- const unsigned int length = (unsigned int)(sz2-sz);
-
- // find an existing group with this name
- for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
- it != end;++it)
- {
- if (length == (*it).name.length() && !::strcmp(sz,(*it).name.c_str()))
- {
- curGroup = it;sz2 = NULL;
- break;
- }
- }
- if (sz2)
- {
- outGroups.push_back(GroupInformation(std::string(sz,length)));
- curGroup = outGroups.end()-1;
- }
- }
- else
- {
- // there can be maximally 12 floats plus an extra texture file name
- float data[12];
- unsigned int num;
- for (num = 0; num < 12;++num)
- {
- if(!SkipSpaces(&sz) || !IsNumeric(*sz))break;
- sz = fast_atoreal_move<float>(sz,data[num]);
- }
- if (num != 12 && num != 9)
- {
- ASSIMP_LOG_ERROR("A line may have either 9 or 12 floats and an optional texture");
- continue;
- }
-
- MeshInformation* output = NULL;
-
- const char* sz2 = sz;
- unsigned int length;
- if (!IsLineEnd(*sz))
- {
- while (!IsSpaceOrNewLine(*sz2))++sz2;
- length = (unsigned int)(sz2-sz);
- }
- else if (9 == num)
- {
- sz = "%default%";
- length = 9;
- }
- else
- {
- sz = "";
- length = 0;
- }
-
- // search in the list of meshes whether we have one with this texture
- for (auto &mesh : (*curGroup).meshes)
- {
- if (length == mesh.name.length() && (length ? !::strcmp(sz, mesh.name.c_str()) : true))
- {
- output = &mesh;
- break;
- }
- }
- // if we don't have the mesh, create it
- if (!output)
- {
- (*curGroup).meshes.push_back(MeshInformation(std::string(sz,length)));
- output = &((*curGroup).meshes.back());
- }
- if (12 == num)
- {
- aiColor4D v(data[0],data[1],data[2],1.0f);
- output->colors.push_back(v);
- output->colors.push_back(v);
- output->colors.push_back(v);
-
- output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
- output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
- output->vertices.push_back(aiVector3D(data[9],data[10],data[11]));
- }
- else
- {
- output->vertices.push_back(aiVector3D(data[0],data[1],data[2]));
- output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
- output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
- }
- }
- }
-
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<RawRoot>");
-
- // count the number of valid groups
- // (meshes can't be empty)
- for (auto & outGroup : outGroups)
- {
- if (!outGroup.meshes.empty())
- {
- ++pScene->mRootNode->mNumChildren;
- pScene->mNumMeshes += (unsigned int) outGroup.meshes.size();
- }
- }
-
- if (!pScene->mNumMeshes)
- {
- throw DeadlyImportError("RAW: No meshes loaded. The file seems to be corrupt or empty.");
- }
-
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- aiNode** cc;
- if (1 == pScene->mRootNode->mNumChildren)
- {
- cc = &pScene->mRootNode;
- pScene->mRootNode->mNumChildren = 0;
- } else {
- cc = new aiNode*[pScene->mRootNode->mNumChildren];
- memset(cc, 0, sizeof(aiNode*) * pScene->mRootNode->mNumChildren);
- pScene->mRootNode->mChildren = cc;
- }
-
- pScene->mNumMaterials = pScene->mNumMeshes;
- aiMaterial** mats = pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
-
- unsigned int meshIdx = 0;
- for (auto & outGroup : outGroups)
- {
- if (outGroup.meshes.empty())continue;
-
- aiNode* node;
- if (pScene->mRootNode->mNumChildren)
- {
- node = *cc = new aiNode();
- node->mParent = pScene->mRootNode;
- }
- else node = *cc;
- node->mName.Set(outGroup.name);
-
- // add all meshes
- node->mNumMeshes = (unsigned int) outGroup.meshes.size();
- unsigned int* pi = node->mMeshes = new unsigned int[ node->mNumMeshes ];
- for (std::vector< MeshInformation >::iterator it2 = outGroup.meshes.begin(),
- end2 = outGroup.meshes.end(); it2 != end2; ++it2)
- {
- ai_assert(!(*it2).vertices.empty());
-
- // allocate the mesh
- *pi++ = meshIdx;
- aiMesh* mesh = pScene->mMeshes[meshIdx] = new aiMesh();
- mesh->mMaterialIndex = meshIdx++;
-
- mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // allocate storage for the vertex components and copy them
- mesh->mNumVertices = (unsigned int)(*it2).vertices.size();
- mesh->mVertices = new aiVector3D[ mesh->mNumVertices ];
- ::memcpy(mesh->mVertices,&(*it2).vertices[0],sizeof(aiVector3D)*mesh->mNumVertices);
-
- if ((*it2).colors.size())
- {
- ai_assert((*it2).colors.size() == mesh->mNumVertices);
-
- mesh->mColors[0] = new aiColor4D[ mesh->mNumVertices ];
- ::memcpy(mesh->mColors[0],&(*it2).colors[0],sizeof(aiColor4D)*mesh->mNumVertices);
- }
-
- // generate triangles
- ai_assert(0 == mesh->mNumVertices % 3);
- aiFace* fc = mesh->mFaces = new aiFace[ mesh->mNumFaces = mesh->mNumVertices/3 ];
- aiFace* const fcEnd = fc + mesh->mNumFaces;
- unsigned int n = 0;
- while (fc != fcEnd)
- {
- aiFace& f = *fc++;
- f.mIndices = new unsigned int[f.mNumIndices = 3];
- for (unsigned int m = 0; m < 3;++m)
- f.mIndices[m] = n++;
- }
-
- // generate a material for the mesh
- aiMaterial* mat = new aiMaterial();
-
- aiColor4D clr(1.0f,1.0f,1.0f,1.0f);
- if ("%default%" == (*it2).name) // a gray default material
- {
- clr.r = clr.g = clr.b = 0.6f;
- }
- else if ((*it2).name.length() > 0) // a texture
- {
- aiString s;
- s.Set((*it2).name);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- mat->AddProperty<aiColor4D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
- *mats++ = mat;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER
diff --git a/thirdparty/assimp/include/assimp/Exporter.hpp b/thirdparty/assimp/include/assimp/Exporter.hpp
index bf0096e7e9..ea0303e804 100644
--- a/thirdparty/assimp/include/assimp/Exporter.hpp
+++ b/thirdparty/assimp/include/assimp/Exporter.hpp
@@ -190,7 +190,7 @@ public:
* @note Use aiCopyScene() to get a modifiable copy of a previously
* imported scene. */
const aiExportDataBlob* ExportToBlob(const aiScene* pScene, const char* pFormatId,
- unsigned int pPreprocessing = 0u, const ExportProperties* = nullptr);
+ unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId,
unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
diff --git a/thirdparty/assimp/include/assimp/ParsingUtils.h b/thirdparty/assimp/include/assimp/ParsingUtils.h
index ca30ce13b0..6b9574fc67 100644
--- a/thirdparty/assimp/include/assimp/ParsingUtils.h
+++ b/thirdparty/assimp/include/assimp/ParsingUtils.h
@@ -196,8 +196,7 @@ bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize ] ) {
// ---------------------------------------------------------------------------------
template <class char_t>
-AI_FORCE_INLINE bool IsNumeric( char_t in)
-{
+AI_FORCE_INLINE bool IsNumeric( char_t in) {
return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
}
diff --git a/thirdparty/assimp/include/assimp/aabb.h b/thirdparty/assimp/include/assimp/aabb.h
new file mode 100644
index 0000000000..a20f317424
--- /dev/null
+++ b/thirdparty/assimp/include/assimp/aabb.h
@@ -0,0 +1,76 @@
+/*
+---------------------------------------------------------------------------
+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 AI_AABB_H_INC
+#define AI_AABB_H_INC
+
+#include <assimp/vector3.h>
+
+struct aiAABB {
+ C_STRUCT aiVector3D mMin;
+ C_STRUCT aiVector3D mMax;
+
+#ifdef __cplusplus
+
+ aiAABB()
+ : mMin()
+ , mMax() {
+ // empty
+ }
+
+ aiAABB(const aiVector3D &min, const aiVector3D &max )
+ : mMin(min)
+ , mMax(max) {
+ // empty
+ }
+
+ ~aiAABB() {
+ // empty
+ }
+
+#endif
+};
+
+
+#endif
diff --git a/thirdparty/assimp/include/assimp/camera.h b/thirdparty/assimp/include/assimp/camera.h
index 99daf69934..e573eea5d1 100644
--- a/thirdparty/assimp/include/assimp/camera.h
+++ b/thirdparty/assimp/include/assimp/camera.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,
@@ -60,7 +58,7 @@ extern "C" {
*
* Cameras have a representation in the node graph and can be animated.
* An important aspect is that the camera itself is also part of the
- * scenegraph. This means, any values such as the look-at vector are not
+ * scene-graph. This means, any values such as the look-at vector are not
* *absolute*, they're <b>relative</b> to the coordinate system defined
* by the node which corresponds to the camera. This allows for camera
* animations. For static cameras parameters like the 'look-at' or 'up' vectors
@@ -162,7 +160,6 @@ struct aiCamera
*/
float mClipPlaneFar;
-
/** Screen aspect ratio.
*
* This is the ration between the width and the height of the
diff --git a/thirdparty/assimp/include/assimp/color4.inl b/thirdparty/assimp/include/assimp/color4.inl
index 3192d55f39..afa53dcb5b 100644
--- a/thirdparty/assimp/include/assimp/color4.inl
+++ b/thirdparty/assimp/include/assimp/color4.inl
@@ -85,6 +85,8 @@ AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
return g;
case 2:
return b;
+ case 3:
+ return a;
default:
break;
}
@@ -100,6 +102,8 @@ AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
return g;
case 2:
return b;
+ case 3:
+ return a;
default:
break;
}
diff --git a/thirdparty/assimp/include/assimp/config.h.in b/thirdparty/assimp/include/assimp/config.h.in
index a37ff0b8c8..d08b929a10 100644
--- a/thirdparty/assimp/include/assimp/config.h.in
+++ b/thirdparty/assimp/include/assimp/config.h.in
@@ -142,7 +142,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @brief Specifies the maximum angle that may be between two vertex tangents
* that their tangents and bi-tangents are smoothed.
*
- * This applies to the CalcTangentSpace-Step. The angle is specified
+ * This applies to the CalcTangentSpace-Step. TFvhe angle is specified
* in degrees. The maximum value is 175.
* Property type: float. Default value: 45 degrees
*/
@@ -651,13 +651,28 @@ enum aiComponent
// ---------------------------------------------------------------------------
/** @brief Set whether the fbx importer will use the legacy embedded texture naming.
-*
-* The default value is false (0)
-* Property type: bool
-*/
+ *
+ * The default value is false (0)
+ * Property type: bool
+ */
#define AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING \
"AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
-
+
+// ---------------------------------------------------------------------------
+/** @brief Set wether the importer shall not remove empty bones.
+ *
+ * Empty bone are often used to define connections for other models.
+ */
+#define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \
+ "AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES"
+
+
+// ---------------------------------------------------------------------------
+/** @brief Set wether the FBX importer shall convert the unit from cm to m.
+ */
+#define AI_CONFIG_FBX_CONVERT_TO_M \
+ "AI_CONFIG_FBX_CONVERT_TO_M"
+
// ---------------------------------------------------------------------------
/** @brief Set the vertex animation keyframe to be imported
*
@@ -966,8 +981,12 @@ enum aiComponent
#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
-/**
- *
+/** @brief Specifies whether the assimp export shall be able to export point clouds
+ *
+ * When this flag is not defined the render data has to contain valid faces.
+ * Point clouds are only a collection of vertices which have nor spatial organization
+ * by a face and the validation process will remove them. Enabling this feature will
+ * switch off the flag and enable the functionality to export pure point clouds.
*/
#define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS"
diff --git a/thirdparty/assimp/include/assimp/defs.h b/thirdparty/assimp/include/assimp/defs.h
index 4a177e3c3e..05a5e3fd4b 100644
--- a/thirdparty/assimp/include/assimp/defs.h
+++ b/thirdparty/assimp/include/assimp/defs.h
@@ -122,7 +122,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* OPTIMIZEANIMS
* OPTIMIZEGRAPH
* GENENTITYMESHES
- * FIXTEXTUREPATHS */
+ * FIXTEXTUREPATHS
+ * GENBOUNDINGBOXES */
//////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
@@ -214,10 +215,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#if (defined(__BORLANDC__) || defined (__BCPLUSPLUS__))
-#error Currently, Borland is unsupported. Feel free to port Assimp.
-
-// "W8059 Packgröße der Struktur geändert"
-
+# error Currently, Borland is unsupported. Feel free to port Assimp.
#endif
@@ -243,10 +241,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
typedef double ai_real;
typedef signed long long int ai_int;
typedef unsigned long long int ai_uint;
+#ifndef ASSIMP_AI_REAL_TEXT_PRECISION
+#define ASSIMP_AI_REAL_TEXT_PRECISION 16
+#endif // ASSIMP_AI_REAL_TEXT_PRECISION
#else // ASSIMP_DOUBLE_PRECISION
typedef float ai_real;
typedef signed int ai_int;
typedef unsigned int ai_uint;
+#ifndef ASSIMP_AI_REAL_TEXT_PRECISION
+#define ASSIMP_AI_REAL_TEXT_PRECISION 8
+#endif // ASSIMP_AI_REAL_TEXT_PRECISION
#endif // ASSIMP_DOUBLE_PRECISION
//////////////////////////////////////////////////////////////////////////
@@ -267,6 +271,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_DEG_TO_RAD(x) ((x)*(ai_real)0.0174532925)
#define AI_RAD_TO_DEG(x) ((x)*(ai_real)57.2957795)
+/* Numerical limits */
+static const ai_real ai_epsilon = (ai_real) 0.00001;
+
/* Support for big-endian builds */
#if defined(__BYTE_ORDER__)
# if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
@@ -293,11 +300,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _MSC_VER
# define AI_NO_EXCEPT noexcept
#else
-# if (_MSC_VER == 1915 )
+# if (_MSC_VER >= 1915 )
# define AI_NO_EXCEPT noexcept
# else
# define AI_NO_EXCEPT
# endif
-#endif
+#endif // _MSC_VER
#endif // !! AI_DEFINES_H_INC
diff --git a/thirdparty/assimp/include/assimp/mesh.h b/thirdparty/assimp/include/assimp/mesh.h
index 36f3ed2afd..f1628f1f54 100644
--- a/thirdparty/assimp/include/assimp/mesh.h
+++ b/thirdparty/assimp/include/assimp/mesh.h
@@ -48,7 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MESH_H_INC
#define AI_MESH_H_INC
-#include "types.h"
+#include <assimp/types.h>
+#include <assimp/aabb.h>
#ifdef __cplusplus
extern "C" {
@@ -714,6 +715,11 @@ struct aiMesh
* Method of morphing when animeshes are specified.
*/
unsigned int mMethod;
+
+ /**
+ *
+ */
+ C_STRUCT aiAABB mAABB;
#ifdef __cplusplus
@@ -735,7 +741,8 @@ struct aiMesh
, mMaterialIndex( 0 )
, mNumAnimMeshes( 0 )
, mAnimMeshes(nullptr)
- , mMethod( 0 ) {
+ , mMethod( 0 )
+ , mAABB() {
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a ) {
mNumUVComponents[a] = 0;
mTextureCoords[a] = nullptr;
diff --git a/thirdparty/assimp/include/assimp/postprocess.h b/thirdparty/assimp/include/assimp/postprocess.h
index c23a5490a5..2a74414216 100644
--- a/thirdparty/assimp/include/assimp/postprocess.h
+++ b/thirdparty/assimp/include/assimp/postprocess.h
@@ -438,7 +438,7 @@ enum aiPostProcessSteps
aiProcess_FindInstances = 0x100000,
// -------------------------------------------------------------------------
- /** <hr>A postprocessing step to reduce the number of meshes.
+ /** <hr>A post-processing step to reduce the number of meshes.
*
* This will, in fact, reduce the number of draw calls.
*
@@ -450,7 +450,7 @@ enum aiPostProcessSteps
// -------------------------------------------------------------------------
- /** <hr>A postprocessing step to optimize the scene hierarchy.
+ /** <hr>A post-processing step to optimize the scene hierarchy.
*
* Nodes without animations, bones, lights or cameras assigned are
* collapsed and joined.
@@ -514,7 +514,7 @@ enum aiPostProcessSteps
// -------------------------------------------------------------------------
/** <hr>This step splits meshes with many bones into sub-meshes so that each
- * su-bmesh has fewer or as many bones as a given limit.
+ * sub-mesh has fewer or as many bones as a given limit.
*/
aiProcess_SplitByBoneCount = 0x2000000,
@@ -541,7 +541,7 @@ enum aiPostProcessSteps
* global scaling from your importer settings like in FBX. Use the flag
* AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY from the global property table to configure this.
*
- * Use <tt>#AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY</tt> to setup the global scaing factor.
+ * Use <tt>#AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY</tt> to setup the global scaling factor.
*/
aiProcess_GlobalScale = 0x8000000,
@@ -574,6 +574,11 @@ enum aiPostProcessSteps
* This process gives sense back to aiProcess_JoinIdenticalVertices
*/
aiProcess_DropNormals = 0x40000000,
+
+ // -------------------------------------------------------------------------
+ /**
+ */
+ aiProcess_GenBoundingBoxes = 0x80000000
};
diff --git a/thirdparty/assimp/include/assimp/scene.h b/thirdparty/assimp/include/assimp/scene.h
index de0239702d..df5d6f3b5e 100644
--- a/thirdparty/assimp/include/assimp/scene.h
+++ b/thirdparty/assimp/include/assimp/scene.h
@@ -56,6 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "material.h"
#include "anim.h"
#include "metadata.h"
+#include <cstdlib>
#ifdef __cplusplus
extern "C" {
@@ -389,6 +390,14 @@ struct aiScene
//! Returns an embedded texture
const aiTexture* GetEmbeddedTexture(const char* filename) const {
+ // lookup using texture ID (if referenced like: "*1", "*2", etc.)
+ if ('*' == *filename) {
+ int index = std::atoi(filename + 1);
+ if (0 > index || mNumTextures <= static_cast<unsigned>(index))
+ return nullptr;
+ return mTextures[index];
+ }
+ // lookup using filename
const char* shortFilename = GetShortFilename(filename);
for (unsigned int i = 0; i < mNumTextures; i++) {
const char* shortTextureFilename = GetShortFilename(mTextures[i]->mFilename.C_Str());
diff --git a/thirdparty/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp
index fad9a37a9a..62fbd1b72d 100644
--- a/thirdparty/jpeg-compressor/jpgd.cpp
+++ b/thirdparty/jpeg-compressor/jpgd.cpp
@@ -29,6 +29,10 @@
#define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b))
#define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b))
+// TODO: Move to header and use these constants when declaring the arrays.
+#define JPGD_HUFF_TREE_MAX_LENGTH 512
+#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256
+
namespace jpgd {
static inline void *jpgd_malloc(size_t nSize) { return malloc(nSize); }
@@ -491,8 +495,9 @@ inline uint jpeg_decoder::get_bits_no_markers(int num_bits)
// Decodes a Huffman encoded symbol.
inline int jpeg_decoder::huff_decode(huff_tables *pH)
{
- int symbol;
+ JPGD_ASSERT(pH);
+ int symbol;
// Check first 8-bits: do we have a complete symbol?
if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0)
{
@@ -500,14 +505,19 @@ inline int jpeg_decoder::huff_decode(huff_tables *pH)
int ofs = 23;
do
{
- symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))];
+ unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
+ JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
+ symbol = pH->tree[idx];
ofs--;
} while (symbol < 0);
get_bits_no_markers(8 + (23 - ofs));
}
else
+ {
+ JPGD_ASSERT(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
get_bits_no_markers(pH->code_size[symbol]);
+ }
return symbol;
}
@@ -517,6 +527,8 @@ inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits)
{
int symbol;
+ JPGD_ASSERT(pH);
+
// Check first 8-bits: do we have a complete symbol?
if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0)
{
@@ -524,7 +536,9 @@ inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits)
int ofs = 23;
do
{
- symbol = pH->tree[-(int)(symbol + ((m_bit_buf >> ofs) & 1))];
+ unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
+ JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
+ symbol = pH->tree[idx];
ofs--;
} while (symbol < 0);
@@ -1495,6 +1509,12 @@ void jpeg_decoder::fix_in_buffer()
void jpeg_decoder::transform_mcu(int mcu_row)
{
jpgd_block_t* pSrc_ptr = m_pMCU_coefficients;
+ if (m_freq_domain_chroma_upsample) {
+ JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_expanded_blocks_per_row);
+ }
+ else {
+ JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_max_blocks_per_row);
+ }
uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64;
for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
@@ -1650,6 +1670,7 @@ void jpeg_decoder::load_next_row()
for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
{
component_id = m_mcu_org[mcu_block];
+ JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES);
q = m_quant[m_comp_quant[component_id]];
p = m_pMCU_coefficients + 64 * mcu_block;
@@ -1770,6 +1791,7 @@ void jpeg_decoder::decode_next_row()
for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64)
{
int component_id = m_mcu_org[mcu_block];
+ JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES);
jpgd_quant_t* q = m_quant[m_comp_quant[component_id]];
int r, s;
@@ -2229,7 +2251,10 @@ void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
for (l = 1; l <= 16; l++)
{
for (i = 1; i <= m_huff_num[index][l]; i++)
+ {
+ JPGD_ASSERT(p < 257);
huffsize[p++] = static_cast<uint8>(l);
+ }
}
huffsize[p] = 0;
@@ -2244,6 +2269,7 @@ void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
{
while (huffsize[p] == si)
{
+ JPGD_ASSERT(p < 257);
huffcode[p++] = code;
code++;
}
@@ -2275,7 +2301,8 @@ void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
for (l = 1 << (8 - code_size); l > 0; l--)
{
- JPGD_ASSERT(i < 256);
+ JPGD_ASSERT(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
+ JPGD_ASSERT(code < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
pH->look_up[code] = i;
@@ -2325,16 +2352,19 @@ void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
if ((code & 0x8000) == 0)
currententry--;
- if (pH->tree[-currententry - 1] == 0)
+ unsigned int idx = -currententry - 1;
+ JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
+ if (pH->tree[idx] == 0)
{
- pH->tree[-currententry - 1] = nextfreeentry;
+ pH->tree[idx] = nextfreeentry;
currententry = nextfreeentry;
nextfreeentry -= 2;
}
- else
- currententry = pH->tree[-currententry - 1];
+ else {
+ currententry = pH->tree[idx];
+ }
code <<= 1;
}
@@ -2636,7 +2666,9 @@ void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int
for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++)
{
- s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]);
+ unsigned int idx = pD->m_comp_ac_tab[component_id];
+ JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES);
+ s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
r = s >> 4;
s &= 15;
@@ -2679,7 +2711,6 @@ void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, in
int p1 = 1 << pD->m_successive_low;
int m1 = (-1) << pD->m_successive_low;
jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
-
JPGD_ASSERT(pD->m_spectral_end <= 63);
k = pD->m_spectral_start;
@@ -2688,7 +2719,9 @@ void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, in
{
for ( ; k <= pD->m_spectral_end; k++)
{
- s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]);
+ unsigned int idx = pD->m_comp_ac_tab[component_id];
+ JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES);
+ s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
r = s >> 4;
s &= 15;