summaryrefslogtreecommitdiff
path: root/thirdparty/assimp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/assimp')
-rw-r--r--thirdparty/assimp/assimp/config.h23
-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)48
-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)161
-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)74
-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)102
-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)70
-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)50
-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)14
-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)18
-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)8
-rw-r--r--thirdparty/assimp/code/FBX/FBXConverter.cpp (renamed from thirdparty/assimp/code/FBXConverter.cpp)598
-rw-r--r--thirdparty/assimp/code/FBX/FBXConverter.h (renamed from thirdparty/assimp/code/FBXConverter.h)106
-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)8
-rw-r--r--thirdparty/assimp/code/FBX/FBXDocument.h (renamed from thirdparty/assimp/code/FBXDocument.h)43
-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)255
-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)270
-rw-r--r--thirdparty/assimp/code/FBX/FBXExporter.h (renamed from thirdparty/assimp/code/FBXExporter.h)2
-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.cpp198
-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)58
-rw-r--r--thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp (renamed from thirdparty/assimp/code/FBXMeshGeometry.cpp)36
-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.cpp243
-rw-r--r--thirdparty/assimp/code/FBX/FBXUtil.h (renamed from thirdparty/assimp/code/FBXUtil.h)34
-rw-r--r--thirdparty/assimp/code/FBXImporter.cpp197
-rw-r--r--thirdparty/assimp/code/FBXUtil.cpp120
-rw-r--r--thirdparty/assimp/code/FIReader.cpp1834
-rw-r--r--thirdparty/assimp/code/MMDImporter.cpp370
-rw-r--r--thirdparty/assimp/code/MMDImporter.h96
-rw-r--r--thirdparty/assimp/code/MMDPmdParser.h597
-rw-r--r--thirdparty/assimp/code/MMDPmxParser.cpp604
-rw-r--r--thirdparty/assimp/code/MMDPmxParser.h782
-rw-r--r--thirdparty/assimp/code/MMDVmdParser.h376
-rw-r--r--thirdparty/assimp/code/Material/MaterialSystem.cpp (renamed from thirdparty/assimp/code/MaterialSystem.cpp)31
-rw-r--r--thirdparty/assimp/code/Material/MaterialSystem.h (renamed from thirdparty/assimp/code/MaterialSystem.h)0
-rw-r--r--thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp268
-rw-r--r--thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h112
-rw-r--r--thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp (renamed from thirdparty/assimp/code/CalcTangentsProcess.cpp)6
-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)6
-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)1
-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.h (renamed from thirdparty/assimp/include/assimp/Macros.h)39
-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)25
-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)29
-rw-r--r--thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h (renamed from thirdparty/assimp/code/MakeVerboseFormat.h)10
-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.cpp208
-rw-r--r--thirdparty/assimp/code/PostProcessing/ScaleProcess.h (renamed from thirdparty/assimp/code/ScaleProcess.h)15
-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)96
-rw-r--r--thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h (renamed from thirdparty/assimp/code/ValidateDataStructure.h)11
-rw-r--r--thirdparty/assimp/code/RawLoader.cpp331
-rw-r--r--thirdparty/assimp/code/ScaleProcess.cpp103
-rw-r--r--thirdparty/assimp/code/res/resource.h14
-rw-r--r--thirdparty/assimp/code/revision.h23
-rw-r--r--thirdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes12
-rw-r--r--thirdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html1789
-rw-r--r--thirdparty/assimp/include/assimp/BaseImporter.h63
-rw-r--r--thirdparty/assimp/include/assimp/Bitmap.h6
-rw-r--r--thirdparty/assimp/include/assimp/ByteSwapper.h5
-rw-r--r--thirdparty/assimp/include/assimp/CreateAnimMesh.h14
-rw-r--r--thirdparty/assimp/include/assimp/DefaultIOStream.h19
-rw-r--r--thirdparty/assimp/include/assimp/DefaultIOSystem.h5
-rw-r--r--thirdparty/assimp/include/assimp/Defines.h9
-rw-r--r--thirdparty/assimp/include/assimp/Exceptional.h23
-rw-r--r--thirdparty/assimp/include/assimp/Exporter.hpp6
-rw-r--r--thirdparty/assimp/include/assimp/GenericProperty.h7
-rw-r--r--thirdparty/assimp/include/assimp/Hash.h6
-rw-r--r--thirdparty/assimp/include/assimp/IOStream.hpp12
-rw-r--r--thirdparty/assimp/include/assimp/IOStreamBuffer.h43
-rw-r--r--thirdparty/assimp/include/assimp/IOSystem.hpp4
-rw-r--r--thirdparty/assimp/include/assimp/Importer.hpp4
-rw-r--r--thirdparty/assimp/include/assimp/LineSplitter.h36
-rw-r--r--thirdparty/assimp/include/assimp/LogAux.h5
-rw-r--r--thirdparty/assimp/include/assimp/MathFunctions.h33
-rw-r--r--thirdparty/assimp/include/assimp/MemoryIOWrapper.h6
-rw-r--r--thirdparty/assimp/include/assimp/ParsingUtils.h12
-rw-r--r--thirdparty/assimp/include/assimp/Profiler.h14
-rw-r--r--thirdparty/assimp/include/assimp/ProgressHandler.hpp8
-rw-r--r--thirdparty/assimp/include/assimp/RemoveComments.h8
-rw-r--r--thirdparty/assimp/include/assimp/SGSpatialSort.h5
-rw-r--r--thirdparty/assimp/include/assimp/SceneCombiner.h11
-rw-r--r--thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h5
-rw-r--r--thirdparty/assimp/include/assimp/SmoothingGroups.h6
-rw-r--r--thirdparty/assimp/include/assimp/SmoothingGroups.inl7
-rw-r--r--thirdparty/assimp/include/assimp/SpatialSort.h5
-rw-r--r--thirdparty/assimp/include/assimp/StandardShapes.h7
-rw-r--r--thirdparty/assimp/include/assimp/StreamReader.h10
-rw-r--r--thirdparty/assimp/include/assimp/StreamWriter.h8
-rw-r--r--thirdparty/assimp/include/assimp/StringComparison.h7
-rw-r--r--thirdparty/assimp/include/assimp/StringUtils.h5
-rw-r--r--thirdparty/assimp/include/assimp/Subdivision.h5
-rw-r--r--thirdparty/assimp/include/assimp/TinyFormatter.h32
-rw-r--r--thirdparty/assimp/include/assimp/Vertex.h67
-rw-r--r--thirdparty/assimp/include/assimp/XMLTools.h5
-rw-r--r--thirdparty/assimp/include/assimp/aabb.h (renamed from thirdparty/assimp/code/MMDCpp14.h)86
-rw-r--r--thirdparty/assimp/include/assimp/ai_assert.h4
-rw-r--r--thirdparty/assimp/include/assimp/anim.h4
-rw-r--r--thirdparty/assimp/include/assimp/camera.h11
-rw-r--r--thirdparty/assimp/include/assimp/cexport.h6
-rw-r--r--thirdparty/assimp/include/assimp/cfileio.h6
-rw-r--r--thirdparty/assimp/include/assimp/cimport.h6
-rw-r--r--thirdparty/assimp/include/assimp/color4.h13
-rw-r--r--thirdparty/assimp/include/assimp/color4.inl98
-rw-r--r--thirdparty/assimp/include/assimp/config.h.in40
-rw-r--r--thirdparty/assimp/include/assimp/defs.h62
-rw-r--r--thirdparty/assimp/include/assimp/fast_atof.h6
-rw-r--r--thirdparty/assimp/include/assimp/importerdesc.h10
-rw-r--r--thirdparty/assimp/include/assimp/irrXMLWrapper.h144
-rw-r--r--thirdparty/assimp/include/assimp/light.h6
-rw-r--r--thirdparty/assimp/include/assimp/material.h53
-rw-r--r--thirdparty/assimp/include/assimp/material.inl265
-rw-r--r--thirdparty/assimp/include/assimp/matrix3x3.h15
-rw-r--r--thirdparty/assimp/include/assimp/matrix3x3.inl70
-rw-r--r--thirdparty/assimp/include/assimp/matrix4x4.h18
-rw-r--r--thirdparty/assimp/include/assimp/matrix4x4.inl179
-rw-r--r--thirdparty/assimp/include/assimp/mesh.h51
-rw-r--r--thirdparty/assimp/include/assimp/metadata.h4
-rw-r--r--thirdparty/assimp/include/assimp/pbrmaterial.h7
-rw-r--r--thirdparty/assimp/include/assimp/postprocess.h34
-rw-r--r--thirdparty/assimp/include/assimp/qnan.h31
-rw-r--r--thirdparty/assimp/include/assimp/quaternion.h6
-rw-r--r--thirdparty/assimp/include/assimp/quaternion.inl6
-rw-r--r--thirdparty/assimp/include/assimp/scene.h51
-rw-r--r--thirdparty/assimp/include/assimp/texture.h13
-rw-r--r--thirdparty/assimp/include/assimp/types.h49
-rw-r--r--thirdparty/assimp/include/assimp/vector2.h4
-rw-r--r--thirdparty/assimp/include/assimp/vector2.inl6
-rw-r--r--thirdparty/assimp/include/assimp/vector3.h12
-rw-r--r--thirdparty/assimp/include/assimp/vector3.inl2
-rw-r--r--thirdparty/assimp/include/assimp/version.h2
230 files changed, 6889 insertions, 7340 deletions
diff --git a/thirdparty/assimp/assimp/config.h b/thirdparty/assimp/assimp/config.h
index 8b0634d28b..d0e4817349 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).
@@ -968,6 +983,13 @@ enum aiComponent {
#define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f
#endif // !! AI_DEBONE_THRESHOLD
+#define AI_CONFIG_APP_SCALE_KEY "APP_SCALE_FACTOR"
+
+#if (!defined AI_CONFIG_APP_SCALE_KEY)
+# define AI_CONFIG_APP_SCALE_KEY 1.0
+#endif // AI_CONFIG_APP_SCALE_KEY
+
+
// ---------- All the Build/Compile-time defines ------------
/** @brief Specifies if double precision is supported inside assimp
@@ -978,3 +1000,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..5c1e605549 100644
--- a/thirdparty/assimp/code/BaseImporter.cpp
+++ b/thirdparty/assimp/code/Common/BaseImporter.cpp
@@ -67,7 +67,20 @@ using namespace Assimp;
// Constructor to be privately used by Importer
BaseImporter::BaseImporter() AI_NO_EXCEPT
: m_progress() {
- // nothing to do here
+ /**
+ * Assimp Importer
+ * unit conversions available
+ * if you need another measurment unit add it below.
+ * it's currently defined in assimp that we prefer meters.
+ *
+ * NOTE: Initialised here rather than in the header file
+ * to workaround a VS2013 bug with brace initialisers
+ * */
+ importerUnits[ImporterUnits::M] = 1.0;
+ importerUnits[ImporterUnits::CM] = 0.01;
+ importerUnits[ImporterUnits::MM] = 0.001;
+ importerUnits[ImporterUnits::INCHES] = 0.0254;
+ importerUnits[ImporterUnits::FEET] = 0.3048;
}
// ------------------------------------------------------------------------------------------------
@@ -76,9 +89,25 @@ BaseImporter::~BaseImporter() {
// nothing to do here
}
+void BaseImporter::UpdateImporterScale( Importer* pImp )
+{
+ ai_assert(pImp != nullptr);
+ ai_assert(importerScale != 0.0);
+ ai_assert(fileScale != 0.0);
+
+ double activeScale = importerScale * fileScale;
+
+ // Set active scaling
+ pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) );
+
+ ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
+}
+
// ------------------------------------------------------------------------------------------------
// Imports the given file and returns the imported data.
-aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
+aiScene* BaseImporter::ReadFile(Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
+
+
m_progress = pImp->GetProgressHandler();
if (nullptr == m_progress) {
return nullptr;
@@ -100,6 +129,11 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
{
InternReadFile( pFile, sc.get(), &filter);
+ // Calculate import scale hook - required because pImp not available anywhere else
+ // passes scale into ScaleProcess
+ UpdateImporterScale(pImp);
+
+
} catch( const std::exception& err ) {
// extract error description
m_ErrorText = err.what();
@@ -112,7 +146,7 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
}
// ------------------------------------------------------------------------------------------------
-void BaseImporter::SetupProperties(const Importer* /*pImp*/)
+void BaseImporter::SetupProperties(const Importer* pImp)
{
// the default implementation does nothing
}
@@ -320,7 +354,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
@@ -584,6 +622,8 @@ aiScene* BatchLoader::GetImport( unsigned int which )
return nullptr;
}
+
+
// ------------------------------------------------------------------------------------------------
void BatchLoader::LoadAll()
{
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..6fdc24dd80 100644
--- a/thirdparty/assimp/code/DefaultIOSystem.cpp
+++ b/thirdparty/assimp/code/Common/DefaultIOSystem.cpp
@@ -61,83 +61,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
-// maximum path length
-// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
-#ifdef PATH_MAX
-# define PATHLIMIT PATH_MAX
-#else
-# define PATHLIMIT 4096
+#ifdef _WIN32
+static std::wstring Utf8ToWide(const char* in)
+{
+ int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0);
+ // size includes terminating null; std::wstring adds null automatically
+ std::wstring out(static_cast<size_t>(size) - 1, L'\0');
+ MultiByteToWideChar(CP_UTF8, 0, in, -1, &out[0], size);
+ return out;
+}
+
+static std::string WideToUtf8(const wchar_t* in)
+{
+ int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr);
+ // size includes terminating null; std::string adds null automatically
+ std::string out(static_cast<size_t>(size) - 1, '\0');
+ WideCharToMultiByte(CP_UTF8, 0, in, -1, &out[0], size, nullptr, nullptr);
+ return out;
+}
#endif
// ------------------------------------------------------------------------------------------------
// Tests for the existence of a file at the given path.
-bool DefaultIOSystem::Exists( const char* pFile) const
+bool DefaultIOSystem::Exists(const char* pFile) const
{
#ifdef _WIN32
- wchar_t fileName16[PATHLIMIT];
-
-#ifndef WindowsStore
- bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
- if (isUnicode) {
-
- MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
- struct __stat64 filestat;
- if (0 != _wstat64(fileName16, &filestat)) {
- return false;
- }
- } else {
-#endif
- FILE* file = ::fopen(pFile, "rb");
- if (!file)
- return false;
-
- ::fclose(file);
-#ifndef WindowsStore
+ struct __stat64 filestat;
+ if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) {
+ return false;
}
-#endif
#else
- FILE* file = ::fopen( pFile, "rb");
- if( !file)
+ FILE* file = ::fopen(pFile, "rb");
+ if (!file)
return false;
- ::fclose( file);
+ ::fclose(file);
#endif
return true;
}
// ------------------------------------------------------------------------------------------------
// Open a new file with a given path.
-IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
+IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode)
{
- ai_assert(NULL != strFile);
- ai_assert(NULL != strMode);
+ ai_assert(strFile != nullptr);
+ ai_assert(strMode != nullptr);
FILE* file;
#ifdef _WIN32
- wchar_t fileName16[PATHLIMIT];
-#ifndef WindowsStore
- bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
- if (isUnicode) {
- MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
- std::string mode8(strMode);
- file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str());
- } else {
-#endif
- file = ::fopen(strFile, strMode);
-#ifndef WindowsStore
- }
-#endif
+ file = ::_wfopen(Utf8ToWide(strFile).c_str(), Utf8ToWide(strMode).c_str());
#else
file = ::fopen(strFile, strMode);
#endif
- if (nullptr == file)
+ if (!file)
return nullptr;
- return new DefaultIOStream(file, (std::string) strFile);
+ return new DefaultIOStream(file, strFile);
}
// ------------------------------------------------------------------------------------------------
// Closes the given file and releases all resources associated with it.
-void DefaultIOSystem::Close( IOStream* pFile)
+void DefaultIOSystem::Close(IOStream* pFile)
{
delete pFile;
}
@@ -155,78 +138,56 @@ char DefaultIOSystem::getOsSeparator() const
// ------------------------------------------------------------------------------------------------
// IOSystem default implementation (ComparePaths isn't a pure virtual function)
-bool IOSystem::ComparePaths (const char* one, const char* second) const
+bool IOSystem::ComparePaths(const char* one, const char* second) const
{
- return !ASSIMP_stricmp(one,second);
+ return !ASSIMP_stricmp(one, second);
}
// ------------------------------------------------------------------------------------------------
// Convert a relative path into an absolute path
-inline static void MakeAbsolutePath (const char* in, char* _out)
+inline static std::string MakeAbsolutePath(const char* in)
{
- ai_assert(in && _out);
-#if defined( _MSC_VER ) || defined( __MINGW32__ )
-#ifndef WindowsStore
- bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0;
- if (isUnicode) {
- wchar_t out16[PATHLIMIT];
- wchar_t in16[PATHLIMIT];
- MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT);
- wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT);
- if (ret) {
- WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr);
- }
- if (!ret) {
- // preserve the input path, maybe someone else is able to fix
- // the path before it is accessed (e.g. our file system filter)
- ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
- strcpy(_out, in);
- }
-
- } else {
-#endif
- char* ret = :: _fullpath(_out, in, PATHLIMIT);
- if (!ret) {
- // preserve the input path, maybe someone else is able to fix
- // the path before it is accessed (e.g. our file system filter)
- ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
- strcpy(_out, in);
- }
-#ifndef WindowsStore
+ ai_assert(in);
+ std::string out;
+#ifdef _WIN32
+ wchar_t* ret = ::_wfullpath(nullptr, Utf8ToWide(in).c_str(), 0);
+ if (ret) {
+ out = WideToUtf8(ret);
+ free(ret);
}
-#endif
#else
- // use realpath
- char* ret = realpath(in, _out);
- if(!ret) {
+ char* ret = realpath(in, nullptr);
+ if (ret) {
+ out = ret;
+ free(ret);
+ }
+#endif
+ if (!ret) {
// preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter)
ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
- strcpy(_out,in);
+ out = in;
}
-#endif
+ return out;
}
// ------------------------------------------------------------------------------------------------
// DefaultIOSystem's more specialized implementation
-bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
+bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const
{
// chances are quite good both paths are formatted identically,
// so we can hopefully return here already
- if( !ASSIMP_stricmp(one,second) )
+ if (!ASSIMP_stricmp(one, second))
return true;
- char temp1[PATHLIMIT];
- char temp2[PATHLIMIT];
-
- MakeAbsolutePath (one, temp1);
- MakeAbsolutePath (second, temp2);
+ std::string temp1 = MakeAbsolutePath(one);
+ std::string temp2 = MakeAbsolutePath(second);
- return !ASSIMP_stricmp(temp1,temp2);
+ return !ASSIMP_stricmp(temp1, temp2);
}
// ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::fileName( const std::string &path )
+std::string DefaultIOSystem::fileName(const std::string& path)
{
std::string ret = path;
std::size_t last = ret.find_last_of("\\/");
@@ -235,16 +196,16 @@ std::string DefaultIOSystem::fileName( const std::string &path )
}
// ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::completeBaseName( const std::string &path )
+std::string DefaultIOSystem::completeBaseName(const std::string& path)
{
std::string ret = fileName(path);
std::size_t pos = ret.find_last_of('.');
- if(pos != ret.npos) ret = ret.substr(0, pos);
+ if (pos != std::string::npos) ret = ret.substr(0, pos);
return ret;
}
// ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::absolutePath( const std::string &path )
+std::string DefaultIOSystem::absolutePath(const std::string& path)
{
std::string ret = path;
std::size_t last = ret.find_last_of("\\/");
@@ -253,5 +214,3 @@ std::string DefaultIOSystem::absolutePath( const std::string &path )
}
// ------------------------------------------------------------------------------------------------
-
-#undef PATHLIMIT
diff --git a/thirdparty/assimp/code/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..4ce1a2bd80 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,9 @@ void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperti
void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
+void ExportSceneM3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneA3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportAssimp2Json(const char* , IOSystem*, const aiScene* , const Assimp::ExportProperties*);
// ------------------------------------------------------------------------------------------------
// global array of all export formats which Assimp supports in its current build
@@ -161,11 +165,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
@@ -177,8 +181,17 @@ Exporter::ExportFormatEntry gExporters[] =
Exporter::ExportFormatEntry( "fbxa", "Autodesk FBX (ascii)", "fbx", &ExportSceneFBXA, 0 ),
#endif
+#ifndef ASSIMP_BUILD_NO_M3D_EXPORTER
+ Exporter::ExportFormatEntry( "m3d", "Model 3D (binary)", "m3d", &ExportSceneM3D, 0 ),
+ Exporter::ExportFormatEntry( "a3d", "Model 3D (ascii)", "m3d", &ExportSceneA3D, 0 ),
+#endif
+
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
- Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 )
+ 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 +301,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 +311,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;
}
@@ -310,34 +323,6 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
}
// ------------------------------------------------------------------------------------------------
-bool IsVerboseFormat(const aiMesh* mesh) {
- // avoid slow vector<bool> specialization
- std::vector<unsigned int> seen(mesh->mNumVertices,0);
- for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
- const aiFace& f = mesh->mFaces[i];
- for(unsigned int j = 0; j < f.mNumIndices; ++j) {
- if(++seen[f.mIndices[j]] == 2) {
- // found a duplicate index
- return false;
- }
- }
- }
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool IsVerboseFormat(const aiScene* pScene) {
- for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- if(!IsVerboseFormat(pScene->mMeshes[i])) {
- return false;
- }
- }
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
unsigned int pPreprocessing, const ExportProperties* pProperties) {
ASSIMP_BEGIN_EXCEPTION_REGION();
@@ -346,7 +331,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
// format. They will likely not be aware that there is a flag in the scene to indicate
// this, however. To avoid surprises and bug reports, we check for duplicates in
// meshes upfront.
- const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
+ const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || MakeVerboseFormatProcess::IsVerboseFormat(pScene);
pimpl->mProgressHandler->UpdateFileWrite(0, 4);
@@ -466,7 +451,10 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
}
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
- exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
+ ExportProperties* pProp = pProperties ? (ExportProperties*)pProperties : &emptyProperties;
+ pProp->SetPropertyBool("bJoinIdenticalVertices", must_join_again);
+ exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
+ exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
pimpl->mProgressHandler->UpdateFileWrite(4, 4);
} catch (DeadlyExportError& err) {
diff --git a/thirdparty/assimp/code/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..b9f28f0356 100644
--- a/thirdparty/assimp/code/ImporterRegistry.cpp
+++ b/thirdparty/assimp/code/Common/ImporterRegistry.cpp
@@ -56,146 +56,149 @@ 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_M3D_IMPORTER
+# include "M3D/M3DImporter.h"
#endif
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
# include "Importer/StepFile/StepFileImporter.h"
@@ -223,6 +226,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
out.push_back( new Discreet3DSImporter());
#endif
+#if (!defined ASSIMP_BUILD_NO_M3D_IMPORTER)
+ out.push_back( new M3DImporter());
+#endif
#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
out.push_back( new MD3Importer());
#endif
@@ -364,7 +370,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..8ff4af0400 100644
--- a/thirdparty/assimp/code/PostStepRegistry.cpp
+++ b/thirdparty/assimp/code/Common/PostStepRegistry.cpp
@@ -48,89 +48,97 @@ 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_ARMATUREPOPULATE_PROCESS)
+# include "PostProcessing/ArmaturePopulate.h"
+#endif
+#if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
+# include "PostProcessing/GenBoundingBoxesProcess.h"
+#endif
+
+
namespace Assimp {
@@ -176,6 +184,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
out.push_back( new ScaleProcess());
#endif
+#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS)
+ out.push_back( new ArmaturePopulate());
+#endif
#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
out.push_back( new PretransformVertices());
#endif
@@ -246,6 +257,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..f7b13cc951 100644
--- a/thirdparty/assimp/code/SceneCombiner.cpp
+++ b/thirdparty/assimp/code/Common/SceneCombiner.cpp
@@ -1091,6 +1091,35 @@ void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) {
aiFace& f = dest->mFaces[i];
GetArrayCopy(f.mIndices,f.mNumIndices);
}
+
+ // make a deep copy of all blend shapes
+ CopyPtrArray(dest->mAnimMeshes, dest->mAnimMeshes, dest->mNumAnimMeshes);
+}
+
+// ------------------------------------------------------------------------------------------------
+void SceneCombiner::Copy(aiAnimMesh** _dest, const aiAnimMesh* src) {
+ if (nullptr == _dest || nullptr == src) {
+ return;
+ }
+
+ aiAnimMesh* dest = *_dest = new aiAnimMesh();
+
+ // get a flat copy
+ ::memcpy(dest, src, sizeof(aiAnimMesh));
+
+ // and reallocate all arrays
+ GetArrayCopy(dest->mVertices, dest->mNumVertices);
+ GetArrayCopy(dest->mNormals, dest->mNumVertices);
+ GetArrayCopy(dest->mTangents, dest->mNumVertices);
+ GetArrayCopy(dest->mBitangents, dest->mNumVertices);
+
+ unsigned int n = 0;
+ while (dest->HasTextureCoords(n))
+ GetArrayCopy(dest->mTextureCoords[n++], dest->mNumVertices);
+
+ n = 0;
+ while (dest->HasVertexColors(n))
+ GetArrayCopy(dest->mColors[n++], dest->mNumVertices);
}
// ------------------------------------------------------------------------------------------------
@@ -1167,6 +1196,7 @@ void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src ) {
// and reallocate all arrays
CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels );
+ CopyPtrArray( dest->mMorphMeshChannels, src->mMorphMeshChannels, dest->mNumMorphMeshChannels );
}
// ------------------------------------------------------------------------------------------------
@@ -1186,6 +1216,26 @@ void SceneCombiner::Copy(aiNodeAnim** _dest, const aiNodeAnim* src) {
GetArrayCopy( dest->mRotationKeys, dest->mNumRotationKeys );
}
+void SceneCombiner::Copy(aiMeshMorphAnim** _dest, const aiMeshMorphAnim* src) {
+ if ( nullptr == _dest || nullptr == src ) {
+ return;
+ }
+
+ aiMeshMorphAnim* dest = *_dest = new aiMeshMorphAnim();
+
+ // get a flat copy
+ ::memcpy(dest,src,sizeof(aiMeshMorphAnim));
+
+ // and reallocate all arrays
+ GetArrayCopy( dest->mKeys, dest->mNumKeys );
+ for (ai_uint i = 0; i < dest->mNumKeys;++i) {
+ dest->mKeys[i].mValues = new unsigned int[dest->mKeys[i].mNumValuesAndWeights];
+ dest->mKeys[i].mWeights = new double[dest->mKeys[i].mNumValuesAndWeights];
+ ::memcpy(dest->mKeys[i].mValues, src->mKeys[i].mValues, dest->mKeys[i].mNumValuesAndWeights * sizeof(unsigned int));
+ ::memcpy(dest->mKeys[i].mWeights, src->mKeys[i].mWeights, dest->mKeys[i].mNumValuesAndWeights * sizeof(double));
+ }
+}
+
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy( aiCamera** _dest,const aiCamera* src) {
if ( nullptr == _dest || nullptr == src ) {
diff --git a/thirdparty/assimp/code/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 cc94340ac8..cf1da7d5ba 100644
--- a/thirdparty/assimp/code/Version.cpp
+++ b/thirdparty/assimp/code/Common/Version.cpp
@@ -46,8 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include "ScenePrivate.h"
-static const unsigned int MajorVersion = 4;
-static const unsigned int MinorVersion = 1;
+#include "revision.h"
// --------------------------------------------------------------------------------
// Legal information string - don't remove this.
@@ -56,9 +55,9 @@ static const char* LEGAL_INFORMATION =
"Open Asset Import Library (Assimp).\n"
"A free C/C++ library to import various 3D file formats into applications\n\n"
-"(c) 2008-2017, assimp team\n"
+"(c) 2006-2019, assimp team\n"
"License under the terms and conditions of the 3-clause BSD license\n"
-"http://assimp.sourceforge.net\n"
+"http://assimp.org\n"
;
// ------------------------------------------------------------------------------------------------
@@ -70,13 +69,13 @@ ASSIMP_API const char* aiGetLegalString () {
// ------------------------------------------------------------------------------------------------
// Get Assimp minor version
ASSIMP_API unsigned int aiGetVersionMinor () {
- return MinorVersion;
+ return VER_MINOR;
}
// ------------------------------------------------------------------------------------------------
// Get Assimp major version
ASSIMP_API unsigned int aiGetVersionMajor () {
- return MajorVersion;
+ return VER_MAJOR;
}
// ------------------------------------------------------------------------------------------------
@@ -104,9 +103,6 @@ ASSIMP_API unsigned int aiGetCompileFlags () {
return flags;
}
-// include current build revision, which is even updated from time to time -- :-)
-#include "revision.h"
-
// ------------------------------------------------------------------------------------------------
ASSIMP_API unsigned int aiGetVersionRevision() {
return GitVersion;
diff --git a/thirdparty/assimp/code/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..d15619acff 100644
--- a/thirdparty/assimp/code/scene.cpp
+++ b/thirdparty/assimp/code/Common/scene.cpp
@@ -44,23 +44,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
aiNode::aiNode()
: mName("")
-, mParent(NULL)
+, mParent(nullptr)
, mNumChildren(0)
-, mChildren(NULL)
+, mChildren(nullptr)
, mNumMeshes(0)
-, mMeshes(NULL)
-, mMetaData(NULL) {
+, mMeshes(nullptr)
+, mMetaData(nullptr) {
// empty
}
aiNode::aiNode(const std::string& name)
: mName(name)
-, mParent(NULL)
+, mParent(nullptr)
, mNumChildren(0)
-, mChildren(NULL)
+, mChildren(nullptr)
, mNumMeshes(0)
-, mMeshes(NULL)
-, mMetaData(NULL) {
+, mMeshes(nullptr)
+, mMetaData(nullptr) {
// empty
}
@@ -68,7 +68,7 @@ aiNode::aiNode(const std::string& name)
aiNode::~aiNode() {
// delete all children recursively
// to make sure we won't crash if the data is invalid ...
- if (mChildren && mNumChildren)
+ if (mNumChildren && mChildren)
{
for (unsigned int a = 0; a < mNumChildren; a++)
delete mChildren[a];
diff --git a/thirdparty/assimp/code/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..03536a1823 100644
--- a/thirdparty/assimp/code/FBXCompileConfig.h
+++ b/thirdparty/assimp/code/FBX/FBXCompileConfig.h
@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INCLUDED_AI_FBX_COMPILECONFIG_H
#include <map>
+#include <set>
//
#if _MSC_VER > 1500 || (defined __GNUC___)
@@ -54,16 +55,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# else
# define fbx_unordered_map map
# define fbx_unordered_multimap multimap
+# define fbx_unordered_set set
+# define fbx_unordered_multiset multiset
#endif
#ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP
# include <unordered_map>
+# include <unordered_set>
# if _MSC_VER > 1600
# define fbx_unordered_map unordered_map
# define fbx_unordered_multimap unordered_multimap
+# define fbx_unordered_set unordered_set
+# define fbx_unordered_multiset unordered_multiset
# else
# define fbx_unordered_map tr1::unordered_map
# define fbx_unordered_multimap tr1::unordered_multimap
+# define fbx_unordered_set tr1::unordered_set
+# define fbx_unordered_multiset tr1::unordered_multiset
# endif
#endif
diff --git a/thirdparty/assimp/code/FBXConverter.cpp b/thirdparty/assimp/code/FBX/FBXConverter.cpp
index 000c4ed53b..d8a22d9f74 100644
--- a/thirdparty/assimp/code/FBXConverter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXConverter.cpp
@@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXImporter.h"
#include <assimp/StringComparison.h>
+#include <assimp/MathFunctions.h>
#include <assimp/scene.h>
@@ -66,6 +67,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <sstream>
#include <iomanip>
+#include <cstdint>
+#include <iostream>
+#include <stdlib.h>
namespace Assimp {
namespace FBX {
@@ -74,16 +78,33 @@ namespace Assimp {
#define MAGIC_NODE_TAG "_$AssimpFbx$"
-#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
-
- FBXConverter::FBXConverter(aiScene* out, const Document& doc)
- : defaultMaterialIndex()
- , out(out)
- , doc(doc) {
+#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL
+
+ FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones )
+ : defaultMaterialIndex()
+ , lights()
+ , cameras()
+ , textures()
+ , materials_converted()
+ , textures_converted()
+ , meshes_converted()
+ , node_anim_chain_bits()
+ , mNodeNames()
+ , anim_fps()
+ , out(out)
+ , doc(doc) {
// 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.
ConvertAnimations();
+ // Embedded textures in FBX could be connected to nothing but to itself,
+ // for instance Texture -> Video connection only but not to the main graph,
+ // The idea here is to traverse all objects to find these Textures and convert them,
+ // so later during material conversion it will find converted texture in the textures_converted array.
+ if (doc.Settings().readTextures)
+ {
+ ConvertOrphantEmbeddedTextures();
+ }
ConvertRootNode();
if (doc.Settings().readAllMaterials) {
@@ -128,13 +149,50 @@ 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);
+ ConvertNodes(0L, out->mRootNode, 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);
}
- void FBXConverter::ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform) {
+ // 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;
+ }
+ /// todo: pre-build node hierarchy
+ /// todo: get bone from stack
+ /// todo: make map of aiBone* to aiNode*
+ /// then update convert clusters to the new format
+ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
std::vector<aiNode*> nodes;
@@ -145,79 +203,69 @@ namespace Assimp {
try {
for (const Connection* con : conns) {
-
// ignore object-property links
if (con->PropertyName().length()) {
- continue;
+ // really important we document why this is ignored.
+ FBXImporter::LogInfo("ignoring property link - no docs on why this is ignored");
+ continue; //?
}
+ // convert connection source object into Object base class
const Object* const object = con->SourceObject();
if (nullptr == object) {
- FBXImporter::LogWarn("failed to convert source object for Model link");
+ FBXImporter::LogError("failed to convert source object for Model link");
continue;
}
+ // FBX Model::Cube, Model::Bone001, etc elements
+ // This detects if we can cast the object into this model structure.
const Model* const model = dynamic_cast<const Model*>(object);
if (nullptr != model) {
nodes_chain.clear();
post_nodes_chain.clear();
- aiMatrix4x4 new_abs_transform = parent_transform;
-
+ aiMatrix4x4 new_abs_transform = parent->mTransformation;
+ std::string node_name = FixNodeName(model->Name());
// even though there is only a single input node, the design of
// assimp (or rather: the complicated transformation chain that
// is employed by fbx) means that we may need multiple aiNode's
// to represent a fbx node's transformation.
- GenerateTransformationNodeChain(*model, nodes_chain, post_nodes_chain);
- ai_assert(nodes_chain.size());
- std::string original_name = FixNodeName(model->Name());
+ // generate node transforms - this includes pivot data
+ // if need_additional_node is true then you t
+ const bool need_additional_node = GenerateTransformationNodeChain(*model, node_name, nodes_chain, post_nodes_chain);
- // 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;
- }
- }
+ // assert that for the current node we must have at least a single transform
+ ai_assert(nodes_chain.size());
- 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(node_name));
}
//setup metadata on newest node
SetupNodeMetadata(*model, *nodes_chain.back());
// link all nodes in a row
- aiNode* last_parent = &parent;
- for (aiNode* prenode : nodes_chain) {
- ai_assert(prenode);
+ aiNode* last_parent = parent;
+ for (aiNode* child : nodes_chain) {
+ ai_assert(child);
- if (last_parent != &parent) {
+ if (last_parent != parent) {
last_parent->mNumChildren = 1;
last_parent->mChildren = new aiNode*[1];
- last_parent->mChildren[0] = prenode;
+ last_parent->mChildren[0] = child;
}
- prenode->mParent = last_parent;
- last_parent = prenode;
+ child->mParent = last_parent;
+ last_parent = child;
- new_abs_transform *= prenode->mTransformation;
+ new_abs_transform *= child->mTransformation;
}
// attach geometry
- ConvertModel(*model, *nodes_chain.back(), new_abs_transform);
+ ConvertModel(*model, nodes_chain.back(), root_node, new_abs_transform);
// check if there will be any child nodes
const std::vector<const Connection*>& child_conns
@@ -229,7 +277,7 @@ namespace Assimp {
for (aiNode* postnode : post_nodes_chain) {
ai_assert(postnode);
- if (last_parent != &parent) {
+ if (last_parent != parent) {
last_parent->mNumChildren = 1;
last_parent->mChildren = new aiNode*[1];
last_parent->mChildren[0] = postnode;
@@ -251,15 +299,15 @@ namespace Assimp {
);
}
- // attach sub-nodes (if any)
- ConvertNodes(model->ID(), *last_parent, new_abs_transform);
+ // recursion call - child nodes
+ ConvertNodes(model->ID(), last_parent, root_node);
if (doc.Settings().readLights) {
- ConvertLights(*model, original_name);
+ ConvertLights(*model, node_name);
}
if (doc.Settings().readCameras) {
- ConvertCameras(*model, original_name);
+ ConvertCameras(*model, node_name);
}
nodes.push_back(nodes_chain.front());
@@ -268,11 +316,17 @@ namespace Assimp {
}
if (nodes.size()) {
- parent.mChildren = new aiNode*[nodes.size()]();
- parent.mNumChildren = static_cast<unsigned int>(nodes.size());
+ parent->mChildren = new aiNode*[nodes.size()]();
+ parent->mNumChildren = static_cast<unsigned int>(nodes.size());
- std::swap_ranges(nodes.begin(), nodes.end(), parent.mChildren);
+ std::swap_ranges(nodes.begin(), nodes.end(), parent->mChildren);
+ }
+ else
+ {
+ parent->mNumChildren = 0;
+ parent->mChildren = nullptr;
}
+
}
catch (std::exception&) {
Util::delete_fun<aiNode> deleter;
@@ -377,6 +431,7 @@ namespace Assimp {
break;
default:
ai_assert(false);
+ break;
}
}
@@ -389,11 +444,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);
@@ -410,19 +460,19 @@ namespace Assimp {
void FBXConverter::GetUniqueName(const std::string &name, std::string &uniqueName)
{
- int i = 0;
uniqueName = name;
- while (mNodeNames.find(uniqueName) != mNodeNames.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;
- std::stringstream ext;
+ i++;
+ std::ostringstream ext;
ext << name << std::setfill('0') << std::setw(3) << i;
uniqueName = ext.str();
+ it_pair = mNodeNames.insert({ uniqueName, 0 });
}
- mNodeNames.insert(uniqueName);
}
-
const char* FBXConverter::NameTransformationComp(TransformationComp comp) {
switch (comp) {
case TransformationComp_Translation:
@@ -529,7 +579,7 @@ namespace Assimp {
return;
}
- const float angle_epsilon = 1e-6f;
+ const float angle_epsilon = Math::getEpsilon<float>();
out = aiMatrix4x4();
@@ -636,8 +686,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;
}
@@ -652,7 +701,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();
@@ -660,30 +709,37 @@ namespace Assimp {
bool ok;
aiMatrix4x4 chain[TransformationComp_MAXIMUM];
+
+ ai_assert(TransformationComp_MAXIMUM < 32);
+ std::uint32_t chainBits = 0;
+ // A node won't need a node chain if it only has these.
+ const std::uint32_t chainMaskSimple = (1 << TransformationComp_Translation) + (1 << TransformationComp_Scaling) + (1 << TransformationComp_Rotation);
+ // A node will need a node chain if it has any of these.
+ const std::uint32_t chainMaskComplex = ((1 << (TransformationComp_MAXIMUM)) - 1) - chainMaskSimple;
+
std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4());
// generate transformation matrices for all the different transformation components
- const float zero_epsilon = 1e-6f;
+ const float zero_epsilon = Math::getEpsilon<float>();
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
- bool is_complex = false;
const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
if (ok && PreRotation.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_PreRotation);
GetRotationMatrix(Model::RotOrder::RotOrder_EulerXYZ, PreRotation, chain[TransformationComp_PreRotation]);
}
const aiVector3D& PostRotation = PropertyGet<aiVector3D>(props, "PostRotation", ok);
if (ok && PostRotation.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_PostRotation);
GetRotationMatrix(Model::RotOrder::RotOrder_EulerXYZ, PostRotation, chain[TransformationComp_PostRotation]);
}
const aiVector3D& RotationPivot = PropertyGet<aiVector3D>(props, "RotationPivot", ok);
if (ok && RotationPivot.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_RotationPivot) | (1 << TransformationComp_RotationPivotInverse);
aiMatrix4x4::Translation(RotationPivot, chain[TransformationComp_RotationPivot]);
aiMatrix4x4::Translation(-RotationPivot, chain[TransformationComp_RotationPivotInverse]);
@@ -691,21 +747,21 @@ namespace Assimp {
const aiVector3D& RotationOffset = PropertyGet<aiVector3D>(props, "RotationOffset", ok);
if (ok && RotationOffset.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_RotationOffset);
aiMatrix4x4::Translation(RotationOffset, chain[TransformationComp_RotationOffset]);
}
const aiVector3D& ScalingOffset = PropertyGet<aiVector3D>(props, "ScalingOffset", ok);
if (ok && ScalingOffset.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_ScalingOffset);
aiMatrix4x4::Translation(ScalingOffset, chain[TransformationComp_ScalingOffset]);
}
const aiVector3D& ScalingPivot = PropertyGet<aiVector3D>(props, "ScalingPivot", ok);
if (ok && ScalingPivot.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_ScalingPivot) | (1 << TransformationComp_ScalingPivotInverse);
aiMatrix4x4::Translation(ScalingPivot, chain[TransformationComp_ScalingPivot]);
aiMatrix4x4::Translation(-ScalingPivot, chain[TransformationComp_ScalingPivotInverse]);
@@ -713,22 +769,28 @@ namespace Assimp {
const aiVector3D& Translation = PropertyGet<aiVector3D>(props, "Lcl Translation", ok);
if (ok && Translation.SquareLength() > zero_epsilon) {
+ chainBits = chainBits | (1 << TransformationComp_Translation);
+
aiMatrix4x4::Translation(Translation, chain[TransformationComp_Translation]);
}
const aiVector3D& Scaling = PropertyGet<aiVector3D>(props, "Lcl Scaling", ok);
if (ok && (Scaling - all_ones).SquareLength() > zero_epsilon) {
+ chainBits = chainBits | (1 << TransformationComp_Scaling);
+
aiMatrix4x4::Scaling(Scaling, chain[TransformationComp_Scaling]);
}
const aiVector3D& Rotation = PropertyGet<aiVector3D>(props, "Lcl Rotation", ok);
if (ok && Rotation.SquareLength() > zero_epsilon) {
+ chainBits = chainBits | (1 << TransformationComp_Rotation);
+
GetRotationMatrix(rot, Rotation, chain[TransformationComp_Rotation]);
}
const aiVector3D& GeometricScaling = PropertyGet<aiVector3D>(props, "GeometricScaling", ok);
if (ok && (GeometricScaling - all_ones).SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_GeometricScaling);
aiMatrix4x4::Scaling(GeometricScaling, chain[TransformationComp_GeometricScaling]);
aiVector3D GeometricScalingInverse = GeometricScaling;
bool canscale = true;
@@ -743,13 +805,14 @@ namespace Assimp {
}
}
if (canscale) {
+ chainBits = chainBits | (1 << TransformationComp_GeometricScalingInverse);
aiMatrix4x4::Scaling(GeometricScalingInverse, chain[TransformationComp_GeometricScalingInverse]);
}
}
const aiVector3D& GeometricRotation = PropertyGet<aiVector3D>(props, "GeometricRotation", ok);
if (ok && GeometricRotation.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_GeometricRotation) | (1 << TransformationComp_GeometricRotationInverse);
GetRotationMatrix(rot, GeometricRotation, chain[TransformationComp_GeometricRotation]);
GetRotationMatrix(rot, GeometricRotation, chain[TransformationComp_GeometricRotationInverse]);
chain[TransformationComp_GeometricRotationInverse].Inverse();
@@ -757,7 +820,7 @@ namespace Assimp {
const aiVector3D& GeometricTranslation = PropertyGet<aiVector3D>(props, "GeometricTranslation", ok);
if (ok && GeometricTranslation.SquareLength() > zero_epsilon) {
- is_complex = true;
+ chainBits = chainBits | (1 << TransformationComp_GeometricTranslation) | (1 << TransformationComp_GeometricTranslationInverse);
aiMatrix4x4::Translation(GeometricTranslation, chain[TransformationComp_GeometricTranslation]);
aiMatrix4x4::Translation(-GeometricTranslation, chain[TransformationComp_GeometricTranslationInverse]);
}
@@ -765,14 +828,12 @@ namespace Assimp {
// is_complex needs to be consistent with NeedsComplexTransformationChain()
// or the interplay between this code and the animation converter would
// not be guaranteed.
- ai_assert(NeedsComplexTransformationChain(model) == is_complex);
-
- std::string name = FixNodeName(model.Name());
+ //ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
// now, if we have more than just Translation, Scaling and Rotation,
// we need to generate a full node chain to accommodate for assimp's
// lack to express pivots and offsets.
- if (is_complex && doc.Settings().preservePivots) {
+ if ((chainBits & chainMaskComplex) && doc.Settings().preservePivots) {
FBXImporter::LogInfo("generating full transformation chain for node: " + name);
// query the anim_chain_bits dictionary to find out which chain elements
@@ -785,7 +846,7 @@ namespace Assimp {
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i, bit <<= 1) {
const TransformationComp comp = static_cast<TransformationComp>(i);
- if (chain[i].IsIdentity() && (anim_chain_bitmask & bit) == 0) {
+ if ((chainBits & bit) == 0 && (anim_chain_bitmask & bit) == 0) {
continue;
}
@@ -810,20 +871,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)
@@ -869,7 +930,8 @@ namespace Assimp {
}
}
- void FBXConverter::ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform)
+ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform)
{
const std::vector<const Geometry*>& geos = model.GetGeometry();
@@ -881,11 +943,12 @@ namespace Assimp {
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
const LineGeometry* const line = dynamic_cast<const LineGeometry*>(geo);
if (mesh) {
- const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform, nd);
+ const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, parent, root_node,
+ absolute_transform);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
}
else if (line) {
- const std::vector<unsigned int>& indices = ConvertLine(*line, model, node_global_transform, nd);
+ const std::vector<unsigned int>& indices = ConvertLine(*line, model, parent, root_node);
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
}
else {
@@ -894,15 +957,16 @@ namespace Assimp {
}
if (meshes.size()) {
- nd.mMeshes = new unsigned int[meshes.size()]();
- nd.mNumMeshes = static_cast<unsigned int>(meshes.size());
+ parent->mMeshes = new unsigned int[meshes.size()]();
+ parent->mNumMeshes = static_cast<unsigned int>(meshes.size());
- std::swap_ranges(meshes.begin(), meshes.end(), nd.mMeshes);
+ std::swap_ranges(meshes.begin(), meshes.end(), parent->mMeshes);
}
}
- std::vector<unsigned int> FBXConverter::ConvertMesh(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd)
+ std::vector<unsigned int>
+ FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform)
{
std::vector<unsigned int> temp;
@@ -926,18 +990,18 @@ namespace Assimp {
const MatIndexArray::value_type base = mindices[0];
for (MatIndexArray::value_type index : mindices) {
if (index != base) {
- return ConvertMeshMultiMaterial(mesh, model, node_global_transform, nd);
+ return ConvertMeshMultiMaterial(mesh, model, parent, root_node, absolute_transform);
}
}
}
// faster code-path, just copy the data
- temp.push_back(ConvertMeshSingleMaterial(mesh, model, node_global_transform, nd));
+ temp.push_back(ConvertMeshSingleMaterial(mesh, model, absolute_transform, parent, root_node));
return temp;
}
std::vector<unsigned int> FBXConverter::ConvertLine(const LineGeometry& line, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd)
+ aiNode *parent, aiNode *root_node)
{
std::vector<unsigned int> temp;
@@ -948,7 +1012,7 @@ namespace Assimp {
return temp;
}
- aiMesh* const out_mesh = SetupEmptyMesh(line, nd);
+ aiMesh* const out_mesh = SetupEmptyMesh(line, root_node);
out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
// copy vertices
@@ -962,7 +1026,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;
@@ -981,7 +1047,7 @@ namespace Assimp {
return temp;
}
- aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode& nd)
+ aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode *parent)
{
aiMesh* const out_mesh = new aiMesh();
meshes.push_back(out_mesh);
@@ -998,17 +1064,18 @@ namespace Assimp {
}
else
{
- out_mesh->mName = nd.mName;
+ out_mesh->mName = parent->mName;
}
return out_mesh;
}
- unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd)
+ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
+ const aiMatrix4x4 &absolute_transform, aiNode *parent,
+ aiNode *root_node)
{
const MatIndexArray& mindices = mesh.GetMaterialIndices();
- aiMesh* const out_mesh = SetupEmptyMesh(mesh, nd);
+ aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent);
const std::vector<aiVector3D>& vertices = mesh.GetVertices();
const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
@@ -1075,7 +1142,7 @@ namespace Assimp {
binormals = &tempBinormals;
}
else {
- binormals = NULL;
+ binormals = nullptr;
}
}
@@ -1125,8 +1192,9 @@ namespace Assimp {
ConvertMaterialForMesh(out_mesh, model, mesh, mindices[0]);
}
- if (doc.Settings().readWeights && mesh.DeformerSkin() != NULL) {
- ConvertWeights(out_mesh, model, mesh, node_global_transform, NO_MATERIAL_SEPARATION);
+ if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr) {
+ ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, NO_MATERIAL_SEPARATION,
+ nullptr);
}
std::vector<aiAnimMesh*> animMeshes;
@@ -1171,8 +1239,10 @@ namespace Assimp {
return static_cast<unsigned int>(meshes.size() - 1);
}
- std::vector<unsigned int> FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd)
+ std::vector<unsigned int>
+ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent,
+ aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform)
{
const MatIndexArray& mindices = mesh.GetMaterialIndices();
ai_assert(mindices.size());
@@ -1183,7 +1253,7 @@ namespace Assimp {
for (MatIndexArray::value_type index : mindices) {
if (had.find(index) == had.end()) {
- indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, node_global_transform, nd));
+ indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node, absolute_transform));
had.insert(index);
}
}
@@ -1191,18 +1261,18 @@ namespace Assimp {
return indices;
}
- unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
- MatIndexArray::value_type index,
- const aiMatrix4x4& node_global_transform,
- aiNode& nd)
+ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model,
+ MatIndexArray::value_type index,
+ aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform)
{
- aiMesh* const out_mesh = SetupEmptyMesh(mesh, nd);
+ aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent);
const MatIndexArray& mindices = mesh.GetMaterialIndices();
const std::vector<aiVector3D>& vertices = mesh.GetVertices();
const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
- const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != NULL;
+ const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != nullptr;
unsigned int count_faces = 0;
unsigned int count_vertices = 0;
@@ -1222,10 +1292,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);
}
@@ -1262,7 +1332,7 @@ namespace Assimp {
binormals = &tempBinormals;
}
else {
- binormals = NULL;
+ binormals = nullptr;
}
}
@@ -1332,6 +1402,7 @@ namespace Assimp {
if (reverseMapping.size()) {
reverseMapping[cursor] = in_cursor;
+ translateIndexMap[in_cursor] = cursor;
}
out_mesh->mVertices[cursor] = vertices[in_cursor];
@@ -1360,16 +1431,60 @@ namespace Assimp {
ConvertMaterialForMesh(out_mesh, model, mesh, index);
if (process_weights) {
- ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping);
+ ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, index, &reverseMapping);
+ }
+
+ std::vector<aiAnimMesh*> animMeshes;
+ 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);
}
- void FBXConverter::ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
- const aiMatrix4x4& node_global_transform,
- unsigned int materialIndex,
- std::vector<unsigned int>* outputVertStartIndices)
+ void FBXConverter::ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo,
+ const aiMatrix4x4 &absolute_transform,
+ aiNode *parent, aiNode *root_node, unsigned int materialIndex,
+ std::vector<unsigned int> *outputVertStartIndices)
{
ai_assert(geo.DeformerSkin());
@@ -1380,41 +1495,35 @@ namespace Assimp {
const Skin& sk = *geo.DeformerSkin();
std::vector<aiBone*> bones;
- bones.reserve(sk.Clusters().size());
const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
ai_assert(no_mat_check || outputVertStartIndices);
try {
-
+ // iterate over the sub deformers
for (const Cluster* cluster : sk.Clusters()) {
ai_assert(cluster);
const WeightIndexArray& indices = cluster->GetIndices();
- if (indices.empty()) {
- continue;
- }
-
const MatIndexArray& mats = geo.GetMaterialIndices();
- bool ok = false;
-
const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
count_out_indices.clear();
index_out_indices.clear();
out_indices.clear();
+
// now check if *any* of these weights is contained in the output mesh,
// taking notes so we don't need to do it twice.
for (WeightIndexArray::value_type index : indices) {
unsigned int count = 0;
const unsigned int* const out_idx = geo.ToOutputVertexIndex(index, count);
- // ToOutputVertexIndex only returns NULL if index is out of bounds
+ // ToOutputVertexIndex only returns nullptr if index is out of bounds
// which should never happen
- ai_assert(out_idx != NULL);
+ ai_assert(out_idx != nullptr);
index_out_indices.push_back(no_index_sentinel);
count_out_indices.push_back(0);
@@ -1424,13 +1533,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(),
@@ -1441,8 +1548,7 @@ namespace Assimp {
out_indices.push_back(std::distance(outputVertStartIndices->begin(), it));
}
- ++count_out_indices.back();
- ok = true;
+ ++count_out_indices.back();
}
}
}
@@ -1450,66 +1556,103 @@ 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) {
- ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
- count_out_indices, node_global_transform);
- }
+ ConvertCluster(bones, cluster, out_indices, index_out_indices,
+ count_out_indices, absolute_transform, parent, root_node);
}
+
+ bone_map.clear();
}
- catch (std::exception&) {
+ catch (std::exception&e) {
std::for_each(bones.begin(), bones.end(), Util::delete_fun<aiBone>());
throw;
}
if (bones.empty()) {
+ out->mBones = nullptr;
+ out->mNumBones = 0;
return;
- }
+ } else {
+ out->mBones = new aiBone *[bones.size()]();
+ out->mNumBones = static_cast<unsigned int>(bones.size());
- out->mBones = new aiBone*[bones.size()]();
- out->mNumBones = static_cast<unsigned int>(bones.size());
-
- std::swap_ranges(bones.begin(), bones.end(), out->mBones);
+ std::swap_ranges(bones.begin(), bones.end(), out->mBones);
+ }
}
- void FBXConverter::ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
- std::vector<size_t>& out_indices,
- std::vector<size_t>& index_out_indices,
- std::vector<size_t>& count_out_indices,
- const aiMatrix4x4& node_global_transform)
+ const aiNode* FBXConverter::GetNodeByName( const aiString& name, aiNode *current_node )
{
+ aiNode * iter = current_node;
+ //printf("Child count: %d", iter->mNumChildren);
+ return iter;
+ }
- aiBone* const bone = new aiBone();
- bones.push_back(bone);
+ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
+ std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
+ std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
+ aiNode *parent, aiNode *root_node) {
+ ai_assert(cl); // make sure cluster valid
+ std::string deformer_name = cl->TargetNode()->Name();
+ aiString bone_name = aiString(FixNodeName(deformer_name));
- bone->mName = FixNodeName(cl.TargetNode()->Name());
+ aiBone *bone = nullptr;
- bone->mOffsetMatrix = cl.TransformLink();
- bone->mOffsetMatrix.Inverse();
+ if (bone_map.count(deformer_name)) {
+ std::cout << "retrieved bone from lookup " << bone_name.C_Str() << ". Deformer: " << deformer_name
+ << std::endl;
+ bone = bone_map[deformer_name];
+ } else {
+ std::cout << "created new bone " << bone_name.C_Str() << ". Deformer: " << deformer_name << std::endl;
+ bone = new aiBone();
+ bone->mName = bone_name;
- bone->mOffsetMatrix = bone->mOffsetMatrix * node_global_transform;
+ // store local transform link for post processing
+ bone->mOffsetMatrix = cl->TransformLink();
+ bone->mOffsetMatrix.Inverse();
- bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
- aiVertexWeight* cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
+ aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
- const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
- const WeightArray& weights = cl.GetWeights();
+ bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
- const size_t c = index_out_indices.size();
- for (size_t i = 0; i < c; ++i) {
- const size_t index_index = index_out_indices[i];
- if (index_index == no_index_sentinel) {
- continue;
- }
+ //
+ // Now calculate the aiVertexWeights
+ //
+
+ aiVertexWeight *cursor = nullptr;
+
+ bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
+ cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
+
+ const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
+ const WeightArray& weights = cl->GetWeights();
- const size_t cc = count_out_indices[i];
- for (size_t j = 0; j < cc; ++j) {
- aiVertexWeight& out_weight = *cursor++;
+ const size_t c = index_out_indices.size();
+ for (size_t i = 0; i < c; ++i) {
+ const size_t index_index = index_out_indices[i];
- out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]);
- out_weight.mWeight = weights[i];
+ if (index_index == no_index_sentinel) {
+ continue;
+ }
+
+ const size_t cc = count_out_indices[i];
+ for (size_t j = 0; j < cc; ++j) {
+ // cursor runs from first element relative to the start
+ // or relative to the start of the next indexes.
+ aiVertexWeight& out_weight = *cursor++;
+
+ out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]);
+ out_weight.mWeight = weights[i];
+ }
}
+
+ bone_map.insert(std::pair<const std::string, aiBone *>(deformer_name, bone));
}
+
+ std::cout << "bone research: Indicies size: " << out_indices.size() << std::endl;
+
+ // lookup must be populated in case something goes wrong
+ // this also allocates bones to mesh instance outside
+ local_mesh_bones.push_back(bone);
}
void FBXConverter::ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@@ -1581,6 +1724,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 );
@@ -1606,7 +1756,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") {
@@ -1617,7 +1767,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);
}
@@ -1632,7 +1782,7 @@ namespace Assimp {
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
unsigned int index;
- VideoMap::const_iterator it = textures_converted.find(media);
+ VideoMap::const_iterator it = textures_converted.find(*media);
if (it != textures_converted.end()) {
index = (*it).second;
textureReady = true;
@@ -1640,7 +1790,7 @@ namespace Assimp {
else {
if (media->ContentLength() > 0) {
index = ConvertVideo(*media);
- textures_converted[media] = index;
+ textures_converted[*media] = index;
textureReady = true;
}
}
@@ -1663,9 +1813,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;
@@ -1924,6 +2073,21 @@ namespace Assimp {
TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
+
+ // Maya PBR
+ TrySetTextureProperties(out_mat, textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
+
+ // Maya stingray
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);
}
void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh)
@@ -2041,6 +2205,12 @@ namespace Assimp {
CalculatedOpacity = 1.0f - ((Transparent.r + Transparent.g + Transparent.b) / 3.0f);
}
+ // try to get the transparency factor
+ const float TransparencyFactor = PropertyGet<float>(props, "TransparencyFactor", ok);
+ if (ok) {
+ out_mat->AddProperty(&TransparencyFactor, 1, AI_MATKEY_TRANSPARENCYFACTOR);
+ }
+
// use of TransparencyFactor is inconsistent.
// Maya always stores it as 1.0,
// so we can't use it to set AI_MATKEY_OPACITY.
@@ -2144,13 +2314,13 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
if (media != nullptr && media->ContentLength() > 0) {
unsigned int index;
- VideoMap::const_iterator it = textures_converted.find(media);
+ VideoMap::const_iterator it = textures_converted.find(*media);
if (it != textures_converted.end()) {
index = (*it).second;
}
else {
index = ConvertVideo(*media);
- textures_converted[media] = index;
+ textures_converted[*media] = index;
}
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
@@ -2578,7 +2748,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
// sanity check whether the input is ok
static void validateAnimCurveNodes(const std::vector<const AnimationCurveNode*>& curves,
bool strictMode) {
- const Object* target(NULL);
+ const Object* target(nullptr);
for (const AnimationCurveNode* node : curves) {
if (!target) {
target = node->Target();
@@ -2609,7 +2779,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
#ifdef ASSIMP_BUILD_DEBUG
validateAnimCurveNodes(curves, doc.Settings().strictMode);
#endif
- const AnimationCurveNode* curve_node = NULL;
+ const AnimationCurveNode* curve_node = nullptr;
for (const AnimationCurveNode* node : curves) {
ai_assert(node);
@@ -2869,7 +3039,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
TransformationCompDefaultValue(comp)
);
- const float epsilon = 1e-6f;
+ const float epsilon = Math::getEpsilon<float>();
return (dyn_val - static_val).SquareLength() < epsilon;
}
@@ -3386,8 +3556,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,
@@ -3456,7 +3627,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
ai_assert(!out->mMeshes);
ai_assert(!out->mNumMeshes);
- // note: the trailing () ensures initialization with NULL - not
+ // note: the trailing () ensures initialization with nullptr - not
// many C++ users seem to know this, so pointing it out to avoid
// confusion why this code works.
@@ -3503,10 +3674,51 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
}
}
+ void FBXConverter::ConvertOrphantEmbeddedTextures()
+ {
+ // in C++14 it could be:
+ // for (auto&& [id, object] : objects)
+ for (auto&& id_and_object : doc.Objects())
+ {
+ auto&& id = std::get<0>(id_and_object);
+ auto&& object = std::get<1>(id_and_object);
+ // If an object doesn't have parent
+ if (doc.ConnectionsBySource().count(id) == 0)
+ {
+ const Texture* realTexture = nullptr;
+ try
+ {
+ const auto& element = object->GetElement();
+ const Token& key = element.KeyToken();
+ const char* obtype = key.begin();
+ const size_t length = static_cast<size_t>(key.end() - key.begin());
+ if (strncmp(obtype, "Texture", length) == 0)
+ {
+ const Texture* texture = static_cast<const Texture*>(object->Get());
+ if (texture->Media() && texture->Media()->ContentLength() > 0)
+ {
+ realTexture = texture;
+ }
+ }
+ }
+ catch (...)
+ {
+ // do nothing
+ }
+ if (realTexture)
+ {
+ const Video* media = realTexture->Media();
+ unsigned int index = ConvertVideo(*media);
+ textures_converted[*media] = index;
+ }
+ }
+ }
+ }
+
// ------------------------------------------------------------------------------------------------
- void ConvertToAssimpScene(aiScene* out, const Document& doc)
+ void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
{
- FBXConverter converter(out, doc);
+ FBXConverter converter(out, doc, removeEmptyBones);
}
} // !FBX
diff --git a/thirdparty/assimp/code/FBXConverter.h b/thirdparty/assimp/code/FBX/FBXConverter.h
index 398baa445f..46693bdca6 100644
--- a/thirdparty/assimp/code/FBXConverter.h
+++ b/thirdparty/assimp/code/FBX/FBXConverter.h
@@ -52,12 +52,15 @@ 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>
#include <assimp/texture.h>
#include <assimp/camera.h>
#include <assimp/StringComparison.h>
+#include <unordered_map>
+#include <unordered_set>
struct aiScene;
struct aiNode;
@@ -73,15 +76,13 @@ namespace Assimp {
namespace FBX {
class Document;
-
-using NodeNameCache = std::set<std::string>;
-
/**
* 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);
/** Dummy class to encapsulate the conversion process */
class FBXConverter {
@@ -112,7 +113,7 @@ public:
};
public:
- FBXConverter(aiScene* out, const Document& doc);
+ FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones);
~FBXConverter();
private:
@@ -122,7 +123,7 @@ private:
// ------------------------------------------------------------------------------------------------
// collect and assign child nodes
- void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4());
+ void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
void ConvertLights(const Model& model, const std::string &orig_name );
@@ -145,6 +146,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,38 +173,41 @@ 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);
// ------------------------------------------------------------------------------------------------
- void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform);
+ void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
- std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd);
+ std::vector<unsigned int>
+ ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------
std::vector<unsigned int> ConvertLine(const LineGeometry& line, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd);
+ aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
- aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode& nd);
+ aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent);
// ------------------------------------------------------------------------------------------------
- unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd);
+ unsigned int ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
+ const aiMatrix4x4 &absolute_transform, aiNode *parent,
+ aiNode *root_node);
// ------------------------------------------------------------------------------------------------
- std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform, aiNode& nd);
+ std::vector<unsigned int>
+ ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
+ const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------
- unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
- MatIndexArray::value_type index,
- const aiMatrix4x4& node_global_transform, aiNode& nd);
+ unsigned int ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, MatIndexArray::value_type index,
+ aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform);
// ------------------------------------------------------------------------------------------------
static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
@@ -211,17 +220,17 @@ private:
* - outputVertStartIndices is only used when a material index is specified, it gives for
* each output vertex the DOM index it maps to.
*/
- void ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
- const aiMatrix4x4& node_global_transform = aiMatrix4x4(),
- unsigned int materialIndex = NO_MATERIAL_SEPARATION,
- std::vector<unsigned int>* outputVertStartIndices = NULL);
-
+ void ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
+ aiNode *parent = NULL, aiNode *root_node = NULL,
+ unsigned int materialIndex = NO_MATERIAL_SEPARATION,
+ std::vector<unsigned int> *outputVertStartIndices = NULL);
+ // lookup
+ static const aiNode* GetNodeByName( const aiString& name, aiNode *current_node );
// ------------------------------------------------------------------------------------------------
- void ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
- std::vector<size_t>& out_indices,
- std::vector<size_t>& index_out_indices,
- std::vector<size_t>& count_out_indices,
- const aiMatrix4x4& node_global_transform);
+ void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
+ std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
+ std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
+ aiNode *parent, aiNode *root_node);
// ------------------------------------------------------------------------------------------------
void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@@ -418,8 +427,11 @@ private:
// copy generated meshes, animations, lights, cameras and textures to the output scene
void TransferDataToScene();
-private:
+ // ------------------------------------------------------------------------------------------------
+ // FBX file could have embedded textures not connected to anything
+ void ConvertOrphantEmbeddedTextures();
+private:
// 0: not assigned yet, others: index is value - 1
unsigned int defaultMaterialIndex;
@@ -429,26 +441,48 @@ private:
std::vector<aiLight*> lights;
std::vector<aiCamera*> cameras;
std::vector<aiTexture*> textures;
-
- typedef std::map<const Material*, unsigned int> MaterialMap;
+ using MaterialMap = std::fbx_unordered_map<const Material*, unsigned int>;
MaterialMap materials_converted;
- typedef std::map<const Video*, unsigned int> VideoMap;
+ using VideoMap = std::fbx_unordered_map<const Video, unsigned int>;
VideoMap textures_converted;
- typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap;
+ using MeshMap = std::fbx_unordered_map<const Geometry*, std::vector<unsigned int> >;
MeshMap meshes_converted;
// fixed node name -> which trafo chain components have animations?
- typedef std::map<std::string, unsigned int> NodeAnimBitMap;
+ using NodeAnimBitMap = std::fbx_unordered_map<std::string, unsigned int> ;
NodeAnimBitMap node_anim_chain_bits;
+ // number of nodes with the same name
+ using NodeNameCache = std::fbx_unordered_map<std::string, unsigned int>;
NodeNameCache mNodeNames;
+
+ // Deformer name is not the same as a bone name - it does contain the bone name though :)
+ // Deformer names in FBX are always unique in an FBX file.
+ std::map<const std::string, aiBone *> bone_map;
+
double anim_fps;
aiScene* const out;
const FBX::Document& doc;
+
+ static void BuildBoneList(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
+ std::vector<aiBone*>& bones);
+
+ void BuildBoneStack(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
+ const std::vector<aiBone *> &bones,
+ std::map<aiBone *, aiNode *> &bone_stack,
+ std::vector<aiNode*> &node_stack );
+
+ static void BuildNodeList(aiNode *current_node, std::vector<aiNode *> &nodes);
+
+ static aiNode *GetNodeFromStack(const aiString &node_name, std::vector<aiNode *> &nodes);
+
+ static aiNode *GetArmatureRoot(aiNode *bone_node, std::vector<aiBone*> &bone_list);
+
+ static bool IsBoneNode(const aiString &bone_name, std::vector<aiBone *> &bones);
};
}
diff --git a/thirdparty/assimp/code/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..506fd978dd 100644
--- a/thirdparty/assimp/code/FBXDocument.cpp
+++ b/thirdparty/assimp/code/FBX/FBXDocument.cpp
@@ -90,14 +90,6 @@ const Object* LazyObject::Get(bool dieOnError)
return object.get();
}
- // if this is the root object, we return a dummy since there
- // is no root object int he fbx file - it is just referenced
- // with id 0.
- if(id == 0L) {
- object.reset(new Object(id, element, "Model::RootNode"));
- return object.get();
- }
-
const Token& key = element.KeyToken();
const TokenList& tokens = element.Tokens();
diff --git a/thirdparty/assimp/code/FBXDocument.h b/thirdparty/assimp/code/FBX/FBXDocument.h
index c849defdcd..a60d7d9efa 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;
}
@@ -637,13 +637,27 @@ public:
return ptr;
}
+ bool operator==(const Video& other) const
+ {
+ return (
+ type == other.type
+ && relativeFileName == other.relativeFileName
+ && fileName == other.fileName
+ );
+ }
+
+ bool operator<(const Video& other) const
+ {
+ return std::tie(type, relativeFileName, fileName) < std::tie(other.type, other.relativeFileName, other.fileName);
+ }
+
private:
std::string type;
std::string relativeFileName;
std::string fileName;
std::shared_ptr<const PropertyTable> props;
- uint32_t contentLength;
+ uint64_t contentLength;
uint8_t* content;
};
@@ -1005,10 +1019,10 @@ public:
// during their entire lifetime (Document). FBX files have
// up to many thousands of objects (most of which we never use),
// so the memory overhead for them should be kept at a minimum.
-typedef std::map<uint64_t, LazyObject*> ObjectMap;
+typedef std::fbx_unordered_map<uint64_t, LazyObject*> ObjectMap;
typedef std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > PropertyTemplateMap;
-typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
+typedef std::fbx_unordered_multimap<uint64_t, const Connection*> ConnectionMap;
/** DOM class for global document settings, a single instance per document can
* be accessed via Document.Globals(). */
@@ -1177,4 +1191,25 @@ private:
} // Namespace FBX
} // Namespace Assimp
+namespace std
+{
+ template <>
+ struct hash<const Assimp::FBX::Video>
+ {
+ std::size_t operator()(const Assimp::FBX::Video& video) const
+ {
+ using std::size_t;
+ using std::hash;
+ using std::string;
+
+ size_t res = 17;
+ res = res * 31 + hash<string>()(video.Name());
+ res = res * 31 + hash<string>()(video.RelativeFilename());
+ res = res * 31 + hash<string>()(video.Type());
+
+ return res;
+ }
+ };
+}
+
#endif // INCLUDED_AI_FBX_DOCUMENT_H
diff --git a/thirdparty/assimp/code/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..f2a63b72b9 100644
--- a/thirdparty/assimp/code/FBXExportProperty.cpp
+++ b/thirdparty/assimp/code/FBX/FBXExportProperty.cpp
@@ -52,187 +52,206 @@ 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, 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 +259,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 +378,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..9316dc4f02 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>
@@ -66,6 +67,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <array>
#include <unordered_set>
+#include <numeric>
// RESOURCES:
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/
@@ -73,7 +75,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 +98,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 +122,7 @@ namespace Assimp {
IOSystem* pIOSystem,
const aiScene* pScene,
const ExportProperties* pProperties
+
){
// initialize the exporter
FBXExporter exporter(pScene, pProperties);
@@ -1004,6 +1006,9 @@ void FBXExporter::WriteObjects ()
object_node.EndProperties(outstream, binary, indent);
object_node.BeginChildren(outstream, binary, indent);
+ bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true);
+ std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later
+
// geometry (aiMesh)
mesh_uids.clear();
indent = 1;
@@ -1030,21 +1035,35 @@ void FBXExporter::WriteObjects ()
std::vector<int32_t> vertex_indices;
// map of vertex value to its index in the data vector
std::map<aiVector3D,size_t> index_by_vertex_value;
- int32_t index = 0;
- for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
- aiVector3D vtx = m->mVertices[vi];
- auto elem = index_by_vertex_value.find(vtx);
- if (elem == index_by_vertex_value.end()) {
- vertex_indices.push_back(index);
- index_by_vertex_value[vtx] = index;
- flattened_vertices.push_back(vtx[0]);
- flattened_vertices.push_back(vtx[1]);
- flattened_vertices.push_back(vtx[2]);
- ++index;
- } else {
- vertex_indices.push_back(int32_t(elem->second));
+ if(bJoinIdenticalVertices){
+ int32_t index = 0;
+ for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
+ aiVector3D vtx = m->mVertices[vi];
+ auto elem = index_by_vertex_value.find(vtx);
+ if (elem == index_by_vertex_value.end()) {
+ vertex_indices.push_back(index);
+ index_by_vertex_value[vtx] = index;
+ flattened_vertices.push_back(vtx[0]);
+ flattened_vertices.push_back(vtx[1]);
+ flattened_vertices.push_back(vtx[2]);
+ ++index;
+ } else {
+ vertex_indices.push_back(int32_t(elem->second));
+ }
}
}
+ else { // do not join vertex, respect the export flag
+ vertex_indices.resize(m->mNumVertices);
+ std::iota(vertex_indices.begin(), vertex_indices.end(), 0);
+ for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
+ aiVector3D vtx = m->mVertices[v];
+ flattened_vertices.push_back(vtx.x);
+ flattened_vertices.push_back(vtx.y);
+ flattened_vertices.push_back(vtx.z);
+ }
+ }
+ vVertexIndice.push_back(vertex_indices);
+
FBX::Node::WritePropertyNode(
"Vertices", flattened_vertices, outstream, binary, indent
);
@@ -1115,6 +1134,51 @@ void FBXExporter::WriteObjects ()
normals.End(outstream, binary, indent, true);
}
+ // colors, if any
+ // TODO only one color channel currently
+ const int32_t colorChannelIndex = 0;
+ if (m->HasVertexColors(colorChannelIndex)) {
+ FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
+ vertexcolors.Begin(outstream, binary, indent);
+ vertexcolors.DumpProperties(outstream, binary, indent);
+ vertexcolors.EndProperties(outstream, binary, indent);
+ vertexcolors.BeginChildren(outstream, binary, indent);
+ indent = 3;
+ FBX::Node::WritePropertyNode(
+ "Version", int32_t(101), outstream, binary, indent
+ );
+ char layerName[8];
+ sprintf(layerName, "COLOR_%d", colorChannelIndex);
+ FBX::Node::WritePropertyNode(
+ "Name", (const char*)layerName, outstream, binary, indent
+ );
+ FBX::Node::WritePropertyNode(
+ "MappingInformationType", "ByPolygonVertex",
+ outstream, binary, indent
+ );
+ FBX::Node::WritePropertyNode(
+ "ReferenceInformationType", "Direct",
+ outstream, binary, indent
+ );
+ std::vector<double> color_data;
+ color_data.reserve(4 * polygon_data.size());
+ for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
+ const aiFace &f = m->mFaces[fi];
+ for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
+ const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]];
+ color_data.push_back(c.r);
+ color_data.push_back(c.g);
+ color_data.push_back(c.b);
+ color_data.push_back(c.a);
+ }
+ }
+ FBX::Node::WritePropertyNode(
+ "Colors", color_data, outstream, binary, indent
+ );
+ indent = 2;
+ vertexcolors.End(outstream, binary, indent, true);
+ }
+
// uvs, if any
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
if (m->mNumUVComponents[uvi] > 2) {
@@ -1208,6 +1272,11 @@ void FBXExporter::WriteObjects ()
le.AddChild("Type", "LayerElementNormal");
le.AddChild("TypedIndex", int32_t(0));
layer.AddChild(le);
+ // TODO only 1 color channel currently
+ le = FBX::Node("LayerElement");
+ le.AddChild("Type", "LayerElementColor");
+ le.AddChild("TypedIndex", int32_t(0));
+ layer.AddChild(le);
le = FBX::Node("LayerElement");
le.AddChild("Type", "LayerElementMaterial");
le.AddChild("TypedIndex", int32_t(0));
@@ -1218,6 +1287,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(lr));
+ 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 +1472,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 +1481,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 +1520,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 +1676,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 +1749,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?
@@ -1646,8 +1774,7 @@ void FBXExporter::WriteObjects ()
}
if (end) { break; }
}
- limbnodes.insert(parent);
- skeleton.insert(parent);
+
// if it was the skeleton root we can finish here
if (end) { break; }
}
@@ -1689,28 +1816,8 @@ void FBXExporter::WriteObjects ()
// connect it
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
- // we will be indexing by vertex...
- // but there might be a different number of "vertices"
- // between assimp and our output FBX.
- // this code is cut-and-pasted from the geometry section above...
- // ideally this should not be so.
- // ---
- // index of original vertex in vertex data vector
- std::vector<int32_t> vertex_indices;
- // map of vertex value to its index in the data vector
- std::map<aiVector3D,size_t> index_by_vertex_value;
- int32_t index = 0;
- for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
- aiVector3D vtx = m->mVertices[vi];
- auto elem = index_by_vertex_value.find(vtx);
- if (elem == index_by_vertex_value.end()) {
- vertex_indices.push_back(index);
- index_by_vertex_value[vtx] = index;
- ++index;
- } else {
- vertex_indices.push_back(int32_t(elem->second));
- }
- }
+ //computed before
+ std::vector<int32_t>& vertex_indices = vVertexIndice[mi];
// TODO, FIXME: this won't work if anything is not in the bind pose.
// for now if such a situation is detected, we throw an exception.
@@ -1728,7 +1835,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;
@@ -1788,41 +1895,10 @@ void FBXExporter::WriteObjects ()
inverse_bone_xform.Inverse();
aiMatrix4x4 tr = inverse_bone_xform * mesh_xform;
- // 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
- bool bone_xform_okay = true;
- if (b && ! tr.Equal(b->mOffsetMatrix, epsilon)) {
- not_in_bind_pose.insert(b);
- bone_xform_okay = false;
- }
+ sdnode.AddChild("Transform", tr);
- // if we have a bone we should use the mOffsetMatrix,
- // otherwise try to just use the calculated transform.
- if (b) {
- sdnode.AddChild("Transform", b->mOffsetMatrix);
- } else {
- sdnode.AddChild("Transform", tr);
- }
- // note: it doesn't matter if we mix these,
- // because if they disagree we'll throw an exception later.
- // it could be that the skeleton is not in the bone pose
- // but all bones are still defined,
- // in which case this would use the mOffsetMatrix for everything
- // and a correct skeleton would still be output.
-
- // transformlink should be the position of the bone in world space.
- // if the bone is in the bind pose (or nonexistent),
- // we can just use the matrix we already calculated
- if (bone_xform_okay) {
- sdnode.AddChild("TransformLink", bone_xform);
- // otherwise we can only work it out using the mesh position.
- } else {
- aiMatrix4x4 trl = b->mOffsetMatrix;
- trl.Inverse();
- trl *= mesh_xform;
- sdnode.AddChild("TransformLink", trl);
- }
+
+ sdnode.AddChild("TransformLink", bone_xform);
// note: this means we ALWAYS rely on the mesh node transform
// being unchanged from the time the skeleton was bound.
// there's not really any way around this at the moment.
@@ -2237,8 +2313,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 +2427,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);
@@ -2407,7 +2483,7 @@ void FBXExporter::WriteModelNodes(
void FBXExporter::WriteAnimationCurveNode(
StreamWriterLE& outstream,
int64_t uid,
- std::string name, // "T", "R", or "S"
+ const std::string& name, // "T", "R", or "S"
aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc
int64_t layer_uid,
diff --git a/thirdparty/assimp/code/FBXExporter.h b/thirdparty/assimp/code/FBX/FBXExporter.h
index 71fb55c57f..1ae727eda9 100644
--- a/thirdparty/assimp/code/FBXExporter.h
+++ b/thirdparty/assimp/code/FBX/FBXExporter.h
@@ -156,7 +156,7 @@ namespace Assimp
void WriteAnimationCurveNode(
StreamWriterLE& outstream,
int64_t uid,
- std::string name, // "T", "R", or "S"
+ const std::string& name, // "T", "R", or "S"
aiVector3D default_value,
std::string property_name, // "Lcl Translation" etc
int64_t animation_layer_uid,
diff --git a/thirdparty/assimp/code/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/FBX/FBXImporter.cpp b/thirdparty/assimp/code/FBX/FBXImporter.cpp
new file mode 100644
index 0000000000..afcc1ddc78
--- /dev/null
+++ b/thirdparty/assimp/code/FBX/FBXImporter.cpp
@@ -0,0 +1,198 @@
+/*
+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.
+r
+* 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 FBXImporter.cpp
+ * @brief Implementation of the FBX importer.
+ */
+
+#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
+
+#include "FBXImporter.h"
+
+#include "FBXConverter.h"
+#include "FBXDocument.h"
+#include "FBXParser.h"
+#include "FBXTokenizer.h"
+#include "FBXUtil.h"
+
+#include <assimp/MemoryIOWrapper.h>
+#include <assimp/StreamReader.h>
+#include <assimp/importerdesc.h>
+#include <assimp/Importer.hpp>
+
+namespace Assimp {
+
+template <>
+const char *LogFunctions<FBXImporter>::Prefix() {
+ static auto prefix = "FBX: ";
+ return prefix;
+}
+
+} // namespace Assimp
+
+using namespace Assimp;
+using namespace Assimp::Formatter;
+using namespace Assimp::FBX;
+
+namespace {
+
+static const aiImporterDesc desc = {
+ "Autodesk FBX Importer",
+ "",
+ "",
+ "",
+ aiImporterFlags_SupportTextFlavour,
+ 0,
+ 0,
+ 0,
+ 0,
+ "fbx"
+};
+}
+
+// ------------------------------------------------------------------------------------------------
+// Constructor to be privately used by #Importer
+FBXImporter::FBXImporter() {
+}
+
+// ------------------------------------------------------------------------------------------------
+// Destructor, private as well
+FBXImporter::~FBXImporter() {
+}
+
+// ------------------------------------------------------------------------------------------------
+// Returns whether the class can handle the format of the given file.
+bool FBXImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
+ const std::string &extension = GetExtension(pFile);
+ if (extension == std::string(desc.mFileExtensions)) {
+ return true;
+ }
+
+ else if ((!extension.length() || checkSig) && pIOHandler) {
+ // at least ASCII-FBX files usually have a 'FBX' somewhere in their head
+ const char *tokens[] = { "fbx" };
+ return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
+ }
+ return false;
+}
+
+// ------------------------------------------------------------------------------------------------
+// List all extensions handled by this loader
+const aiImporterDesc *FBXImporter::GetInfo() const {
+ return &desc;
+}
+
+// ------------------------------------------------------------------------------------------------
+// Setup configuration properties for the loader
+void FBXImporter::SetupProperties(const Importer *pImp) {
+ settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
+ settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
+ settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
+ settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
+ settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
+ settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
+ settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
+ settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
+ settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
+ settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
+ settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
+ settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
+ settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Imports the given file into the given scene structure.
+void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
+ std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
+ if (!stream) {
+ ThrowException("Could not open file for reading");
+ }
+
+ // read entire file into memory - no streaming for this, fbx
+ // files can grow large, but the assimp output data structure
+ // then becomes very large, too. Assimp doesn't support
+ // streaming for its output data structures so the net win with
+ // streaming input data would be very low.
+ std::vector<char> contents;
+ contents.resize(stream->FileSize() + 1);
+ stream->Read(&*contents.begin(), 1, contents.size() - 1);
+ contents[contents.size() - 1] = 0;
+ const char *const begin = &*contents.begin();
+
+ // broadphase tokenizing pass in which we identify the core
+ // syntax elements of FBX (brackets, commas, key:value mappings)
+ TokenList tokens;
+ try {
+
+ bool is_binary = false;
+ if (!strncmp(begin, "Kaydara FBX Binary", 18)) {
+ is_binary = true;
+ TokenizeBinary(tokens, begin, contents.size());
+ } else {
+ Tokenize(tokens, begin);
+ }
+
+ // use this information to construct a very rudimentary
+ // parse-tree representing the FBX scope structure
+ Parser parser(tokens, is_binary);
+
+ // take the raw parse-tree and convert it to a FBX DOM
+ Document doc(parser, settings);
+
+ // convert the FBX DOM to aiScene
+ ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
+
+ // size relative to cm
+ float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
+
+ // Set FBX file scale is relative to CM must be converted to M for
+ // assimp universal format (M)
+ SetFileScale(size_relative_to_cm * 0.01f);
+
+ std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>());
+ } catch (std::exception &) {
+ std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>());
+ throw;
+ }
+}
+
+#endif // !ASSIMP_BUILD_NO_FBX_IMPORTER
diff --git a/thirdparty/assimp/code/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 08347740fa..f43a8b84b0 100644
--- a/thirdparty/assimp/code/FBXMaterial.cpp
+++ b/thirdparty/assimp/code/FBX/FBXMaterial.cpp
@@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ByteSwapper.h>
#include <algorithm> // std::transform
+#include "FBXUtil.h"
namespace Assimp {
namespace FBX {
@@ -206,6 +207,20 @@ Texture::Texture(uint64_t id, const Element& element, const Document& doc, const
props = GetPropertyTable(doc,"Texture.FbxFileTexture",element,sc);
+ // 3DS Max and FBX SDK use "Scaling" and "Translation" instead of "ModelUVScaling" and "ModelUVTranslation". Use these properties if available.
+ bool ok;
+ const aiVector3D& scaling = PropertyGet<aiVector3D>(*props, "Scaling", ok);
+ if (ok) {
+ uvScaling.x = scaling.x;
+ uvScaling.y = scaling.y;
+ }
+
+ const aiVector3D& trans = PropertyGet<aiVector3D>(*props, "Translation", ok);
+ if (ok) {
+ uvTrans.x = trans.x;
+ uvTrans.y = trans.y;
+ }
+
// resolve video links
if(doc.Settings().readTextures) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
@@ -301,13 +316,52 @@ 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);
const char* data = token.begin();
if (!token.IsBinary()) {
- DOMWarning("video content is not binary data, ignoring", &element);
+ if (*data != '"') {
+ DOMError("embedded content is not surrounded by quotation marks", &element);
+ }
+ else {
+ 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;
+ }
+ 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);
+ }
+ }
}
else if (static_cast<size_t>(token.end() - data) < 5) {
DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element);
diff --git a/thirdparty/assimp/code/FBXMeshGeometry.cpp b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp
index d75476b826..1386e2383c 100644
--- a/thirdparty/assimp/code/FBXMeshGeometry.cpp
+++ b/thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp
@@ -115,7 +115,6 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
if(tempVerts.empty()) {
FBXImporter::LogWarn("encountered mesh with no vertices");
- return;
}
std::vector<int> tempFaces;
@@ -123,7 +122,6 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
if(tempFaces.empty()) {
FBXImporter::LogWarn("encountered mesh with no faces");
- return;
}
m_vertices.reserve(tempFaces.size());
@@ -568,15 +566,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,
@@ -612,8 +610,11 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
const std::string& ReferenceInformationType)
{
const size_t face_count = m_faces.size();
- ai_assert(face_count);
-
+ if( 0 == face_count )
+ {
+ return;
+ }
+
// materials are handled separately. First of all, they are assigned per-face
// and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect
// has a slightly different meaning for materials.
@@ -624,16 +625,15 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
if (materials_out.empty()) {
FBXImporter::LogError(Formatter::format("expected material index, ignoring"));
return;
- }
- else if (materials_out.size() > 1) {
+ } else if (materials_out.size() > 1) {
FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one"));
materials_out.clear();
}
- m_materials.assign(m_vertices.size(),materials_out[0]);
- }
- else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
- m_materials.resize(face_count);
+ materials_out.resize(m_vertices.size());
+ std::fill(materials_out.begin(), materials_out.end(), materials_out.at(0));
+ } else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
+ materials_out.resize(face_count);
if(materials_out.size() != face_count) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
@@ -641,18 +641,16 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
);
return;
}
- }
- else {
+ } else {
FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ")
<< MappingInformationType << "," << ReferenceInformationType);
}
}
// ------------------------------------------------------------------------------------------------
ShapeGeometry::ShapeGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
- : Geometry(id, element, name, doc)
-{
- const Scope* sc = element.Compound();
- if (!sc) {
+: Geometry(id, element, name, doc) {
+ const Scope *sc = element.Compound();
+ if (nullptr == sc) {
DOMError("failed to read Geometry object (class: Shape), no data scope found");
}
const Element& Indexes = GetRequiredElement(*sc, "Indexes", &element);
diff --git a/thirdparty/assimp/code/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/FBX/FBXUtil.cpp b/thirdparty/assimp/code/FBX/FBXUtil.cpp
new file mode 100644
index 0000000000..c10e057c8c
--- /dev/null
+++ b/thirdparty/assimp/code/FBX/FBXUtil.cpp
@@ -0,0 +1,243 @@
+/*
+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 FBXUtil.cpp
+ * @brief Implementation of internal FBX utility functions
+ */
+
+#include "FBXUtil.h"
+#include "FBXTokenizer.h"
+
+#include <assimp/TinyFormatter.h>
+#include <string>
+#include <cstring>
+
+#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
+
+namespace Assimp {
+namespace FBX {
+namespace Util {
+
+// ------------------------------------------------------------------------------------------------
+const char* TokenTypeString(TokenType t)
+{
+ switch(t) {
+ case TokenType_OPEN_BRACKET:
+ return "TOK_OPEN_BRACKET";
+
+ case TokenType_CLOSE_BRACKET:
+ return "TOK_CLOSE_BRACKET";
+
+ case TokenType_DATA:
+ return "TOK_DATA";
+
+ case TokenType_COMMA:
+ return "TOK_COMMA";
+
+ case TokenType_KEY:
+ return "TOK_KEY";
+
+ case TokenType_BINARY_DATA:
+ return "TOK_BINARY_DATA";
+ }
+
+ ai_assert(false);
+ return "";
+}
+
+
+// ------------------------------------------------------------------------------------------------
+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) );
+}
+
+// ------------------------------------------------------------------------------------------------
+std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column)
+{
+ return static_cast<std::string>( (Formatter::format() << prefix << " (line " << line << " << col " << column << ") " << text) );
+}
+
+// ------------------------------------------------------------------------------------------------
+std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok)
+{
+ if(tok->IsBinary()) {
+ return static_cast<std::string>( (Formatter::format() << prefix <<
+ " (" << TokenTypeString(tok->Type()) <<
+ ", offset 0x" << std::hex << tok->Offset() << ") " <<
+ text) );
+ }
+
+ return static_cast<std::string>( (Formatter::format() << prefix <<
+ " (" << TokenTypeString(tok->Type()) <<
+ ", line " << tok->Line() <<
+ ", col " << tok->Column() << ") " <<
+ text) );
+}
+
+// Generated by this formula: T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
+static const uint8_t base64DecodeTable[128] = {
+ 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)
+{
+ const auto idx = static_cast<uint8_t>(ch);
+ if (idx > 127)
+ return 255;
+ return base64DecodeTable[idx];
+}
+
+size_t ComputeDecodedSizeBase64(const char* in, size_t inLength)
+{
+ 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;
+}
+
+static const char to_base64_string[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+char EncodeBase64(char byte)
+{
+ return to_base64_string[(size_t)byte];
+}
+
+/** 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++)
+ {
+ 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 encoded_string;
+}
+
+} // !Util
+} // !FBX
+} // !Assimp
+
+#endif
diff --git a/thirdparty/assimp/code/FBXUtil.h b/thirdparty/assimp/code/FBX/FBXUtil.h
index 1a37d346b4..b634418858 100644
--- a/thirdparty/assimp/code/FBXUtil.h
+++ b/thirdparty/assimp/code/FBX/FBXUtil.h
@@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXCompileConfig.h"
#include "FBXTokenizer.h"
+#include <stdint.h>
namespace Assimp {
namespace FBX {
@@ -77,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.
@@ -98,6 +99,37 @@ std::string AddLineAndColumn(const std::string& prefix, const std::string& text,
* @return A string of the following format: {prefix} ({token-type}, line {line}, col {column}) {text}*/
std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok);
+/** Decode a single Base64-encoded character.
+*
+* @param ch Character to decode (from base64 to binary).
+* @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 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 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/FBXImporter.cpp b/thirdparty/assimp/code/FBXImporter.cpp
deleted file mode 100644
index 2cc8bffc29..0000000000
--- a/thirdparty/assimp/code/FBXImporter.cpp
+++ /dev/null
@@ -1,197 +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.
-r
-* 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 FBXImporter.cpp
- * @brief Implementation of the FBX importer.
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include "FBXImporter.h"
-
-#include "FBXTokenizer.h"
-#include "FBXParser.h"
-#include "FBXUtil.h"
-#include "FBXDocument.h"
-#include "FBXConverter.h"
-
-#include <assimp/StreamReader.h>
-#include <assimp/MemoryIOWrapper.h>
-#include <assimp/Importer.hpp>
-#include <assimp/importerdesc.h>
-
-namespace Assimp {
-
-template<>
-const char* LogFunctions<FBXImporter>::Prefix() {
- static auto prefix = "FBX: ";
- return prefix;
-}
-
-}
-
-using namespace Assimp;
-using namespace Assimp::Formatter;
-using namespace Assimp::FBX;
-
-namespace {
-
-static const aiImporterDesc desc = {
- "Autodesk FBX Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "fbx"
-};
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by #Importer
-FBXImporter::FBXImporter()
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FBXImporter::~FBXImporter()
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string& extension = GetExtension(pFile);
- if (extension == std::string( desc.mFileExtensions ) ) {
- return true;
- }
-
- else if ((!extension.length() || checkSig) && pIOHandler) {
- // at least ASCII-FBX files usually have a 'FBX' somewhere in their head
- const char* tokens[] = {"fbx"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// List all extensions handled by this loader
-const aiImporterDesc* FBXImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void FBXImporter::SetupProperties(const Importer* pImp)
-{
- settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
- settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
- settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
- settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
- settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
- settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
- settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
- settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
- settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
- settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
- settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
- if (!stream) {
- ThrowException("Could not open file for reading");
- }
-
- // read entire file into memory - no streaming for this, fbx
- // files can grow large, but the assimp output data structure
- // then becomes very large, too. Assimp doesn't support
- // streaming for its output data structures so the net win with
- // streaming input data would be very low.
- std::vector<char> contents;
- contents.resize(stream->FileSize()+1);
- stream->Read( &*contents.begin(), 1, contents.size()-1 );
- contents[ contents.size() - 1 ] = 0;
- const char* const begin = &*contents.begin();
-
- // broadphase tokenizing pass in which we identify the core
- // syntax elements of FBX (brackets, commas, key:value mappings)
- TokenList tokens;
- try {
-
- bool is_binary = false;
- if (!strncmp(begin,"Kaydara FBX Binary",18)) {
- is_binary = true;
- TokenizeBinary(tokens,begin,static_cast<unsigned int>(contents.size()));
- }
- else {
- Tokenize(tokens,begin);
- }
-
- // use this information to construct a very rudimentary
- // parse-tree representing the FBX scope structure
- Parser parser(tokens, is_binary);
-
- // take the raw parse-tree and convert it to a FBX DOM
- Document doc(parser,settings);
-
- // convert the FBX DOM to aiScene
- ConvertToAssimpScene(pScene,doc);
-
- std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
- }
- catch(std::exception&) {
- std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
- throw;
- }
-}
-
-#endif // !ASSIMP_BUILD_NO_FBX_IMPORTER
diff --git a/thirdparty/assimp/code/FBXUtil.cpp b/thirdparty/assimp/code/FBXUtil.cpp
deleted file mode 100644
index c184c4a00b..0000000000
--- a/thirdparty/assimp/code/FBXUtil.cpp
+++ /dev/null
@@ -1,120 +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 FBXUtil.cpp
- * @brief Implementation of internal FBX utility functions
- */
-
-#include "FBXUtil.h"
-#include "FBXTokenizer.h"
-
-#include <assimp/TinyFormatter.h>
-#include <string>
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-namespace Assimp {
-namespace FBX {
-namespace Util {
-
-// ------------------------------------------------------------------------------------------------
-const char* TokenTypeString(TokenType t)
-{
- switch(t) {
- case TokenType_OPEN_BRACKET:
- return "TOK_OPEN_BRACKET";
-
- case TokenType_CLOSE_BRACKET:
- return "TOK_CLOSE_BRACKET";
-
- case TokenType_DATA:
- return "TOK_DATA";
-
- case TokenType_COMMA:
- return "TOK_COMMA";
-
- case TokenType_KEY:
- return "TOK_KEY";
-
- case TokenType_BINARY_DATA:
- return "TOK_BINARY_DATA";
- }
-
- ai_assert(false);
- return "";
-}
-
-
-// ------------------------------------------------------------------------------------------------
-std::string AddOffset(const std::string& prefix, const std::string& text, unsigned int offset)
-{
- return static_cast<std::string>( (Formatter::format() << prefix << " (offset 0x" << std::hex << offset << ") " << text) );
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column)
-{
- return static_cast<std::string>( (Formatter::format() << prefix << " (line " << line << " << col " << column << ") " << text) );
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok)
-{
- if(tok->IsBinary()) {
- return static_cast<std::string>( (Formatter::format() << prefix <<
- " (" << TokenTypeString(tok->Type()) <<
- ", offset 0x" << std::hex << tok->Offset() << ") " <<
- text) );
- }
-
- return static_cast<std::string>( (Formatter::format() << prefix <<
- " (" << TokenTypeString(tok->Type()) <<
- ", line " << tok->Line() <<
- ", col " << tok->Column() << ") " <<
- text) );
-}
-
-} // !Util
-} // !FBX
-} // !Assimp
-
-#endif
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/MMDImporter.cpp b/thirdparty/assimp/code/MMDImporter.cpp
deleted file mode 100644
index 84b9e35a6b..0000000000
--- a/thirdparty/assimp/code/MMDImporter.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2016, assimp team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
-
-#include "MMDImporter.h"
-#include "MMDPmdParser.h"
-#include "MMDPmxParser.h"
-#include "MMDVmdParser.h"
-#include "ConvertToLHProcess.h"
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/Importer.hpp>
-#include <assimp/ai_assert.h>
-#include <assimp/scene.h>
-#include <fstream>
-#include <iomanip>
-#include <memory>
-
-static const aiImporterDesc desc = {"MMD Importer",
- "",
- "",
- "surfaces supported?",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "pmx"};
-
-namespace Assimp {
-
-using namespace std;
-
-// ------------------------------------------------------------------------------------------------
-// Default constructor
-MMDImporter::MMDImporter()
-: m_Buffer()
-, m_strAbsPath("") {
- DefaultIOSystem io;
- m_strAbsPath = io.getOsSeparator();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-MMDImporter::~MMDImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if file is an pmx file.
-bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler,
- bool checkSig) const {
- if (!checkSig) // Check File Extension
- {
- return SimpleExtensionCheck(pFile, "pmx");
- } else // Check file Header
- {
- static const char *pTokens[] = {"PMX "};
- return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 1);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc *MMDImporter::GetInfo() const { return &desc; }
-
-// ------------------------------------------------------------------------------------------------
-// MMD import implementation
-void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
- IOSystem * /*pIOHandler*/) {
- // Read file by istream
- std::filebuf fb;
- if (!fb.open(file, std::ios::in | std::ios::binary)) {
- throw DeadlyImportError("Failed to open file " + file + ".");
- }
-
- std::istream fileStream(&fb);
-
- // Get the file-size and validate it, throwing an exception when fails
- fileStream.seekg(0, fileStream.end);
- size_t fileSize = static_cast<size_t>(fileStream.tellg());
- fileStream.seekg(0, fileStream.beg);
-
- if (fileSize < sizeof(pmx::PmxModel)) {
- throw DeadlyImportError(file + " is too small.");
- }
-
- pmx::PmxModel model;
- model.Read(&fileStream);
-
- CreateDataFromImport(&model, pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
- aiScene *pScene) {
- if (pModel == NULL) {
- return;
- }
-
- aiNode *pNode = new aiNode;
- if (!pModel->model_name.empty()) {
- pNode->mName.Set(pModel->model_name);
- }
-
- pScene->mRootNode = pNode;
-
- pNode = new aiNode;
- pScene->mRootNode->addChildren(1, &pNode);
- pNode->mName.Set(string(pModel->model_name) + string("_mesh"));
-
- // split mesh by materials
- pNode->mNumMeshes = pModel->material_count;
- pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
- for (unsigned int index = 0; index < pNode->mNumMeshes; index++) {
- pNode->mMeshes[index] = index;
- }
-
- pScene->mNumMeshes = pModel->material_count;
- pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
- for (unsigned int i = 0, indexStart = 0; i < pScene->mNumMeshes; i++) {
- const int indexCount = pModel->materials[i].index_count;
-
- pScene->mMeshes[i] = CreateMesh(pModel, indexStart, indexCount);
- pScene->mMeshes[i]->mName = pModel->materials[i].material_name;
- pScene->mMeshes[i]->mMaterialIndex = i;
- indexStart += indexCount;
- }
-
- // create node hierarchy for bone position
- std::unique_ptr<aiNode *[]> ppNode(new aiNode *[pModel->bone_count]);
- for (auto i = 0; i < pModel->bone_count; i++) {
- ppNode[i] = new aiNode(pModel->bones[i].bone_name);
- }
-
- for (auto i = 0; i < pModel->bone_count; i++) {
- const pmx::PmxBone &bone = pModel->bones[i];
-
- if (bone.parent_index < 0) {
- pScene->mRootNode->addChildren(1, ppNode.get() + i);
- } else {
- ppNode[bone.parent_index]->addChildren(1, ppNode.get() + i);
-
- aiVector3D v3 = aiVector3D(
- bone.position[0] - pModel->bones[bone.parent_index].position[0],
- bone.position[1] - pModel->bones[bone.parent_index].position[1],
- bone.position[2] - pModel->bones[bone.parent_index].position[2]);
- aiMatrix4x4::Translation(v3, ppNode[i]->mTransformation);
- }
- }
-
- // create materials
- pScene->mNumMaterials = pModel->material_count;
- pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials; i++) {
- pScene->mMaterials[i] = CreateMaterial(&pModel->materials[i], pModel);
- }
-
- // Convert everything to OpenGL space
- MakeLeftHandedProcess convertProcess;
- convertProcess.Execute(pScene);
-
- FlipUVsProcess uvFlipper;
- uvFlipper.Execute(pScene);
-
- FlipWindingOrderProcess windingFlipper;
- windingFlipper.Execute(pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
- const int indexStart, const int indexCount) {
- aiMesh *pMesh = new aiMesh;
-
- pMesh->mNumVertices = indexCount;
-
- pMesh->mNumFaces = indexCount / 3;
- pMesh->mFaces = new aiFace[pMesh->mNumFaces];
-
- const int numIndices = 3; // triangular face
- for (unsigned int index = 0; index < pMesh->mNumFaces; index++) {
- pMesh->mFaces[index].mNumIndices = numIndices;
- unsigned int *indices = new unsigned int[numIndices];
- indices[0] = numIndices * index;
- indices[1] = numIndices * index + 1;
- indices[2] = numIndices * index + 2;
- pMesh->mFaces[index].mIndices = indices;
- }
-
- pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
- pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices];
- pMesh->mNumUVComponents[0] = 2;
-
- // additional UVs
- for (int i = 1; i <= pModel->setting.uv; i++) {
- pMesh->mTextureCoords[i] = new aiVector3D[pMesh->mNumVertices];
- pMesh->mNumUVComponents[i] = 4;
- }
-
- map<int, vector<aiVertexWeight>> bone_vertex_map;
-
- // fill in contents and create bones
- for (int index = 0; index < indexCount; index++) {
- const pmx::PmxVertex *v =
- &pModel->vertices[pModel->indices[indexStart + index]];
- const float *position = v->position;
- pMesh->mVertices[index].Set(position[0], position[1], position[2]);
- const float *normal = v->normal;
-
- pMesh->mNormals[index].Set(normal[0], normal[1], normal[2]);
- pMesh->mTextureCoords[0][index].x = v->uv[0];
- pMesh->mTextureCoords[0][index].y = v->uv[1];
-
- for (int i = 1; i <= pModel->setting.uv; i++) {
- // TODO: wrong here? use quaternion transform?
- pMesh->mTextureCoords[i][index].x = v->uva[i][0];
- pMesh->mTextureCoords[i][index].y = v->uva[i][1];
- }
-
- // handle bone map
- const auto vsBDEF1_ptr =
- dynamic_cast<pmx::PmxVertexSkinningBDEF1 *>(v->skinning.get());
- const auto vsBDEF2_ptr =
- dynamic_cast<pmx::PmxVertexSkinningBDEF2 *>(v->skinning.get());
- const auto vsBDEF4_ptr =
- dynamic_cast<pmx::PmxVertexSkinningBDEF4 *>(v->skinning.get());
- const auto vsSDEF_ptr =
- dynamic_cast<pmx::PmxVertexSkinningSDEF *>(v->skinning.get());
- switch (v->skinning_type) {
- case pmx::PmxVertexSkinningType::BDEF1:
- bone_vertex_map[vsBDEF1_ptr->bone_index].push_back(
- aiVertexWeight(index, 1.0));
- break;
- case pmx::PmxVertexSkinningType::BDEF2:
- bone_vertex_map[vsBDEF2_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsBDEF2_ptr->bone_weight));
- bone_vertex_map[vsBDEF2_ptr->bone_index2].push_back(
- aiVertexWeight(index, 1.0f - vsBDEF2_ptr->bone_weight));
- break;
- case pmx::PmxVertexSkinningType::BDEF4:
- bone_vertex_map[vsBDEF4_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight1));
- bone_vertex_map[vsBDEF4_ptr->bone_index2].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight2));
- bone_vertex_map[vsBDEF4_ptr->bone_index3].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight3));
- bone_vertex_map[vsBDEF4_ptr->bone_index4].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight4));
- break;
- case pmx::PmxVertexSkinningType::SDEF: // TODO: how to use sdef_c, sdef_r0,
- // sdef_r1?
- bone_vertex_map[vsSDEF_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsSDEF_ptr->bone_weight));
- bone_vertex_map[vsSDEF_ptr->bone_index2].push_back(
- aiVertexWeight(index, 1.0f - vsSDEF_ptr->bone_weight));
- break;
- case pmx::PmxVertexSkinningType::QDEF:
- const auto vsQDEF_ptr =
- dynamic_cast<pmx::PmxVertexSkinningQDEF *>(v->skinning.get());
- bone_vertex_map[vsQDEF_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight1));
- bone_vertex_map[vsQDEF_ptr->bone_index2].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight2));
- bone_vertex_map[vsQDEF_ptr->bone_index3].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight3));
- bone_vertex_map[vsQDEF_ptr->bone_index4].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight4));
- break;
- }
- }
-
- // make all bones for each mesh
- // assign bone weights to skinned bones (otherwise just initialize)
- auto bone_ptr_ptr = new aiBone *[pModel->bone_count];
- pMesh->mNumBones = pModel->bone_count;
- pMesh->mBones = bone_ptr_ptr;
- for (auto ii = 0; ii < pModel->bone_count; ++ii) {
- auto pBone = new aiBone;
- const auto &pmxBone = pModel->bones[ii];
- pBone->mName = pmxBone.bone_name;
- aiVector3D pos(pmxBone.position[0], pmxBone.position[1], pmxBone.position[2]);
- aiMatrix4x4::Translation(-pos, pBone->mOffsetMatrix);
- auto it = bone_vertex_map.find(ii);
- if (it != bone_vertex_map.end()) {
- pBone->mNumWeights = static_cast<unsigned int>(it->second.size());
- pBone->mWeights = new aiVertexWeight[pBone->mNumWeights];
- for (unsigned int j = 0; j < pBone->mNumWeights; j++) {
- pBone->mWeights[j] = it->second[j];
- }
- }
- bone_ptr_ptr[ii] = pBone;
- }
-
- return pMesh;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMaterial *MMDImporter::CreateMaterial(const pmx::PmxMaterial *pMat,
- const pmx::PmxModel *pModel) {
- aiMaterial *mat = new aiMaterial();
- aiString name(pMat->material_english_name);
- mat->AddProperty(&name, AI_MATKEY_NAME);
-
- aiColor3D diffuse(pMat->diffuse[0], pMat->diffuse[1], pMat->diffuse[2]);
- mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- aiColor3D specular(pMat->specular[0], pMat->specular[1], pMat->specular[2]);
- mat->AddProperty(&specular, 1, AI_MATKEY_COLOR_SPECULAR);
- aiColor3D ambient(pMat->ambient[0], pMat->ambient[1], pMat->ambient[2]);
- mat->AddProperty(&ambient, 1, AI_MATKEY_COLOR_AMBIENT);
-
- float opacity = pMat->diffuse[3];
- mat->AddProperty(&opacity, 1, AI_MATKEY_OPACITY);
- float shininess = pMat->specularlity;
- mat->AddProperty(&shininess, 1, AI_MATKEY_SHININESS_STRENGTH);
-
- if(pMat->diffuse_texture_index >= 0) {
- aiString texture_path(pModel->textures[pMat->diffuse_texture_index]);
- mat->AddProperty(&texture_path, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
- }
-
- int mapping_uvwsrc = 0;
- mat->AddProperty(&mapping_uvwsrc, 1,
- AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE, 0));
-
- return mat;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_MMD_IMPORTER
diff --git a/thirdparty/assimp/code/MMDImporter.h b/thirdparty/assimp/code/MMDImporter.h
deleted file mode 100644
index 4ee94eeb00..0000000000
--- a/thirdparty/assimp/code/MMDImporter.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2016, assimp team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#ifndef MMD_FILE_IMPORTER_H_INC
-#define MMD_FILE_IMPORTER_H_INC
-
-#include <assimp/BaseImporter.h>
-#include "MMDPmxParser.h"
-#include <assimp/material.h>
-#include <vector>
-
-struct aiMesh;
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-/// \class MMDImporter
-/// \brief Imports MMD a pmx/pmd/vmd file
-// ------------------------------------------------------------------------------------------------
-class MMDImporter : public BaseImporter {
-public:
- /// \brief Default constructor
- MMDImporter();
-
- /// \brief Destructor
- ~MMDImporter();
-
-public:
- /// \brief Returns whether the class can handle the format of the given file.
- /// \remark See BaseImporter::CanRead() for details.
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-private:
- //! \brief Appends the supported extension.
- const aiImporterDesc* GetInfo () const;
-
- //! \brief File import implementation.
- void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
- //! \brief Create the data from imported content.
- void CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene);
-
- //! \brief Create the mesh
- aiMesh* CreateMesh(const pmx::PmxModel* pModel, const int indexStart, const int indexCount);
-
- //! \brief Create the material
- aiMaterial* CreateMaterial(const pmx::PmxMaterial* pMat, const pmx::PmxModel* pModel);
-
-private:
- //! Data buffer
- std::vector<char> m_Buffer;
- //! Absolute pathname of model in file system
- std::string m_strAbsPath;
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif \ No newline at end of file
diff --git a/thirdparty/assimp/code/MMDPmdParser.h b/thirdparty/assimp/code/MMDPmdParser.h
deleted file mode 100644
index d2f2224aa1..0000000000
--- a/thirdparty/assimp/code/MMDPmdParser.h
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <iostream>
-#include <fstream>
-#include "MMDCpp14.h"
-
-namespace pmd
-{
- class PmdHeader
- {
- public:
- std::string name;
- std::string name_english;
- std::string comment;
- std::string comment_english;
-
- bool Read(std::ifstream* stream)
- {
- char buffer[256];
- stream->read(buffer, 20);
- name = std::string(buffer);
- stream->read(buffer, 256);
- comment = std::string(buffer);
- return true;
- }
-
- bool ReadExtension(std::ifstream* stream)
- {
- char buffer[256];
- stream->read(buffer, 20);
- name_english = std::string(buffer);
- stream->read(buffer, 256);
- comment_english = std::string(buffer);
- return true;
- }
- };
-
- class PmdVertex
- {
- public:
- float position[3];
-
- float normal[3];
-
- float uv[2];
-
- uint16_t bone_index[2];
-
- uint8_t bone_weight;
-
- bool edge_invisible;
-
- bool Read(std::ifstream* stream)
- {
- stream->read((char*) position, sizeof(float) * 3);
- stream->read((char*) normal, sizeof(float) * 3);
- stream->read((char*) uv, sizeof(float) * 2);
- stream->read((char*) bone_index, sizeof(uint16_t) * 2);
- stream->read((char*) &bone_weight, sizeof(uint8_t));
- stream->read((char*) &edge_invisible, sizeof(uint8_t));
- return true;
- }
- };
-
- class PmdMaterial
- {
- public:
- float diffuse[4];
- float power;
- float specular[3];
- float ambient[3];
- uint8_t toon_index;
- uint8_t edge_flag;
- uint32_t index_count;
- std::string texture_filename;
- std::string sphere_filename;
-
- bool Read(std::ifstream* stream)
- {
- char buffer[20];
- stream->read((char*) &diffuse, sizeof(float) * 4);
- stream->read((char*) &power, sizeof(float));
- stream->read((char*) &specular, sizeof(float) * 3);
- stream->read((char*) &ambient, sizeof(float) * 3);
- stream->read((char*) &toon_index, sizeof(uint8_t));
- stream->read((char*) &edge_flag, sizeof(uint8_t));
- stream->read((char*) &index_count, sizeof(uint32_t));
- stream->read((char*) &buffer, sizeof(char) * 20);
- char* pstar = strchr(buffer, '*');
- if (NULL == pstar)
- {
- texture_filename = std::string(buffer);
- sphere_filename.clear();
- }
- else {
- *pstar = 0;
- texture_filename = std::string(buffer);
- sphere_filename = std::string(pstar+1);
- }
- return true;
- }
- };
-
- enum class BoneType : uint8_t
- {
- Rotation,
- RotationAndMove,
- IkEffector,
- Unknown,
- IkEffectable,
- RotationEffectable,
- IkTarget,
- Invisible,
- Twist,
- RotationMovement
- };
-
- class PmdBone
- {
- public:
- std::string name;
- std::string name_english;
- uint16_t parent_bone_index;
- uint16_t tail_pos_bone_index;
- BoneType bone_type;
- uint16_t ik_parent_bone_index;
- float bone_head_pos[3];
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name = std::string(buffer);
- stream->read((char*) &parent_bone_index, sizeof(uint16_t));
- stream->read((char*) &tail_pos_bone_index, sizeof(uint16_t));
- stream->read((char*) &bone_type, sizeof(uint8_t));
- stream->read((char*) &ik_parent_bone_index, sizeof(uint16_t));
- stream->read((char*) &bone_head_pos, sizeof(float) * 3);
- }
-
- void ReadExpantion(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name_english = std::string(buffer);
- }
- };
-
- class PmdIk
- {
- public:
- uint16_t ik_bone_index;
- uint16_t target_bone_index;
- uint16_t interations;
- float angle_limit;
- std::vector<uint16_t> ik_child_bone_index;
-
- void Read(std::istream *stream)
- {
- stream->read((char *) &ik_bone_index, sizeof(uint16_t));
- stream->read((char *) &target_bone_index, sizeof(uint16_t));
- uint8_t ik_chain_length;
- stream->read((char*) &ik_chain_length, sizeof(uint8_t));
- stream->read((char *) &interations, sizeof(uint16_t));
- stream->read((char *) &angle_limit, sizeof(float));
- ik_child_bone_index.resize(ik_chain_length);
- for (int i = 0; i < ik_chain_length; i++)
- {
- stream->read((char *) &ik_child_bone_index[i], sizeof(uint16_t));
- }
- }
- };
-
- class PmdFaceVertex
- {
- public:
- int vertex_index;
- float position[3];
-
- void Read(std::istream *stream)
- {
- stream->read((char *) &vertex_index, sizeof(int));
- stream->read((char *) position, sizeof(float) * 3);
- }
- };
-
- enum class FaceCategory : uint8_t
- {
- Base,
- Eyebrow,
- Eye,
- Mouth,
- Other
- };
-
- class PmdFace
- {
- public:
- std::string name;
- FaceCategory type;
- std::vector<PmdFaceVertex> vertices;
- std::string name_english;
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name = std::string(buffer);
- int vertex_count;
- stream->read((char*) &vertex_count, sizeof(int));
- stream->read((char*) &type, sizeof(uint8_t));
- vertices.resize(vertex_count);
- for (int i = 0; i < vertex_count; i++)
- {
- vertices[i].Read(stream);
- }
- }
-
- void ReadExpantion(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name_english = std::string(buffer);
- }
- };
-
- class PmdBoneDispName
- {
- public:
- std::string bone_disp_name;
- std::string bone_disp_name_english;
-
- void Read(std::istream *stream)
- {
- char buffer[50];
- stream->read(buffer, 50);
- bone_disp_name = std::string(buffer);
- bone_disp_name_english.clear();
- }
- void ReadExpantion(std::istream *stream)
- {
- char buffer[50];
- stream->read(buffer, 50);
- bone_disp_name_english = std::string(buffer);
- }
- };
-
- class PmdBoneDisp
- {
- public:
- uint16_t bone_index;
- uint8_t bone_disp_index;
-
- void Read(std::istream *stream)
- {
- stream->read((char*) &bone_index, sizeof(uint16_t));
- stream->read((char*) &bone_disp_index, sizeof(uint8_t));
- }
- };
-
- enum class RigidBodyShape : uint8_t
- {
- Sphere = 0,
- Box = 1,
- Cpusel = 2
- };
-
- enum class RigidBodyType : uint8_t
- {
- BoneConnected = 0,
- Physics = 1,
- ConnectedPhysics = 2
- };
-
- class PmdRigidBody
- {
- public:
- std::string name;
- uint16_t related_bone_index;
- uint8_t group_index;
- uint16_t mask;
- RigidBodyShape shape;
- float size[3];
- float position[3];
- float orientation[3];
- float weight;
- float linear_damping;
- float anglar_damping;
- float restitution;
- float friction;
- RigidBodyType rigid_type;
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, sizeof(char) * 20);
- name = (std::string(buffer));
- stream->read((char*) &related_bone_index, sizeof(uint16_t));
- stream->read((char*) &group_index, sizeof(uint8_t));
- stream->read((char*) &mask, sizeof(uint16_t));
- stream->read((char*) &shape, sizeof(uint8_t));
- stream->read((char*) size, sizeof(float) * 3);
- stream->read((char*) position, sizeof(float) * 3);
- stream->read((char*) orientation, sizeof(float) * 3);
- stream->read((char*) &weight, sizeof(float));
- stream->read((char*) &linear_damping, sizeof(float));
- stream->read((char*) &anglar_damping, sizeof(float));
- stream->read((char*) &restitution, sizeof(float));
- stream->read((char*) &friction, sizeof(float));
- stream->read((char*) &rigid_type, sizeof(char));
- }
- };
-
- class PmdConstraint
- {
- public:
- std::string name;
- uint32_t rigid_body_index_a;
- uint32_t rigid_body_index_b;
- float position[3];
- float orientation[3];
- float linear_lower_limit[3];
- float linear_upper_limit[3];
- float angular_lower_limit[3];
- float angular_upper_limit[3];
- float linear_stiffness[3];
- float angular_stiffness[3];
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name = std::string(buffer);
- stream->read((char *) &rigid_body_index_a, sizeof(uint32_t));
- stream->read((char *) &rigid_body_index_b, sizeof(uint32_t));
- stream->read((char *) position, sizeof(float) * 3);
- stream->read((char *) orientation, sizeof(float) * 3);
- stream->read((char *) linear_lower_limit, sizeof(float) * 3);
- stream->read((char *) linear_upper_limit, sizeof(float) * 3);
- stream->read((char *) angular_lower_limit, sizeof(float) * 3);
- stream->read((char *) angular_upper_limit, sizeof(float) * 3);
- stream->read((char *) linear_stiffness, sizeof(float) * 3);
- stream->read((char *) angular_stiffness, sizeof(float) * 3);
- }
- };
-
- class PmdModel
- {
- public:
- float version;
- PmdHeader header;
- std::vector<PmdVertex> vertices;
- std::vector<uint16_t> indices;
- std::vector<PmdMaterial> materials;
- std::vector<PmdBone> bones;
- std::vector<PmdIk> iks;
- std::vector<PmdFace> faces;
- std::vector<uint16_t> faces_indices;
- std::vector<PmdBoneDispName> bone_disp_name;
- std::vector<PmdBoneDisp> bone_disp;
- std::vector<std::string> toon_filenames;
- std::vector<PmdRigidBody> rigid_bodies;
- std::vector<PmdConstraint> constraints;
-
- static std::unique_ptr<PmdModel> LoadFromFile(const char *filename)
- {
- std::ifstream stream(filename, std::ios::binary);
- if (stream.fail())
- {
- std::cerr << "could not open \"" << filename << "\"" << std::endl;
- return nullptr;
- }
- auto result = LoadFromStream(&stream);
- stream.close();
- return result;
- }
-
- static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream)
- {
- auto result = mmd::make_unique<PmdModel>();
- char buffer[100];
-
- // magic
- char magic[3];
- stream->read(magic, 3);
- if (magic[0] != 'P' || magic[1] != 'm' || magic[2] != 'd')
- {
- std::cerr << "invalid file" << std::endl;
- return nullptr;
- }
-
- // version
- stream->read((char*) &(result->version), sizeof(float));
- if (result ->version != 1.0f)
- {
- std::cerr << "invalid version" << std::endl;
- return nullptr;
- }
-
- // header
- result->header.Read(stream);
-
- // vertices
- uint32_t vertex_num;
- stream->read((char*) &vertex_num, sizeof(uint32_t));
- result->vertices.resize(vertex_num);
- for (uint32_t i = 0; i < vertex_num; i++)
- {
- result->vertices[i].Read(stream);
- }
-
- // indices
- uint32_t index_num;
- stream->read((char*) &index_num, sizeof(uint32_t));
- result->indices.resize(index_num);
- for (uint32_t i = 0; i < index_num; i++)
- {
- stream->read((char*) &result->indices[i], sizeof(uint16_t));
- }
-
- // materials
- uint32_t material_num;
- stream->read((char*) &material_num, sizeof(uint32_t));
- result->materials.resize(material_num);
- for (uint32_t i = 0; i < material_num; i++)
- {
- result->materials[i].Read(stream);
- }
-
- // bones
- uint16_t bone_num;
- stream->read((char*) &bone_num, sizeof(uint16_t));
- result->bones.resize(bone_num);
- for (uint32_t i = 0; i < bone_num; i++)
- {
- result->bones[i].Read(stream);
- }
-
- // iks
- uint16_t ik_num;
- stream->read((char*) &ik_num, sizeof(uint16_t));
- result->iks.resize(ik_num);
- for (uint32_t i = 0; i < ik_num; i++)
- {
- result->iks[i].Read(stream);
- }
-
- // faces
- uint16_t face_num;
- stream->read((char*) &face_num, sizeof(uint16_t));
- result->faces.resize(face_num);
- for (uint32_t i = 0; i < face_num; i++)
- {
- result->faces[i].Read(stream);
- }
-
- // face frames
- uint8_t face_frame_num;
- stream->read((char*) &face_frame_num, sizeof(uint8_t));
- result->faces_indices.resize(face_frame_num);
- for (uint32_t i = 0; i < face_frame_num; i++)
- {
- stream->read((char*) &result->faces_indices[i], sizeof(uint16_t));
- }
-
- // bone names
- uint8_t bone_disp_num;
- stream->read((char*) &bone_disp_num, sizeof(uint8_t));
- result->bone_disp_name.resize(bone_disp_num);
- for (uint32_t i = 0; i < bone_disp_num; i++)
- {
- result->bone_disp_name[i].Read(stream);
- }
-
- // bone frame
- uint32_t bone_frame_num;
- stream->read((char*) &bone_frame_num, sizeof(uint32_t));
- result->bone_disp.resize(bone_frame_num);
- for (uint32_t i = 0; i < bone_frame_num; i++)
- {
- result->bone_disp[i].Read(stream);
- }
-
- // english name
- bool english;
- stream->read((char*) &english, sizeof(char));
- if (english)
- {
- result->header.ReadExtension(stream);
- for (uint32_t i = 0; i < bone_num; i++)
- {
- result->bones[i].ReadExpantion(stream);
- }
- for (uint32_t i = 0; i < face_num; i++)
- {
- if (result->faces[i].type == pmd::FaceCategory::Base)
- {
- continue;
- }
- result->faces[i].ReadExpantion(stream);
- }
- for (uint32_t i = 0; i < result->bone_disp_name.size(); i++)
- {
- result->bone_disp_name[i].ReadExpantion(stream);
- }
- }
-
- // toon textures
- if (stream->peek() == std::ios::traits_type::eof())
- {
- result->toon_filenames.clear();
- }
- else {
- result->toon_filenames.resize(10);
- for (uint32_t i = 0; i < 10; i++)
- {
- stream->read(buffer, 100);
- result->toon_filenames[i] = std::string(buffer);
- }
- }
-
- // physics
- if (stream->peek() == std::ios::traits_type::eof())
- {
- result->rigid_bodies.clear();
- result->constraints.clear();
- }
- else {
- uint32_t rigid_body_num;
- stream->read((char*) &rigid_body_num, sizeof(uint32_t));
- result->rigid_bodies.resize(rigid_body_num);
- for (uint32_t i = 0; i < rigid_body_num; i++)
- {
- result->rigid_bodies[i].Read(stream);
- }
- uint32_t constraint_num;
- stream->read((char*) &constraint_num, sizeof(uint32_t));
- result->constraints.resize(constraint_num);
- for (uint32_t i = 0; i < constraint_num; i++)
- {
- result->constraints[i].Read(stream);
- }
- }
-
- if (stream->peek() != std::ios::traits_type::eof())
- {
- std::cerr << "there is unknown data" << std::endl;
- }
-
- return result;
- }
- };
-}
diff --git a/thirdparty/assimp/code/MMDPmxParser.cpp b/thirdparty/assimp/code/MMDPmxParser.cpp
deleted file mode 100644
index 7425ceac22..0000000000
--- a/thirdparty/assimp/code/MMDPmxParser.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#include <utility>
-#include "MMDPmxParser.h"
-#include <assimp/StringUtils.h>
-#include "../contrib/utf8cpp/source/utf8.h"
-#include <assimp/Exceptional.h>
-
-namespace pmx
-{
- int ReadIndex(std::istream *stream, int size)
- {
- switch (size)
- {
- case 1:
- uint8_t tmp8;
- stream->read((char*) &tmp8, sizeof(uint8_t));
- if (255 == tmp8)
- {
- return -1;
- }
- else {
- return (int) tmp8;
- }
- case 2:
- uint16_t tmp16;
- stream->read((char*) &tmp16, sizeof(uint16_t));
- if (65535 == tmp16)
- {
- return -1;
- }
- else {
- return (int) tmp16;
- }
- case 4:
- int tmp32;
- stream->read((char*) &tmp32, sizeof(int));
- return tmp32;
- default:
- return -1;
- }
- }
-
- std::string ReadString(std::istream *stream, uint8_t encoding)
- {
- int size;
- stream->read((char*) &size, sizeof(int));
- std::vector<char> buffer;
- if (size == 0)
- {
- return std::string("");
- }
- buffer.reserve(size);
- stream->read((char*) buffer.data(), size);
- if (encoding == 0)
- {
- // UTF16 to UTF8
- const uint16_t* sourceStart = (uint16_t*)buffer.data();
- const unsigned int targetSize = size * 3; // enough to encode
- char *targetStart = new char[targetSize];
- std::memset(targetStart, 0, targetSize * sizeof(char));
-
- utf8::utf16to8( sourceStart, sourceStart + size/2, targetStart );
-
- std::string result(targetStart);
- delete [] targetStart;
- return result;
- }
- else
- {
- // the name is already UTF8
- return std::string((const char*)buffer.data(), size);
- }
- }
-
- void PmxSetting::Read(std::istream *stream)
- {
- uint8_t count;
- stream->read((char*) &count, sizeof(uint8_t));
- if (count < 8)
- {
- throw DeadlyImportError("MMD: invalid size");
- }
- stream->read((char*) &encoding, sizeof(uint8_t));
- stream->read((char*) &uv, sizeof(uint8_t));
- stream->read((char*) &vertex_index_size, sizeof(uint8_t));
- stream->read((char*) &texture_index_size, sizeof(uint8_t));
- stream->read((char*) &material_index_size, sizeof(uint8_t));
- stream->read((char*) &bone_index_size, sizeof(uint8_t));
- stream->read((char*) &morph_index_size, sizeof(uint8_t));
- stream->read((char*) &rigidbody_index_size, sizeof(uint8_t));
- uint8_t temp;
- for (int i = 8; i < count; i++)
- {
- stream->read((char*)&temp, sizeof(uint8_t));
- }
- }
-
- void PmxVertexSkinningBDEF1::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index = ReadIndex(stream, setting->bone_index_size);
- }
-
- void PmxVertexSkinningBDEF2::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight, sizeof(float));
- }
-
- void PmxVertexSkinningBDEF4::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight1, sizeof(float));
- stream->read((char*) &this->bone_weight2, sizeof(float));
- stream->read((char*) &this->bone_weight3, sizeof(float));
- stream->read((char*) &this->bone_weight4, sizeof(float));
- }
-
- void PmxVertexSkinningSDEF::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight, sizeof(float));
- stream->read((char*) this->sdef_c, sizeof(float) * 3);
- stream->read((char*) this->sdef_r0, sizeof(float) * 3);
- stream->read((char*) this->sdef_r1, sizeof(float) * 3);
- }
-
- void PmxVertexSkinningQDEF::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight1, sizeof(float));
- stream->read((char*) &this->bone_weight2, sizeof(float));
- stream->read((char*) &this->bone_weight3, sizeof(float));
- stream->read((char*) &this->bone_weight4, sizeof(float));
- }
-
- void PmxVertex::Read(std::istream *stream, PmxSetting *setting)
- {
- stream->read((char*) this->position, sizeof(float) * 3);
- stream->read((char*) this->normal, sizeof(float) * 3);
- stream->read((char*) this->uv, sizeof(float) * 2);
- for (int i = 0; i < setting->uv; ++i)
- {
- stream->read((char*) this->uva[i], sizeof(float) * 4);
- }
- stream->read((char*) &this->skinning_type, sizeof(PmxVertexSkinningType));
- switch (this->skinning_type)
- {
- case PmxVertexSkinningType::BDEF1:
- this->skinning = mmd::make_unique<PmxVertexSkinningBDEF1>();
- break;
- case PmxVertexSkinningType::BDEF2:
- this->skinning = mmd::make_unique<PmxVertexSkinningBDEF2>();
- break;
- case PmxVertexSkinningType::BDEF4:
- this->skinning = mmd::make_unique<PmxVertexSkinningBDEF4>();
- break;
- case PmxVertexSkinningType::SDEF:
- this->skinning = mmd::make_unique<PmxVertexSkinningSDEF>();
- break;
- case PmxVertexSkinningType::QDEF:
- this->skinning = mmd::make_unique<PmxVertexSkinningQDEF>();
- break;
- default:
- throw "invalid skinning type";
- }
- this->skinning->Read(stream, setting);
- stream->read((char*) &this->edge, sizeof(float));
- }
-
- void PmxMaterial::Read(std::istream *stream, PmxSetting *setting)
- {
- this->material_name = ReadString(stream, setting->encoding);
- this->material_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) this->diffuse, sizeof(float) * 4);
- stream->read((char*) this->specular, sizeof(float) * 3);
- stream->read((char*) &this->specularlity, sizeof(float));
- stream->read((char*) this->ambient, sizeof(float) * 3);
- stream->read((char*) &this->flag, sizeof(uint8_t));
- stream->read((char*) this->edge_color, sizeof(float) * 4);
- stream->read((char*) &this->edge_size, sizeof(float));
- this->diffuse_texture_index = ReadIndex(stream, setting->texture_index_size);
- this->sphere_texture_index = ReadIndex(stream, setting->texture_index_size);
- stream->read((char*) &this->sphere_op_mode, sizeof(uint8_t));
- stream->read((char*) &this->common_toon_flag, sizeof(uint8_t));
- if (this->common_toon_flag)
- {
- stream->read((char*) &this->toon_texture_index, sizeof(uint8_t));
- }
- else {
- this->toon_texture_index = ReadIndex(stream, setting->texture_index_size);
- }
- this->memo = ReadString(stream, setting->encoding);
- stream->read((char*) &this->index_count, sizeof(int));
- }
-
- void PmxIkLink::Read(std::istream *stream, PmxSetting *setting)
- {
- this->link_target = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->angle_lock, sizeof(uint8_t));
- if (angle_lock == 1)
- {
- stream->read((char*) this->max_radian, sizeof(float) * 3);
- stream->read((char*) this->min_radian, sizeof(float) * 3);
- }
- }
-
- void PmxBone::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_name = ReadString(stream, setting->encoding);
- this->bone_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) this->position, sizeof(float) * 3);
- this->parent_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->level, sizeof(int));
- stream->read((char*) &this->bone_flag, sizeof(uint16_t));
- if (this->bone_flag & 0x0001) {
- this->target_index = ReadIndex(stream, setting->bone_index_size);
- }
- else {
- stream->read((char*)this->offset, sizeof(float) * 3);
- }
- if (this->bone_flag & (0x0100 | 0x0200)) {
- this->grant_parent_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->grant_weight, sizeof(float));
- }
- if (this->bone_flag & 0x0400) {
- stream->read((char*)this->lock_axis_orientation, sizeof(float) * 3);
- }
- if (this->bone_flag & 0x0800) {
- stream->read((char*)this->local_axis_x_orientation, sizeof(float) * 3);
- stream->read((char*)this->local_axis_y_orientation, sizeof(float) * 3);
- }
- if (this->bone_flag & 0x2000) {
- stream->read((char*) &this->key, sizeof(int));
- }
- if (this->bone_flag & 0x0020) {
- this->ik_target_bone_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &ik_loop, sizeof(int));
- stream->read((char*) &ik_loop_angle_limit, sizeof(float));
- stream->read((char*) &ik_link_count, sizeof(int));
- this->ik_links = mmd::make_unique<PmxIkLink []>(ik_link_count);
- for (int i = 0; i < ik_link_count; i++) {
- ik_links[i].Read(stream, setting);
- }
- }
- }
-
- void PmxMorphVertexOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
- stream->read((char*)this->position_offset, sizeof(float) * 3);
- }
-
- void PmxMorphUVOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
- stream->read((char*)this->uv_offset, sizeof(float) * 4);
- }
-
- void PmxMorphBoneOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*)this->translation, sizeof(float) * 3);
- stream->read((char*)this->rotation, sizeof(float) * 4);
- }
-
- void PmxMorphMaterialOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->material_index = ReadIndex(stream, setting->material_index_size);
- stream->read((char*) &this->offset_operation, sizeof(uint8_t));
- stream->read((char*)this->diffuse, sizeof(float) * 4);
- stream->read((char*)this->specular, sizeof(float) * 3);
- stream->read((char*) &this->specularity, sizeof(float));
- stream->read((char*)this->ambient, sizeof(float) * 3);
- stream->read((char*)this->edge_color, sizeof(float) * 4);
- stream->read((char*) &this->edge_size, sizeof(float));
- stream->read((char*)this->texture_argb, sizeof(float) * 4);
- stream->read((char*)this->sphere_texture_argb, sizeof(float) * 4);
- stream->read((char*)this->toon_texture_argb, sizeof(float) * 4);
- }
-
- void PmxMorphGroupOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->morph_index = ReadIndex(stream, setting->morph_index_size);
- stream->read((char*) &this->morph_weight, sizeof(float));
- }
-
- void PmxMorphFlipOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->morph_index = ReadIndex(stream, setting->morph_index_size);
- stream->read((char*) &this->morph_value, sizeof(float));
- }
-
- void PmxMorphImplusOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->rigid_body_index = ReadIndex(stream, setting->rigidbody_index_size);
- stream->read((char*) &this->is_local, sizeof(uint8_t));
- stream->read((char*)this->velocity, sizeof(float) * 3);
- stream->read((char*)this->angular_torque, sizeof(float) * 3);
- }
-
- void PmxMorph::Read(std::istream *stream, PmxSetting *setting)
- {
- this->morph_name = ReadString(stream, setting->encoding);
- this->morph_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) &category, sizeof(MorphCategory));
- stream->read((char*) &morph_type, sizeof(MorphType));
- stream->read((char*) &this->offset_count, sizeof(int));
- switch (this->morph_type)
- {
- case MorphType::Group:
- group_offsets = mmd::make_unique<PmxMorphGroupOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- group_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::Vertex:
- vertex_offsets = mmd::make_unique<PmxMorphVertexOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- vertex_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::Bone:
- bone_offsets = mmd::make_unique<PmxMorphBoneOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- bone_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::Matrial:
- material_offsets = mmd::make_unique<PmxMorphMaterialOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- material_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::UV:
- case MorphType::AdditionalUV1:
- case MorphType::AdditionalUV2:
- case MorphType::AdditionalUV3:
- case MorphType::AdditionalUV4:
- uv_offsets = mmd::make_unique<PmxMorphUVOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- uv_offsets[i].Read(stream, setting);
- }
- break;
- default:
- throw DeadlyImportError("MMD: unknown morth type");
- }
- }
-
- void PmxFrameElement::Read(std::istream *stream, PmxSetting *setting)
- {
- stream->read((char*) &this->element_target, sizeof(uint8_t));
- if (this->element_target == 0x00)
- {
- this->index = ReadIndex(stream, setting->bone_index_size);
- }
- else {
- this->index = ReadIndex(stream, setting->morph_index_size);
- }
- }
-
- void PmxFrame::Read(std::istream *stream, PmxSetting *setting)
- {
- this->frame_name = ReadString(stream, setting->encoding);
- this->frame_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) &this->frame_flag, sizeof(uint8_t));
- stream->read((char*) &this->element_count, sizeof(int));
- this->elements = mmd::make_unique<PmxFrameElement []>(this->element_count);
- for (int i = 0; i < this->element_count; i++)
- {
- this->elements[i].Read(stream, setting);
- }
- }
-
- void PmxRigidBody::Read(std::istream *stream, PmxSetting *setting)
- {
- this->girid_body_name = ReadString(stream, setting->encoding);
- this->girid_body_english_name = ReadString(stream, setting->encoding);
- this->target_bone = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->group, sizeof(uint8_t));
- stream->read((char*) &this->mask, sizeof(uint16_t));
- stream->read((char*) &this->shape, sizeof(uint8_t));
- stream->read((char*) this->size, sizeof(float) * 3);
- stream->read((char*) this->position, sizeof(float) * 3);
- stream->read((char*) this->orientation, sizeof(float) * 3);
- stream->read((char*) &this->mass, sizeof(float));
- stream->read((char*) &this->move_attenuation, sizeof(float));
- stream->read((char*) &this->rotation_attenuation, sizeof(float));
- stream->read((char*) &this->repulsion, sizeof(float));
- stream->read((char*) &this->friction, sizeof(float));
- stream->read((char*) &this->physics_calc_type, sizeof(uint8_t));
- }
-
- void PmxJointParam::Read(std::istream *stream, PmxSetting *setting)
- {
- this->rigid_body1 = ReadIndex(stream, setting->rigidbody_index_size);
- this->rigid_body2 = ReadIndex(stream, setting->rigidbody_index_size);
- stream->read((char*) this->position, sizeof(float) * 3);
- stream->read((char*) this->orientaiton, sizeof(float) * 3);
- stream->read((char*) this->move_limitation_min, sizeof(float) * 3);
- stream->read((char*) this->move_limitation_max, sizeof(float) * 3);
- stream->read((char*) this->rotation_limitation_min, sizeof(float) * 3);
- stream->read((char*) this->rotation_limitation_max, sizeof(float) * 3);
- stream->read((char*) this->spring_move_coefficient, sizeof(float) * 3);
- stream->read((char*) this->spring_rotation_coefficient, sizeof(float) * 3);
- }
-
- void PmxJoint::Read(std::istream *stream, PmxSetting *setting)
- {
- this->joint_name = ReadString(stream, setting->encoding);
- this->joint_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) &this->joint_type, sizeof(uint8_t));
- this->param.Read(stream, setting);
- }
-
- void PmxAncherRigidBody::Read(std::istream *stream, PmxSetting *setting)
- {
- this->related_rigid_body = ReadIndex(stream, setting->rigidbody_index_size);
- this->related_vertex = ReadIndex(stream, setting->vertex_index_size);
- stream->read((char*) &this->is_near, sizeof(uint8_t));
- }
-
- void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
- {
- std::cerr << "Not Implemented Exception" << std::endl;
- throw DeadlyImportError("MMD: Not Implemented Exception");
- }
-
- void PmxModel::Init()
- {
- this->version = 0.0f;
- this->model_name.clear();
- this->model_english_name.clear();
- this->model_comment.clear();
- this->model_english_comment.clear();
- this->vertex_count = 0;
- this->vertices = nullptr;
- this->index_count = 0;
- this->indices = nullptr;
- this->texture_count = 0;
- this->textures = nullptr;
- this->material_count = 0;
- this->materials = nullptr;
- this->bone_count = 0;
- this->bones = nullptr;
- this->morph_count = 0;
- this->morphs = nullptr;
- this->frame_count = 0;
- this->frames = nullptr;
- this->rigid_body_count = 0;
- this->rigid_bodies = nullptr;
- this->joint_count = 0;
- this->joints = nullptr;
- this->soft_body_count = 0;
- this->soft_bodies = nullptr;
- }
-
- void PmxModel::Read(std::istream *stream)
- {
- char magic[4];
- stream->read((char*) magic, sizeof(char) * 4);
- if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
- {
- std::cerr << "invalid magic number." << std::endl;
- throw DeadlyImportError("MMD: invalid magic number.");
- }
- stream->read((char*) &version, sizeof(float));
- if (version != 2.0f && version != 2.1f)
- {
- std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
- throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but " + to_string(version));
- }
- this->setting.Read(stream);
-
- this->model_name = ReadString(stream, setting.encoding);
- this->model_english_name = ReadString(stream, setting.encoding);
- this->model_comment = ReadString(stream, setting.encoding);
- this->model_english_comment = ReadString(stream, setting.encoding);
-
- // read vertices
- stream->read((char*) &vertex_count, sizeof(int));
- this->vertices = mmd::make_unique<PmxVertex []>(vertex_count);
- for (int i = 0; i < vertex_count; i++)
- {
- vertices[i].Read(stream, &setting);
- }
-
- // read indices
- stream->read((char*) &index_count, sizeof(int));
- this->indices = mmd::make_unique<int []>(index_count);
- for (int i = 0; i < index_count; i++)
- {
- this->indices[i] = ReadIndex(stream, setting.vertex_index_size);
- }
-
- // read texture names
- stream->read((char*) &texture_count, sizeof(int));
- this->textures = mmd::make_unique<std::string []>(texture_count);
- for (int i = 0; i < texture_count; i++)
- {
- this->textures[i] = ReadString(stream, setting.encoding);
- }
-
- // read materials
- stream->read((char*) &material_count, sizeof(int));
- this->materials = mmd::make_unique<PmxMaterial []>(material_count);
- for (int i = 0; i < material_count; i++)
- {
- this->materials[i].Read(stream, &setting);
- }
-
- // read bones
- stream->read((char*) &this->bone_count, sizeof(int));
- this->bones = mmd::make_unique<PmxBone []>(this->bone_count);
- for (int i = 0; i < this->bone_count; i++)
- {
- this->bones[i].Read(stream, &setting);
- }
-
- // read morphs
- stream->read((char*) &this->morph_count, sizeof(int));
- this->morphs = mmd::make_unique<PmxMorph []>(this->morph_count);
- for (int i = 0; i < this->morph_count; i++)
- {
- this->morphs[i].Read(stream, &setting);
- }
-
- // read display frames
- stream->read((char*) &this->frame_count, sizeof(int));
- this->frames = mmd::make_unique<PmxFrame []>(this->frame_count);
- for (int i = 0; i < this->frame_count; i++)
- {
- this->frames[i].Read(stream, &setting);
- }
-
- // read rigid bodies
- stream->read((char*) &this->rigid_body_count, sizeof(int));
- this->rigid_bodies = mmd::make_unique<PmxRigidBody []>(this->rigid_body_count);
- for (int i = 0; i < this->rigid_body_count; i++)
- {
- this->rigid_bodies[i].Read(stream, &setting);
- }
-
- // read joints
- stream->read((char*) &this->joint_count, sizeof(int));
- this->joints = mmd::make_unique<PmxJoint []>(this->joint_count);
- for (int i = 0; i < this->joint_count; i++)
- {
- this->joints[i].Read(stream, &setting);
- }
- }
-}
diff --git a/thirdparty/assimp/code/MMDPmxParser.h b/thirdparty/assimp/code/MMDPmxParser.h
deleted file mode 100644
index cf523a1298..0000000000
--- a/thirdparty/assimp/code/MMDPmxParser.h
+++ /dev/null
@@ -1,782 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include <vector>
-#include <string>
-#include <iostream>
-#include <fstream>
-#include <memory>
-#include "MMDCpp14.h"
-
-namespace pmx
-{
- class PmxSetting
- {
- public:
- PmxSetting()
- : encoding(0)
- , uv(0)
- , vertex_index_size(0)
- , texture_index_size(0)
- , material_index_size(0)
- , bone_index_size(0)
- , morph_index_size(0)
- , rigidbody_index_size(0)
- {}
-
- uint8_t encoding;
- uint8_t uv;
- uint8_t vertex_index_size;
- uint8_t texture_index_size;
- uint8_t material_index_size;
- uint8_t bone_index_size;
- uint8_t morph_index_size;
- uint8_t rigidbody_index_size;
- void Read(std::istream *stream);
- };
-
- enum class PmxVertexSkinningType : uint8_t
- {
- BDEF1 = 0,
- BDEF2 = 1,
- BDEF4 = 2,
- SDEF = 3,
- QDEF = 4,
- };
-
- class PmxVertexSkinning
- {
- public:
- virtual void Read(std::istream *stream, PmxSetting *setting) = 0;
- virtual ~PmxVertexSkinning() {}
- };
-
- class PmxVertexSkinningBDEF1 : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningBDEF1()
- : bone_index(0)
- {}
-
- int bone_index;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningBDEF2 : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningBDEF2()
- : bone_index1(0)
- , bone_index2(0)
- , bone_weight(0.0f)
- {}
-
- int bone_index1;
- int bone_index2;
- float bone_weight;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningBDEF4 : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningBDEF4()
- : bone_index1(0)
- , bone_index2(0)
- , bone_index3(0)
- , bone_index4(0)
- , bone_weight1(0.0f)
- , bone_weight2(0.0f)
- , bone_weight3(0.0f)
- , bone_weight4(0.0f)
- {}
-
- int bone_index1;
- int bone_index2;
- int bone_index3;
- int bone_index4;
- float bone_weight1;
- float bone_weight2;
- float bone_weight3;
- float bone_weight4;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningSDEF : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningSDEF()
- : bone_index1(0)
- , bone_index2(0)
- , bone_weight(0.0f)
- {
- for (int i = 0; i < 3; ++i) {
- sdef_c[i] = 0.0f;
- sdef_r0[i] = 0.0f;
- sdef_r1[i] = 0.0f;
- }
- }
-
- int bone_index1;
- int bone_index2;
- float bone_weight;
- float sdef_c[3];
- float sdef_r0[3];
- float sdef_r1[3];
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningQDEF : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningQDEF()
- : bone_index1(0)
- , bone_index2(0)
- , bone_index3(0)
- , bone_index4(0)
- , bone_weight1(0.0f)
- , bone_weight2(0.0f)
- , bone_weight3(0.0f)
- , bone_weight4(0.0f)
- {}
-
- int bone_index1;
- int bone_index2;
- int bone_index3;
- int bone_index4;
- float bone_weight1;
- float bone_weight2;
- float bone_weight3;
- float bone_weight4;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertex
- {
- public:
- PmxVertex()
- : edge(0.0f)
- {
- uv[0] = uv[1] = 0.0f;
- for (int i = 0; i < 3; ++i) {
- position[i] = 0.0f;
- normal[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- for (int k = 0; k < 4; ++k) {
- uva[i][k] = 0.0f;
- }
- }
- }
-
- float position[3];
- float normal[3];
- float uv[2];
- float uva[4][4];
- PmxVertexSkinningType skinning_type;
- std::unique_ptr<PmxVertexSkinning> skinning;
- float edge;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxMaterial
- {
- public:
- PmxMaterial()
- : specularlity(0.0f)
- , flag(0)
- , edge_size(0.0f)
- , diffuse_texture_index(0)
- , sphere_texture_index(0)
- , sphere_op_mode(0)
- , common_toon_flag(0)
- , toon_texture_index(0)
- , index_count(0)
- {
- for (int i = 0; i < 3; ++i) {
- specular[i] = 0.0f;
- ambient[i] = 0.0f;
- edge_color[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- diffuse[i] = 0.0f;
- }
- }
-
- std::string material_name;
- std::string material_english_name;
- float diffuse[4];
- float specular[3];
- float specularlity;
- float ambient[3];
- uint8_t flag;
- float edge_color[4];
- float edge_size;
- int diffuse_texture_index;
- int sphere_texture_index;
- uint8_t sphere_op_mode;
- uint8_t common_toon_flag;
- int toon_texture_index;
- std::string memo;
- int index_count;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxIkLink
- {
- public:
- PmxIkLink()
- : link_target(0)
- , angle_lock(0)
- {
- for (int i = 0; i < 3; ++i) {
- max_radian[i] = 0.0f;
- min_radian[i] = 0.0f;
- }
- }
-
- int link_target;
- uint8_t angle_lock;
- float max_radian[3];
- float min_radian[3];
- void Read(std::istream *stream, PmxSetting *settingn);
- };
-
- class PmxBone
- {
- public:
- PmxBone()
- : parent_index(0)
- , level(0)
- , bone_flag(0)
- , target_index(0)
- , grant_parent_index(0)
- , grant_weight(0.0f)
- , key(0)
- , ik_target_bone_index(0)
- , ik_loop(0)
- , ik_loop_angle_limit(0.0f)
- , ik_link_count(0)
- {
- for (int i = 0; i < 3; ++i) {
- position[i] = 0.0f;
- offset[i] = 0.0f;
- lock_axis_orientation[i] = 0.0f;
- local_axis_x_orientation[i] = 0.0f;
- local_axis_y_orientation[i] = 0.0f;
- }
- }
-
- std::string bone_name;
- std::string bone_english_name;
- float position[3];
- int parent_index;
- int level;
- uint16_t bone_flag;
- float offset[3];
- int target_index;
- int grant_parent_index;
- float grant_weight;
- float lock_axis_orientation[3];
- float local_axis_x_orientation[3];
- float local_axis_y_orientation[3];
- int key;
- int ik_target_bone_index;
- int ik_loop;
- float ik_loop_angle_limit;
- int ik_link_count;
- std::unique_ptr<PmxIkLink []> ik_links;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- enum class MorphType : uint8_t
- {
- Group = 0,
- Vertex = 1,
- Bone = 2,
- UV = 3,
- AdditionalUV1 = 4,
- AdditionalUV2 = 5,
- AdditionalUV3 = 6,
- AdditionalUV4 = 7,
- Matrial = 8,
- Flip = 9,
- Implus = 10,
- };
-
- enum class MorphCategory : uint8_t
- {
- ReservedCategory = 0,
- Eyebrow = 1,
- Eye = 2,
- Mouth = 3,
- Other = 4,
- };
-
- class PmxMorphOffset
- {
- public:
- void virtual Read(std::istream *stream, PmxSetting *setting) = 0;
- };
-
- class PmxMorphVertexOffset : public PmxMorphOffset
- {
- public:
- PmxMorphVertexOffset()
- : vertex_index(0)
- {
- for (int i = 0; i < 3; ++i) {
- position_offset[i] = 0.0f;
- }
- }
- int vertex_index;
- float position_offset[3];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphUVOffset : public PmxMorphOffset
- {
- public:
- PmxMorphUVOffset()
- : vertex_index(0)
- {
- for (int i = 0; i < 4; ++i) {
- uv_offset[i] = 0.0f;
- }
- }
- int vertex_index;
- float uv_offset[4];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphBoneOffset : public PmxMorphOffset
- {
- public:
- PmxMorphBoneOffset()
- : bone_index(0)
- {
- for (int i = 0; i < 3; ++i) {
- translation[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- rotation[i] = 0.0f;
- }
- }
- int bone_index;
- float translation[3];
- float rotation[4];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphMaterialOffset : public PmxMorphOffset
- {
- public:
- PmxMorphMaterialOffset()
- : specularity(0.0f)
- , edge_size(0.0f)
- {
- for (int i = 0; i < 3; ++i) {
- specular[i] = 0.0f;
- ambient[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- diffuse[i] = 0.0f;
- edge_color[i] = 0.0f;
- texture_argb[i] = 0.0f;
- sphere_texture_argb[i] = 0.0f;
- toon_texture_argb[i] = 0.0f;
- }
- }
- int material_index;
- uint8_t offset_operation;
- float diffuse[4];
- float specular[3];
- float specularity;
- float ambient[3];
- float edge_color[4];
- float edge_size;
- float texture_argb[4];
- float sphere_texture_argb[4];
- float toon_texture_argb[4];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphGroupOffset : public PmxMorphOffset
- {
- public:
- PmxMorphGroupOffset()
- : morph_index(0)
- , morph_weight(0.0f)
- {}
- int morph_index;
- float morph_weight;
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphFlipOffset : public PmxMorphOffset
- {
- public:
- PmxMorphFlipOffset()
- : morph_index(0)
- , morph_value(0.0f)
- {}
- int morph_index;
- float morph_value;
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphImplusOffset : public PmxMorphOffset
- {
- public:
- PmxMorphImplusOffset()
- : rigid_body_index(0)
- , is_local(0)
- {
- for (int i = 0; i < 3; ++i) {
- velocity[i] = 0.0f;
- angular_torque[i] = 0.0f;
- }
- }
- int rigid_body_index;
- uint8_t is_local;
- float velocity[3];
- float angular_torque[3];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorph
- {
- public:
- PmxMorph()
- : offset_count(0)
- {
- }
- std::string morph_name;
- std::string morph_english_name;
- MorphCategory category;
- MorphType morph_type;
- int offset_count;
- std::unique_ptr<PmxMorphVertexOffset []> vertex_offsets;
- std::unique_ptr<PmxMorphUVOffset []> uv_offsets;
- std::unique_ptr<PmxMorphBoneOffset []> bone_offsets;
- std::unique_ptr<PmxMorphMaterialOffset []> material_offsets;
- std::unique_ptr<PmxMorphGroupOffset []> group_offsets;
- std::unique_ptr<PmxMorphFlipOffset []> flip_offsets;
- std::unique_ptr<PmxMorphImplusOffset []> implus_offsets;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxFrameElement
- {
- public:
- PmxFrameElement()
- : element_target(0)
- , index(0)
- {
- }
- uint8_t element_target;
- int index;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxFrame
- {
- public:
- PmxFrame()
- : frame_flag(0)
- , element_count(0)
- {
- }
- std::string frame_name;
- std::string frame_english_name;
- uint8_t frame_flag;
- int element_count;
- std::unique_ptr<PmxFrameElement []> elements;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxRigidBody
- {
- public:
- PmxRigidBody()
- : target_bone(0)
- , group(0)
- , mask(0)
- , shape(0)
- , mass(0.0f)
- , move_attenuation(0.0f)
- , rotation_attenuation(0.0f)
- , repulsion(0.0f)
- , friction(0.0f)
- , physics_calc_type(0)
- {
- for (int i = 0; i < 3; ++i) {
- size[i] = 0.0f;
- position[i] = 0.0f;
- orientation[i] = 0.0f;
- }
- }
- std::string girid_body_name;
- std::string girid_body_english_name;
- int target_bone;
- uint8_t group;
- uint16_t mask;
- uint8_t shape;
- float size[3];
- float position[3];
- float orientation[3];
- float mass;
- float move_attenuation;
- float rotation_attenuation;
- float repulsion;
- float friction;
- uint8_t physics_calc_type;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- enum class PmxJointType : uint8_t
- {
- Generic6DofSpring = 0,
- Generic6Dof = 1,
- Point2Point = 2,
- ConeTwist = 3,
- Slider = 5,
- Hinge = 6
- };
-
- class PmxJointParam
- {
- public:
- PmxJointParam()
- : rigid_body1(0)
- , rigid_body2(0)
- {
- for (int i = 0; i < 3; ++i) {
- position[i] = 0.0f;
- orientaiton[i] = 0.0f;
- move_limitation_min[i] = 0.0f;
- move_limitation_max[i] = 0.0f;
- rotation_limitation_min[i] = 0.0f;
- rotation_limitation_max[i] = 0.0f;
- spring_move_coefficient[i] = 0.0f;
- spring_rotation_coefficient[i] = 0.0f;
- }
- }
- int rigid_body1;
- int rigid_body2;
- float position[3];
- float orientaiton[3];
- float move_limitation_min[3];
- float move_limitation_max[3];
- float rotation_limitation_min[3];
- float rotation_limitation_max[3];
- float spring_move_coefficient[3];
- float spring_rotation_coefficient[3];
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxJoint
- {
- public:
- std::string joint_name;
- std::string joint_english_name;
- PmxJointType joint_type;
- PmxJointParam param;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- enum PmxSoftBodyFlag : uint8_t
- {
- BLink = 0x01,
- Cluster = 0x02,
- Link = 0x04
- };
-
- class PmxAncherRigidBody
- {
- public:
- PmxAncherRigidBody()
- : related_rigid_body(0)
- , related_vertex(0)
- , is_near(false)
- {}
- int related_rigid_body;
- int related_vertex;
- bool is_near;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxSoftBody
- {
- public:
- PmxSoftBody()
- : shape(0)
- , target_material(0)
- , group(0)
- , mask(0)
- , blink_distance(0)
- , cluster_count(0)
- , mass(0.0)
- , collisioni_margin(0.0)
- , aero_model(0)
- , VCF(0.0f)
- , DP(0.0f)
- , DG(0.0f)
- , LF(0.0f)
- , PR(0.0f)
- , VC(0.0f)
- , DF(0.0f)
- , MT(0.0f)
- , CHR(0.0f)
- , KHR(0.0f)
- , SHR(0.0f)
- , AHR(0.0f)
- , SRHR_CL(0.0f)
- , SKHR_CL(0.0f)
- , SSHR_CL(0.0f)
- , SR_SPLT_CL(0.0f)
- , SK_SPLT_CL(0.0f)
- , SS_SPLT_CL(0.0f)
- , V_IT(0)
- , P_IT(0)
- , D_IT(0)
- , C_IT(0)
- , LST(0.0f)
- , AST(0.0f)
- , VST(0.0f)
- , anchor_count(0)
- , pin_vertex_count(0)
- {}
- std::string soft_body_name;
- std::string soft_body_english_name;
- uint8_t shape;
- int target_material;
- uint8_t group;
- uint16_t mask;
- PmxSoftBodyFlag flag;
- int blink_distance;
- int cluster_count;
- float mass;
- float collisioni_margin;
- int aero_model;
- float VCF;
- float DP;
- float DG;
- float LF;
- float PR;
- float VC;
- float DF;
- float MT;
- float CHR;
- float KHR;
- float SHR;
- float AHR;
- float SRHR_CL;
- float SKHR_CL;
- float SSHR_CL;
- float SR_SPLT_CL;
- float SK_SPLT_CL;
- float SS_SPLT_CL;
- int V_IT;
- int P_IT;
- int D_IT;
- int C_IT;
- float LST;
- float AST;
- float VST;
- int anchor_count;
- std::unique_ptr<PmxAncherRigidBody []> anchers;
- int pin_vertex_count;
- std::unique_ptr<int []> pin_vertices;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxModel
- {
- public:
- PmxModel()
- : version(0.0f)
- , vertex_count(0)
- , index_count(0)
- , texture_count(0)
- , material_count(0)
- , bone_count(0)
- , morph_count(0)
- , frame_count(0)
- , rigid_body_count(0)
- , joint_count(0)
- , soft_body_count(0)
- {}
-
- float version;
- PmxSetting setting;
- std::string model_name;
- std::string model_english_name;
- std::string model_comment;
- std::string model_english_comment;
- int vertex_count;
- std::unique_ptr<PmxVertex []> vertices;
- int index_count;
- std::unique_ptr<int []> indices;
- int texture_count;
- std::unique_ptr< std::string []> textures;
- int material_count;
- std::unique_ptr<PmxMaterial []> materials;
- int bone_count;
- std::unique_ptr<PmxBone []> bones;
- int morph_count;
- std::unique_ptr<PmxMorph []> morphs;
- int frame_count;
- std::unique_ptr<PmxFrame [] > frames;
- int rigid_body_count;
- std::unique_ptr<PmxRigidBody []> rigid_bodies;
- int joint_count;
- std::unique_ptr<PmxJoint []> joints;
- int soft_body_count;
- std::unique_ptr<PmxSoftBody []> soft_bodies;
- void Init();
- void Read(std::istream *stream);
- //static std::unique_ptr<PmxModel> ReadFromFile(const char *filename);
- //static std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream);
- };
-}
diff --git a/thirdparty/assimp/code/MMDVmdParser.h b/thirdparty/assimp/code/MMDVmdParser.h
deleted file mode 100644
index 947c3a2422..0000000000
--- a/thirdparty/assimp/code/MMDVmdParser.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <iostream>
-#include <fstream>
-#include <ostream>
-#include "MMDCpp14.h"
-
-namespace vmd
-{
- class VmdBoneFrame
- {
- public:
- std::string name;
- int frame;
- float position[3];
- float orientation[4];
- char interpolation[4][4][4];
-
- void Read(std::istream* stream)
- {
- char buffer[15];
- stream->read((char*) buffer, sizeof(char)*15);
- name = std::string(buffer);
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) position, sizeof(float)*3);
- stream->read((char*) orientation, sizeof(float)*4);
- stream->read((char*) interpolation, sizeof(char) * 4 * 4 * 4);
- }
-
- void Write(std::ostream* stream)
- {
- stream->write((char*)name.c_str(), sizeof(char) * 15);
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)position, sizeof(float) * 3);
- stream->write((char*)orientation, sizeof(float) * 4);
- stream->write((char*)interpolation, sizeof(char) * 4 * 4 * 4);
- }
- };
-
- class VmdFaceFrame
- {
- public:
- std::string face_name;
- float weight;
- uint32_t frame;
-
- void Read(std::istream* stream)
- {
- char buffer[15];
- stream->read((char*) &buffer, sizeof(char) * 15);
- face_name = std::string(buffer);
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) &weight, sizeof(float));
- }
-
- void Write(std::ostream* stream)
- {
- stream->write((char*)face_name.c_str(), sizeof(char) * 15);
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)&weight, sizeof(float));
- }
- };
-
- class VmdCameraFrame
- {
- public:
- int frame;
- float distance;
- float position[3];
- float orientation[3];
- char interpolation[6][4];
- float angle;
- char unknown[3];
-
- void Read(std::istream *stream)
- {
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) &distance, sizeof(float));
- stream->read((char*) position, sizeof(float) * 3);
- stream->read((char*) orientation, sizeof(float) * 3);
- stream->read((char*) interpolation, sizeof(char) * 24);
- stream->read((char*) &angle, sizeof(float));
- stream->read((char*) unknown, sizeof(char) * 3);
- }
-
- void Write(std::ostream *stream)
- {
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)&distance, sizeof(float));
- stream->write((char*)position, sizeof(float) * 3);
- stream->write((char*)orientation, sizeof(float) * 3);
- stream->write((char*)interpolation, sizeof(char) * 24);
- stream->write((char*)&angle, sizeof(float));
- stream->write((char*)unknown, sizeof(char) * 3);
- }
- };
-
- class VmdLightFrame
- {
- public:
- int frame;
- float color[3];
- float position[3];
-
- void Read(std::istream* stream)
- {
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) color, sizeof(float) * 3);
- stream->read((char*) position, sizeof(float) * 3);
- }
-
- void Write(std::ostream* stream)
- {
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)color, sizeof(float) * 3);
- stream->write((char*)position, sizeof(float) * 3);
- }
- };
-
- class VmdIkEnable
- {
- public:
- std::string ik_name;
- bool enable;
- };
-
- class VmdIkFrame
- {
- public:
- int frame;
- bool display;
- std::vector<VmdIkEnable> ik_enable;
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) &display, sizeof(uint8_t));
- int ik_count;
- stream->read((char*) &ik_count, sizeof(int));
- ik_enable.resize(ik_count);
- for (int i = 0; i < ik_count; i++)
- {
- stream->read(buffer, 20);
- ik_enable[i].ik_name = std::string(buffer);
- stream->read((char*) &ik_enable[i].enable, sizeof(uint8_t));
- }
- }
-
- void Write(std::ostream *stream)
- {
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)&display, sizeof(uint8_t));
- int ik_count = static_cast<int>(ik_enable.size());
- stream->write((char*)&ik_count, sizeof(int));
- for (int i = 0; i < ik_count; i++)
- {
- const VmdIkEnable& ik_enable = this->ik_enable.at(i);
- stream->write(ik_enable.ik_name.c_str(), 20);
- stream->write((char*)&ik_enable.enable, sizeof(uint8_t));
- }
- }
- };
-
- class VmdMotion
- {
- public:
- std::string model_name;
- int version;
- std::vector<VmdBoneFrame> bone_frames;
- std::vector<VmdFaceFrame> face_frames;
- std::vector<VmdCameraFrame> camera_frames;
- std::vector<VmdLightFrame> light_frames;
- std::vector<VmdIkFrame> ik_frames;
-
- static std::unique_ptr<VmdMotion> LoadFromFile(char const *filename)
- {
- std::ifstream stream(filename, std::ios::binary);
- auto result = LoadFromStream(&stream);
- stream.close();
- return result;
- }
-
- static std::unique_ptr<VmdMotion> LoadFromStream(std::ifstream *stream)
- {
-
- char buffer[30];
- auto result = mmd::make_unique<VmdMotion>();
-
- // magic and version
- stream->read((char*) buffer, 30);
- if (strncmp(buffer, "Vocaloid Motion Data", 20))
- {
- std::cerr << "invalid vmd file." << std::endl;
- return nullptr;
- }
- result->version = std::atoi(buffer + 20);
-
- // name
- stream->read(buffer, 20);
- result->model_name = std::string(buffer);
-
- // bone frames
- int bone_frame_num;
- stream->read((char*) &bone_frame_num, sizeof(int));
- result->bone_frames.resize(bone_frame_num);
- for (int i = 0; i < bone_frame_num; i++)
- {
- result->bone_frames[i].Read(stream);
- }
-
- // face frames
- int face_frame_num;
- stream->read((char*) &face_frame_num, sizeof(int));
- result->face_frames.resize(face_frame_num);
- for (int i = 0; i < face_frame_num; i++)
- {
- result->face_frames[i].Read(stream);
- }
-
- // camera frames
- int camera_frame_num;
- stream->read((char*) &camera_frame_num, sizeof(int));
- result->camera_frames.resize(camera_frame_num);
- for (int i = 0; i < camera_frame_num; i++)
- {
- result->camera_frames[i].Read(stream);
- }
-
- // light frames
- int light_frame_num;
- stream->read((char*) &light_frame_num, sizeof(int));
- result->light_frames.resize(light_frame_num);
- for (int i = 0; i < light_frame_num; i++)
- {
- result->light_frames[i].Read(stream);
- }
-
- // unknown2
- stream->read(buffer, 4);
-
- // ik frames
- if (stream->peek() != std::ios::traits_type::eof())
- {
- int ik_num;
- stream->read((char*) &ik_num, sizeof(int));
- result->ik_frames.resize(ik_num);
- for (int i = 0; i < ik_num; i++)
- {
- result->ik_frames[i].Read(stream);
- }
- }
-
- if (stream->peek() != std::ios::traits_type::eof())
- {
- std::cerr << "vmd stream has unknown data." << std::endl;
- }
-
- return result;
- }
-
- bool SaveToFile(const std::u16string& /*filename*/)
- {
- // TODO: How to adapt u16string to string?
- /*
- std::ofstream stream(filename.c_str(), std::ios::binary);
- auto result = SaveToStream(&stream);
- stream.close();
- return result;
- */
- return false;
- }
-
- bool SaveToStream(std::ofstream *stream)
- {
- std::string magic = "Vocaloid Motion Data 0002\0";
- magic.resize(30);
-
- // magic and version
- stream->write(magic.c_str(), 30);
-
- // name
- stream->write(model_name.c_str(), 20);
-
- // bone frames
- const int bone_frame_num = static_cast<int>(bone_frames.size());
- stream->write(reinterpret_cast<const char*>(&bone_frame_num), sizeof(int));
- for (int i = 0; i < bone_frame_num; i++)
- {
- bone_frames[i].Write(stream);
- }
-
- // face frames
- const int face_frame_num = static_cast<int>(face_frames.size());
- stream->write(reinterpret_cast<const char*>(&face_frame_num), sizeof(int));
- for (int i = 0; i < face_frame_num; i++)
- {
- face_frames[i].Write(stream);
- }
-
- // camera frames
- const int camera_frame_num = static_cast<int>(camera_frames.size());
- stream->write(reinterpret_cast<const char*>(&camera_frame_num), sizeof(int));
- for (int i = 0; i < camera_frame_num; i++)
- {
- camera_frames[i].Write(stream);
- }
-
- // light frames
- const int light_frame_num = static_cast<int>(light_frames.size());
- stream->write(reinterpret_cast<const char*>(&light_frame_num), sizeof(int));
- for (int i = 0; i < light_frame_num; i++)
- {
- light_frames[i].Write(stream);
- }
-
- // self shadow datas
- const int self_shadow_num = 0;
- stream->write(reinterpret_cast<const char*>(&self_shadow_num), sizeof(int));
-
- // ik frames
- const int ik_num = static_cast<int>(ik_frames.size());
- stream->write(reinterpret_cast<const char*>(&ik_num), sizeof(int));
- for (int i = 0; i < ik_num; i++)
- {
- ik_frames[i].Write(stream);
- }
-
- return true;
- }
- };
-}
diff --git a/thirdparty/assimp/code/MaterialSystem.cpp b/thirdparty/assimp/code/Material/MaterialSystem.cpp
index 03d5a18a34..0be6e9f7bb 100644
--- a/thirdparty/assimp/code/MaterialSystem.cpp
+++ b/thirdparty/assimp/code/Material/MaterialSystem.cpp
@@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/types.h>
#include <assimp/material.h>
#include <assimp/DefaultLogger.hpp>
-#include <assimp/Macros.h>
using namespace Assimp;
@@ -96,12 +95,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 +111,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;
}
@@ -543,23 +544,7 @@ aiReturn aiMaterial::AddProperty (const aiString* pInput,
unsigned int type,
unsigned int index)
{
- // We don't want to add the whole buffer .. write a 32 bit length
- // prefix followed by the zero-terminated UTF8 string.
- // (HACK) I don't want to break the ABI now, but we definitely
- // ought to change aiString::mLength to uint32_t one day.
- if (sizeof(size_t) == 8) {
- aiString copy = *pInput;
- uint32_t* s = reinterpret_cast<uint32_t*>(&copy.length);
- s[1] = static_cast<uint32_t>(pInput->length);
-
- return AddBinaryProperty(s+1,
- static_cast<unsigned int>(pInput->length+1+4),
- pKey,
- type,
- index,
- aiPTI_String);
- }
- ai_assert(sizeof(size_t)==4);
+ ai_assert(sizeof(ai_uint32)==4);
return AddBinaryProperty(pInput,
static_cast<unsigned int>(pInput->length+1+4),
pKey,
diff --git a/thirdparty/assimp/code/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/PostProcessing/ArmaturePopulate.cpp b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp
new file mode 100644
index 0000000000..75daeb6b59
--- /dev/null
+++ b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp
@@ -0,0 +1,268 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+#include "ArmaturePopulate.h"
+
+#include <assimp/BaseImporter.h>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <iostream>
+
+namespace Assimp {
+
+/// The default class constructor.
+ArmaturePopulate::ArmaturePopulate() : BaseProcess()
+{}
+
+/// The class destructor.
+ArmaturePopulate::~ArmaturePopulate()
+{}
+
+bool ArmaturePopulate::IsActive(unsigned int pFlags) const {
+ return (pFlags & aiProcess_PopulateArmatureData) != 0;
+}
+
+void ArmaturePopulate::SetupProperties(const Importer *pImp) {
+ // do nothing
+}
+
+void ArmaturePopulate::Execute(aiScene *out) {
+
+ // Now convert all bone positions to the correct mOffsetMatrix
+ std::vector<aiBone *> bones;
+ std::vector<aiNode *> nodes;
+ std::map<aiBone *, aiNode *> bone_stack;
+ BuildBoneList(out->mRootNode, out->mRootNode, out, bones);
+ BuildNodeList(out->mRootNode, nodes);
+
+ BuildBoneStack(out->mRootNode, out->mRootNode, out, bones, bone_stack, nodes);
+
+ ASSIMP_LOG_DEBUG_F("Bone stack size: ", bone_stack.size());
+
+ for (std::pair<aiBone *, aiNode *> kvp : bone_stack) {
+ aiBone *bone = kvp.first;
+ aiNode *bone_node = kvp.second;
+ ASSIMP_LOG_DEBUG_F("active node lookup: ", bone->mName.C_Str());
+ // lcl transform grab - done in generate_nodes :)
+
+ // bone->mOffsetMatrix = bone_node->mTransformation;
+ aiNode *armature = GetArmatureRoot(bone_node, bones);
+
+ ai_assert(armature);
+
+ // set up bone armature id
+ bone->mArmature = armature;
+
+ // set this bone node to be referenced properly
+ ai_assert(bone_node);
+ bone->mNode = bone_node;
+ }
+}
+
+
+/* Reprocess all nodes to calculate bone transforms properly based on the REAL
+ * mOffsetMatrix not the local. */
+/* Before this would use mesh transforms which is wrong for bone transforms */
+/* Before this would work for simple character skeletons but not complex meshes
+ * with multiple origins */
+/* Source: sketch fab log cutter fbx */
+void ArmaturePopulate::BuildBoneList(aiNode *current_node,
+ const aiNode *root_node,
+ const aiScene *scene,
+ std::vector<aiBone *> &bones) {
+ ai_assert(scene);
+ for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) {
+ aiNode *child = current_node->mChildren[nodeId];
+ ai_assert(child);
+
+ // check for bones
+ for (unsigned int meshId = 0; meshId < child->mNumMeshes; ++meshId) {
+ ai_assert(child->mMeshes);
+ unsigned int mesh_index = child->mMeshes[meshId];
+ aiMesh *mesh = scene->mMeshes[mesh_index];
+ ai_assert(mesh);
+
+ for (unsigned int boneId = 0; boneId < mesh->mNumBones; ++boneId) {
+ aiBone *bone = mesh->mBones[boneId];
+ ai_assert(bone);
+
+ // duplicate meshes exist with the same bones sometimes :)
+ // so this must be detected
+ if (std::find(bones.begin(), bones.end(), bone) == bones.end()) {
+ // add the element once
+ bones.push_back(bone);
+ }
+ }
+
+ // find mesh and get bones
+ // then do recursive lookup for bones in root node hierarchy
+ }
+
+ BuildBoneList(child, root_node, scene, bones);
+ }
+}
+
+/* Prepare flat node list which can be used for non recursive lookups later */
+void ArmaturePopulate::BuildNodeList(const aiNode *current_node,
+ std::vector<aiNode *> &nodes) {
+ ai_assert(current_node);
+
+ for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) {
+ aiNode *child = current_node->mChildren[nodeId];
+ ai_assert(child);
+
+ nodes.push_back(child);
+
+ BuildNodeList(child, nodes);
+ }
+}
+
+/* A bone stack allows us to have multiple armatures, with the same bone names
+ * A bone stack allows us also to retrieve bones true transform even with
+ * duplicate names :)
+ */
+void ArmaturePopulate::BuildBoneStack(aiNode *current_node,
+ const aiNode *root_node,
+ const aiScene *scene,
+ const std::vector<aiBone *> &bones,
+ std::map<aiBone *, aiNode *> &bone_stack,
+ std::vector<aiNode *> &node_stack) {
+ ai_assert(scene);
+ ai_assert(root_node);
+ ai_assert(!node_stack.empty());
+
+ for (aiBone *bone : bones) {
+ ai_assert(bone);
+ aiNode *node = GetNodeFromStack(bone->mName, node_stack);
+ if (node == nullptr) {
+ node_stack.clear();
+ BuildNodeList(root_node, node_stack);
+ ASSIMP_LOG_DEBUG_F("Resetting bone stack: nullptr element ", bone->mName.C_Str());
+
+ node = GetNodeFromStack(bone->mName, node_stack);
+
+ if (!node) {
+ ASSIMP_LOG_ERROR("serious import issue node for bone was not detected");
+ continue;
+ }
+ }
+
+ ASSIMP_LOG_DEBUG_F("Successfully added bone[", bone->mName.C_Str(), "] to stack and bone node is: ", node->mName.C_Str());
+
+ bone_stack.insert(std::pair<aiBone *, aiNode *>(bone, node));
+ }
+}
+
+
+/* Returns the armature root node */
+/* This is required to be detected for a bone initially, it will recurse up
+ * until it cannot find another bone and return the node No known failure
+ * points. (yet)
+ */
+aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node,
+ std::vector<aiBone *> &bone_list) {
+ while (bone_node) {
+ if (!IsBoneNode(bone_node->mName, bone_list)) {
+ ASSIMP_LOG_DEBUG_F("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str());
+ return bone_node;
+ }
+
+ bone_node = bone_node->mParent;
+ }
+
+ ASSIMP_LOG_ERROR("GetArmatureRoot() can't find armature!");
+
+ return nullptr;
+}
+
+
+
+/* Simple IsBoneNode check if this could be a bone */
+bool ArmaturePopulate::IsBoneNode(const aiString &bone_name,
+ std::vector<aiBone *> &bones) {
+ for (aiBone *bone : bones) {
+ if (bone->mName == bone_name) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Pop this node by name from the stack if found */
+/* Used in multiple armature situations with duplicate node / bone names */
+/* Known flaw: cannot have nodes with bone names, will be fixed in later release
+ */
+/* (serious to be fixed) Known flaw: nodes which have more than one bone could
+ * be prematurely dropped from stack */
+aiNode *ArmaturePopulate::GetNodeFromStack(const aiString &node_name,
+ std::vector<aiNode *> &nodes) {
+ std::vector<aiNode *>::iterator iter;
+ aiNode *found = nullptr;
+ for (iter = nodes.begin(); iter < nodes.end(); ++iter) {
+ aiNode *element = *iter;
+ ai_assert(element);
+ // node valid and node name matches
+ if (element->mName == node_name) {
+ found = element;
+ break;
+ }
+ }
+
+ if (found != nullptr) {
+ ASSIMP_LOG_INFO_F("Removed node from stack: ", found->mName.C_Str());
+ // now pop the element from the node list
+ nodes.erase(iter);
+
+ return found;
+ }
+
+ // unique names can cause this problem
+ ASSIMP_LOG_ERROR("[Serious] GetNodeFromStack() can't find node from stack!");
+
+ return nullptr;
+}
+
+
+
+
+} // Namespace Assimp
diff --git a/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h
new file mode 100644
index 0000000000..aa1ad7c80c
--- /dev/null
+++ b/thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h
@@ -0,0 +1,112 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+#ifndef ARMATURE_POPULATE_H_
+#define ARMATURE_POPULATE_H_
+
+#include "Common/BaseProcess.h"
+#include <assimp/BaseImporter.h>
+#include <vector>
+#include <map>
+
+
+struct aiNode;
+struct aiBone;
+
+namespace Assimp {
+
+// ---------------------------------------------------------------------------
+/** Armature Populate: This is a post process designed
+ * To save you time when importing models into your game engines
+ * This was originally designed only for fbx but will work with other formats
+ * it is intended to auto populate aiBone data with armature and the aiNode
+ * This is very useful when dealing with skinned meshes
+ * or when dealing with many different skeletons
+ * It's off by default but recommend that you try it and use it
+ * It should reduce down any glue code you have in your
+ * importers
+ * You can contact RevoluPowered <gordon@gordonite.tech>
+ * For more info about this
+*/
+class ASSIMP_API ArmaturePopulate : public BaseProcess {
+public:
+ /// The default class constructor.
+ ArmaturePopulate();
+
+ /// The class destructor.
+ virtual ~ArmaturePopulate();
+
+ /// Overwritten, @see BaseProcess
+ virtual bool IsActive( unsigned int pFlags ) const;
+
+ /// Overwritten, @see BaseProcess
+ virtual void SetupProperties( const Importer* pImp );
+
+ /// Overwritten, @see BaseProcess
+ virtual void Execute( aiScene* pScene );
+
+ static aiNode *GetArmatureRoot(aiNode *bone_node,
+ std::vector<aiBone *> &bone_list);
+
+ static bool IsBoneNode(const aiString &bone_name,
+ std::vector<aiBone *> &bones);
+
+ static aiNode *GetNodeFromStack(const aiString &node_name,
+ std::vector<aiNode *> &nodes);
+
+ static void BuildNodeList(const aiNode *current_node,
+ std::vector<aiNode *> &nodes);
+
+ static void BuildBoneList(aiNode *current_node, const aiNode *root_node,
+ const aiScene *scene,
+ std::vector<aiBone *> &bones);
+
+ static void BuildBoneStack(aiNode *current_node, const aiNode *root_node,
+ const aiScene *scene,
+ const std::vector<aiBone *> &bones,
+ std::map<aiBone *, aiNode *> &bone_stack,
+ std::vector<aiNode *> &node_stack);
+};
+
+} // Namespace Assimp
+
+
+#endif // SCALE_PROCESS_H_ \ No newline at end of file
diff --git a/thirdparty/assimp/code/CalcTangentsProcess.cpp b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp
index b30f39c274..a3f7dd2557 100644
--- a/thirdparty/assimp/code/CalcTangentsProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/CalcTangentsProcess.cpp
@@ -212,7 +212,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// project tangent and bitangent into the plane formed by the vertex' normal
aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
- localTangent.Normalize(); localBitangent.Normalize();
+ localTangent.NormalizeSafe(); localBitangent.NormalizeSafe();
// reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN.
bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z);
@@ -220,10 +220,10 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
if (invalid_tangent != invalid_bitangent) {
if (invalid_tangent) {
localTangent = meshNorm[p] ^ localBitangent;
- localTangent.Normalize();
+ localTangent.NormalizeSafe();
} else {
localBitangent = localTangent ^ meshNorm[p];
- localBitangent.Normalize();
+ localBitangent.NormalizeSafe();
}
}
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..df4d44337d 100644
--- a/thirdparty/assimp/code/ComputeUVMappingProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp
@@ -354,12 +354,12 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
}
else if (axis * base_axis_z >= angle_epsilon) {
FindMeshCenter(mesh, center, min, max);
- diffu = max.y - min.y;
- diffv = max.z - min.z;
+ diffu = max.x - min.x;
+ diffv = max.y - min.y;
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
const aiVector3D& pos = mesh->mVertices[pnt];
- out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.0);
+ out[pnt].Set((pos.x - min.x) / diffu,(pos.y - min.y) / diffv,0.0);
}
}
// slower code path in case the mapping axis is not one of the coordinate system axes
diff --git a/thirdparty/assimp/code/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..016884c6e7 100644
--- a/thirdparty/assimp/code/FindInvalidDataProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp
@@ -52,7 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FindInvalidDataProcess.h"
#include "ProcessHelper.h"
-#include <assimp/Macros.h>
#include <assimp/Exceptional.h>
#include <assimp/qnan.h>
diff --git a/thirdparty/assimp/code/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/include/assimp/Macros.h b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h
index 6515303372..4b43c82a42 100644
--- a/thirdparty/assimp/include/assimp/Macros.h
+++ b/thirdparty/assimp/code/PostProcessing/GenBoundingBoxesProcess.h
@@ -39,11 +39,38 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
-/* Helper macro to set a pointer to NULL in debug builds
+/** @file Defines a post-processing step to generate Axis-aligned bounding
+ * volumes for all meshes.
*/
-#if (defined ASSIMP_BUILD_DEBUG)
-# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
-#else
-# define AI_DEBUG_INVALIDATE_PTR(x)
-#endif
+#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..f121fc60d3 100644
--- a/thirdparty/assimp/code/JoinVerticesProcess.cpp
+++ b/thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp
@@ -431,31 +431,6 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
bone->mWeights = new aiVertexWeight[bone->mNumWeights];
memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight));
}
- else {
-
- /* NOTE:
- *
- * In the algorithm above we're assuming that there are no vertices
- * with a different bone weight setup at the same position. That wouldn't
- * make sense, but it is not absolutely impossible. SkeletonMeshBuilder
- * for example generates such input data if two skeleton points
- * share the same position. Again this doesn't make sense but is
- * reality for some model formats (MD5 for example uses these special
- * nodes as attachment tags for its weapons).
- *
- * Then it is possible that a bone has no weights anymore .... as a quick
- * workaround, we're just removing these bones. If they're animated,
- * model geometry might be modified but at least there's no risk of a crash.
- */
- delete bone;
- --pMesh->mNumBones;
- for (unsigned int n = a; n < pMesh->mNumBones; ++n) {
- pMesh->mBones[n] = pMesh->mBones[n+1];
- }
-
- --a;
- ASSIMP_LOG_WARN("Removing bone -> no weights remaining");
- }
}
return pMesh->mNumVertices;
}
diff --git a/thirdparty/assimp/code/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..41f50a5ba5 100644
--- a/thirdparty/assimp/code/MakeVerboseFormat.cpp
+++ b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp
@@ -224,3 +224,32 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
}
return (pcMesh->mNumVertices != iOldNumVertices);
}
+
+
+// ------------------------------------------------------------------------------------------------
+bool IsMeshInVerboseFormat(const aiMesh* mesh) {
+ // avoid slow vector<bool> specialization
+ std::vector<unsigned int> seen(mesh->mNumVertices,0);
+ for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
+ const aiFace& f = mesh->mFaces[i];
+ for(unsigned int j = 0; j < f.mNumIndices; ++j) {
+ if(++seen[f.mIndices[j]] == 2) {
+ // found a duplicate index
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+// ------------------------------------------------------------------------------------------------
+bool MakeVerboseFormatProcess::IsVerboseFormat(const aiScene* pScene) {
+ for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
+ if(!IsMeshInVerboseFormat(pScene->mMeshes[i])) {
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/thirdparty/assimp/code/MakeVerboseFormat.h b/thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h
index d12db63ae1..8565d5933a 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 {
@@ -93,6 +94,13 @@ public:
* @param pScene The imported data to work at. */
void Execute( aiScene* pScene);
+public:
+
+ // -------------------------------------------------------------------
+ /** Checks whether the scene is already in verbose format.
+ * @param pScene The data to check.
+ * @return true if the scene is already in verbose format. */
+ static bool IsVerboseFormat(const aiScene* pScene);
private:
diff --git a/thirdparty/assimp/code/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/PostProcessing/ScaleProcess.cpp b/thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp
new file mode 100644
index 0000000000..ac770c41f2
--- /dev/null
+++ b/thirdparty/assimp/code/PostProcessing/ScaleProcess.cpp
@@ -0,0 +1,208 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+#include "ScaleProcess.h"
+
+#include <assimp/scene.h>
+#include <assimp/postprocess.h>
+#include <assimp/BaseImporter.h>
+
+namespace Assimp {
+
+ScaleProcess::ScaleProcess()
+: BaseProcess()
+, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
+}
+
+ScaleProcess::~ScaleProcess() {
+ // empty
+}
+
+void ScaleProcess::setScale( ai_real scale ) {
+ mScale = scale;
+}
+
+ai_real ScaleProcess::getScale() const {
+ return mScale;
+}
+
+bool ScaleProcess::IsActive( unsigned int pFlags ) const {
+ return ( pFlags & aiProcess_GlobalScale ) != 0;
+}
+
+void ScaleProcess::SetupProperties( const Importer* pImp ) {
+ // User scaling
+ mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 1.0f );
+
+ // File scaling * Application Scaling
+ float importerScale = pImp->GetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, 1.0f );
+
+ // apply scale to the scale
+ // helps prevent bugs with backward compatibility for anyone using normal scaling.
+ mScale *= importerScale;
+}
+
+void ScaleProcess::Execute( aiScene* pScene ) {
+ if(mScale == 1.0f) {
+ return; // nothing to scale
+ }
+
+ ai_assert( mScale != 0 );
+ ai_assert( nullptr != pScene );
+ ai_assert( nullptr != pScene->mRootNode );
+
+ if ( nullptr == pScene ) {
+ return;
+ }
+
+ if ( nullptr == pScene->mRootNode ) {
+ return;
+ }
+
+ // Process animations and update position transform to new unit system
+ for( unsigned int animationID = 0; animationID < pScene->mNumAnimations; animationID++ )
+ {
+ aiAnimation* animation = pScene->mAnimations[animationID];
+
+ for( unsigned int animationChannel = 0; animationChannel < animation->mNumChannels; animationChannel++)
+ {
+ aiNodeAnim* anim = animation->mChannels[animationChannel];
+
+ for( unsigned int posKey = 0; posKey < anim->mNumPositionKeys; posKey++)
+ {
+ aiVectorKey& vectorKey = anim->mPositionKeys[posKey];
+ vectorKey.mValue *= mScale;
+ }
+ }
+ }
+
+ for( unsigned int meshID = 0; meshID < pScene->mNumMeshes; meshID++)
+ {
+ aiMesh *mesh = pScene->mMeshes[meshID];
+
+ // Reconstruct mesh vertexes to the new unit system
+ for( unsigned int vertexID = 0; vertexID < mesh->mNumVertices; vertexID++)
+ {
+ aiVector3D& vertex = mesh->mVertices[vertexID];
+ vertex *= mScale;
+ }
+
+
+ // bone placement / scaling
+ for( unsigned int boneID = 0; boneID < mesh->mNumBones; boneID++)
+ {
+ // Reconstruct matrix by transform rather than by scale
+ // This prevent scale values being changed which can
+ // be meaningful in some cases
+ // like when you want the modeller to see 1:1 compatibility.
+ aiBone* bone = mesh->mBones[boneID];
+
+ aiVector3D pos, scale;
+ aiQuaternion rotation;
+
+ bone->mOffsetMatrix.Decompose( scale, rotation, pos);
+
+ aiMatrix4x4 translation;
+ aiMatrix4x4::Translation( pos * mScale, translation );
+
+ aiMatrix4x4 scaling;
+ aiMatrix4x4::Scaling( aiVector3D(scale), scaling );
+
+ aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix());
+
+ bone->mOffsetMatrix = translation * RotMatrix * scaling;
+ }
+
+
+ // animation mesh processing
+ // convert by position rather than scale.
+ for( unsigned int animMeshID = 0; animMeshID < mesh->mNumAnimMeshes; animMeshID++)
+ {
+ aiAnimMesh * animMesh = mesh->mAnimMeshes[animMeshID];
+
+ for( unsigned int vertexID = 0; vertexID < animMesh->mNumVertices; vertexID++)
+ {
+ aiVector3D& vertex = animMesh->mVertices[vertexID];
+ vertex *= mScale;
+ }
+ }
+ }
+
+ traverseNodes( pScene->mRootNode );
+}
+
+void ScaleProcess::traverseNodes( aiNode *node, unsigned int nested_node_id ) {
+ applyScaling( node );
+
+ for( size_t i = 0; i < node->mNumChildren; i++)
+ {
+ // recurse into the tree until we are done!
+ traverseNodes( node->mChildren[i], nested_node_id+1 );
+ }
+}
+
+void ScaleProcess::applyScaling( aiNode *currentNode ) {
+ if ( nullptr != currentNode ) {
+ // Reconstruct matrix by transform rather than by scale
+ // This prevent scale values being changed which can
+ // be meaningful in some cases
+ // like when you want the modeller to
+ // see 1:1 compatibility.
+
+ aiVector3D pos, scale;
+ aiQuaternion rotation;
+ currentNode->mTransformation.Decompose( scale, rotation, pos);
+
+ aiMatrix4x4 translation;
+ aiMatrix4x4::Translation( pos * mScale, translation );
+
+ aiMatrix4x4 scaling;
+
+ // note: we do not use mScale here, this is on purpose.
+ aiMatrix4x4::Scaling( scale, scaling );
+
+ aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix());
+
+ currentNode->mTransformation = translation * RotMatrix * scaling;
+ }
+}
+
+} // Namespace Assimp
diff --git a/thirdparty/assimp/code/ScaleProcess.h b/thirdparty/assimp/code/PostProcessing/ScaleProcess.h
index 55146ae064..468a216736 100644
--- a/thirdparty/assimp/code/ScaleProcess.h
+++ b/thirdparty/assimp/code/PostProcessing/ScaleProcess.h
@@ -39,9 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
-#pragma once
+#ifndef SCALE_PROCESS_H_
+#define SCALE_PROCESS_H_
-#include "BaseProcess.h"
+#include "Common/BaseProcess.h"
struct aiNode;
@@ -53,6 +54,11 @@ namespace Assimp {
// ---------------------------------------------------------------------------
/** ScaleProcess: Class to rescale the whole model.
+ * Now rescales animations, bones, and blend shapes properly.
+ * Please note this will not write to 'scale' transform it will rewrite mesh
+ * and matrixes so that your scale values
+ * from your model package are preserved, so this is completely intentional
+ * bugs should be reported as soon as they are found.
*/
class ASSIMP_API ScaleProcess : public BaseProcess {
public:
@@ -78,7 +84,7 @@ public:
virtual void Execute( aiScene* pScene );
private:
- void traverseNodes( aiNode *currentNode );
+ void traverseNodes( aiNode *currentNode, unsigned int nested_node_id = 0 );
void applyScaling( aiNode *currentNode );
private:
@@ -86,3 +92,6 @@ private:
};
} // Namespace Assimp
+
+
+#endif // SCALE_PROCESS_H_ \ No newline at end of file
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..75d1b6ef78 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
@@ -543,13 +538,17 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
{
Validate(&pAnimation->mName);
- // validate all materials
- if (pAnimation->mNumChannels)
+ // validate all animations
+ if (pAnimation->mNumChannels || pAnimation->mNumMorphMeshChannels)
{
- if (!pAnimation->mChannels) {
+ if (!pAnimation->mChannels && pAnimation->mNumChannels) {
ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)",
pAnimation->mNumChannels);
}
+ if (!pAnimation->mMorphMeshChannels && pAnimation->mNumMorphMeshChannels) {
+ ReportError("aiAnimation::mMorphMeshChannels is NULL (aiAnimation::mNumMorphMeshChannels is %i)",
+ pAnimation->mNumMorphMeshChannels);
+ }
for (unsigned int i = 0; i < pAnimation->mNumChannels;++i)
{
if (!pAnimation->mChannels[i])
@@ -559,13 +558,19 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
}
Validate(pAnimation, pAnimation->mChannels[i]);
}
+ for (unsigned int i = 0; i < pAnimation->mNumMorphMeshChannels;++i)
+ {
+ if (!pAnimation->mMorphMeshChannels[i])
+ {
+ ReportError("aiAnimation::mMorphMeshChannels[%i] is NULL (aiAnimation::mNumMorphMeshChannels is %i)",
+ i, pAnimation->mNumMorphMeshChannels);
+ }
+ Validate(pAnimation, pAnimation->mMorphMeshChannels[i]);
+ }
}
else {
ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
}
-
- // 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 +751,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)) {
@@ -910,6 +916,48 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
}
}
+void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
+ const aiMeshMorphAnim* pMeshMorphAnim)
+{
+ Validate(&pMeshMorphAnim->mName);
+
+ if (!pMeshMorphAnim->mNumKeys) {
+ ReportError("Empty mesh morph animation channel");
+ }
+
+ // otherwise check whether one of the keys exceeds the total duration of the animation
+ if (pMeshMorphAnim->mNumKeys)
+ {
+ if (!pMeshMorphAnim->mKeys)
+ {
+ ReportError("aiMeshMorphAnim::mKeys is NULL (aiMeshMorphAnim::mNumKeys is %i)",
+ pMeshMorphAnim->mNumKeys);
+ }
+ double dLast = -10e10;
+ for (unsigned int i = 0; i < pMeshMorphAnim->mNumKeys;++i)
+ {
+ // ScenePreprocessor will compute the duration if still the default value
+ // (Aramis) Add small epsilon, comparison tended to fail if max_time == duration,
+ // seems to be due the compilers register usage/width.
+ if (pAnimation->mDuration > 0. && pMeshMorphAnim->mKeys[i].mTime > pAnimation->mDuration+0.001)
+ {
+ ReportError("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is larger "
+ "than aiAnimation::mDuration (which is %.5f)",i,
+ (float)pMeshMorphAnim->mKeys[i].mTime,
+ (float)pAnimation->mDuration);
+ }
+ if (i && pMeshMorphAnim->mKeys[i].mTime <= dLast)
+ {
+ ReportWarning("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is smaller "
+ "than aiMeshMorphAnim::mKeys[%i] (which is %.5f)",i,
+ (float)pMeshMorphAnim->mKeys[i].mTime,
+ i-1, (float)dLast);
+ }
+ dLast = pMeshMorphAnim->mKeys[i].mTime;
+ }
+ }
+}
+
// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiNode* pNode)
{
@@ -965,7 +1013,7 @@ void ValidateDSProcess::Validate( const aiString* pString)
{
if (pString->length > MAXLEN)
{
- ReportError("aiString::length is too large (%lu, maximum is %lu)",
+ ReportError("aiString::length is too large (%u, maximum is %lu)",
pString->length,MAXLEN);
}
const char* sz = pString->data;
diff --git a/thirdparty/assimp/code/ValidateDataStructure.h b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h
index bd21e88545..7b309c9251 100644
--- a/thirdparty/assimp/code/ValidateDataStructure.h
+++ b/thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h
@@ -48,12 +48,14 @@ 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;
struct aiAnimation;
struct aiNodeAnim;
+struct aiMeshMorphAnim;
struct aiTexture;
struct aiMaterial;
struct aiNode;
@@ -149,6 +151,13 @@ protected:
void Validate( const aiAnimation* pAnimation,
const aiNodeAnim* pBoneAnim);
+ /** Validates a mesh morph animation channel.
+ * @param pAnimation Input animation.
+ * @param pMeshMorphAnim Mesh morph animation channel.
+ * */
+ void Validate( const aiAnimation* pAnimation,
+ const aiMeshMorphAnim* pMeshMorphAnim);
+
// -------------------------------------------------------------------
/** Validates a node and all of its subnodes
* @param Node Input node*/
diff --git a/thirdparty/assimp/code/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/code/ScaleProcess.cpp b/thirdparty/assimp/code/ScaleProcess.cpp
deleted file mode 100644
index 6d458c4b11..0000000000
--- a/thirdparty/assimp/code/ScaleProcess.cpp
+++ /dev/null
@@ -1,103 +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.
-
-----------------------------------------------------------------------
-*/
-#ifndef ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS
-
-#include "ScaleProcess.h"
-
-#include <assimp/scene.h>
-#include <assimp/postprocess.h>
-
-namespace Assimp {
-
-ScaleProcess::ScaleProcess()
-: BaseProcess()
-, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
- // empty
-}
-
-ScaleProcess::~ScaleProcess() {
- // empty
-}
-
-void ScaleProcess::setScale( ai_real scale ) {
- mScale = scale;
-}
-
-ai_real ScaleProcess::getScale() const {
- return mScale;
-}
-
-bool ScaleProcess::IsActive( unsigned int pFlags ) const {
- return ( pFlags & aiProcess_GlobalScale ) != 0;
-}
-
-void ScaleProcess::SetupProperties( const Importer* pImp ) {
- mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 0 );
-}
-
-void ScaleProcess::Execute( aiScene* pScene ) {
- if ( nullptr == pScene ) {
- return;
- }
-
- if ( nullptr == pScene->mRootNode ) {
- return;
- }
-
- traverseNodes( pScene->mRootNode );
-}
-
-void ScaleProcess::traverseNodes( aiNode *node ) {
- applyScaling( node );
-}
-
-void ScaleProcess::applyScaling( aiNode *currentNode ) {
- if ( nullptr != currentNode ) {
- currentNode->mTransformation.a1 = currentNode->mTransformation.a1 * mScale;
- currentNode->mTransformation.b2 = currentNode->mTransformation.b2 * mScale;
- currentNode->mTransformation.c3 = currentNode->mTransformation.c3 * mScale;
- }
-}
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS
diff --git a/thirdparty/assimp/code/res/resource.h b/thirdparty/assimp/code/res/resource.h
deleted file mode 100644
index 37d39284fe..0000000000
--- a/thirdparty/assimp/code/res/resource.h
+++ /dev/null
@@ -1,14 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by assimp.rc
-
-// Nächste Standardwerte für neue Objekte
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 101
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1001
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
diff --git a/thirdparty/assimp/code/revision.h b/thirdparty/assimp/code/revision.h
index 88872aef22..66eb875303 100644
--- a/thirdparty/assimp/code/revision.h
+++ b/thirdparty/assimp/code/revision.h
@@ -1,7 +1,28 @@
#ifndef ASSIMP_REVISION_H_INC
#define ASSIMP_REVISION_H_INC
-#define GitVersion 0x00000000
+#define GitVersion 0x308db73d
#define GitBranch "master"
+#define VER_MAJOR 5
+#define VER_MINOR 0
+#define VER_PATCH 0
+#define VER_BUILD 0
+
+#define STR_HELP(x) #x
+#define STR(x) STR_HELP(x)
+
+#define VER_FILEVERSION VER_MAJOR,VER_MINOR,VER_PATCH,VER_BUILD
+#if (GitVersion == 0)
+#define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD)
+#else
+#define VER_FILEVERSION_STR STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) " (Commit 308db73d)"
+#endif
+
+#ifdef NDEBUG
+#define VER_ORIGINAL_FILENAME_STR "assimp.dll"
+#else
+#define VER_ORIGINAL_FILENAME_STR "assimp.dll"
+#endif // NDEBUG
+
#endif // ASSIMP_REVISION_H_INC
diff --git a/thirdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes b/thirdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes
new file mode 100644
index 0000000000..364411a23d
--- /dev/null
+++ b/thirdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes
@@ -0,0 +1,12 @@
+utf8 cpp library
+Release 2.3.4
+
+A minor bug fix release. Thanks to all who reported bugs.
+
+Note: Version 2.3.3 contained a regression, and therefore was removed.
+
+Changes from version 2.3.2
+- Bug fix [39]: checked.h Line 273 and unchecked.h Line 182 have an extra ';'
+- Bug fix [36]: replace_invalid() only works with back_inserter
+
+Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes
diff --git a/thirdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html b/thirdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html
new file mode 100644
index 0000000000..6f2aacbe7b
--- /dev/null
+++ b/thirdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html
@@ -0,0 +1,1789 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 1st November 2002), see www.w3.org">
+ <meta name="description" content=
+ "A simple, portable and lightweigt C++ library for easy handling of UTF-8 encoded strings">
+ <meta name="keywords" content="UTF-8 C++ portable utf8 unicode generic templates">
+ <meta name="author" content="Nemanja Trifunovic">
+ <title>
+ UTF8-CPP: UTF-8 with C++ in a Portable Way
+ </title>
+ <style type="text/css">
+ <!--
+ span.return_value {
+ color: brown;
+ }
+ span.keyword {
+ color: blue;
+ }
+ span.preprocessor {
+ color: navy;
+ }
+ span.literal {
+ color: olive;
+ }
+ span.comment {
+ color: green;
+ }
+ code {
+ font-weight: bold;
+ }
+ ul.toc {
+ list-style-type: none;
+ }
+ p.version {
+ font-size: small;
+ font-style: italic;
+ }
+ -->
+ </style>
+ </head>
+ <body>
+ <h1>
+ UTF8-CPP: UTF-8 with C++ in a Portable Way
+ </h1>
+ <p>
+ <a href="https://sourceforge.net/projects/utfcpp">The Sourceforge project page</a>
+ </p>
+ <div id="toc">
+ <h2>
+ Table of Contents
+ </h2>
+ <ul class="toc">
+ <li>
+ <a href="#introduction">Introduction</a>
+ </li>
+ <li>
+ <a href="#examples">Examples of Use</a>
+ <ul class="toc">
+ <li>
+ <a href=#introsample>Introductionary Sample </a>
+ </li>
+ <li>
+ <a href=#validfile>Checking if a file contains valid UTF-8 text</a>
+ </li>
+ <li>
+ <a href=#fixinvalid>Ensure that a string contains valid UTF-8 text</a>
+ </li>
+ </ul>
+ <li>
+ <a href="#reference">Reference</a>
+ <ul class="toc">
+ <li>
+ <a href="#funutf8">Functions From utf8 Namespace </a>
+ </li>
+ <li>
+ <a href="#typesutf8">Types From utf8 Namespace </a>
+ </li>
+ <li>
+ <a href="#fununchecked">Functions From utf8::unchecked Namespace </a>
+ </li>
+ <li>
+ <a href="#typesunchecked">Types From utf8::unchecked Namespace </a>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <a href="#points">Points of Interest</a>
+ </li>
+ <li>
+ <a href="#links">Links</a>
+ </li>
+ </ul>
+ </div>
+ <h2 id="introduction">
+ Introduction
+ </h2>
+ <p>
+ Many C++ developers miss an easy and portable way of handling Unicode encoded
+ strings. The original C++ Standard (known as C++98 or C++03) is Unicode agnostic.
+ C++11 provides some support for Unicode on core language and library level:
+ u8, u, and U character and string literals, char16_t and char32_t character types,
+ u16string and u32string library classes, and codecvt support for conversions
+ between Unicode encoding forms.
+ In the meantime, developers use third party libraries like ICU, OS specific capabilities, or simply
+ roll out their own solutions.
+ </p>
+ <p>
+ In order to easily handle UTF-8 encoded Unicode strings, I came up with a small
+ generic library. For anybody used to work with STL algorithms and iterators, it should be
+ easy and natural to use. The code is freely available for any purpose - check out
+ the license at the beginning of the utf8.h file. If you run into
+ bugs or performance issues, please let me know and I'll do my best to address them.
+ </p>
+ <p>
+ The purpose of this article is not to offer an introduction to Unicode in general,
+ and UTF-8 in particular. If you are not familiar with Unicode, be sure to check out
+ <a href="http://www.unicode.org/">Unicode Home Page</a> or some other source of
+ information for Unicode. Also, it is not my aim to advocate the use of UTF-8
+ encoded strings in C++ programs; if you want to handle UTF-8 encoded strings from
+ C++, I am sure you have good reasons for it.
+ </p>
+ <h2 id="examples">
+ Examples of use
+ </h2>
+ <h3 id="introsample">
+ Introductionary Sample
+ </h3>
+ <p>
+ To illustrate the use of the library, let's start with a small but complete program
+ that opens a file containing UTF-8 encoded text, reads it line by line, checks each line
+ for invalid UTF-8 byte sequences, and converts it to UTF-16 encoding and back to UTF-8:
+ </p>
+<pre>
+<span class="preprocessor">#include &lt;fstream&gt;</span>
+<span class="preprocessor">#include &lt;iostream&gt;</span>
+<span class="preprocessor">#include &lt;string&gt;</span>
+<span class="preprocessor">#include &lt;vector&gt;</span>
+<span class="preprocessor">#include "utf8.h"</span>
+<span class="keyword">using namespace</span> std;
+<span class="keyword">int</span> main(<span class="keyword">int</span> argc, <span class="keyword">char</span>** argv)
+{
+ <span class="keyword">if</span> (argc != <span class="literal">2</span>) {
+ cout &lt;&lt; <span class="literal">"\nUsage: docsample filename\n"</span>;
+ <span class="keyword">return</span> <span class="literal">0</span>;
+ }
+
+ <span class="keyword">const char</span>* test_file_path = argv[1];
+ <span class="comment">// Open the test file (contains UTF-8 encoded text)</span>
+ ifstream fs8(test_file_path);
+ <span class="keyword">if</span> (!fs8.is_open()) {
+ cout &lt;&lt; <span class=
+"literal">"Could not open "</span> &lt;&lt; test_file_path &lt;&lt; endl;
+ <span class="keyword">return</span> <span class="literal">0</span>;
+ }
+
+ <span class="keyword">unsigned</span> line_count = <span class="literal">1</span>;
+ string line;
+ <span class="comment">// Play with all the lines in the file</span>
+ <span class="keyword">while</span> (getline(fs8, line)) {
+ <span class="comment">// check for invalid utf-8 (for a simple yes/no check, there is also utf8::is_valid function)</span>
+ string::iterator end_it = utf8::find_invalid(line.begin(), line.end());
+ <span class="keyword">if</span> (end_it != line.end()) {
+ cout &lt;&lt; <span class=
+"literal">"Invalid UTF-8 encoding detected at line "</span> &lt;&lt; line_count &lt;&lt; <span
+ class="literal">"\n"</span>;
+ cout &lt;&lt; <span class=
+"literal">"This part is fine: "</span> &lt;&lt; string(line.begin(), end_it) &lt;&lt; <span
+ class="literal">"\n"</span>;
+ }
+
+ <span class="comment">// Get the line length (at least for the valid part)</span>
+ <span class="keyword">int</span> length = utf8::distance(line.begin(), end_it);
+ cout &lt;&lt; <span class=
+"literal">"Length of line "</span> &lt;&lt; line_count &lt;&lt; <span class=
+"literal">" is "</span> &lt;&lt; length &lt;&lt; <span class="literal">"\n"</span>;
+
+ <span class="comment">// Convert it to utf-16</span>
+ vector&lt;unsigned short&gt; utf16line;
+ utf8::utf8to16(line.begin(), end_it, back_inserter(utf16line));
+
+ <span class="comment">// And back to utf-8</span>
+ string utf8line;
+ utf8::utf16to8(utf16line.begin(), utf16line.end(), back_inserter(utf8line));
+
+ <span class="comment">// Confirm that the conversion went OK:</span>
+ <span class="keyword">if</span> (utf8line != string(line.begin(), end_it))
+ cout &lt;&lt; <span class=
+"literal">"Error in UTF-16 conversion at line: "</span> &lt;&lt; line_count &lt;&lt; <span
+ class="literal">"\n"</span>;
+
+ line_count++;
+ }
+ <span class="keyword">return</span> <span class="literal">0</span>;
+}
+</pre>
+ <p>
+ In the previous code sample, for each line we performed
+ a detection of invalid UTF-8 sequences with <code>find_invalid</code>; the number
+ of characters (more precisely - the number of Unicode code points, including the end
+ of line and even BOM if there is one) in each line was
+ determined with a use of <code>utf8::distance</code>; finally, we have converted
+ each line to UTF-16 encoding with <code>utf8to16</code> and back to UTF-8 with
+ <code>utf16to8</code>.
+ </p>
+ <h3 id="validfile">Checking if a file contains valid UTF-8 text</h3>
+<p>
+Here is a function that checks whether the content of a file is valid UTF-8 encoded text without
+reading the content into the memory:
+</p>
+<pre>
+<span class="keyword">bool</span> valid_utf8_file(i<span class="keyword">const char</span>* file_name)
+{
+ ifstream ifs(file_name);
+ <span class="keyword">if</span> (!ifs)
+ <span class="keyword">return false</span>; <span class="comment">// even better, throw here</span>
+
+ istreambuf_iterator&lt;<span class="keyword">char</span>&gt; it(ifs.rdbuf());
+ istreambuf_iterator&lt;<span class="keyword">char</span>&gt; eos;
+
+ <span class="keyword">return</span> utf8::is_valid(it, eos);
+}
+</pre>
+<p>
+Because the function <code>utf8::is_valid()</code> works with input iterators, we were able
+to pass an <code>istreambuf_iterator</code> to it and read the content of the file directly
+without loading it to the memory first.</p>
+<p>
+Note that other functions that take input iterator arguments can be used in a similar way. For
+instance, to read the content of a UTF-8 encoded text file and convert the text to UTF-16, just
+do something like:
+</p>
+<pre>
+ utf8::utf8to16(it, eos, back_inserter(u16string));
+</pre>
+ <h3 id="fixinvalid">Ensure that a string contains valid UTF-8 text</h3>
+<p>
+If we have some text that "probably" contains UTF-8 encoded text and we want to
+replace any invalid UTF-8 sequence with a replacement character, something like
+the following function may be used:
+</p>
+<pre>
+<span class="keyword">void</span> fix_utf8_string(std::string&amp; str)
+{
+ std::string temp;
+ utf8::replace_invalid(str.begin(), str.end(), back_inserter(temp));
+ str = temp;
+}
+</pre>
+<p>The function will replace any invalid UTF-8 sequence with a Unicode replacement character.
+There is an overloaded function that enables the caller to supply their own replacement character.
+</p>
+ <h2 id="reference">
+ Reference
+ </h2>
+ <h3 id="funutf8">
+ Functions From utf8 Namespace
+ </h3>
+ <h4>
+ utf8::append
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence
+ to a UTF-8 string.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+octet_iterator append(uint32_t cp, octet_iterator result);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an output iterator.<br>
+ <code>cp</code>: a 32 bit integer representing a code point to append to the
+ sequence.<br>
+ <code>result</code>: an output iterator to the place in the sequence where to
+ append the code point.<br>
+ <span class="return_value">Return value</span>: an iterator pointing to the place
+ after the newly appended sequence.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned char</span> u[<span class="literal">5</span>] = {<span
+class="literal">0</span>,<span class="literal">0</span>,<span class=
+"literal">0</span>,<span class="literal">0</span>,<span class="literal">0</span>};
+<span class="keyword">unsigned char</span>* end = append(<span class=
+"literal">0x0448</span>, u);
+assert (u[<span class="literal">0</span>] == <span class=
+"literal">0xd1</span> &amp;&amp; u[<span class="literal">1</span>] == <span class=
+"literal">0x88</span> &amp;&amp; u[<span class="literal">2</span>] == <span class=
+"literal">0</span> &amp;&amp; u[<span class="literal">3</span>] == <span class=
+"literal">0</span> &amp;&amp; u[<span class="literal">4</span>] == <span class=
+"literal">0</span>);
+</pre>
+ <p>
+ Note that <code>append</code> does not allocate any memory - it is the burden of
+ the caller to make sure there is enough memory allocated for the operation. To make
+ things more interesting, <code>append</code> can add anywhere between 1 and 4
+ octets to the sequence. In practice, you would most often want to use
+ <code>std::back_inserter</code> to ensure that the necessary memory is allocated.
+ </p>
+ <p>
+ In case of an invalid code point, a <code>utf8::invalid_code_point</code> exception
+ is thrown.
+ </p>
+ <h4>
+ utf8::next
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Given the iterator to the beginning of the UTF-8 sequence, it returns the code
+ point and moves the iterator to the next position.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t next(octet_iterator&amp; it, octet_iterator end);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
+ encoded code point. After the function returns, it is incremented to point to the
+ beginning of the next code point.<br>
+ <code>end</code>: end of the UTF-8 sequence to be processed. If <code>it</code>
+ gets equal to <code>end</code> during the extraction of a code point, an
+ <code>utf8::not_enough_room</code> exception is thrown.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ processed UTF-8 code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars;
+<span class="keyword">int</span> cp = next(w, twochars + <span class="literal">6</span>);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars + <span class="literal">3</span>);
+</pre>
+ <p>
+ This function is typically used to iterate through a UTF-8 encoded string.
+ </p>
+ <p>
+ In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
+ thrown.
+ </p>
+ <h4>
+ utf8::peek_next
+ </h4>
+ <p class="version">
+ Available in version 2.1 and later.
+ </p>
+ <p>
+ Given the iterator to the beginning of the UTF-8 sequence, it returns the code
+ point for the following sequence without changing the value of the iterator.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t peek_next(octet_iterator it, octet_iterator end);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>it</code>: an iterator pointing to the beginning of an UTF-8
+ encoded code point.<br>
+ <code>end</code>: end of the UTF-8 sequence to be processed. If <code>it</code>
+ gets equal to <code>end</code> during the extraction of a code point, an
+ <code>utf8::not_enough_room</code> exception is thrown.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ processed UTF-8 code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars;
+<span class="keyword">int</span> cp = peek_next(w, twochars + <span class="literal">6</span>);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
+ thrown.
+ </p>
+ <h4>
+ utf8::prior
+ </h4>
+ <p class="version">
+ Available in version 1.02 and later.
+ </p>
+ <p>
+ Given a reference to an iterator pointing to an octet in a UTF-8 sequence, it
+ decreases the iterator until it hits the beginning of the previous UTF-8 encoded
+ code point and returns the 32 bits representation of the code point.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t prior(octet_iterator&amp; it, octet_iterator start);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: a bidirectional iterator.<br>
+ <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
+ After the function returns, it is decremented to point to the beginning of the
+ previous code point.<br>
+ <code>start</code>: an iterator to the beginning of the sequence where the search
+ for the beginning of a code point is performed. It is a
+ safety measure to prevent passing the beginning of the string in the search for a
+ UTF-8 lead octet.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ previous code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">unsigned char</span>* w = twochars + <span class=
+"literal">3</span>;
+<span class="keyword">int</span> cp = prior (w, twochars);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ This function has two purposes: one is two iterate backwards through a UTF-8
+ encoded string. Note that it is usually a better idea to iterate forward instead,
+ since <code>utf8::next</code> is faster. The second purpose is to find a beginning
+ of a UTF-8 sequence if we have a random position within a string. Note that in that
+ case <code>utf8::prior</code> may not detect an invalid UTF-8 sequence in some scenarios:
+ for instance if there are superfluous trail octets, it will just skip them.
+ </p>
+ <p>
+ <code>it</code> will typically point to the beginning of
+ a code point, and <code>start</code> will point to the
+ beginning of the string to ensure we don't go backwards too far. <code>it</code> is
+ decreased until it points to a lead UTF-8 octet, and then the UTF-8 sequence
+ beginning with that octet is decoded to a 32 bit representation and returned.
+ </p>
+ <p>
+ In case <code>start</code> is reached before a UTF-8 lead octet is hit, or if an
+ invalid UTF-8 sequence is started by the lead octet, an <code>invalid_utf8</code>
+ exception is thrown.
+ </p>
+ <p>In case <code>start</code> equals <code>it</code>, a <code>not_enough_room</code>
+ exception is thrown.
+ <h4>
+ utf8::previous
+ </h4>
+ <p class="version">
+ Deprecated in version 1.02 and later.
+ </p>
+ <p>
+ Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it
+ decreases the iterator until it hits the beginning of the previous UTF-8 encoded
+ code point and returns the 32 bits representation of the code point.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t previous(octet_iterator&amp; it, octet_iterator pass_start);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: a random access iterator.<br>
+ <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
+ After the function returns, it is decremented to point to the beginning of the
+ previous code point.<br>
+ <code>pass_start</code>: an iterator to the point in the sequence where the search
+ for the beginning of a code point is aborted if no result was reached. It is a
+ safety measure to prevent passing the beginning of the string in the search for a
+ UTF-8 lead octet.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ previous code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">unsigned char</span>* w = twochars + <span class=
+"literal">3</span>;
+<span class="keyword">int</span> cp = previous (w, twochars - <span class=
+"literal">1</span>);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ <code>utf8::previous</code> is deprecated, and <code>utf8::prior</code> should
+ be used instead, although the existing code can continue using this function.
+ The problem is the parameter <code>pass_start</code> that points to the position
+ just before the beginning of the sequence. Standard containers don't have the
+ concept of "pass start" and the function can not be used with their iterators.
+ </p>
+ <p>
+ <code>it</code> will typically point to the beginning of
+ a code point, and <code>pass_start</code> will point to the octet just before the
+ beginning of the string to ensure we don't go backwards too far. <code>it</code> is
+ decreased until it points to a lead UTF-8 octet, and then the UTF-8 sequence
+ beginning with that octet is decoded to a 32 bit representation and returned.
+ </p>
+ <p>
+ In case <code>pass_start</code> is reached before a UTF-8 lead octet is hit, or if an
+ invalid UTF-8 sequence is started by the lead octet, an <code>invalid_utf8</code>
+ exception is thrown
+ </p>
+ <h4>
+ utf8::advance
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Advances an iterator by the specified number of code points within an UTF-8
+ sequence.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, typename distance_type&gt;
+<span class=
+"keyword">void</span> advance (octet_iterator&amp; it, distance_type n, octet_iterator end);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>distance_type</code>: an integral type convertible to <code>octet_iterator</code>'s difference type.<br>
+ <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
+ encoded code point. After the function returns, it is incremented to point to the
+ nth following code point.<br>
+ <code>n</code>: a positive integer that shows how many code points we want to
+ advance.<br>
+ <code>end</code>: end of the UTF-8 sequence to be processed. If <code>it</code>
+ gets equal to <code>end</code> during the extraction of a code point, an
+ <code>utf8::not_enough_room</code> exception is thrown.<br>
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">unsigned char</span>* w = twochars;
+advance (w, <span class="literal">2</span>, twochars + <span class="literal">6</span>);
+assert (w == twochars + <span class="literal">5</span>);
+</pre>
+ <p>
+ This function works only "forward". In case of a negative <code>n</code>, there is
+ no effect.
+ </p>
+ <p>
+ In case of an invalid code point, a <code>utf8::invalid_code_point</code> exception
+ is thrown.
+ </p>
+ <h4>
+ utf8::distance
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Given the iterators to two UTF-8 encoded code points in a seqence, returns the
+ number of code points between them.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+<span class=
+"keyword">typename</span> std::iterator_traits&lt;octet_iterator&gt;::difference_type distance (octet_iterator first, octet_iterator last);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>first</code>: an iterator to a beginning of a UTF-8 encoded code point.<br>
+ <code>last</code>: an iterator to a "post-end" of the last UTF-8 encoded code
+ point in the sequence we are trying to determine the length. It can be the
+ beginning of a new code point, or not.<br>
+ <span class="return_value">Return value</span> the distance between the iterators,
+ in code points.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+size_t dist = utf8::distance(twochars, twochars + <span class="literal">5</span>);
+assert (dist == <span class="literal">2</span>);
+</pre>
+ <p>
+ This function is used to find the length (in code points) of a UTF-8 encoded
+ string. The reason it is called <em>distance</em>, rather than, say,
+ <em>length</em> is mainly because developers are used that <em>length</em> is an
+ O(1) function. Computing the length of an UTF-8 string is a linear operation, and
+ it looked better to model it after <code>std::distance</code> algorithm.
+ </p>
+ <p>
+ In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
+ thrown. If <code>last</code> does not point to the past-of-end of a UTF-8 seqence,
+ a <code>utf8::not_enough_room</code> exception is thrown.
+ </p>
+ <h4>
+ utf8::utf16to8
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-16 encoded string to UTF-8.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> u16bit_iterator, <span class=
+"keyword">typename</span> octet_iterator&gt;
+octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result);
+
+</pre>
+ <p>
+ <code>u16bit_iterator</code>: an input iterator.<br>
+ <code>octet_iterator</code>: an output iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-16 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-16 encoded
+ string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-8 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-8 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned short</span> utf16string[] = {<span class=
+"literal">0x41</span>, <span class="literal">0x0448</span>, <span class=
+"literal">0x65e5</span>, <span class="literal">0xd834</span>, <span class=
+"literal">0xdd1e</span>};
+vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
+utf16to8(utf16string, utf16string + <span class=
+"literal">5</span>, back_inserter(utf8result));
+assert (utf8result.size() == <span class="literal">10</span>);
+</pre>
+ <p>
+ In case of invalid UTF-16 sequence, a <code>utf8::invalid_utf16</code> exception is
+ thrown.
+ </p>
+ <h4>
+ utf8::utf8to16
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts an UTF-8 encoded string to UTF-16
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> u16bit_iterator, typename octet_iterator&gt;
+u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>u16bit_iterator</code>: an output iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
+ string to convert. &lt; br /&gt; <code>end</code>: an iterator pointing to
+ pass-the-end of the UTF-8 encoded string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-16 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-16 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span> utf8_with_surrogates[] = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"</span>;
+vector &lt;<span class="keyword">unsigned short</span>&gt; utf16result;
+utf8to16(utf8_with_surrogates, utf8_with_surrogates + <span class=
+"literal">9</span>, back_inserter(utf16result));
+assert (utf16result.size() == <span class="literal">4</span>);
+assert (utf16result[<span class="literal">2</span>] == <span class=
+"literal">0xd834</span>);
+assert (utf16result[<span class="literal">3</span>] == <span class=
+"literal">0xdd1e</span>);
+</pre>
+ <p>
+ In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
+ thrown. If <code>end</code> does not point to the past-of-end of a UTF-8 seqence, a
+ <code>utf8::not_enough_room</code> exception is thrown.
+ </p>
+ <h4>
+ utf8::utf32to8
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-32 encoded string to UTF-8.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, typename u32bit_iterator&gt;
+octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an output iterator.<br>
+ <code>u32bit_iterator</code>: an input iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-32 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-32 encoded
+ string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-8 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-8 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">int</span> utf32string[] = {<span class=
+"literal">0x448</span>, <span class="literal">0x65E5</span>, <span class=
+"literal">0x10346</span>, <span class="literal">0</span>};
+vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
+utf32to8(utf32string, utf32string + <span class=
+"literal">3</span>, back_inserter(utf8result));
+assert (utf8result.size() == <span class="literal">9</span>);
+</pre>
+ <p>
+ In case of invalid UTF-32 string, a <code>utf8::invalid_code_point</code> exception
+ is thrown.
+ </p>
+ <h4>
+ utf8::utf8to32
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-8 encoded string to UTF-32.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, <span class=
+"keyword">typename</span> u32bit_iterator&gt;
+u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>u32bit_iterator</code>: an output iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 encoded string
+ to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-32 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-32 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+vector&lt;<span class="keyword">int</span>&gt; utf32result;
+utf8to32(twochars, twochars + <span class=
+"literal">5</span>, back_inserter(utf32result));
+assert (utf32result.size() == <span class="literal">2</span>);
+</pre>
+ <p>
+ In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
+ thrown. If <code>end</code> does not point to the past-of-end of a UTF-8 seqence, a
+ <code>utf8::not_enough_room</code> exception is thrown.
+ </p>
+ <h4>
+ utf8::find_invalid
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Detects an invalid sequence within a UTF-8 string.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+octet_iterator find_invalid(octet_iterator start, octet_iterator end);
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 string to
+ test for validity.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 string to test
+ for validity.<br>
+ <span class="return_value">Return value</span>: an iterator pointing to the first
+ invalid octet in the UTF-8 string. In case none were found, equals
+ <code>end</code>.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span> utf_invalid[] = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88\xfa"</span>;
+<span class=
+"keyword">char</span>* invalid = find_invalid(utf_invalid, utf_invalid + <span class=
+"literal">6</span>);
+assert (invalid == utf_invalid + <span class="literal">5</span>);
+</pre>
+ <p>
+ This function is typically used to make sure a UTF-8 string is valid before
+ processing it with other functions. It is especially important to call it if before
+ doing any of the <em>unchecked</em> operations on it.
+ </p>
+ <h4>
+ utf8::is_valid
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Checks whether a sequence of octets is a valid UTF-8 string.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+<span class="keyword">bool</span> is_valid(octet_iterator start, octet_iterator end);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 string to
+ test for validity.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 string to test
+ for validity.<br>
+ <span class="return_value">Return value</span>: <code>true</code> if the sequence
+ is a valid UTF-8 string; <code>false</code> if not.
+ </p>
+ Example of use:
+<pre>
+<span class="keyword">char</span> utf_invalid[] = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88\xfa"</span>;
+<span class="keyword">bool</span> bvalid = is_valid(utf_invalid, utf_invalid + <span
+class="literal">6</span>);
+assert (bvalid == false);
+</pre>
+ <p>
+ <code>is_valid</code> is a shorthand for <code>find_invalid(start, end) ==
+ end;</code>. You may want to use it to make sure that a byte seqence is a valid
+ UTF-8 string without the need to know where it fails if it is not valid.
+ </p>
+ <h4>
+ utf8::replace_invalid
+ </h4>
+ <p class="version">
+ Available in version 2.0 and later.
+ </p>
+ <p>
+ Replaces all invalid UTF-8 sequences within a string with a replacement marker.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, <span class=
+"keyword">typename</span> output_iterator&gt;
+output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement);
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, <span class=
+"keyword">typename</span> output_iterator&gt;
+output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out);
+
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>output_iterator</code>: an output iterator.<br>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 string to
+ look for invalid UTF-8 sequences.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 string to look
+ for invalid UTF-8 sequences.<br>
+ <code>out</code>: An output iterator to the range where the result of replacement
+ is stored.<br>
+ <code>replacement</code>: A Unicode code point for the replacement marker. The
+ version without this parameter assumes the value <code>0xfffd</code><br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the UTF-8 string with replaced invalid sequences.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span> invalid_sequence[] = <span class=
+"literal">"a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"</span>;
+vector&lt;<span class="keyword">char</span>&gt; replace_invalid_result;
+replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), back_inserter(replace_invalid_result), <span
+ class="literal">'?'</span>);
+bvalid = is_valid(replace_invalid_result.begin(), replace_invalid_result.end());
+assert (bvalid);
+<span class="keyword">char</span>* fixed_invalid_sequence = <span class=
+"literal">"a????z"</span>;
+assert (std::equal(replace_invalid_result.begin(), replace_invalid_result.end(), fixed_invalid_sequence));
+</pre>
+ <p>
+ <code>replace_invalid</code> does not perform in-place replacement of invalid
+ sequences. Rather, it produces a copy of the original string with the invalid
+ sequences replaced with a replacement marker. Therefore, <code>out</code> must not
+ be in the <code>[start, end]</code> range.
+ </p>
+ <p>
+ If <code>end</code> does not point to the past-of-end of a UTF-8 sequence, a
+ <code>utf8::not_enough_room</code> exception is thrown.
+ </p>
+ <h4>
+ utf8::starts_with_bom
+ </h4>
+ <p class="version">
+ Available in version 2.3 and later. Relaces deprecated <code>is_bom()</code> function.
+ </p>
+ <p>
+ Checks whether an octet sequence starts with a UTF-8 byte order mark (BOM)
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+<span class="keyword">bool</span> starts_with_bom (octet_iterator it, octet_iterator end);
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>it</code>: beginning of the octet sequence to check<br>
+ <code>end</code>: pass-end of the sequence to check<br>
+ <span class="return_value">Return value</span>: <code>true</code> if the sequence
+ starts with a UTF-8 byte order mark; <code>false</code> if not.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned char</span> byte_order_mark[] = {<span class=
+"literal">0xef</span>, <span class="literal">0xbb</span>, <span class=
+"literal">0xbf</span>};
+<span class="keyword">bool</span> bbom = starts_with_bom(byte_order_mark, byte_order_mark + <span class="keyword">sizeof</span>(byte_order_mark));
+assert (bbom == <span class="literal">true</span>);
+</pre>
+ <p>
+ The typical use of this function is to check the first three bytes of a file. If
+ they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8
+ encoded text.
+ </p>
+ <h4>
+ utf8::is_bom
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later. Deprecated in version 2.3. <code>starts_with_bom()</code> should be used
+ instead.
+ </p>
+ <p>
+ Checks whether a sequence of three octets is a UTF-8 byte order mark (BOM)
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+<span class="keyword">bool</span> is_bom (octet_iterator it); <span class="comment"> // Deprecated</span>
+</pre>
+ <p>
+ <code>octet_iterator</code>: an input iterator.<br>
+ <code>it</code>: beginning of the 3-octet sequence to check<br>
+ <span class="return_value">Return value</span>: <code>true</code> if the sequence
+ is UTF-8 byte order mark; <code>false</code> if not.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned char</span> byte_order_mark[] = {<span class=
+"literal">0xef</span>, <span class="literal">0xbb</span>, <span class=
+"literal">0xbf</span>};
+<span class="keyword">bool</span> bbom = is_bom(byte_order_mark);
+assert (bbom == <span class="literal">true</span>);
+</pre>
+ <p>
+ The typical use of this function is to check the first three bytes of a file. If
+ they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8
+ encoded text.
+ </p>
+ <p>
+ If a sequence is
+ shorter than three bytes, an invalid iterator will be dereferenced. Therefore, this function is deprecated
+ in favor of <code>starts_with_bom()</code>that takes the end of sequence as an argument.
+ </p>
+ <h3 id="typesutf8">
+ Types From utf8 Namespace
+ </h3>
+ <h4>utf8::exception
+ </h4>
+ <p class="version">
+ Available in version 2.3 and later.
+ </p>
+ <p>
+ Base class for the exceptions thrown by UTF CPP library functions.
+ </p>
+<pre>
+<span class="keyword">class</span> exception : <span class="keyword">public</span> std::exception {};
+</pre>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">try</span> {
+ code_that_uses_utf_cpp_library();
+}
+<span class="keyword">catch</span>(<span class="keyword">const</span> utf8::exception&amp; utfcpp_ex) {
+ cerr &lt;&lt; utfcpp_ex.what();
+}
+</pre>
+
+ <h4>utf8::invalid_code_point
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Thrown by UTF8 CPP functions such as <code>advance</code> and <code>next</code> if an UTF-8 sequence represents and invalid code point.
+ </p>
+
+<pre>
+<span class="keyword">class</span> invalid_code_point : <span class="keyword">public</span> exception {
+<span class="keyword">public</span>:
+ uint32_t code_point() <span class="keyword">const</span>;
+};
+
+</pre>
+ <p>
+ Member function <code>code_point()</code> can be used to determine the invalid code point that
+ caused the exception to be thrown.
+ </p>
+ <h4>utf8::invalid_utf8
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Thrown by UTF8 CPP functions such as <code>next</code> and <code>prior</code> if an invalid UTF-8 sequence
+ is detected during decoding.
+ </p>
+
+<pre>
+<span class="keyword">class</span> invalid_utf8 : <span class="keyword">public</span> exception {
+<span class="keyword">public</span>:
+ uint8_t utf8_octet() <span class="keyword">const</span>;
+};
+</pre>
+
+ <p>
+ Member function <code>utf8_octet()</code> can be used to determine the beginning of the byte
+ sequence that caused the exception to be thrown.
+ </p>
+</pre>
+ <h4>utf8::invalid_utf16
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Thrown by UTF8 CPP function <code>utf16to8</code> if an invalid UTF-16 sequence
+ is detected during decoding.
+ </p>
+
+<pre>
+<span class="keyword">class</span> invalid_utf16 : <span class="keyword">public</span> exception {
+<span class="keyword">public</span>:
+ uint16_t utf16_word() <span class="keyword">const</span>;
+};
+</pre>
+
+ <p>
+ Member function <code>utf16_word()</code> can be used to determine the UTF-16 code unit
+ that caused the exception to be thrown.
+ </p>
+ <h4>utf8::not_enough_room
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Thrown by UTF8 CPP functions such as <code>next</code> if the end of the decoded UTF-8 sequence
+ was reached before the code point was decoded.
+ </p>
+
+<pre>
+<span class="keyword">class</span> not_enough_room : <span class="keyword">public</span> exception {};
+</pre>
+ <h4>
+ utf8::iterator
+ </h4>
+ <p class="version">
+ Available in version 2.0 and later.
+ </p>
+ <p>
+ Adapts the underlying octet iterator to iterate over the sequence of code points,
+ rather than raw octets.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class="keyword">typename</span> octet_iterator&gt;
+<span class="keyword">class</span> iterator;
+</pre>
+
+ <h5>Member functions</h5>
+ <dl>
+ <dt><code>iterator();</code> <dd> the deafult constructor; the underlying <code>octet_iterator</code> is
+ constructed with its default constructor.
+ <dt><code><span class="keyword">explicit</span> iterator (const octet_iterator&amp; octet_it,
+ const octet_iterator&amp; range_start,
+ const octet_iterator&amp; range_end);</code> <dd> a constructor
+ that initializes the underlying <code>octet_iterator</code> with <code>octet_it</code>
+ and sets the range in which the iterator is considered valid.
+ <dt><code>octet_iterator base () <span class="keyword">const</span>;</code> <dd> returns the
+ underlying <code>octet_iterator</code>.
+ <dt><code>uint32_t operator * () <span class="keyword">const</span>;</code> <dd> decodes the utf-8 sequence
+ the underlying <code>octet_iterator</code> is pointing to and returns the code point.
+ <dt><code><span class="keyword">bool operator</span> == (const iterator&amp; rhs)
+ <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
+ if the two underlaying iterators are equal.
+ <dt><code><span class="keyword">bool operator</span> != (const iterator&amp; rhs)
+ <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
+ if the two underlaying iterators are not equal.
+ <dt><code>iterator&amp; <span class="keyword">operator</span> ++ (); </code> <dd> the prefix increment - moves
+ the iterator to the next UTF-8 encoded code point.
+ <dt><code>iterator <span class="keyword">operator</span> ++ (<span class="keyword">int</span>); </code> <dd>
+ the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one.
+ <dt><code>iterator&amp; <span class="keyword">operator</span> -- (); </code> <dd> the prefix decrement - moves
+ the iterator to the previous UTF-8 encoded code point.
+ <dt><code>iterator <span class="keyword">operator</span> -- (<span class="keyword">int</span>); </code> <dd>
+ the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one.
+ </dl>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* threechars = <span class="literal">"\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"</span>;
+utf8::iterator&lt;<span class="keyword">char</span>*&gt; it(threechars, threechars, threechars + <span class="literal">9</span>);
+utf8::iterator&lt;<span class="keyword">char</span>*&gt; it2 = it;
+assert (it2 == it);
+assert (*it == <span class="literal">0x10346</span>);
+assert (*(++it) == <span class="literal">0x65e5</span>);
+assert ((*it++) == <span class="literal">0x65e5</span>);
+assert (*it == <span class="literal">0x0448</span>);
+assert (it != it2);
+utf8::iterator&lt;<span class="keyword">char</span>*&gt; endit (threechars + <span class="literal">9</span>, threechars, threechars + <span class="literal">9</span>);
+assert (++it == endit);
+assert (*(--it) == <span class="literal">0x0448</span>);
+assert ((*it--) == <span class="literal">0x0448</span>);
+assert (*it == <span class="literal">0x65e5</span>);
+assert (--it == utf8::iterator&lt;<span class="keyword">char</span>*&gt;(threechars, threechars, threechars + <span class="literal">9</span>));
+assert (*it == <span class="literal">0x10346</span>);
+</pre>
+ <p>
+ The purpose of <code>utf8::iterator</code> adapter is to enable easy iteration as well as the use of STL
+ algorithms with UTF-8 encoded strings. Increment and decrement operators are implemented in terms of
+ <code>utf8::next()</code> and <code>utf8::prior()</code> functions.
+ </p>
+ <p>
+ Note that <code>utf8::iterator</code> adapter is a checked iterator. It operates on the range specified in
+ the constructor; any attempt to go out of that range will result in an exception. Even the comparison operators
+ require both iterator object to be constructed against the same range - otherwise an exception is thrown. Typically,
+ the range will be determined by sequence container functions <code>begin</code> and <code>end</code>, i.e.:
+ </p>
+<pre>
+std::string s = <span class="literal">"example"</span>;
+utf8::iterator i (s.begin(), s.begin(), s.end());
+</pre>
+ <h3 id="fununchecked">
+ Functions From utf8::unchecked Namespace
+ </h3>
+ <h4>
+ utf8::unchecked::append
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence
+ to a UTF-8 string.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+octet_iterator append(uint32_t cp, octet_iterator result);
+
+</pre>
+ <p>
+ <code>cp</code>: A 32 bit integer representing a code point to append to the
+ sequence.<br>
+ <code>result</code>: An output iterator to the place in the sequence where to
+ append the code point.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the newly appended sequence.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned char</span> u[<span class="literal">5</span>] = {<span
+class="literal">0</span>,<span class="literal">0</span>,<span class=
+"literal">0</span>,<span class="literal">0</span>,<span class="literal">0</span>};
+<span class="keyword">unsigned char</span>* end = unchecked::append(<span class=
+"literal">0x0448</span>, u);
+assert (u[<span class="literal">0</span>] == <span class=
+"literal">0xd1</span> &amp;&amp; u[<span class="literal">1</span>] == <span class=
+"literal">0x88</span> &amp;&amp; u[<span class="literal">2</span>] == <span class=
+"literal">0</span> &amp;&amp; u[<span class="literal">3</span>] == <span class=
+"literal">0</span> &amp;&amp; u[<span class="literal">4</span>] == <span class=
+"literal">0</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::append</code>. It does not
+ check for validity of the supplied code point, and may produce an invalid UTF-8
+ sequence.
+ </p>
+ <h4>
+ utf8::unchecked::next
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Given the iterator to the beginning of a UTF-8 sequence, it returns the code point
+ and moves the iterator to the next position.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t next(octet_iterator&amp; it);
+
+</pre>
+ <p>
+ <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
+ encoded code point. After the function returns, it is incremented to point to the
+ beginning of the next code point.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ processed UTF-8 code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars;
+<span class="keyword">int</span> cp = unchecked::next(w);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars + <span class="literal">3</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::next</code>. It does not
+ check for validity of the supplied UTF-8 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::peek_next
+ </h4>
+ <p class="version">
+ Available in version 2.1 and later.
+ </p>
+ <p>
+ Given the iterator to the beginning of a UTF-8 sequence, it returns the code point.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t peek_next(octet_iterator it);
+
+</pre>
+ <p>
+ <code>it</code>: an iterator pointing to the beginning of an UTF-8
+ encoded code point.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ processed UTF-8 code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars;
+<span class="keyword">int</span> cp = unchecked::peek_next(w);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::peek_next</code>. It does not
+ check for validity of the supplied UTF-8 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::prior
+ </h4>
+ <p class="version">
+ Available in version 1.02 and later.
+ </p>
+ <p>
+ Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it
+ decreases the iterator until it hits the beginning of the previous UTF-8 encoded
+ code point and returns the 32 bits representation of the code point.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t prior(octet_iterator&amp; it);
+
+</pre>
+ <p>
+ <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
+ After the function returns, it is decremented to point to the beginning of the
+ previous code point.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ previous code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars + <span class="literal">3</span>;
+<span class="keyword">int</span> cp = unchecked::prior (w);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::prior</code>. It does not
+ check for validity of the supplied UTF-8 sequence and offers no boundary checking.
+ </p>
+ <h4>
+ utf8::unchecked::previous (deprecated, see utf8::unchecked::prior)
+ </h4>
+ <p class="version">
+ Deprecated in version 1.02 and later.
+ </p>
+ <p>
+ Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it
+ decreases the iterator until it hits the beginning of the previous UTF-8 encoded
+ code point and returns the 32 bits representation of the code point.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+uint32_t previous(octet_iterator&amp; it);
+
+</pre>
+ <p>
+ <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
+ After the function returns, it is decremented to point to the beginning of the
+ previous code point.<br>
+ <span class="return_value">Return value</span>: the 32 bit representation of the
+ previous code point.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars + <span class="literal">3</span>;
+<span class="keyword">int</span> cp = unchecked::previous (w);
+assert (cp == <span class="literal">0x65e5</span>);
+assert (w == twochars);
+</pre>
+ <p>
+ The reason this function is deprecated is just the consistency with the "checked"
+ versions, where <code>prior</code> should be used instead of <code>previous</code>.
+ In fact, <code>unchecked::previous</code> behaves exactly the same as <code>
+ unchecked::prior</code>
+ </p>
+ <p>
+ This is a faster but less safe version of <code>utf8::previous</code>. It does not
+ check for validity of the supplied UTF-8 sequence and offers no boundary checking.
+ </p>
+ <h4>
+ utf8::unchecked::advance
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Advances an iterator by the specified number of code points within an UTF-8
+ sequence.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, typename distance_type&gt;
+<span class="keyword">void</span> advance (octet_iterator&amp; it, distance_type n);
+
+</pre>
+ <p>
+ <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
+ encoded code point. After the function returns, it is incremented to point to the
+ nth following code point.<br>
+ <code>n</code>: a positive integer that shows how many code points we want to
+ advance.<br>
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+<span class="keyword">char</span>* w = twochars;
+unchecked::advance (w, <span class="literal">2</span>);
+assert (w == twochars + <span class="literal">5</span>);
+</pre>
+ <p>
+ This function works only "forward". In case of a negative <code>n</code>, there is
+ no effect.
+ </p>
+ <p>
+ This is a faster but less safe version of <code>utf8::advance</code>. It does not
+ check for validity of the supplied UTF-8 sequence and offers no boundary checking.
+ </p>
+ <h4>
+ utf8::unchecked::distance
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Given the iterators to two UTF-8 encoded code points in a seqence, returns the
+ number of code points between them.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator&gt;
+<span class=
+"keyword">typename</span> std::iterator_traits&lt;octet_iterator&gt;::difference_type distance (octet_iterator first, octet_iterator last);
+</pre>
+ <p>
+ <code>first</code>: an iterator to a beginning of a UTF-8 encoded code point.<br>
+ <code>last</code>: an iterator to a "post-end" of the last UTF-8 encoded code
+ point in the sequence we are trying to determine the length. It can be the
+ beginning of a new code point, or not.<br>
+ <span class="return_value">Return value</span> the distance between the iterators,
+ in code points.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+size_t dist = utf8::unchecked::distance(twochars, twochars + <span class=
+"literal">5</span>);
+assert (dist == <span class="literal">2</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::distance</code>. It does not
+ check for validity of the supplied UTF-8 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::utf16to8
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-16 encoded string to UTF-8.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> u16bit_iterator, <span class=
+"keyword">typename</span> octet_iterator&gt;
+octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result);
+
+</pre>
+ <p>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-16 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-16 encoded
+ string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-8 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-8 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">unsigned short</span> utf16string[] = {<span class=
+"literal">0x41</span>, <span class="literal">0x0448</span>, <span class=
+"literal">0x65e5</span>, <span class="literal">0xd834</span>, <span class=
+"literal">0xdd1e</span>};
+vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
+unchecked::utf16to8(utf16string, utf16string + <span class=
+"literal">5</span>, back_inserter(utf8result));
+assert (utf8result.size() == <span class="literal">10</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::utf16to8</code>. It does not
+ check for validity of the supplied UTF-16 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::utf8to16
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts an UTF-8 encoded string to UTF-16
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> u16bit_iterator, typename octet_iterator&gt;
+u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result);
+
+</pre>
+ <p>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
+ string to convert. &lt; br /&gt; <code>end</code>: an iterator pointing to
+ pass-the-end of the UTF-8 encoded string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-16 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-16 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span> utf8_with_surrogates[] = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"</span>;
+vector &lt;<span class="keyword">unsigned short</span>&gt; utf16result;
+unchecked::utf8to16(utf8_with_surrogates, utf8_with_surrogates + <span class=
+"literal">9</span>, back_inserter(utf16result));
+assert (utf16result.size() == <span class="literal">4</span>);
+assert (utf16result[<span class="literal">2</span>] == <span class=
+"literal">0xd834</span>);
+assert (utf16result[<span class="literal">3</span>] == <span class=
+"literal">0xdd1e</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::utf8to16</code>. It does not
+ check for validity of the supplied UTF-8 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::utf32to8
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-32 encoded string to UTF-8.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, <span class=
+"keyword">typename</span> u32bit_iterator&gt;
+octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result);
+
+</pre>
+ <p>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-32 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-32 encoded
+ string to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-8 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-8 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">int</span> utf32string[] = {<span class=
+"literal">0x448</span>, <span class="literal">0x65e5</span>, <span class=
+"literal">0x10346</span>, <span class="literal">0</span>};
+vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
+utf32to8(utf32string, utf32string + <span class=
+"literal">3</span>, back_inserter(utf8result));
+assert (utf8result.size() == <span class="literal">9</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::utf32to8</code>. It does not
+ check for validity of the supplied UTF-32 sequence.
+ </p>
+ <h4>
+ utf8::unchecked::utf8to32
+ </h4>
+ <p class="version">
+ Available in version 1.0 and later.
+ </p>
+ <p>
+ Converts a UTF-8 encoded string to UTF-32.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class=
+"keyword">typename</span> octet_iterator, typename u32bit_iterator&gt;
+u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
+
+</pre>
+ <p>
+ <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
+ string to convert.<br>
+ <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 encoded string
+ to convert.<br>
+ <code>result</code>: an output iterator to the place in the UTF-32 string where to
+ append the result of conversion.<br>
+ <span class="return_value">Return value</span>: An iterator pointing to the place
+ after the appended UTF-32 string.
+ </p>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* twochars = <span class=
+"literal">"\xe6\x97\xa5\xd1\x88"</span>;
+vector&lt;<span class="keyword">int</span>&gt; utf32result;
+unchecked::utf8to32(twochars, twochars + <span class=
+"literal">5</span>, back_inserter(utf32result));
+assert (utf32result.size() == <span class="literal">2</span>);
+</pre>
+ <p>
+ This is a faster but less safe version of <code>utf8::utf8to32</code>. It does not
+ check for validity of the supplied UTF-8 sequence.
+ </p>
+ <h3 id="typesunchecked">
+ Types From utf8::unchecked Namespace
+ </h3>
+ <h4>
+ utf8::iterator
+ </h4>
+ <p class="version">
+ Available in version 2.0 and later.
+ </p>
+ <p>
+ Adapts the underlying octet iterator to iterate over the sequence of code points,
+ rather than raw octets.
+ </p>
+<pre>
+<span class="keyword">template</span> &lt;<span class="keyword">typename</span> octet_iterator&gt;
+<span class="keyword">class</span> iterator;
+</pre>
+
+ <h5>Member functions</h5>
+ <dl>
+ <dt><code>iterator();</code> <dd> the deafult constructor; the underlying <code>octet_iterator</code> is
+ constructed with its default constructor.
+ <dt><code><span class="keyword">explicit</span> iterator (const octet_iterator&amp; octet_it);
+ </code> <dd> a constructor
+ that initializes the underlying <code>octet_iterator</code> with <code>octet_it</code>
+ <dt><code>octet_iterator base () <span class="keyword">const</span>;</code> <dd> returns the
+ underlying <code>octet_iterator</code>.
+ <dt><code>uint32_t operator * () <span class="keyword">const</span>;</code> <dd> decodes the utf-8 sequence
+ the underlying <code>octet_iterator</code> is pointing to and returns the code point.
+ <dt><code><span class="keyword">bool operator</span> == (const iterator&amp; rhs)
+ <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
+ if the two underlaying iterators are equal.
+ <dt><code><span class="keyword">bool operator</span> != (const iterator&amp; rhs)
+ <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
+ if the two underlaying iterators are not equal.
+ <dt><code>iterator&amp; <span class="keyword">operator</span> ++ (); </code> <dd> the prefix increment - moves
+ the iterator to the next UTF-8 encoded code point.
+ <dt><code>iterator <span class="keyword">operator</span> ++ (<span class="keyword">int</span>); </code> <dd>
+ the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one.
+ <dt><code>iterator&amp; <span class="keyword">operator</span> -- (); </code> <dd> the prefix decrement - moves
+ the iterator to the previous UTF-8 encoded code point.
+ <dt><code>iterator <span class="keyword">operator</span> -- (<span class="keyword">int</span>); </code> <dd>
+ the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one.
+ </dl>
+ <p>
+ Example of use:
+ </p>
+<pre>
+<span class="keyword">char</span>* threechars = <span class="literal">"\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"</span>;
+utf8::unchecked::iterator&lt;<span class="keyword">char</span>*&gt; un_it(threechars);
+utf8::unchecked::iterator&lt;<span class="keyword">char</span>*&gt; un_it2 = un_it;
+assert (un_it2 == un_it);
+assert (*un_it == <span class="literal">0x10346</span>);
+assert (*(++un_it) == <span class="literal">0x65e5</span>);
+assert ((*un_it++) == <span class="literal">0x65e5</span>);
+assert (*un_it == <span class="literal">0x0448</span>);
+assert (un_it != un_it2);
+utf8::::unchecked::iterator&lt;<span class="keyword">char</span>*&gt; un_endit (threechars + <span class="literal">9</span>);
+assert (++un_it == un_endit);
+assert (*(--un_it) == <span class="literal">0x0448</span>);
+assert ((*un_it--) == <span class="literal">0x0448</span>);
+assert (*un_it == <span class="literal">0x65e5</span>);
+assert (--un_it == utf8::unchecked::iterator&lt;<span class="keyword">char</span>*&gt;(threechars));
+assert (*un_it == <span class="literal">0x10346</span>);
+</pre>
+ <p>
+ This is an unchecked version of <code>utf8::iterator</code>. It is faster in many cases, but offers
+ no validity or range checks.
+ </p>
+ <h2 id="points">
+ Points of interest
+ </h2>
+ <h4>
+ Design goals and decisions
+ </h4>
+ <p>
+ The library was designed to be:
+ </p>
+ <ol>
+ <li>
+ Generic: for better or worse, there are many C++ string classes out there, and
+ the library should work with as many of them as possible.
+ </li>
+ <li>
+ Portable: the library should be portable both accross different platforms and
+ compilers. The only non-portable code is a small section that declares unsigned
+ integers of different sizes: three typedefs. They can be changed by the users of
+ the library if they don't match their platform. The default setting should work
+ for Windows (both 32 and 64 bit), and most 32 bit and 64 bit Unix derivatives.
+ </li>
+ <li>
+ Lightweight: follow the "pay only for what you use" guideline.
+ </li>
+ <li>
+ Unintrusive: avoid forcing any particular design or even programming style on the
+ user. This is a library, not a framework.
+ </li>
+ </ol>
+ <h4>
+ Alternatives
+ </h4>
+ <p>
+ In case you want to look into other means of working with UTF-8 strings from C++,
+ here is the list of solutions I am aware of:
+ </p>
+ <ol>
+ <li>
+ <a href="http://icu.sourceforge.net/">ICU Library</a>. It is very powerful,
+ complete, feature-rich, mature, and widely used. Also big, intrusive,
+ non-generic, and doesn't play well with the Standard Library. I definitelly
+ recommend looking at ICU even if you don't plan to use it.
+ </li>
+ <li>
+ C++11 language and library features. Still far from complete, and not widely
+ supported by compiler vendors.
+ </li>
+ <li>
+ <a href=
+ "http://www.gtkmm.org/gtkmm2/docs/tutorial/html/ch03s04.html">Glib::ustring</a>.
+ A class specifically made to work with UTF-8 strings, and also feel like
+ <code>std::string</code>. If you prefer to have yet another string class in your
+ code, it may be worth a look. Be aware of the licensing issues, though.
+ </li>
+ <li>
+ Platform dependent solutions: Windows and POSIX have functions to convert strings
+ from one encoding to another. That is only a subset of what my library offers,
+ but if that is all you need it may be good enough.
+ </li>
+ </ol>
+ <h2 id="links">
+ Links
+ </h2>
+ <ol>
+ <li>
+ <a href="http://www.unicode.org/">The Unicode Consortium</a>.
+ </li>
+ <li>
+ <a href="http://icu.sourceforge.net/">ICU Library</a>.
+ </li>
+ <li>
+ <a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8 at Wikipedia</a>
+ </li>
+ <li>
+ <a href="http://www.cl.cam.ac.uk/~mgk25/unicode.html">UTF-8 and Unicode FAQ for
+ Unix/Linux</a>
+ </li>
+ </ol>
+ </body>
+</html>
diff --git a/thirdparty/assimp/include/assimp/BaseImporter.h b/thirdparty/assimp/include/assimp/BaseImporter.h
index 48dfc8ed8b..ad8a3dafd8 100644
--- a/thirdparty/assimp/include/assimp/BaseImporter.h
+++ b/thirdparty/assimp/include/assimp/BaseImporter.h
@@ -41,15 +41,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Definition of the base class for all importer worker classes. */
+#pragma once
#ifndef INCLUDED_AI_BASEIMPORTER_H
#define INCLUDED_AI_BASEIMPORTER_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include "Exceptional.h"
#include <vector>
#include <set>
+#include <map>
#include <assimp/types.h>
#include <assimp/ProgressHandler.hpp>
+#include <assimp/ai_assert.h>
struct aiScene;
struct aiImporterDesc;
@@ -80,6 +87,10 @@ class IOStream;
class ASSIMP_API BaseImporter {
friend class Importer;
+private:
+ /* Pushes state into importer for the importer scale */
+ virtual void UpdateImporterScale( Importer* pImp );
+
public:
/** Constructor to be privately used by #Importer */
@@ -132,7 +143,7 @@ public:
* a suitable response to the caller.
*/
aiScene* ReadFile(
- const Importer* pImp,
+ Importer* pImp,
const std::string& pFile,
IOSystem* pIOHandler
);
@@ -161,14 +172,62 @@ public:
* some loader features. Importers must provide this information. */
virtual const aiImporterDesc* GetInfo() const = 0;
+ /**
+ * Will be called only by scale process when scaling is requested.
+ */
+ virtual void SetFileScale(double scale)
+ {
+ fileScale = scale;
+ }
+
+ virtual double GetFileScale() const
+ {
+ return fileScale;
+ }
+
+ enum ImporterUnits {
+ M,
+ MM,
+ CM,
+ INCHES,
+ FEET
+ };
+
+ /**
+ * Assimp Importer
+ * unit conversions available
+ * NOTE: Valid options are initialised in the
+ * constructor in the implementation file to
+ * work around a VS2013 compiler bug if support
+ * for that compiler is dropped in the future
+ * initialisation can be moved back here
+ * */
+ std::map<ImporterUnits, double> importerUnits;
+
+ virtual void SetApplicationUnits( const ImporterUnits& unit )
+ {
+ importerScale = importerUnits[unit];
+ applicationUnits = unit;
+ }
+
+ virtual const ImporterUnits& GetApplicationUnits()
+ {
+ return applicationUnits;
+ }
+
// -------------------------------------------------------------------
/** Called by #Importer::GetExtensionList for each loaded importer.
* Take the extension list contained in the structure returned by
* #GetInfo and insert all file extensions into the given set.
* @param extension set to collect file extensions in*/
void GetExtensionList(std::set<std::string>& extensions);
+
+protected:
+ ImporterUnits applicationUnits = ImporterUnits::M;
+ double importerScale = 1.0;
+ double fileScale = 1.0;
+
-protected:
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure. The
diff --git a/thirdparty/assimp/include/assimp/Bitmap.h b/thirdparty/assimp/include/assimp/Bitmap.h
index e6b5fb1327..4c3f5a437b 100644
--- a/thirdparty/assimp/include/assimp/Bitmap.h
+++ b/thirdparty/assimp/include/assimp/Bitmap.h
@@ -46,10 +46,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Used for file formats which embed their textures into the model file.
*/
-
+#pragma once
#ifndef AI_BITMAP_H_INC
#define AI_BITMAP_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include "defs.h"
#include <stdint.h>
#include <cstddef>
diff --git a/thirdparty/assimp/include/assimp/ByteSwapper.h b/thirdparty/assimp/include/assimp/ByteSwapper.h
index 20a2463fb8..3f14c471a8 100644
--- a/thirdparty/assimp/include/assimp/ByteSwapper.h
+++ b/thirdparty/assimp/include/assimp/ByteSwapper.h
@@ -42,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Helper class tp perform various byte oder swappings
(e.g. little to big endian) */
+#pragma once
#ifndef AI_BYTESWAPPER_H_INC
#define AI_BYTESWAPPER_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/ai_assert.h>
#include <assimp/types.h>
#include <stdint.h>
diff --git a/thirdparty/assimp/include/assimp/CreateAnimMesh.h b/thirdparty/assimp/include/assimp/CreateAnimMesh.h
index a60173588f..1266d1de11 100644
--- a/thirdparty/assimp/include/assimp/CreateAnimMesh.h
+++ b/thirdparty/assimp/include/assimp/CreateAnimMesh.h
@@ -43,16 +43,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file CreateAnimMesh.h
* Create AnimMesh from Mesh
*/
+#pragma once
#ifndef INCLUDED_AI_CREATE_ANIM_MESH_H
#define INCLUDED_AI_CREATE_ANIM_MESH_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/mesh.h>
-namespace Assimp {
+namespace Assimp {
-/** Create aiAnimMesh from aiMesh. */
+/**
+ * Create aiAnimMesh from aiMesh.
+ * @param mesh The input mesh to create an animated mesh from.
+ * @return The new created animated mesh.
+ */
ASSIMP_API aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh);
} // end of namespace Assimp
+
#endif // INCLUDED_AI_CREATE_ANIM_MESH_H
diff --git a/thirdparty/assimp/include/assimp/DefaultIOStream.h b/thirdparty/assimp/include/assimp/DefaultIOStream.h
index 994d728ff5..c6d382c1b5 100644
--- a/thirdparty/assimp/include/assimp/DefaultIOStream.h
+++ b/thirdparty/assimp/include/assimp/DefaultIOStream.h
@@ -41,15 +41,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Default file I/O using fXXX()-family of functions */
+#pragma once
#ifndef AI_DEFAULTIOSTREAM_H_INC
#define AI_DEFAULTIOSTREAM_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <stdio.h>
#include <assimp/IOStream.hpp>
#include <assimp/importerdesc.h>
#include <assimp/Defines.h>
-namespace Assimp {
+namespace Assimp {
// ----------------------------------------------------------------------------------
//! @class DefaultIOStream
@@ -57,8 +62,7 @@ namespace Assimp {
//! @note An instance of this class can exist without a valid file handle
//! attached to it. All calls fail, but the instance can nevertheless be
//! used with no restrictions.
-class ASSIMP_API DefaultIOStream : public IOStream
-{
+class ASSIMP_API DefaultIOStream : public IOStream {
friend class DefaultIOSystem;
#if __ANDROID__
# if __ANDROID_API__ > 9
@@ -82,7 +86,6 @@ public:
size_t pSize,
size_t pCount);
-
// -------------------------------------------------------------------
/// Write to stream
size_t Write(const void* pvBuffer,
@@ -107,16 +110,13 @@ public:
void Flush();
private:
- // File data-structure, using clib
FILE* mFile;
- // Filename
std::string mFilename;
- // Cached file size
mutable size_t mCachedSize;
};
// ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
: mFile(nullptr)
, mFilename("")
@@ -125,7 +125,7 @@ DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
}
// ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
: mFile(pFile)
, mFilename(strFilename)
@@ -137,4 +137,3 @@ DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
} // ns assimp
#endif //!!AI_DEFAULTIOSTREAM_H_INC
-
diff --git a/thirdparty/assimp/include/assimp/DefaultIOSystem.h b/thirdparty/assimp/include/assimp/DefaultIOSystem.h
index 2dd5c801b5..46f6d447c5 100644
--- a/thirdparty/assimp/include/assimp/DefaultIOSystem.h
+++ b/thirdparty/assimp/include/assimp/DefaultIOSystem.h
@@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Default implementation of IOSystem using the standard C file functions */
+#pragma once
#ifndef AI_DEFAULTIOSYSTEM_H_INC
#define AI_DEFAULTIOSYSTEM_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/IOSystem.hpp>
namespace Assimp {
diff --git a/thirdparty/assimp/include/assimp/Defines.h b/thirdparty/assimp/include/assimp/Defines.h
index 15e1d83c26..be3e2fafd6 100644
--- a/thirdparty/assimp/include/assimp/Defines.h
+++ b/thirdparty/assimp/include/assimp/Defines.h
@@ -38,6 +38,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
+#pragma once
+#ifndef AI_DEFINES_H_INC
+#define AI_DEFINES_H_INC
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
// We need those constants, workaround for any platforms where nobody defined them yet
#if (!defined SIZE_MAX)
# define SIZE_MAX (~((size_t)0))
@@ -47,3 +55,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# define UINT_MAX (~((unsigned int)0))
#endif
+#endif // AI_DEINES_H_INC
diff --git a/thirdparty/assimp/include/assimp/Exceptional.h b/thirdparty/assimp/include/assimp/Exceptional.h
index 5109b8f077..6bb6ce1e39 100644
--- a/thirdparty/assimp/include/assimp/Exceptional.h
+++ b/thirdparty/assimp/include/assimp/Exceptional.h
@@ -38,11 +38,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
-#ifndef INCLUDED_EXCEPTIONAL_H
-#define INCLUDED_EXCEPTIONAL_H
+#pragma once
+#ifndef AI_INCLUDED_EXCEPTIONAL_H
+#define AI_INCLUDED_EXCEPTIONAL_H
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
#include <stdexcept>
#include <assimp/DefaultIOStream.h>
+
using std::runtime_error;
#ifdef _MSC_VER
@@ -53,17 +59,14 @@ using std::runtime_error;
/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an
* unrecoverable error occurs while importing. Loading APIs return
* NULL instead of a valid aiScene then. */
-class DeadlyImportError
- : public runtime_error
-{
+class DeadlyImportError : public runtime_error {
public:
/** Constructor with arguments */
explicit DeadlyImportError( const std::string& errorText)
- : runtime_error(errorText)
- {
+ : runtime_error(errorText) {
+ // empty
}
-private:
};
typedef DeadlyImportError DeadlyExportError;
@@ -84,7 +87,7 @@ struct ExceptionSwallower {
template <typename T>
struct ExceptionSwallower<T*> {
T* operator ()() const {
- return NULL;
+ return nullptr;
}
};
@@ -122,4 +125,4 @@ struct ExceptionSwallower<void> {
}\
}
-#endif // INCLUDED_EXCEPTIONAL_H
+#endif // AI_INCLUDED_EXCEPTIONAL_H
diff --git a/thirdparty/assimp/include/assimp/Exporter.hpp b/thirdparty/assimp/include/assimp/Exporter.hpp
index bf0096e7e9..2612e1f9d2 100644
--- a/thirdparty/assimp/include/assimp/Exporter.hpp
+++ b/thirdparty/assimp/include/assimp/Exporter.hpp
@@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_EXPORT_HPP_INC
#define AI_EXPORT_HPP_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifndef ASSIMP_BUILD_NO_EXPORT
#include "cexport.h"
@@ -190,7 +194,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/GenericProperty.h b/thirdparty/assimp/include/assimp/GenericProperty.h
index 183ecd5197..7796d595b8 100644
--- a/thirdparty/assimp/include/assimp/GenericProperty.h
+++ b/thirdparty/assimp/include/assimp/GenericProperty.h
@@ -40,12 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
+#pragma once
#ifndef AI_GENERIC_PROPERTY_H_INCLUDED
#define AI_GENERIC_PROPERTY_H_INCLUDED
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/Importer.hpp>
#include <assimp/ai_assert.h>
-#include "Hash.h"
+#include <assimp/Hash.h>
#include <map>
diff --git a/thirdparty/assimp/include/assimp/Hash.h b/thirdparty/assimp/include/assimp/Hash.h
index 30657be198..9056440789 100644
--- a/thirdparty/assimp/include/assimp/Hash.h
+++ b/thirdparty/assimp/include/assimp/Hash.h
@@ -39,10 +39,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
-
+#pragma once
#ifndef AI_HASH_H_INCLUDED
#define AI_HASH_H_INCLUDED
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <stdint.h>
#include <string.h>
diff --git a/thirdparty/assimp/include/assimp/IOStream.hpp b/thirdparty/assimp/include/assimp/IOStream.hpp
index 0623d0f70b..39932cd949 100644
--- a/thirdparty/assimp/include/assimp/IOStream.hpp
+++ b/thirdparty/assimp/include/assimp/IOStream.hpp
@@ -48,14 +48,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IOSTREAM_H_INC
#define AI_IOSTREAM_H_INC
-#include "types.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
#ifndef __cplusplus
# error This header requires C++ to be used. aiFileIO.h is the \
corresponding C interface.
#endif
-namespace Assimp {
+namespace Assimp {
// ----------------------------------------------------------------------------------
/** @brief CPP-API: Class to handle file I/O for C++
@@ -125,13 +129,13 @@ public:
}; //! class IOStream
// ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
IOStream::IOStream() AI_NO_EXCEPT {
// empty
}
// ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
IOStream::~IOStream() {
// empty
}
diff --git a/thirdparty/assimp/include/assimp/IOStreamBuffer.h b/thirdparty/assimp/include/assimp/IOStreamBuffer.h
index 58abd97a02..97c84b23e2 100644
--- a/thirdparty/assimp/include/assimp/IOStreamBuffer.h
+++ b/thirdparty/assimp/include/assimp/IOStreamBuffer.h
@@ -1,5 +1,3 @@
-#pragma once
-
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
@@ -42,10 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
+#pragma once
+#ifndef AI_IOSTREAMBUFFER_H_INC
+#define AI_IOSTREAMBUFFER_H_INC
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
#include <assimp/IOStream.hpp>
-
-#include "ParsingUtils.h"
+#include <assimp/ParsingUtils.h>
#include <vector>
@@ -124,7 +129,7 @@ private:
};
template<class T>
-inline
+AI_FORCE_INLINE
IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
: m_stream( nullptr )
, m_filesize( 0 )
@@ -138,13 +143,13 @@ IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
}
template<class T>
-inline
+AI_FORCE_INLINE
IOStreamBuffer<T>::~IOStreamBuffer() {
// empty
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::open( IOStream *stream ) {
// file still opened!
if ( nullptr != m_stream ) {
@@ -174,7 +179,7 @@ bool IOStreamBuffer<T>::open( IOStream *stream ) {
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::close() {
if ( nullptr == m_stream ) {
return false;
@@ -192,19 +197,19 @@ bool IOStreamBuffer<T>::close() {
}
template<class T>
-inline
+AI_FORCE_INLINE
size_t IOStreamBuffer<T>::size() const {
return m_filesize;
}
template<class T>
-inline
+AI_FORCE_INLINE
size_t IOStreamBuffer<T>::cacheSize() const {
return m_cacheSize;
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::readNextBlock() {
m_stream->Seek( m_filePos, aiOrigin_SET );
size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize );
@@ -222,25 +227,25 @@ bool IOStreamBuffer<T>::readNextBlock() {
}
template<class T>
-inline
+AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getNumBlocks() const {
return m_numBlocks;
}
template<class T>
-inline
+AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getCurrentBlockIndex() const {
return m_blockIdx;
}
template<class T>
-inline
+AI_FORCE_INLINE
size_t IOStreamBuffer<T>::getFilePos() const {
return m_filePos;
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
buffer.resize( m_cacheSize );
if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) {
@@ -289,13 +294,13 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT
return true;
}
-static inline
+static AI_FORCE_INLINE
bool isEndOfCache( size_t pos, size_t cacheSize ) {
return ( pos == cacheSize );
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
buffer.resize(m_cacheSize);
if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) {
@@ -335,7 +340,7 @@ bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
}
template<class T>
-inline
+AI_FORCE_INLINE
bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
// Return the last block-value if getNextLine was used before
if ( 0 != m_cachePos ) {
@@ -353,3 +358,5 @@ bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
}
} // !ns Assimp
+
+#endif // AI_IOSTREAMBUFFER_H_INC
diff --git a/thirdparty/assimp/include/assimp/IOSystem.hpp b/thirdparty/assimp/include/assimp/IOSystem.hpp
index 78139c2839..f1fb3b0c27 100644
--- a/thirdparty/assimp/include/assimp/IOSystem.hpp
+++ b/thirdparty/assimp/include/assimp/IOSystem.hpp
@@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IOSYSTEM_H_INC
#define AI_IOSYSTEM_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifndef __cplusplus
# error This header requires C++ to be used. aiFileIO.h is the \
corresponding C interface.
diff --git a/thirdparty/assimp/include/assimp/Importer.hpp b/thirdparty/assimp/include/assimp/Importer.hpp
index 4941df4122..bf449a9a25 100644
--- a/thirdparty/assimp/include/assimp/Importer.hpp
+++ b/thirdparty/assimp/include/assimp/Importer.hpp
@@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASSIMP_HPP_INC
#define AI_ASSIMP_HPP_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifndef __cplusplus
# error This header requires C++ to be used. Use assimp.h for plain C.
#endif // __cplusplus
diff --git a/thirdparty/assimp/include/assimp/LineSplitter.h b/thirdparty/assimp/include/assimp/LineSplitter.h
index 4afe45b92a..6c1097bb6d 100644
--- a/thirdparty/assimp/include/assimp/LineSplitter.h
+++ b/thirdparty/assimp/include/assimp/LineSplitter.h
@@ -48,9 +48,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_LINE_SPLITTER_H
#define INCLUDED_LINE_SPLITTER_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <stdexcept>
-#include "StreamReader.h"
-#include "ParsingUtils.h"
+#include <assimp/StreamReader.h>
+#include <assimp/ParsingUtils.h>
namespace Assimp {
@@ -140,7 +144,7 @@ private:
bool mSwallow, mSkip_empty_lines, mTrim;
};
-inline
+AI_FORCE_INLINE
LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim )
: mIdx(0)
, mCur()
@@ -153,12 +157,12 @@ LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool t
mIdx = 0;
}
-inline
+AI_FORCE_INLINE
LineSplitter::~LineSplitter() {
// empty
}
-inline
+AI_FORCE_INLINE
LineSplitter& LineSplitter::operator++() {
if (mSwallow) {
mSwallow = false;
@@ -199,12 +203,12 @@ LineSplitter& LineSplitter::operator++() {
return *this;
}
-inline
+AI_FORCE_INLINE
LineSplitter &LineSplitter::operator++(int) {
return ++(*this);
}
-inline
+AI_FORCE_INLINE
const char *LineSplitter::operator[] (size_t idx) const {
const char* s = operator->()->c_str();
@@ -222,7 +226,7 @@ const char *LineSplitter::operator[] (size_t idx) const {
}
template <size_t N>
-inline
+AI_FORCE_INLINE
void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
const char* s = operator->()->c_str();
@@ -238,44 +242,44 @@ void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
}
}
-inline
+AI_FORCE_INLINE
const std::string* LineSplitter::operator -> () const {
return &mCur;
}
-inline
+AI_FORCE_INLINE
std::string LineSplitter::operator* () const {
return mCur;
}
-inline
+AI_FORCE_INLINE
LineSplitter::operator bool() const {
return mStream.GetRemainingSize() > 0;
}
-inline
+AI_FORCE_INLINE
LineSplitter::operator line_idx() const {
return mIdx;
}
-inline
+AI_FORCE_INLINE
LineSplitter::line_idx LineSplitter::get_index() const {
return mIdx;
}
-inline
+AI_FORCE_INLINE
StreamReaderLE &LineSplitter::get_stream() {
return mStream;
}
-inline
+AI_FORCE_INLINE
bool LineSplitter::match_start(const char* check) {
const size_t len = ::strlen(check);
return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
}
-inline
+AI_FORCE_INLINE
void LineSplitter::swallow_next_increment() {
mSwallow = true;
}
diff --git a/thirdparty/assimp/include/assimp/LogAux.h b/thirdparty/assimp/include/assimp/LogAux.h
index 558485272e..bcead78dd3 100644
--- a/thirdparty/assimp/include/assimp/LogAux.h
+++ b/thirdparty/assimp/include/assimp/LogAux.h
@@ -43,9 +43,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file LogAux.h
* @brief Common logging usage patterns for importer implementations
*/
+#pragma once
#ifndef INCLUDED_AI_LOGAUX_H
#define INCLUDED_AI_LOGAUX_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/TinyFormatter.h>
#include <assimp/Exceptional.h>
#include <assimp/DefaultLogger.hpp>
diff --git a/thirdparty/assimp/include/assimp/MathFunctions.h b/thirdparty/assimp/include/assimp/MathFunctions.h
index cb3b696076..b6c5872a72 100644
--- a/thirdparty/assimp/include/assimp/MathFunctions.h
+++ b/thirdparty/assimp/include/assimp/MathFunctions.h
@@ -39,22 +39,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
+#pragma once
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
/** @file MathFunctions.h
- * @brief Implementation of the math functions (gcd and lcm)
+* @brief Implementation of math utility functions.
*
- * Copied from BoostWorkaround/math
- */
+*/
+
+#include <limits>
namespace Assimp {
namespace Math {
// TODO: use binary GCD for unsigned integers ....
template < typename IntegerType >
-IntegerType gcd( IntegerType a, IntegerType b )
-{
+inline
+IntegerType gcd( IntegerType a, IntegerType b ) {
const IntegerType zero = (IntegerType)0;
- while ( true )
- {
+ while ( true ) {
if ( a == zero )
return b;
b %= a;
@@ -66,12 +72,19 @@ IntegerType gcd( IntegerType a, IntegerType b )
}
template < typename IntegerType >
-IntegerType lcm( IntegerType a, IntegerType b )
-{
+inline
+IntegerType lcm( IntegerType a, IntegerType b ) {
const IntegerType t = gcd (a,b);
- if (!t)return t;
+ if (!t)
+ return t;
return a / t * b;
}
+template<class T>
+inline
+T getEpsilon() {
+ return std::numeric_limits<T>::epsilon();
+}
+
}
}
diff --git a/thirdparty/assimp/include/assimp/MemoryIOWrapper.h b/thirdparty/assimp/include/assimp/MemoryIOWrapper.h
index c522787184..5598d4fc5f 100644
--- a/thirdparty/assimp/include/assimp/MemoryIOWrapper.h
+++ b/thirdparty/assimp/include/assimp/MemoryIOWrapper.h
@@ -42,12 +42,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file MemoryIOWrapper.h
* Handy IOStream/IOSystem implemetation to read directly from a memory buffer */
+#pragma once
#ifndef AI_MEMORYIOSTREAM_H_INC
#define AI_MEMORYIOSTREAM_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/ai_assert.h>
+
#include <stdint.h>
namespace Assimp {
diff --git a/thirdparty/assimp/include/assimp/ParsingUtils.h b/thirdparty/assimp/include/assimp/ParsingUtils.h
index ca30ce13b0..3025601246 100644
--- a/thirdparty/assimp/include/assimp/ParsingUtils.h
+++ b/thirdparty/assimp/include/assimp/ParsingUtils.h
@@ -44,11 +44,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file ParsingUtils.h
* @brief Defines helper functions for text parsing
*/
+#pragma once
#ifndef AI_PARSING_UTILS_H_INC
#define AI_PARSING_UTILS_H_INC
-#include "StringComparison.h"
-#include "StringUtils.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/StringComparison.h>
+#include <assimp/StringUtils.h>
#include <assimp/defs.h>
namespace Assimp {
@@ -196,8 +201,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/Profiler.h b/thirdparty/assimp/include/assimp/Profiler.h
index 6ff9d41c0a..624029be99 100644
--- a/thirdparty/assimp/include/assimp/Profiler.h
+++ b/thirdparty/assimp/include/assimp/Profiler.h
@@ -43,12 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Profiler.h
* @brief Utility to measure the respective runtime of each import step
*/
-#ifndef INCLUDED_PROFILER_H
-#define INCLUDED_PROFILER_H
+#pragma once
+#ifndef AI_INCLUDED_PROFILER_H
+#define AI_INCLUDED_PROFILER_H
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
#include <chrono>
#include <assimp/DefaultLogger.hpp>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
#include <map>
@@ -67,7 +72,6 @@ public:
// empty
}
-public:
/** Start a named timer */
void BeginRegion(const std::string& region) {
@@ -95,5 +99,5 @@ private:
}
}
-#endif
+#endif // AI_INCLUDED_PROFILER_H
diff --git a/thirdparty/assimp/include/assimp/ProgressHandler.hpp b/thirdparty/assimp/include/assimp/ProgressHandler.hpp
index 4e47f1d0a6..8991a64618 100644
--- a/thirdparty/assimp/include/assimp/ProgressHandler.hpp
+++ b/thirdparty/assimp/include/assimp/ProgressHandler.hpp
@@ -47,9 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_PROGRESSHANDLER_H_INC
#define AI_PROGRESSHANDLER_H_INC
-#include "types.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
-namespace Assimp {
+namespace Assimp {
// ------------------------------------------------------------------------------------
/** @brief CPP-API: Abstract interface for custom progress report receivers.
diff --git a/thirdparty/assimp/include/assimp/RemoveComments.h b/thirdparty/assimp/include/assimp/RemoveComments.h
index 404b496719..f129420535 100644
--- a/thirdparty/assimp/include/assimp/RemoveComments.h
+++ b/thirdparty/assimp/include/assimp/RemoveComments.h
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -43,9 +42,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Declares a helper class, "CommentRemover", which can be
* used to remove comments (single and multi line) from a text file.
*/
+#pragma once
#ifndef AI_REMOVE_COMMENTS_H_INC
#define AI_REMOVE_COMMENTS_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
#include <assimp/defs.h>
@@ -58,8 +61,7 @@ namespace Assimp {
* to those in C or C++ so this code has been moved to a separate
* module.
*/
-class ASSIMP_API CommentRemover
-{
+class ASSIMP_API CommentRemover {
// class cannot be instanced
CommentRemover() {}
diff --git a/thirdparty/assimp/include/assimp/SGSpatialSort.h b/thirdparty/assimp/include/assimp/SGSpatialSort.h
index 5b4f3f41f2..fdb5ce8174 100644
--- a/thirdparty/assimp/include/assimp/SGSpatialSort.h
+++ b/thirdparty/assimp/include/assimp/SGSpatialSort.h
@@ -42,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** Small helper classes to optimize finding vertices close to a given location
*/
+#pragma once
#ifndef AI_D3DSSPATIALSORT_H_INC
#define AI_D3DSSPATIALSORT_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
#include <vector>
#include <stdint.h>
diff --git a/thirdparty/assimp/include/assimp/SceneCombiner.h b/thirdparty/assimp/include/assimp/SceneCombiner.h
index 679a2acea4..0683c1e052 100644
--- a/thirdparty/assimp/include/assimp/SceneCombiner.h
+++ b/thirdparty/assimp/include/assimp/SceneCombiner.h
@@ -43,17 +43,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Declares a helper class, "SceneCombiner" providing various
* utilities to merge scenes.
*/
+#pragma once
#ifndef AI_SCENE_COMBINER_H_INC
#define AI_SCENE_COMBINER_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/ai_assert.h>
#include <assimp/types.h>
#include <assimp/Defines.h>
+
#include <stddef.h>
#include <set>
#include <list>
#include <stdint.h>
-
#include <vector>
struct aiScene;
@@ -65,8 +70,10 @@ struct aiLight;
struct aiMetadata;
struct aiBone;
struct aiMesh;
+struct aiAnimMesh;
struct aiAnimation;
struct aiNodeAnim;
+struct aiMeshMorphAnim;
namespace Assimp {
@@ -363,6 +370,7 @@ public:
static void Copy (aiMesh** dest, const aiMesh* src);
// similar to Copy():
+ static void Copy (aiAnimMesh** dest, const aiAnimMesh* src);
static void Copy (aiMaterial** dest, const aiMaterial* src);
static void Copy (aiTexture** dest, const aiTexture* src);
static void Copy (aiAnimation** dest, const aiAnimation* src);
@@ -370,6 +378,7 @@ public:
static void Copy (aiBone** dest, const aiBone* src);
static void Copy (aiLight** dest, const aiLight* src);
static void Copy (aiNodeAnim** dest, const aiNodeAnim* src);
+ static void Copy (aiMeshMorphAnim** dest, const aiMeshMorphAnim* src);
static void Copy (aiMetadata** dest, const aiMetadata* src);
// recursive, of course
diff --git a/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h b/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h
index f9b8d9f55c..ad979a33fa 100644
--- a/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h
+++ b/thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h
@@ -47,9 +47,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* for animation skeletons.
*/
+#pragma once
#ifndef AI_SKELETONMESHBUILDER_H_INC
#define AI_SKELETONMESHBUILDER_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <vector>
#include <assimp/mesh.h>
diff --git a/thirdparty/assimp/include/assimp/SmoothingGroups.h b/thirdparty/assimp/include/assimp/SmoothingGroups.h
index 92d65cea02..c1a93947f1 100644
--- a/thirdparty/assimp/include/assimp/SmoothingGroups.h
+++ b/thirdparty/assimp/include/assimp/SmoothingGroups.h
@@ -43,10 +43,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines the helper data structures for importing 3DS files.
http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */
+#pragma once
#ifndef AI_SMOOTHINGGROUPS_H_INC
#define AI_SMOOTHINGGROUPS_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/vector3.h>
+
#include <stdint.h>
#include <vector>
diff --git a/thirdparty/assimp/include/assimp/SmoothingGroups.inl b/thirdparty/assimp/include/assimp/SmoothingGroups.inl
index 84ea4a1b00..37ea083dbe 100644
--- a/thirdparty/assimp/include/assimp/SmoothingGroups.inl
+++ b/thirdparty/assimp/include/assimp/SmoothingGroups.inl
@@ -41,13 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Generation of normal vectors basing on smoothing groups */
+#pragma once
#ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED
#define AI_SMOOTHINGGROUPS_INL_INCLUDED
-// internal headers
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/SGSpatialSort.h>
-// CRT header
#include <algorithm>
using namespace Assimp;
diff --git a/thirdparty/assimp/include/assimp/SpatialSort.h b/thirdparty/assimp/include/assimp/SpatialSort.h
index 61b345bcbf..9f93543150 100644
--- a/thirdparty/assimp/include/assimp/SpatialSort.h
+++ b/thirdparty/assimp/include/assimp/SpatialSort.h
@@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** Small helper classes to optimise finding vertizes close to a given location */
+#pragma once
#ifndef AI_SPATIALSORT_H_INC
#define AI_SPATIALSORT_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <vector>
#include <assimp/types.h>
diff --git a/thirdparty/assimp/include/assimp/StandardShapes.h b/thirdparty/assimp/include/assimp/StandardShapes.h
index 3791569b83..c594cb63f4 100644
--- a/thirdparty/assimp/include/assimp/StandardShapes.h
+++ b/thirdparty/assimp/include/assimp/StandardShapes.h
@@ -41,11 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Declares a helper class, "StandardShapes" which generates
- * vertices for standard shapes, such as cylnders, cones, spheres ..
+ * vertices for standard shapes, such as cylinders, cones, spheres ..
*/
+#pragma once
#ifndef AI_STANDARD_SHAPES_H_INC
#define AI_STANDARD_SHAPES_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/vector3.h>
#include <vector>
diff --git a/thirdparty/assimp/include/assimp/StreamReader.h b/thirdparty/assimp/include/assimp/StreamReader.h
index 9116c14261..cb24f1595b 100644
--- a/thirdparty/assimp/include/assimp/StreamReader.h
+++ b/thirdparty/assimp/include/assimp/StreamReader.h
@@ -44,15 +44,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines the StreamReader class which reads data from
* a binary stream with a well-defined endianness.
*/
-
+#pragma once
#ifndef AI_STREAMREADER_H_INCLUDED
#define AI_STREAMREADER_H_INCLUDED
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/IOStream.hpp>
#include <assimp/Defines.h>
+#include <assimp/ByteSwapper.h>
+#include <assimp/Exceptional.h>
-#include "ByteSwapper.h"
-#include "Exceptional.h"
#include <memory>
namespace Assimp {
diff --git a/thirdparty/assimp/include/assimp/StreamWriter.h b/thirdparty/assimp/include/assimp/StreamWriter.h
index c7cf6c0d74..489e8adfe3 100644
--- a/thirdparty/assimp/include/assimp/StreamWriter.h
+++ b/thirdparty/assimp/include/assimp/StreamWriter.h
@@ -43,11 +43,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Defines the StreamWriter class which writes data to
* a binary stream with a well-defined endianness. */
-
+#pragma once
#ifndef AI_STREAMWRITER_H_INCLUDED
#define AI_STREAMWRITER_H_INCLUDED
-#include "ByteSwapper.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/ByteSwapper.h>
#include <assimp/IOStream.hpp>
#include <memory>
diff --git a/thirdparty/assimp/include/assimp/StringComparison.h b/thirdparty/assimp/include/assimp/StringComparison.h
index 8acef277b9..d3ca3e9714 100644
--- a/thirdparty/assimp/include/assimp/StringComparison.h
+++ b/thirdparty/assimp/include/assimp/StringComparison.h
@@ -49,12 +49,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
These functions are not consistently available on all platforms,
or the provided implementations behave too differently.
*/
+#pragma once
#ifndef INCLUDED_AI_STRING_WORKERS_H
#define INCLUDED_AI_STRING_WORKERS_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/ai_assert.h>
#include <assimp/defs.h>
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
#include <string.h>
#include <stdint.h>
diff --git a/thirdparty/assimp/include/assimp/StringUtils.h b/thirdparty/assimp/include/assimp/StringUtils.h
index d68b7fa479..af481f819e 100644
--- a/thirdparty/assimp/include/assimp/StringUtils.h
+++ b/thirdparty/assimp/include/assimp/StringUtils.h
@@ -39,9 +39,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
+#pragma once
#ifndef INCLUDED_AI_STRINGUTILS_H
#define INCLUDED_AI_STRINGUTILS_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/defs.h>
#include <sstream>
diff --git a/thirdparty/assimp/include/assimp/Subdivision.h b/thirdparty/assimp/include/assimp/Subdivision.h
index 43feb73b30..e9450267ec 100644
--- a/thirdparty/assimp/include/assimp/Subdivision.h
+++ b/thirdparty/assimp/include/assimp/Subdivision.h
@@ -45,7 +45,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_SUBDISIVION_H_INC
#define AI_SUBDISIVION_H_INC
-#include <cstddef>
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
struct aiMesh;
diff --git a/thirdparty/assimp/include/assimp/TinyFormatter.h b/thirdparty/assimp/include/assimp/TinyFormatter.h
index 1226b482e6..6227e42c52 100644
--- a/thirdparty/assimp/include/assimp/TinyFormatter.h
+++ b/thirdparty/assimp/include/assimp/TinyFormatter.h
@@ -45,9 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* to get rid of the boost::format dependency. Much slinker,
* basically just extends stringstream.
*/
+#pragma once
#ifndef INCLUDED_TINY_FORMATTER_H
#define INCLUDED_TINY_FORMATTER_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <sstream>
namespace Assimp {
@@ -65,24 +70,15 @@ namespace Formatter {
* @endcode */
template < typename T,
typename CharTraits = std::char_traits<T>,
- typename Allocator = std::allocator<T>
->
-class basic_formatter
-{
-
-public:
-
- typedef class std::basic_string<
- T,CharTraits,Allocator
- > string;
-
- typedef class std::basic_ostringstream<
- T,CharTraits,Allocator
- > stringstream;
-
+ typename Allocator = std::allocator<T> >
+class basic_formatter {
public:
+ typedef class std::basic_string<T,CharTraits,Allocator> string;
+ typedef class std::basic_ostringstream<T,CharTraits,Allocator> stringstream;
- basic_formatter() {}
+ basic_formatter() {
+ // empty
+ }
/* Allow basic_formatter<T>'s to be used almost interchangeably
* with std::(w)string or const (w)char* arguments because the
@@ -104,14 +100,10 @@ public:
}
#endif
-
-public:
-
operator string () const {
return underlying.str();
}
-
/* note - this is declared const because binding temporaries does only
* work for const references, so many function prototypes will
* include const basic_formatter<T>& s but might still want to
diff --git a/thirdparty/assimp/include/assimp/Vertex.h b/thirdparty/assimp/include/assimp/Vertex.h
index 2a7f0256ad..5e63db5fe4 100644
--- a/thirdparty/assimp/include/assimp/Vertex.h
+++ b/thirdparty/assimp/include/assimp/Vertex.h
@@ -47,12 +47,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
that are not currently well-defined (and would cause compile errors
due to missing operators in the math library), are commented.
*/
+#pragma once
#ifndef AI_VERTEX_H_INC
#define AI_VERTEX_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/vector3.h>
#include <assimp/mesh.h>
#include <assimp/ai_assert.h>
+
#include <functional>
namespace Assimp {
@@ -91,23 +97,14 @@ namespace Assimp {
* to *all* vertex components equally. This is useful for stuff like interpolation
* or subdivision, but won't work if special handling is required for some vertex components. */
// ------------------------------------------------------------------------------------------------
-class Vertex
-{
+class Vertex {
friend Vertex operator + (const Vertex&,const Vertex&);
friend Vertex operator - (const Vertex&,const Vertex&);
-
-// friend Vertex operator + (const Vertex&,ai_real);
-// friend Vertex operator - (const Vertex&,ai_real);
friend Vertex operator * (const Vertex&,ai_real);
friend Vertex operator / (const Vertex&,ai_real);
-
-// friend Vertex operator + (ai_real, const Vertex&);
-// friend Vertex operator - (ai_real, const Vertex&);
friend Vertex operator * (ai_real, const Vertex&);
-// friend Vertex operator / (ai_real, const Vertex&);
public:
-
Vertex() {}
// ----------------------------------------------------------------------------
@@ -158,8 +155,6 @@ public:
}
}
-public:
-
Vertex& operator += (const Vertex& v) {
*this = *this+v;
return *this;
@@ -170,18 +165,6 @@ public:
return *this;
}
-
-/*
- Vertex& operator += (ai_real v) {
- *this = *this+v;
- return *this;
- }
-
- Vertex& operator -= (ai_real v) {
- *this = *this-v;
- return *this;
- }
-*/
Vertex& operator *= (ai_real v) {
*this = *this*v;
return *this;
@@ -192,12 +175,9 @@ public:
return *this;
}
-public:
-
// ----------------------------------------------------------------------------
/** Convert back to non-interleaved storage */
void SortBack(aiMesh* out, unsigned int idx) const {
-
ai_assert(idx<out->mNumVertices);
out->mVertices[idx] = position;
@@ -291,8 +271,6 @@ public:
aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
};
-
-
// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE Vertex operator + (const Vertex& v0,const Vertex& v1) {
return Vertex::BinaryOp<std::plus>(v0,v1);
@@ -302,19 +280,6 @@ AI_FORCE_INLINE Vertex operator - (const Vertex& v0,const Vertex& v1) {
return Vertex::BinaryOp<std::minus>(v0,v1);
}
-
-// ------------------------------------------------------------------------------------------------
-/*
-AI_FORCE_INLINE Vertex operator + (const Vertex& v0,ai_real f) {
- return Vertex::BinaryOp<Intern::plus>(v0,f);
-}
-
-AI_FORCE_INLINE Vertex operator - (const Vertex& v0,ai_real f) {
- return Vertex::BinaryOp<Intern::minus>(v0,f);
-}
-
-*/
-
AI_FORCE_INLINE Vertex operator * (const Vertex& v0,ai_real f) {
return Vertex::BinaryOp<Intern::multiplies>(v0,f);
}
@@ -323,26 +288,10 @@ AI_FORCE_INLINE Vertex operator / (const Vertex& v0,ai_real f) {
return Vertex::BinaryOp<Intern::multiplies>(v0,1.f/f);
}
-// ------------------------------------------------------------------------------------------------
-/*
-AI_FORCE_INLINE Vertex operator + (ai_real f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::plus>(f,v0);
-}
-
-AI_FORCE_INLINE Vertex operator - (ai_real f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::minus>(f,v0);
-}
-*/
-
AI_FORCE_INLINE Vertex operator * (ai_real f,const Vertex& v0) {
return Vertex::BinaryOp<Intern::multiplies>(f,v0);
}
-/*
-AI_FORCE_INLINE Vertex operator / (ai_real f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::divides>(f,v0);
}
-*/
-}
-#endif
+#endif // AI_VERTEX_H_INC
diff --git a/thirdparty/assimp/include/assimp/XMLTools.h b/thirdparty/assimp/include/assimp/XMLTools.h
index b0d3276873..95f12cdebf 100644
--- a/thirdparty/assimp/include/assimp/XMLTools.h
+++ b/thirdparty/assimp/include/assimp/XMLTools.h
@@ -40,9 +40,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
+#pragma once
#ifndef INCLUDED_ASSIMP_XML_TOOLS_H
#define INCLUDED_ASSIMP_XML_TOOLS_H
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <string>
namespace Assimp {
diff --git a/thirdparty/assimp/code/MMDCpp14.h b/thirdparty/assimp/include/assimp/aabb.h
index 638b0bfd2f..83bb62256b 100644
--- a/thirdparty/assimp/code/MMDCpp14.h
+++ b/thirdparty/assimp/include/assimp/aabb.h
@@ -1,15 +1,15 @@
/*
+---------------------------------------------------------------------------
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:
+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
@@ -36,48 +36,44 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
+---------------------------------------------------------------------------
*/
-#pragma once
-#ifndef MMD_CPP14_H
-#define MMD_CPP14_H
-
-#include <cstddef>
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-namespace mmd {
- template<class T> struct _Unique_if {
- typedef std::unique_ptr<T> _Single_object;
- };
-
- template<class T> struct _Unique_if<T[]> {
- typedef std::unique_ptr<T[]> _Unknown_bound;
- };
-
- template<class T, size_t N> struct _Unique_if<T[N]> {
- typedef void _Known_bound;
- };
-
- template<class T, class... Args>
- typename _Unique_if<T>::_Single_object
- make_unique(Args&&... args) {
- return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
- }
-
- template<class T>
- typename _Unique_if<T>::_Unknown_bound
- make_unique(size_t n) {
- typedef typename std::remove_extent<T>::type U;
- return std::unique_ptr<T>(new U[n]());
- }
-
- template<class T, class... Args>
- typename _Unique_if<T>::_Known_bound
- make_unique(Args&&...) = delete;
-}
+#pragma once
+#ifndef AI_AABB_H_INC
+#define AI_AABB_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
#endif
+
+#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 // __cplusplus
+
+};
+
+
+#endif // AI_AABB_H_INC
diff --git a/thirdparty/assimp/include/assimp/ai_assert.h b/thirdparty/assimp/include/assimp/ai_assert.h
index e5de5d3f36..2b32b01d3e 100644
--- a/thirdparty/assimp/include/assimp/ai_assert.h
+++ b/thirdparty/assimp/include/assimp/ai_assert.h
@@ -44,6 +44,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASSERT_H_INC
#define AI_ASSERT_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef ASSIMP_BUILD_DEBUG
# include <assert.h>
# define ai_assert(expression) assert( expression )
diff --git a/thirdparty/assimp/include/assimp/anim.h b/thirdparty/assimp/include/assimp/anim.h
index 02e92739ec..e208b11adb 100644
--- a/thirdparty/assimp/include/assimp/anim.h
+++ b/thirdparty/assimp/include/assimp/anim.h
@@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ANIM_H_INC
#define AI_ANIM_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
#include <assimp/quaternion.h>
diff --git a/thirdparty/assimp/include/assimp/camera.h b/thirdparty/assimp/include/assimp/camera.h
index 99daf69934..adb749ff59 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,
@@ -49,6 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_CAMERA_H_INC
#define AI_CAMERA_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include "types.h"
#ifdef __cplusplus
@@ -60,7 +62,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
@@ -115,7 +117,6 @@ struct aiCamera
*/
C_STRUCT aiVector3D mPosition;
-
/** 'Up' - vector of the camera coordinate system relative to
* the coordinate space defined by the corresponding node.
*
@@ -136,7 +137,6 @@ struct aiCamera
*/
C_STRUCT aiVector3D mLookAt;
-
/** Half horizontal field of view angle, in radians.
*
* The field of view angle is the angle between the center
@@ -162,7 +162,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/cexport.h b/thirdparty/assimp/include/assimp/cexport.h
index 1d62dc26b3..cbc0253d50 100644
--- a/thirdparty/assimp/include/assimp/cexport.h
+++ b/thirdparty/assimp/include/assimp/cexport.h
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2011, assimp team
+Copyright (c) 2006-2019, assimp team
All rights reserved.
@@ -46,6 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_EXPORT_H_INC
#define AI_EXPORT_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifndef ASSIMP_BUILD_NO_EXPORT
// Public ASSIMP data structures
diff --git a/thirdparty/assimp/include/assimp/cfileio.h b/thirdparty/assimp/include/assimp/cfileio.h
index 8f7ca45469..be90999d87 100644
--- a/thirdparty/assimp/include/assimp/cfileio.h
+++ b/thirdparty/assimp/include/assimp/cfileio.h
@@ -48,10 +48,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_FILEIO_H_INC
#define AI_FILEIO_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
+
#ifdef __cplusplus
extern "C" {
#endif
+
struct aiFileIO;
struct aiFile;
diff --git a/thirdparty/assimp/include/assimp/cimport.h b/thirdparty/assimp/include/assimp/cimport.h
index dbd10f1370..66b1c9a174 100644
--- a/thirdparty/assimp/include/assimp/cimport.h
+++ b/thirdparty/assimp/include/assimp/cimport.h
@@ -48,8 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASSIMP_H_INC
#define AI_ASSIMP_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/types.h>
-#include "importerdesc.h"
+#include <assimp/importerdesc.h>
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/assimp/include/assimp/color4.h b/thirdparty/assimp/include/assimp/color4.h
index 3c97c8eda2..fa86128f4f 100644
--- a/thirdparty/assimp/include/assimp/color4.h
+++ b/thirdparty/assimp/include/assimp/color4.h
@@ -47,7 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_COLOR4D_H_INC
#define AI_COLOR4D_H_INC
-#include "defs.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/defs.h>
#ifdef __cplusplus
@@ -56,8 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* alpha component. Color values range from 0 to 1. */
// ----------------------------------------------------------------------------------
template <typename TReal>
-class aiColor4t
-{
+class aiColor4t {
public:
aiColor4t() AI_NO_EXCEPT : r(), g(), b(), a() {}
aiColor4t (TReal _r, TReal _g, TReal _b, TReal _a)
@@ -65,14 +68,12 @@ public:
explicit aiColor4t (TReal _r) : r(_r), g(_r), b(_r), a(_r) {}
aiColor4t (const aiColor4t& o) = default;
-public:
// combined operators
const aiColor4t& operator += (const aiColor4t& o);
const aiColor4t& operator -= (const aiColor4t& o);
const aiColor4t& operator *= (TReal f);
const aiColor4t& operator /= (TReal f);
-public:
// comparison
bool operator == (const aiColor4t& other) const;
bool operator != (const aiColor4t& other) const;
@@ -85,8 +86,6 @@ public:
/** check whether a color is (close to) black */
inline bool IsBlack() const;
-public:
-
// Red, green, blue and alpha color values
TReal r, g, b, a;
}; // !struct aiColor4D
diff --git a/thirdparty/assimp/include/assimp/color4.inl b/thirdparty/assimp/include/assimp/color4.inl
index 3192d55f39..d4a2a98109 100644
--- a/thirdparty/assimp/include/assimp/color4.inl
+++ b/thirdparty/assimp/include/assimp/color4.inl
@@ -48,36 +48,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_COLOR4D_INL_INC
#define AI_COLOR4D_INL_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
-#include "color4.h"
+#include <assimp/color4.h>
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator += (const aiColor4t<TReal>& o) {
- r += o.r; g += o.g; b += o.b; a += o.a;
+AI_FORCE_INLINE
+const aiColor4t<TReal>& aiColor4t<TReal>::operator += (const aiColor4t<TReal>& o) {
+ r += o.r;
+ g += o.g;
+ b += o.b;
+ a += o.a;
+
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator -= (const aiColor4t<TReal>& o) {
- r -= o.r; g -= o.g; b -= o.b; a -= o.a;
+AI_FORCE_INLINE
+const aiColor4t<TReal>& aiColor4t<TReal>::operator -= (const aiColor4t<TReal>& o) {
+ r -= o.r;
+ g -= o.g;
+ b -= o.b;
+ a -= o.a;
+
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator *= (TReal f) {
- r *= f; g *= f; b *= f; a *= f;
+AI_FORCE_INLINE
+const aiColor4t<TReal>& aiColor4t<TReal>::operator *= (TReal f) {
+ r *= f;
+ g *= f;
+ b *= f;
+ a *= f;
+
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f) {
- r /= f; g /= f; b /= f; a /= f;
+AI_FORCE_INLINE
+const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f) {
+ r /= f;
+ g /= f;
+ b /= f;
+ a /= f;
+
return *this;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
+AI_FORCE_INLINE
+TReal aiColor4t<TReal>::operator[](unsigned int i) const {
switch ( i ) {
case 0:
return r;
@@ -85,6 +110,8 @@ AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
return g;
case 2:
return b;
+ case 3:
+ return a;
default:
break;
}
@@ -92,7 +119,8 @@ AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
+AI_FORCE_INLINE
+TReal& aiColor4t<TReal>::operator[](unsigned int i) {
switch ( i ) {
case 0:
return r;
@@ -100,6 +128,8 @@ AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
return g;
case 2:
return b;
+ case 3:
+ return a;
default:
break;
}
@@ -107,17 +137,20 @@ AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const {
+AI_FORCE_INLINE
+bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const {
return r == other.r && g == other.g && b == other.b && a == other.a;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other) const {
+AI_FORCE_INLINE
+bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other) const {
return r != other.r || g != other.g || b != other.b || a != other.a;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) const {
+AI_FORCE_INLINE
+bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) const {
return r < other.r || (
r == other.r && (
g < other.g || (
@@ -132,14 +165,17 @@ AI_FORCE_INLINE bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other)
)
);
}
+
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator - (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator - (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r - v2.r, v1.g - v2.g, v1.b - v2.b, v1.a - v2.a);
}
// ------------------------------------------------------------------------------------------------
@@ -149,53 +185,63 @@ AI_FORCE_INLINE aiColor4t<TReal> operator * (const aiColor4t<TReal>& v1, const a
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator / (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator / (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2) {
return aiColor4t<TReal>( v1.r / v2.r, v1.g / v2.g, v1.b / v2.b, v1.a / v2.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator * ( TReal f, const aiColor4t<TReal>& v) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator * ( TReal f, const aiColor4t<TReal>& v) {
return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator * ( const aiColor4t<TReal>& v, TReal f) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator * ( const aiColor4t<TReal>& v, TReal f) {
return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator / ( const aiColor4t<TReal>& v, TReal f) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator / ( const aiColor4t<TReal>& v, TReal f) {
return v * (1/f);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator / ( TReal f,const aiColor4t<TReal>& v) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator / ( TReal f,const aiColor4t<TReal>& v) {
return aiColor4t<TReal>(f,f,f,f)/v;
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator + ( const aiColor4t<TReal>& v, TReal f) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator + ( const aiColor4t<TReal>& v, TReal f) {
return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator - ( const aiColor4t<TReal>& v, TReal f) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator - ( const aiColor4t<TReal>& v, TReal f) {
return aiColor4t<TReal>( v.r-f, v.g-f, v.b-f, v.a-f);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator + ( TReal f, const aiColor4t<TReal>& v) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator + ( TReal f, const aiColor4t<TReal>& v) {
return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator - ( TReal f, const aiColor4t<TReal>& v) {
+AI_FORCE_INLINE
+aiColor4t<TReal> operator - ( TReal f, const aiColor4t<TReal>& v) {
return aiColor4t<TReal>( f-v.r, f-v.g, f-v.b, f-v.a);
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiColor4t<TReal> :: IsBlack() const {
+AI_FORCE_INLINE
+bool aiColor4t<TReal>::IsBlack() const {
// The alpha component doesn't care here. black is black.
static const TReal epsilon = 10e-3f;
return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon;
diff --git a/thirdparty/assimp/include/assimp/config.h.in b/thirdparty/assimp/include/assimp/config.h.in
index a37ff0b8c8..3a6379bf40 100644
--- a/thirdparty/assimp/include/assimp/config.h.in
+++ b/thirdparty/assimp/include/assimp/config.h.in
@@ -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"
@@ -980,6 +999,13 @@ enum aiComponent
# define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f
#endif // !! AI_DEBONE_THRESHOLD
+#define AI_CONFIG_APP_SCALE_KEY "APP_SCALE_FACTOR"
+
+#if (!defined AI_CONFIG_APP_SCALE_KEY)
+# define AI_CONFIG_APP_SCALE_KEY 1.0
+#endif // AI_CONFIG_APP_SCALE_KEY
+
+
// ---------- All the Build/Compile-time defines ------------
/** @brief Specifies if double precision is supported inside assimp
diff --git a/thirdparty/assimp/include/assimp/defs.h b/thirdparty/assimp/include/assimp/defs.h
index 4a177e3c3e..6f2f8ae88b 100644
--- a/thirdparty/assimp/include/assimp/defs.h
+++ b/thirdparty/assimp/include/assimp/defs.h
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -50,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_DEFINES_H_INC
#define AI_DEFINES_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/config.h>
//////////////////////////////////////////////////////////////////////////
@@ -122,19 +124,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* OPTIMIZEANIMS
* OPTIMIZEGRAPH
* GENENTITYMESHES
- * FIXTEXTUREPATHS */
+ * FIXTEXTUREPATHS
+ * GENBOUNDINGBOXES */
//////////////////////////////////////////////////////////////////////////
-#ifdef _MSC_VER
+#ifdef _WIN32
# undef ASSIMP_API
-
//////////////////////////////////////////////////////////////////////////
/* Define 'ASSIMP_BUILD_DLL_EXPORT' to build a DLL of the library */
//////////////////////////////////////////////////////////////////////////
# ifdef ASSIMP_BUILD_DLL_EXPORT
# define ASSIMP_API __declspec(dllexport)
# define ASSIMP_API_WINONLY __declspec(dllexport)
-# pragma warning (disable : 4251)
//////////////////////////////////////////////////////////////////////////
/* Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in
@@ -147,7 +148,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# define ASSIMP_API
# define ASSIMP_API_WINONLY
# endif
+#elif defined(SWIG)
+
+ /* Do nothing, the relevant defines are all in AssimpSwigPort.i */
+
+#else
+# define ASSIMP_API __attribute__ ((visibility("default")))
+# define ASSIMP_API_WINONLY
+#endif
+#ifdef _MSC_VER
+# ifdef ASSIMP_BUILD_DLL_EXPORT
+# pragma warning (disable : 4251)
+# endif
/* Force the compiler to inline a function, if possible
*/
# define AI_FORCE_INLINE __forceinline
@@ -155,17 +168,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/* Tells the compiler that a function never returns. Used in code analysis
* to skip dead paths (e.g. after an assertion evaluated to false). */
# define AI_WONT_RETURN __declspec(noreturn)
-
#elif defined(SWIG)
/* Do nothing, the relevant defines are all in AssimpSwigPort.i */
#else
-
# define AI_WONT_RETURN
-
-# define ASSIMP_API __attribute__ ((visibility("default")))
-# define ASSIMP_API_WINONLY
# define AI_FORCE_INLINE inline
#endif // (defined _MSC_VER)
@@ -214,10 +222,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 +248,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 +278,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__)
@@ -284,20 +298,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
-/* To avoid running out of memory
- * This can be adjusted for specific use cases
- * It's NOT a total limit, just a limit for individual allocations
+/**
+ * To avoid running out of memory
+ * This can be adjusted for specific use cases
+ * It's NOT a total limit, just a limit for individual allocations
*/
#define AI_MAX_ALLOC(type) ((256U * 1024 * 1024) / sizeof(type))
#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 // _MSC_VER
+
+/**
+ * Helper macro to set a pointer to NULL in debug builds
+ */
+#if (defined ASSIMP_BUILD_DEBUG)
+# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
+#else
+# define AI_DEBUG_INVALIDATE_PTR(x)
#endif
#endif // !! AI_DEFINES_H_INC
diff --git a/thirdparty/assimp/include/assimp/fast_atof.h b/thirdparty/assimp/include/assimp/fast_atof.h
index 62ea969e97..6e9a1bba7a 100644
--- a/thirdparty/assimp/include/assimp/fast_atof.h
+++ b/thirdparty/assimp/include/assimp/fast_atof.h
@@ -13,10 +13,14 @@
// to ensure long numbers are handled correctly
// ------------------------------------------------------------------------------------
-
+#pragma once
#ifndef FAST_A_TO_F_H_INCLUDED
#define FAST_A_TO_F_H_INCLUDED
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <cmath>
#include <limits>
#include <stdint.h>
diff --git a/thirdparty/assimp/include/assimp/importerdesc.h b/thirdparty/assimp/include/assimp/importerdesc.h
index 36e387f011..0a6919c1ae 100644
--- a/thirdparty/assimp/include/assimp/importerdesc.h
+++ b/thirdparty/assimp/include/assimp/importerdesc.h
@@ -48,11 +48,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IMPORTER_DESC_H_INC
#define AI_IMPORTER_DESC_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
/** Mixed set of flags for #aiImporterDesc, indicating some features
* common to many importers*/
-enum aiImporterFlags
-{
+enum aiImporterFlags {
/** Indicates that there is a textual encoding of the
* file format; and that it is supported.*/
aiImporterFlags_SupportTextFlavour = 0x1,
@@ -87,8 +90,7 @@ enum aiImporterFlags
* as importers/exporters are added to Assimp, so it might be useful
* to have a common mechanism to query some rough importer
* characteristics. */
-struct aiImporterDesc
-{
+struct aiImporterDesc {
/** Full name of the importer (i.e. Blender3D importer)*/
const char* mName;
diff --git a/thirdparty/assimp/include/assimp/irrXMLWrapper.h b/thirdparty/assimp/include/assimp/irrXMLWrapper.h
deleted file mode 100644
index ec8ee7c76e..0000000000
--- a/thirdparty/assimp/include/assimp/irrXMLWrapper.h
+++ /dev/null
@@ -1,144 +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.
-
-----------------------------------------------------------------------
-*/
-
-#ifndef INCLUDED_AI_IRRXML_WRAPPER
-#define INCLUDED_AI_IRRXML_WRAPPER
-
-// some long includes ....
-#include <irrXML.h>
-#include "IOStream.hpp"
-#include "BaseImporter.h"
-#include <vector>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------------
-/** @brief Utility class to make IrrXML work together with our custom IO system
- * See the IrrXML docs for more details.
- *
- * Construct IrrXML-Reader in BaseImporter::InternReadFile():
- * @code
- * // open the file
- * std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
- * if( file.get() == NULL) {
- * throw DeadlyImportError( "Failed to open file " + pFile + ".");
- * }
- *
- * // generate a XML reader for it
- * std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
- * mReader = irr::io::createIrrXMLReader( mIOWrapper.get());
- * if( !mReader) {
- * ThrowException( "xxxx: Unable to open file.");
- * }
- * @endcode
- **/
-class CIrrXML_IOStreamReader : public irr::io::IFileReadCallBack {
-public:
-
- // ----------------------------------------------------------------------------------
- //! Construction from an existing IOStream
- explicit CIrrXML_IOStreamReader(IOStream* _stream)
- : stream (_stream)
- , t (0)
- {
-
- // Map the buffer into memory and convert it to UTF8. IrrXML provides its
- // own conversion, which is merely a cast from uintNN_t to uint8_t. Thus,
- // it is not suitable for our purposes and we have to do it BEFORE IrrXML
- // gets the buffer. Sadly, this forces us to map the whole file into
- // memory.
-
- data.resize(stream->FileSize());
- stream->Read(&data[0],data.size(),1);
-
- // Remove null characters from the input sequence otherwise the parsing will utterly fail
- unsigned int size = 0;
- unsigned int size_max = static_cast<unsigned int>(data.size());
- for(unsigned int i = 0; i < size_max; i++) {
- if(data[i] != '\0') {
- data[size++] = data[i];
- }
- }
- data.resize(size);
-
- BaseImporter::ConvertToUTF8(data);
- }
-
- // ----------------------------------------------------------------------------------
- //! Virtual destructor
- virtual ~CIrrXML_IOStreamReader() {}
-
- // ----------------------------------------------------------------------------------
- //! Reads an amount of bytes from the file.
- /** @param buffer: Pointer to output buffer.
- * @param sizeToRead: Amount of bytes to read
- * @return Returns how much bytes were read. */
- virtual int read(void* buffer, int sizeToRead) {
- if(sizeToRead<0) {
- return 0;
- }
- if(t+sizeToRead>data.size()) {
- sizeToRead = static_cast<int>(data.size()-t);
- }
-
- memcpy(buffer,&data.front()+t,sizeToRead);
-
- t += sizeToRead;
- return sizeToRead;
- }
-
- // ----------------------------------------------------------------------------------
- //! Returns size of file in bytes
- virtual int getSize() {
- return (int)data.size();
- }
-
-private:
- IOStream* stream;
- std::vector<char> data;
- size_t t;
-
-}; // ! class CIrrXML_IOStreamReader
-
-} // ! Assimp
-
-#endif // !! INCLUDED_AI_IRRXML_WRAPPER
diff --git a/thirdparty/assimp/include/assimp/light.h b/thirdparty/assimp/include/assimp/light.h
index 1667cfb8c1..bdb2368c4f 100644
--- a/thirdparty/assimp/include/assimp/light.h
+++ b/thirdparty/assimp/include/assimp/light.h
@@ -49,7 +49,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_LIGHT_H_INC
#define AI_LIGHT_H_INC
-#include "types.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/assimp/include/assimp/material.h b/thirdparty/assimp/include/assimp/material.h
index b882bbc72c..19a7c69709 100644
--- a/thirdparty/assimp/include/assimp/material.h
+++ b/thirdparty/assimp/include/assimp/material.h
@@ -48,7 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATERIAL_H_INC
#define AI_MATERIAL_H_INC
-#include "types.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
#ifdef __cplusplus
extern "C" {
@@ -196,34 +200,40 @@ enum aiTextureType
* (#aiMaterialProperty::mSemantic) for all material properties
* *not* related to textures.
*/
- aiTextureType_NONE = 0x0,
+ aiTextureType_NONE = 0,
+
+ /** LEGACY API MATERIALS
+ * Legacy refers to materials which
+ * Were originally implemented in the specifications around 2000.
+ * These must never be removed, as most engines support them.
+ */
/** The texture is combined with the result of the diffuse
* lighting equation.
*/
- aiTextureType_DIFFUSE = 0x1,
+ aiTextureType_DIFFUSE = 1,
/** The texture is combined with the result of the specular
* lighting equation.
*/
- aiTextureType_SPECULAR = 0x2,
+ aiTextureType_SPECULAR = 2,
/** The texture is combined with the result of the ambient
* lighting equation.
*/
- aiTextureType_AMBIENT = 0x3,
+ aiTextureType_AMBIENT = 3,
/** The texture is added to the result of the lighting
* calculation. It isn't influenced by incoming light.
*/
- aiTextureType_EMISSIVE = 0x4,
+ aiTextureType_EMISSIVE = 4,
/** The texture is a height map.
*
* By convention, higher gray-scale values stand for
* higher elevations from the base height.
*/
- aiTextureType_HEIGHT = 0x5,
+ aiTextureType_HEIGHT = 5,
/** The texture is a (tangent space) normal-map.
*
@@ -231,7 +241,7 @@ enum aiTextureType
* normal maps. Assimp does (intentionally) not
* distinguish here.
*/
- aiTextureType_NORMALS = 0x6,
+ aiTextureType_NORMALS = 6,
/** The texture defines the glossiness of the material.
*
@@ -240,21 +250,21 @@ enum aiTextureType
* function defined to map the linear color values in the
* texture to a suitable exponent. Have fun.
*/
- aiTextureType_SHININESS = 0x7,
+ aiTextureType_SHININESS = 7,
/** The texture defines per-pixel opacity.
*
* Usually 'white' means opaque and 'black' means
* 'transparency'. Or quite the opposite. Have fun.
*/
- aiTextureType_OPACITY = 0x8,
+ aiTextureType_OPACITY = 8,
/** Displacement texture
*
* The exact purpose and format is application-dependent.
* Higher color values stand for higher vertex displacements.
*/
- aiTextureType_DISPLACEMENT = 0x9,
+ aiTextureType_DISPLACEMENT = 9,
/** Lightmap texture (aka Ambient Occlusion)
*
@@ -263,14 +273,28 @@ enum aiTextureType
* scaling value for the final color value of a pixel. Its
* intensity is not affected by incoming light.
*/
- aiTextureType_LIGHTMAP = 0xA,
+ aiTextureType_LIGHTMAP = 10,
/** Reflection texture
*
* Contains the color of a perfect mirror reflection.
* Rarely used, almost never for real-time applications.
*/
- aiTextureType_REFLECTION = 0xB,
+ aiTextureType_REFLECTION = 11,
+
+ /** PBR Materials
+ * PBR definitions from maya and other modelling packages now use this standard.
+ * This was originally introduced around 2012.
+ * Support for this is in game engines like Godot, Unreal or Unity3D.
+ * Modelling packages which use this are very common now.
+ */
+
+ aiTextureType_BASE_COLOR = 12,
+ aiTextureType_NORMAL_CAMERA = 13,
+ aiTextureType_EMISSION_COLOR = 14,
+ aiTextureType_METALNESS = 15,
+ aiTextureType_DIFFUSE_ROUGHNESS = 16,
+ aiTextureType_AMBIENT_OCCLUSION = 17,
/** Unknown texture
*
@@ -278,7 +302,7 @@ enum aiTextureType
* above is considered to be 'unknown'. It is still imported,
* but is excluded from any further post-processing.
*/
- aiTextureType_UNKNOWN = 0xC,
+ aiTextureType_UNKNOWN = 18,
#ifndef SWIG
@@ -900,6 +924,7 @@ extern "C" {
#define AI_MATKEY_ENABLE_WIREFRAME "$mat.wireframe",0,0
#define AI_MATKEY_BLEND_FUNC "$mat.blend",0,0
#define AI_MATKEY_OPACITY "$mat.opacity",0,0
+#define AI_MATKEY_TRANSPARENCYFACTOR "$mat.transparencyfactor",0,0
#define AI_MATKEY_BUMPSCALING "$mat.bumpscaling",0,0
#define AI_MATKEY_SHININESS "$mat.shininess",0,0
#define AI_MATKEY_REFLECTIVITY "$mat.reflectivity",0,0
diff --git a/thirdparty/assimp/include/assimp/material.inl b/thirdparty/assimp/include/assimp/material.inl
index b05d6af6c3..8ae6b88d3e 100644
--- a/thirdparty/assimp/include/assimp/material.inl
+++ b/thirdparty/assimp/include/assimp/material.inl
@@ -49,14 +49,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATERIAL_INL_INC
#define AI_MATERIAL_INL_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
// ---------------------------------------------------------------------------
-inline aiPropertyTypeInfo ai_real_to_property_type_info(float)
-{
+AI_FORCE_INLINE
+aiPropertyTypeInfo ai_real_to_property_type_info(float) {
return aiPTI_Float;
}
-inline aiPropertyTypeInfo ai_real_to_property_type_info(double)
-{
+AI_FORCE_INLINE
+aiPropertyTypeInfo ai_real_to_property_type_info(double) {
return aiPTI_Double;
}
// ---------------------------------------------------------------------------
@@ -64,30 +68,30 @@ inline aiPropertyTypeInfo ai_real_to_property_type_info(double)
//! @cond never
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::GetTexture( aiTextureType type,
- unsigned int index,
- C_STRUCT aiString* path,
- aiTextureMapping* mapping /*= NULL*/,
- unsigned int* uvindex /*= NULL*/,
- ai_real* blend /*= NULL*/,
- aiTextureOp* op /*= NULL*/,
- aiTextureMapMode* mapmode /*= NULL*/) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::GetTexture( aiTextureType type,
+ unsigned int index,
+ C_STRUCT aiString* path,
+ aiTextureMapping* mapping /*= NULL*/,
+ unsigned int* uvindex /*= NULL*/,
+ ai_real* blend /*= NULL*/,
+ aiTextureOp* op /*= NULL*/,
+ aiTextureMapMode* mapmode /*= NULL*/) const {
return ::aiGetMaterialTexture(this,type,index,path,mapping,uvindex,blend,op,mapmode);
}
// ---------------------------------------------------------------------------
-inline unsigned int aiMaterial::GetTextureCount(aiTextureType type) const
-{
+AI_FORCE_INLINE
+unsigned int aiMaterial::GetTextureCount(aiTextureType type) const {
return ::aiGetMaterialTextureCount(this,type);
}
// ---------------------------------------------------------------------------
template <typename Type>
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx, Type* pOut,
- unsigned int* pMax) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx, Type* pOut,
+ unsigned int* pMax) const {
unsigned int iNum = pMax ? *pMax : 1;
const aiMaterialProperty* prop;
@@ -114,9 +118,9 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
// ---------------------------------------------------------------------------
template <typename Type>
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,Type& pOut) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,Type& pOut) const {
const aiMaterialProperty* prop;
const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,
(const aiMaterialProperty**)&prop);
@@ -136,60 +140,56 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,ai_real* pOut,
- unsigned int* pMax) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,ai_real* pOut,
+ unsigned int* pMax) const {
return ::aiGetMaterialFloatArray(this,pKey,type,idx,pOut,pMax);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,int* pOut,
- unsigned int* pMax) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,int* pOut,
+ unsigned int* pMax) const {
return ::aiGetMaterialIntegerArray(this,pKey,type,idx,pOut,pMax);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,ai_real& pOut) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,ai_real& pOut) const {
return aiGetMaterialFloat(this,pKey,type,idx,&pOut);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,int& pOut) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,int& pOut) const {
return aiGetMaterialInteger(this,pKey,type,idx,&pOut);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,aiColor4D& pOut) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,aiColor4D& pOut) const {
return aiGetMaterialColor(this,pKey,type,idx,&pOut);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,aiColor3D& pOut) const
-{
+AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,aiColor3D& pOut) const {
aiColor4D c;
const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c);
pOut = aiColor3D(c.r,c.g,c.b);
return ret;
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,aiString& pOut) const
-{
+AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,aiString& pOut) const {
return aiGetMaterialString(this,pKey,type,idx,&pOut);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,aiUVTransform& pOut) const
-{
+AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+ unsigned int idx,aiUVTransform& pOut) const {
return aiGetMaterialUVTransform(this,pKey,type,idx,&pOut);
}
-
// ---------------------------------------------------------------------------
template<class TYPE>
aiReturn aiMaterial::AddProperty (const TYPE* pInput,
@@ -204,84 +204,83 @@ aiReturn aiMaterial::AddProperty (const TYPE* pInput,
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const float* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE aiReturn aiMaterial::AddProperty(const float* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(float),
pKey,type,index,aiPTI_Float);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const double* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const double* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(double),
pKey,type,index,aiPTI_Double);
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiUVTransform),
pKey,type,index,ai_real_to_property_type_info(pInput->mRotation));
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiColor4D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const aiColor4D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor4D),
pKey,type,index,ai_real_to_property_type_info(pInput->a));
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiColor3D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const aiColor3D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor3D),
pKey,type,index,ai_real_to_property_type_info(pInput->b));
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiVector3D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const aiVector3D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiVector3D),
pKey,type,index,ai_real_to_property_type_info(pInput->x));
}
// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const int* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const int* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(int),
pKey,type,index,aiPTI_Integer);
@@ -296,12 +295,12 @@ inline aiReturn aiMaterial::AddProperty(const int* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<float>(const float* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<float>(const float* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(float),
pKey,type,index,aiPTI_Float);
@@ -309,12 +308,12 @@ inline aiReturn aiMaterial::AddProperty<float>(const float* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<double>(const double* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<double>(const double* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(double),
pKey,type,index,aiPTI_Double);
@@ -322,12 +321,12 @@ inline aiReturn aiMaterial::AddProperty<double>(const double* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiUVTransform),
pKey,type,index,aiPTI_Float);
@@ -335,12 +334,12 @@ inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInp
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor4D),
pKey,type,index,aiPTI_Float);
@@ -348,12 +347,12 @@ inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiColor3D),
pKey,type,index,aiPTI_Float);
@@ -361,12 +360,12 @@ inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(aiVector3D),
pKey,type,index,aiPTI_Float);
@@ -374,12 +373,12 @@ inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput,
// ---------------------------------------------------------------------------
template<>
-inline aiReturn aiMaterial::AddProperty<int>(const int* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<int>(const int* pInput,
+ const unsigned int pNumValues,
+ const char* pKey,
+ unsigned int type,
+ unsigned int index) {
return AddBinaryProperty((const void*)pInput,
pNumValues * sizeof(int),
pKey,type,index,aiPTI_Integer);
diff --git a/thirdparty/assimp/include/assimp/matrix3x3.h b/thirdparty/assimp/include/assimp/matrix3x3.h
index 22b69561ff..2c26cf92bb 100644
--- a/thirdparty/assimp/include/assimp/matrix3x3.h
+++ b/thirdparty/assimp/include/assimp/matrix3x3.h
@@ -48,7 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATRIX3X3_H_INC
#define AI_MATRIX3X3_H_INC
-#include "defs.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/defs.h>
#ifdef __cplusplus
@@ -65,10 +69,8 @@ template <typename T> class aiVector2t;
* defined thereby.
*/
template <typename TReal>
-class aiMatrix3x3t
-{
+class aiMatrix3x3t {
public:
-
aiMatrix3x3t() AI_NO_EXCEPT :
a1(static_cast<TReal>(1.0f)), a2(), a3(),
b1(), b2(static_cast<TReal>(1.0f)), b3(),
@@ -82,8 +84,6 @@ public:
c1(_c1), c2(_c2), c3(_c3)
{}
-public:
-
// matrix multiplication.
aiMatrix3x3t& operator *= (const aiMatrix3x3t& m);
aiMatrix3x3t operator * (const aiMatrix3x3t& m) const;
@@ -101,8 +101,6 @@ public:
template <typename TOther>
operator aiMatrix3x3t<TOther> () const;
-public:
-
// -------------------------------------------------------------------
/** @brief Construction from a 4x4 matrix. The remaining parts
* of the matrix are ignored.
@@ -122,7 +120,6 @@ public:
aiMatrix3x3t& Inverse();
TReal Determinant() const;
-public:
// -------------------------------------------------------------------
/** @brief Returns a rotation matrix for a rotation around z
* @param a Rotation angle, in radians
diff --git a/thirdparty/assimp/include/assimp/matrix3x3.inl b/thirdparty/assimp/include/assimp/matrix3x3.inl
index d9d45a3e92..1ce8c9691c 100644
--- a/thirdparty/assimp/include/assimp/matrix3x3.inl
+++ b/thirdparty/assimp/include/assimp/matrix3x3.inl
@@ -48,10 +48,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATRIX3X3_INL_INC
#define AI_MATRIX3X3_INL_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
-#include "matrix3x3.h"
+#include <assimp/matrix3x3.h>
+#include <assimp/matrix4x4.h>
-#include "matrix4x4.h"
#include <algorithm>
#include <cmath>
#include <limits>
@@ -59,8 +63,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ------------------------------------------------------------------------------------------------
// Construction from a 4x4 matrix. The remaining parts of the matrix are ignored.
template <typename TReal>
-inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix) {
a1 = pMatrix.a1; a2 = pMatrix.a2; a3 = pMatrix.a3;
b1 = pMatrix.b1; b2 = pMatrix.b2; b3 = pMatrix.b3;
c1 = pMatrix.c1; c2 = pMatrix.c2; c3 = pMatrix.c3;
@@ -68,8 +72,8 @@ inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m) {
*this = aiMatrix3x3t<TReal>(m.a1 * a1 + m.b1 * a2 + m.c1 * a3,
m.a2 * a1 + m.b2 * a2 + m.c2 * a3,
m.a3 * a1 + m.b3 * a2 + m.c3 * a3,
@@ -85,8 +89,7 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t
// ------------------------------------------------------------------------------------------------
template <typename TReal>
template <typename TOther>
-aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
-{
+aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const {
return aiMatrix3x3t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),
static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),
static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3));
@@ -94,8 +97,8 @@ aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const {
aiMatrix3x3t<TReal> temp( *this);
temp *= m;
return temp;
@@ -103,7 +106,8 @@ inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TR
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
+AI_FORCE_INLINE
+TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
switch ( p_iIndex ) {
case 0:
return &a1;
@@ -119,7 +123,8 @@ inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const {
+AI_FORCE_INLINE
+const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const {
switch ( p_iIndex ) {
case 0:
return &a1;
@@ -135,8 +140,8 @@ inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) cons
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const {
return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 &&
b1 == m.b1 && b2 == m.b2 && b3 == m.b3 &&
c1 == m.c1 && c2 == m.c2 && c3 == m.c3;
@@ -144,14 +149,15 @@ inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const {
return !(*this == m);
}
// ---------------------------------------------------------------------------
template<typename TReal>
-inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
+AI_FORCE_INLINE
+bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
return
std::abs(a1 - m.a1) <= epsilon &&
std::abs(a2 - m.a2) <= epsilon &&
@@ -166,8 +172,8 @@ inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsil
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose() {
// (TReal&) don't remove, GCC complains cause of packed fields
std::swap( (TReal&)a2, (TReal&)b1);
std::swap( (TReal&)a3, (TReal&)c1);
@@ -177,15 +183,15 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline TReal aiMatrix3x3t<TReal>::Determinant() const
-{
+AI_FORCE_INLINE
+TReal aiMatrix3x3t<TReal>::Determinant() const {
return a1*b2*c3 - a1*b3*c2 + a2*b3*c1 - a2*b1*c3 + a3*b1*c2 - a3*b2*c1;
}
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse()
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse() {
// Compute the reciprocal determinant
TReal det = Determinant();
if(det == static_cast<TReal>(0.0))
@@ -219,8 +225,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse()
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out) {
out.a1 = out.b2 = std::cos(a);
out.b1 = std::sin(a);
out.a2 = - out.b1;
@@ -234,8 +240,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t
// ------------------------------------------------------------------------------------------------
// Returns a rotation matrix for a rotation around an arbitrary axis.
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out) {
TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
TReal x = axis.x, y = axis.y, z = axis.z;
@@ -249,8 +255,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVect
// ------------------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out) {
out = aiMatrix3x3t<TReal>();
out.a3 = v.x;
out.b3 = v.y;
@@ -268,9 +274,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<T
*/
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
- const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx)
-{
+AI_FORCE_INLINE aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
+ const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx) {
const TReal e = from * to;
const TReal f = (e < 0)? -e:e;
@@ -352,6 +357,5 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<T
return mtx;
}
-
#endif // __cplusplus
#endif // AI_MATRIX3X3_INL_INC
diff --git a/thirdparty/assimp/include/assimp/matrix4x4.h b/thirdparty/assimp/include/assimp/matrix4x4.h
index 046bb535f2..8fc216f669 100644
--- a/thirdparty/assimp/include/assimp/matrix4x4.h
+++ b/thirdparty/assimp/include/assimp/matrix4x4.h
@@ -47,8 +47,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_MATRIX4X4_H_INC
#define AI_MATRIX4X4_H_INC
-#include "vector3.h"
-#include "defs.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/vector3.h>
+#include <assimp/defs.h>
#ifdef __cplusplus
@@ -66,8 +70,7 @@ template<typename TReal> class aiQuaterniont;
* defined thereby.
*/
template<typename TReal>
-class aiMatrix4x4t
-{
+class aiMatrix4x4t {
public:
/** set to identity */
@@ -91,8 +94,6 @@ public:
aiMatrix4x4t(const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation,
const aiVector3t<TReal>& position);
-public:
-
// array access operators
/** @fn TReal* operator[] (unsigned int p_iIndex)
* @param [in] p_iIndex - index of the row.
@@ -120,8 +121,6 @@ public:
template <typename TOther>
operator aiMatrix4x4t<TOther> () const;
-public:
-
// -------------------------------------------------------------------
/** @brief Transpose the matrix */
aiMatrix4x4t& Transpose();
@@ -182,7 +181,6 @@ public:
void DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
aiVector3t<TReal>& position) const;
-
// -------------------------------------------------------------------
/** @brief Creates a trafo matrix from a set of euler angles
* @param x Rotation angle for the x-axis, in radians
@@ -192,7 +190,6 @@ public:
aiMatrix4x4t& FromEulerAnglesXYZ(TReal x, TReal y, TReal z);
aiMatrix4x4t& FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb);
-public:
// -------------------------------------------------------------------
/** @brief Returns a rotation matrix for a rotation around the x axis
* @param a Rotation angle, in radians
@@ -256,7 +253,6 @@ public:
static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from,
const aiVector3t<TReal>& to, aiMatrix4x4t& out);
-public:
TReal a1, a2, a3, a4;
TReal b1, b2, b3, b4;
TReal c1, c2, c3, c4;
diff --git a/thirdparty/assimp/include/assimp/matrix4x4.inl b/thirdparty/assimp/include/assimp/matrix4x4.inl
index ebc67a06ec..84079974f7 100644
--- a/thirdparty/assimp/include/assimp/matrix4x4.inl
+++ b/thirdparty/assimp/include/assimp/matrix4x4.inl
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -53,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "matrix4x4.h"
#include "matrix3x3.h"
#include "quaternion.h"
+#include "MathFunctions.h"
#include <algorithm>
#include <limits>
@@ -61,12 +60,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ----------------------------------------------------------------------------------------
template <typename TReal>
aiMatrix4x4t<TReal>::aiMatrix4x4t() AI_NO_EXCEPT :
- a1(1.0f), a2(), a3(), a4(),
- b1(), b2(1.0f), b3(), b4(),
- c1(), c2(), c3(1.0f), c4(),
- d1(), d2(), d3(), d4(1.0f)
-{
-
+ a1(1.0f), a2(), a3(), a4(),
+ b1(), b2(1.0f), b3(), b4(),
+ c1(), c2(), c3(1.0f), c4(),
+ d1(), d2(), d3(), d4(1.0f) {
+ // empty
}
// ----------------------------------------------------------------------------------------
@@ -75,19 +73,17 @@ aiMatrix4x4t<TReal>::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4,
TReal _b1, TReal _b2, TReal _b3, TReal _b4,
TReal _c1, TReal _c2, TReal _c3, TReal _c4,
TReal _d1, TReal _d2, TReal _d3, TReal _d4) :
- a1(_a1), a2(_a2), a3(_a3), a4(_a4),
- b1(_b1), b2(_b2), b3(_b3), b4(_b4),
- c1(_c1), c2(_c2), c3(_c3), c4(_c4),
- d1(_d1), d2(_d2), d3(_d3), d4(_d4)
-{
-
+ a1(_a1), a2(_a2), a3(_a3), a4(_a4),
+ b1(_b1), b2(_b2), b3(_b3), b4(_b4),
+ c1(_c1), c2(_c2), c3(_c3), c4(_c4),
+ d1(_d1), d2(_d2), d3(_d3), d4(_d4) {
+ // empty
}
// ------------------------------------------------------------------------------------------------
template <typename TReal>
template <typename TOther>
-aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
-{
+aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const {
return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4),
static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4),
static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4),
@@ -97,8 +93,8 @@ aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m) {
a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0);
b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0);
c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0);
@@ -107,8 +103,8 @@ inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position) {
// build a 3x3 rotation matrix
aiMatrix3x3t<TReal> m = rotation.GetMatrix();
@@ -135,8 +131,8 @@ inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, cons
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m) {
*this = aiMatrix4x4t<TReal>(
m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4,
m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4,
@@ -159,8 +155,7 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const
-{
+AI_FORCE_INLINE aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const {
aiMatrix4x4t<TReal> temp(
a1 * aFloat,
a2 * aFloat,
@@ -183,8 +178,8 @@ inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat)
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const {
aiMatrix4x4t<TReal> temp(
m.a1 + a1,
m.a2 + a2,
@@ -207,18 +202,16 @@ inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TR
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const {
aiMatrix4x4t<TReal> temp( *this);
temp *= m;
return temp;
}
-
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
-{
+AI_FORCE_INLINE aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose() {
// (TReal&) don't remove, GCC complains cause of packed fields
std::swap( (TReal&)b1, (TReal&)a2);
std::swap( (TReal&)c1, (TReal&)a3);
@@ -229,11 +222,10 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
return *this;
}
-
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline TReal aiMatrix4x4t<TReal>::Determinant() const
-{
+AI_FORCE_INLINE
+TReal aiMatrix4x4t<TReal>::Determinant() const {
return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4
+ a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4
- a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3
@@ -244,8 +236,8 @@ inline TReal aiMatrix4x4t<TReal>::Determinant() const
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() {
// Compute the reciprocal determinant
const TReal det = Determinant();
if(det == static_cast<TReal>(0.0))
@@ -289,9 +281,10 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
+AI_FORCE_INLINE
+TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
if (p_iIndex > 3) {
- return NULL;
+ return nullptr;
}
switch ( p_iIndex ) {
case 0:
@@ -310,9 +303,10 @@ inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const {
+AI_FORCE_INLINE
+const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const {
if (p_iIndex > 3) {
- return NULL;
+ return nullptr;
}
switch ( p_iIndex ) {
@@ -332,8 +326,8 @@ inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const {
return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 &&
@@ -342,14 +336,15 @@ inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const {
return !(*this == m);
}
// ---------------------------------------------------------------------------
template<typename TReal>
-inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
+AI_FORCE_INLINE
+bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
return
std::abs(a1 - m.a1) <= epsilon &&
std::abs(a2 - m.a2) <= epsilon &&
@@ -401,13 +396,10 @@ inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsil
\
do {} while(false)
-
-
-
template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation,
- aiVector3t<TReal>& pPosition) const
-{
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation,
+ aiVector3t<TReal>& pPosition) const {
ASSIMP_MATRIX4_4_DECOMPOSE_PART;
// build a 3x3 rotation matrix
@@ -420,8 +412,8 @@ inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuate
}
template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const
-{
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const {
ASSIMP_MATRIX4_4_DECOMPOSE_PART;
/*
@@ -442,7 +434,7 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
*/
// Use a small epsilon to solve floating-point inaccuracies
- const TReal epsilon = 10e-3f;
+ const TReal epsilon = Assimp::Math::getEpsilon<TReal>();
pRotation.y = std::asin(-vCols[0].z);// D. Angle around oY.
@@ -475,10 +467,10 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
#undef ASSIMP_MATRIX4_4_DECOMPOSE_PART
template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle,
- aiVector3t<TReal>& pPosition) const
-{
-aiQuaterniont<TReal> pRotation;
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle,
+ aiVector3t<TReal>& pPosition) const {
+ aiQuaterniont<TReal> pRotation;
Decompose(pScaling, pRotation, pPosition);
pRotation.Normalize();
@@ -500,9 +492,9 @@ aiQuaterniont<TReal> pRotation;
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
- aiVector3t<TReal>& position) const
-{
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
+ aiVector3t<TReal>& position) const {
const aiMatrix4x4t<TReal>& _this = *this;
// extract translation
@@ -516,15 +508,15 @@ inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotat
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb) {
return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z);
}
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z) {
aiMatrix4x4t<TReal>& _this = *this;
TReal cx = std::cos(x);
@@ -552,8 +544,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TRe
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::IsIdentity() const
-{
+AI_FORCE_INLINE
+bool aiMatrix4x4t<TReal>::IsIdentity() const {
// Use a small epsilon to solve floating-point inaccuracies
const static TReal epsilon = 10e-3f;
@@ -577,8 +569,8 @@ inline bool aiMatrix4x4t<TReal>::IsIdentity() const
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out) {
/*
| 1 0 0 0 |
M = | 0 cos(A) -sin(A) 0 |
@@ -592,8 +584,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out) {
/*
| cos(A) 0 sin(A) 0 |
M = | 0 1 0 0 |
@@ -608,8 +600,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out) {
/*
| cos(A) -sin(A) 0 0 |
M = | sin(A) cos(A) 0 0 |
@@ -624,26 +616,25 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t
// ----------------------------------------------------------------------------------------
// Returns a rotation matrix for a rotation around an arbitrary axis.
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out)
-{
- TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
- TReal x = axis.x, y = axis.y, z = axis.z;
-
- // Many thanks to MathWorld and Wikipedia
- out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
- out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x;
- out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
- out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
- out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
- out.d4 = static_cast<TReal>(1.0);
-
- return out;
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out) {
+ TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
+ TReal x = axis.x, y = axis.y, z = axis.z;
+
+ // Many thanks to MathWorld and Wikipedia
+ out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
+ out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x;
+ out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
+ out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
+ out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
+ out.d4 = static_cast<TReal>(1.0);
+
+ return out;
}
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) {
out = aiMatrix4x4t<TReal>();
out.a4 = v.x;
out.b4 = v.y;
@@ -653,8 +644,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<T
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) {
out = aiMatrix4x4t<TReal>();
out.a1 = v.x;
out.b2 = v.y;
@@ -673,9 +664,9 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal
*/
// ----------------------------------------------------------------------------------------
template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
- const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
+ const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx) {
aiMatrix3x3t<TReal> m3;
aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3);
mtx = aiMatrix4x4t<TReal>(m3);
diff --git a/thirdparty/assimp/include/assimp/mesh.h b/thirdparty/assimp/include/assimp/mesh.h
index 36f3ed2afd..fbf2a857ad 100644
--- a/thirdparty/assimp/include/assimp/mesh.h
+++ b/thirdparty/assimp/include/assimp/mesh.h
@@ -48,7 +48,12 @@ 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"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
+#include <assimp/aabb.h>
#ifdef __cplusplus
extern "C" {
@@ -247,6 +252,9 @@ struct aiVertexWeight {
};
+// Forward declare aiNode (pointer use only)
+struct aiNode;
+
// ---------------------------------------------------------------------------
/** @brief A single bone of a mesh.
*
@@ -263,6 +271,16 @@ struct aiBone {
//! The maximum value for this member is #AI_MAX_BONE_WEIGHTS.
unsigned int mNumWeights;
+#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
+ // The bone armature node - used for skeleton conversion
+ // you must enable aiProcess_PopulateArmatureData to populate this
+ C_STRUCT aiNode* mArmature;
+
+ // The bone node in the scene - used for skeleton conversion
+ // you must enable aiProcess_PopulateArmatureData to populate this
+ C_STRUCT aiNode* mNode;
+
+#endif
//! The influence weights of this bone, by vertex index.
C_STRUCT aiVertexWeight* mWeights;
@@ -417,11 +435,11 @@ struct aiAnimMesh
/**Anim Mesh name */
C_STRUCT aiString mName;
- /** Replacement for aiMesh::mVertices. If this array is non-NULL,
+ /** Replacement for aiMesh::mVertices. If this array is non-nullptr,
* it *must* contain mNumVertices entries. The corresponding
- * array in the host mesh must be non-NULL as well - animation
+ * array in the host mesh must be non-nullptr as well - animation
* meshes may neither add or nor remove vertex components (if
- * a replacement array is NULL and the corresponding source
+ * a replacement array is nullptr and the corresponding source
* array is not, the source data is taken instead)*/
C_STRUCT aiVector3D* mVertices;
@@ -595,7 +613,7 @@ struct aiMesh
C_STRUCT aiVector3D* mVertices;
/** Vertex normals.
- * The array contains normalized vectors, NULL if not present.
+ * The array contains normalized vectors, nullptr if not present.
* The array is mNumVertices in size. Normals are undefined for
* point and line primitives. A mesh consisting of points and
* lines only may not have normal vectors. Meshes with mixed
@@ -618,7 +636,7 @@ struct aiMesh
/** Vertex tangents.
* The tangent of a vertex points in the direction of the positive
- * X texture axis. The array contains normalized vectors, NULL if
+ * X texture axis. The array contains normalized vectors, nullptr if
* not present. The array is mNumVertices in size. A mesh consisting
* of points and lines only may not have normal vectors. Meshes with
* mixed primitive types (i.e. lines and triangles) may have
@@ -632,7 +650,7 @@ struct aiMesh
/** Vertex bitangents.
* The bitangent of a vertex points in the direction of the positive
- * Y texture axis. The array contains normalized vectors, NULL if not
+ * Y texture axis. The array contains normalized vectors, nullptr if not
* present. The array is mNumVertices in size.
* @note If the mesh contains tangents, it automatically also contains
* bitangents.
@@ -641,14 +659,14 @@ struct aiMesh
/** Vertex color sets.
* A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex
- * colors per vertex. NULL if not present. Each array is
+ * colors per vertex. nullptr if not present. Each array is
* mNumVertices in size if present.
*/
C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
/** Vertex texture coords, also known as UV channels.
* A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per
- * vertex. NULL if not present. The array is mNumVertices in size.
+ * vertex. nullptr if not present. The array is mNumVertices in size.
*/
C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
@@ -670,7 +688,7 @@ struct aiMesh
C_STRUCT aiFace* mFaces;
/** The number of bones this mesh contains.
- * Can be 0, in which case the mBones array is NULL.
+ * Can be 0, in which case the mBones array is nullptr.
*/
unsigned int mNumBones;
@@ -714,6 +732,11 @@ struct aiMesh
* Method of morphing when animeshes are specified.
*/
unsigned int mMethod;
+
+ /**
+ *
+ */
+ C_STRUCT aiAABB mAABB;
#ifdef __cplusplus
@@ -735,7 +758,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;
@@ -762,7 +786,10 @@ struct aiMesh
// DO NOT REMOVE THIS ADDITIONAL CHECK
if (mNumBones && mBones) {
for( unsigned int a = 0; a < mNumBones; a++) {
- delete mBones[a];
+ if(mBones[a])
+ {
+ delete mBones[a];
+ }
}
delete [] mBones;
}
diff --git a/thirdparty/assimp/include/assimp/metadata.h b/thirdparty/assimp/include/assimp/metadata.h
index 3a1dd1442a..849d90f485 100644
--- a/thirdparty/assimp/include/assimp/metadata.h
+++ b/thirdparty/assimp/include/assimp/metadata.h
@@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_METADATA_H_INC
#define AI_METADATA_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#if defined(_MSC_VER) && (_MSC_VER <= 1500)
# include "Compiler/pstdint.h"
#else
diff --git a/thirdparty/assimp/include/assimp/pbrmaterial.h b/thirdparty/assimp/include/assimp/pbrmaterial.h
index ce5f822173..892a6347f7 100644
--- a/thirdparty/assimp/include/assimp/pbrmaterial.h
+++ b/thirdparty/assimp/include/assimp/pbrmaterial.h
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -44,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file pbrmaterial.h
* @brief Defines the material system of the library
*/
+#pragma once
#ifndef AI_PBRMATERIAL_H_INC
#define AI_PBRMATERIAL_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0
diff --git a/thirdparty/assimp/include/assimp/postprocess.h b/thirdparty/assimp/include/assimp/postprocess.h
index c23a5490a5..4b6732e80a 100644
--- a/thirdparty/assimp/include/assimp/postprocess.h
+++ b/thirdparty/assimp/include/assimp/postprocess.h
@@ -47,7 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_POSTPROCESS_H_INC
#define AI_POSTPROCESS_H_INC
-#include "types.h"
+#include <assimp/types.h>
+
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
#ifdef __cplusplus
extern "C" {
@@ -316,6 +320,19 @@ enum aiPostProcessSteps
*/
aiProcess_FixInfacingNormals = 0x2000,
+
+
+ // -------------------------------------------------------------------------
+ /**
+ * This step generically populates aiBone->mArmature and aiBone->mNode generically
+ * The point of these is it saves you later having to calculate these elements
+ * This is useful when handling rest information or skin information
+ * If you have multiple armatures on your models we strongly recommend enabling this
+ * Instead of writing your own multi-root, multi-armature lookups we have done the
+ * hard work for you :)
+ */
+ aiProcess_PopulateArmatureData = 0x4000,
+
// -------------------------------------------------------------------------
/** <hr>This step splits meshes with more than one primitive type in
* homogeneous sub-meshes.
@@ -438,7 +455,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 +467,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 +531,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,
@@ -533,6 +550,8 @@ enum aiPostProcessSteps
*/
aiProcess_Debone = 0x4000000,
+
+
// -------------------------------------------------------------------------
/** <hr>This step will perform a global scale of the model.
*
@@ -541,7 +560,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 +593,11 @@ enum aiPostProcessSteps
* This process gives sense back to aiProcess_JoinIdenticalVertices
*/
aiProcess_DropNormals = 0x40000000,
+
+ // -------------------------------------------------------------------------
+ /**
+ */
+ aiProcess_GenBoundingBoxes = 0x80000000
};
diff --git a/thirdparty/assimp/include/assimp/qnan.h b/thirdparty/assimp/include/assimp/qnan.h
index 0918bde5e7..06780da5b8 100644
--- a/thirdparty/assimp/include/assimp/qnan.h
+++ b/thirdparty/assimp/include/assimp/qnan.h
@@ -50,19 +50,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* but last time I checked compiler coverage was so bad that I decided
* to reinvent the wheel.
*/
-
+#pragma once
#ifndef AI_QNAN_H_INCLUDED
#define AI_QNAN_H_INCLUDED
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#include <assimp/defs.h>
+
#include <limits>
#include <stdint.h>
// ---------------------------------------------------------------------------
/** Data structure to represent the bit pattern of a 32 Bit
* IEEE 754 floating-point number. */
-union _IEEESingle
-{
+union _IEEESingle {
float Float;
struct
{
@@ -75,8 +79,7 @@ union _IEEESingle
// ---------------------------------------------------------------------------
/** Data structure to represent the bit pattern of a 64 Bit
* IEEE 754 floating-point number. */
-union _IEEEDouble
-{
+union _IEEEDouble {
double Double;
struct
{
@@ -89,8 +92,7 @@ union _IEEEDouble
// ---------------------------------------------------------------------------
/** Check whether a given float is qNaN.
* @param in Input value */
-AI_FORCE_INLINE bool is_qnan(float in)
-{
+AI_FORCE_INLINE bool is_qnan(float in) {
// the straightforward solution does not work:
// return (in != in);
// compiler generates code like this
@@ -107,8 +109,7 @@ AI_FORCE_INLINE bool is_qnan(float in)
// ---------------------------------------------------------------------------
/** Check whether a given double is qNaN.
* @param in Input value */
-AI_FORCE_INLINE bool is_qnan(double in)
-{
+AI_FORCE_INLINE bool is_qnan(double in) {
// the straightforward solution does not work:
// return (in != in);
// compiler generates code like this
@@ -127,8 +128,7 @@ AI_FORCE_INLINE bool is_qnan(double in)
*
* Denorms return false, they're treated like normal values.
* @param in Input value */
-AI_FORCE_INLINE bool is_special_float(float in)
-{
+AI_FORCE_INLINE bool is_special_float(float in) {
_IEEESingle temp;
memcpy(&temp, &in, sizeof(float));
return (temp.IEEE.Exp == (1u << 8)-1);
@@ -139,8 +139,7 @@ AI_FORCE_INLINE bool is_special_float(float in)
*
* Denorms return false, they're treated like normal values.
* @param in Input value */
-AI_FORCE_INLINE bool is_special_float(double in)
-{
+AI_FORCE_INLINE bool is_special_float(double in) {
_IEEESingle temp;
memcpy(&temp, &in, sizeof(float));
return (temp.IEEE.Exp == (1u << 11)-1);
@@ -150,15 +149,13 @@ AI_FORCE_INLINE bool is_special_float(double in)
/** Check whether a float is NOT qNaN.
* @param in Input value */
template<class TReal>
-AI_FORCE_INLINE bool is_not_qnan(TReal in)
-{
+AI_FORCE_INLINE bool is_not_qnan(TReal in) {
return !is_qnan(in);
}
// ---------------------------------------------------------------------------
/** @brief Get a fresh qnan. */
-AI_FORCE_INLINE ai_real get_qnan()
-{
+AI_FORCE_INLINE ai_real get_qnan() {
return std::numeric_limits<ai_real>::quiet_NaN();
}
diff --git a/thirdparty/assimp/include/assimp/quaternion.h b/thirdparty/assimp/include/assimp/quaternion.h
index 96574d24b9..ae45959b41 100644
--- a/thirdparty/assimp/include/assimp/quaternion.h
+++ b/thirdparty/assimp/include/assimp/quaternion.h
@@ -49,7 +49,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef __cplusplus
-#include "defs.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/defs.h>
template <typename TReal> class aiVector3t;
template <typename TReal> class aiMatrix3x3t;
diff --git a/thirdparty/assimp/include/assimp/quaternion.inl b/thirdparty/assimp/include/assimp/quaternion.inl
index c26648215e..3ce514d1bb 100644
--- a/thirdparty/assimp/include/assimp/quaternion.inl
+++ b/thirdparty/assimp/include/assimp/quaternion.inl
@@ -48,8 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_QUATERNION_INL_INC
#define AI_QUATERNION_INL_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
-#include "quaternion.h"
+#include <assimp/quaternion.h>
#include <cmath>
diff --git a/thirdparty/assimp/include/assimp/scene.h b/thirdparty/assimp/include/assimp/scene.h
index de0239702d..b76709eb15 100644
--- a/thirdparty/assimp/include/assimp/scene.h
+++ b/thirdparty/assimp/include/assimp/scene.h
@@ -48,16 +48,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_SCENE_H_INC
#define AI_SCENE_H_INC
-#include "types.h"
-#include "texture.h"
-#include "mesh.h"
-#include "light.h"
-#include "camera.h"
-#include "material.h"
-#include "anim.h"
-#include "metadata.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
+#include <assimp/texture.h>
+#include <assimp/mesh.h>
+#include <assimp/light.h>
+#include <assimp/camera.h>
+#include <assimp/material.h>
+#include <assimp/anim.h>
+#include <assimp/metadata.h>
#ifdef __cplusplus
+# include <cstdlib>
extern "C" {
#endif
@@ -105,13 +110,13 @@ struct ASSIMP_API aiNode
/** The transformation relative to the node's parent. */
C_STRUCT aiMatrix4x4 mTransformation;
- /** Parent node. NULL if this node is the root node. */
+ /** Parent node. nullptr if this node is the root node. */
C_STRUCT aiNode* mParent;
/** The number of child nodes of this node. */
unsigned int mNumChildren;
- /** The child nodes of this node. NULL if mNumChildren is 0. */
+ /** The child nodes of this node. nullptr if mNumChildren is 0. */
C_STRUCT aiNode** mChildren;
/** The number of meshes of this node. */
@@ -122,7 +127,7 @@ struct ASSIMP_API aiNode
*/
unsigned int* mMeshes;
- /** Metadata associated with this node or NULL if there is no metadata.
+ /** Metadata associated with this node or nullptr if there is no metadata.
* Whether any metadata is generated depends on the source file format. See the
* @link importer_notes @endlink page for more information on every source file
* format. Importers that don't document any metadata don't write any.
@@ -144,7 +149,7 @@ struct ASSIMP_API aiNode
* of the scene.
*
* @param name Name to search for
- * @return NULL or a valid Node if the search was successful.
+ * @return nullptr or a valid Node if the search was successful.
*/
inline
const aiNode* FindNode(const aiString& name) const {
@@ -339,7 +344,7 @@ struct aiScene
#ifdef __cplusplus
- //! Default constructor - set everything to 0/NULL
+ //! Default constructor - set everything to 0/nullptr
ASSIMP_API aiScene();
//! Destructor
@@ -348,33 +353,33 @@ struct aiScene
//! Check whether the scene contains meshes
//! Unless no special scene flags are set this will always be true.
inline bool HasMeshes() const {
- return mMeshes != NULL && mNumMeshes > 0;
+ return mMeshes != nullptr && mNumMeshes > 0;
}
//! Check whether the scene contains materials
//! Unless no special scene flags are set this will always be true.
inline bool HasMaterials() const {
- return mMaterials != NULL && mNumMaterials > 0;
+ return mMaterials != nullptr && mNumMaterials > 0;
}
//! Check whether the scene contains lights
inline bool HasLights() const {
- return mLights != NULL && mNumLights > 0;
+ return mLights != nullptr && mNumLights > 0;
}
//! Check whether the scene contains textures
inline bool HasTextures() const {
- return mTextures != NULL && mNumTextures > 0;
+ return mTextures != nullptr && mNumTextures > 0;
}
//! Check whether the scene contains cameras
inline bool HasCameras() const {
- return mCameras != NULL && mNumCameras > 0;
+ return mCameras != nullptr && mNumCameras > 0;
}
//! Check whether the scene contains animations
inline bool HasAnimations() const {
- return mAnimations != NULL && mNumAnimations > 0;
+ return mAnimations != nullptr && mNumAnimations > 0;
}
//! Returns a short filename from a full path
@@ -389,6 +394,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/assimp/include/assimp/texture.h b/thirdparty/assimp/include/assimp/texture.h
index dc6cbef65c..0867659f46 100644
--- a/thirdparty/assimp/include/assimp/texture.h
+++ b/thirdparty/assimp/include/assimp/texture.h
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2019, assimp team
-
-
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -53,13 +51,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_TEXTURE_H_INC
#define AI_TEXTURE_H_INC
-#include "types.h"
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
#ifdef __cplusplus
extern "C" {
#endif
-
// --------------------------------------------------------------------------------
/** \def AI_EMBEDDED_TEXNAME_PREFIX
@@ -79,7 +80,6 @@ extern "C" {
# define AI_MAKE_EMBEDDED_TEXNAME(_n_) AI_EMBEDDED_TEXNAME_PREFIX # _n_
#endif
-
#include "./Compiler/pushpack1.h"
// --------------------------------------------------------------------------------
@@ -87,8 +87,7 @@ extern "C" {
*
* Used by aiTexture.
*/
-struct aiTexel
-{
+struct aiTexel {
unsigned char b,g,r,a;
#ifdef __cplusplus
diff --git a/thirdparty/assimp/include/assimp/types.h b/thirdparty/assimp/include/assimp/types.h
index 748e4851f3..e32cae331c 100644
--- a/thirdparty/assimp/include/assimp/types.h
+++ b/thirdparty/assimp/include/assimp/types.h
@@ -48,22 +48,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_TYPES_H_INC
#define AI_TYPES_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
// Some runtime headers
#include <sys/types.h>
#include <stddef.h>
#include <string.h>
#include <limits.h>
+#include <stdint.h>
// Our compile configuration
-#include "defs.h"
+#include <assimp/defs.h>
// Some types moved to separate header due to size of operators
-#include "vector3.h"
-#include "vector2.h"
-#include "color4.h"
-#include "matrix3x3.h"
-#include "matrix4x4.h"
-#include "quaternion.h"
+#include <assimp/vector3.h>
+#include <assimp/vector2.h>
+#include <assimp/color4.h>
+#include <assimp/matrix3x3.h>
+#include <assimp/matrix4x4.h>
+#include <assimp/quaternion.h>
+
+typedef int32_t ai_int32;
+typedef uint32_t ai_uint32 ;
#ifdef __cplusplus
#include <cstring>
@@ -71,7 +79,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string> // for aiString::Set(const std::string&)
namespace Assimp {
- //! @cond never
+//! @cond never
namespace Intern {
// --------------------------------------------------------------------
/** @brief Internal helper class to utilize our internal new/delete
@@ -161,7 +169,14 @@ struct aiColor3D
explicit aiColor3D (ai_real _r) : r(_r), g(_r), b(_r) {}
aiColor3D (const aiColor3D& o) : r(o.r), g(o.g), b(o.b) {}
- /** Component-wise comparison */
+ aiColor3D &operator=(const aiColor3D &o) {
+ r = o.r;
+ g = o.g;
+ b = o.b;
+ return *this;
+ }
+
+ /** Component-wise comparison */
// TODO: add epsilon?
bool operator == (const aiColor3D& other) const
{return r == other.r && g == other.g && b == other.b;}
@@ -262,8 +277,8 @@ struct aiString
}
/** Copy constructor */
- aiString(const aiString& rOther) :
- length(rOther.length)
+ aiString(const aiString& rOther)
+ : length(rOther.length)
{
// Crop the string to the maximum length
length = length>=MAXLEN?MAXLEN-1:length;
@@ -273,7 +288,7 @@ struct aiString
/** Constructor from std::string */
explicit aiString(const std::string& pString) :
- length(pString.length())
+ length( (ai_uint32) pString.length())
{
length = length>=MAXLEN?MAXLEN-1:length;
memcpy( data, pString.c_str(), length);
@@ -285,15 +300,15 @@ struct aiString
if( pString.length() > MAXLEN - 1) {
return;
}
- length = pString.length();
+ length = (ai_uint32)pString.length();
memcpy( data, pString.c_str(), length);
data[length] = 0;
}
/** Copy a const char* to the aiString */
void Set( const char* sz) {
- const size_t len = ::strlen(sz);
- if( len > MAXLEN - 1) {
+ const ai_int32 len = (ai_uint32) ::strlen(sz);
+ if( len > (ai_int32)MAXLEN - 1) {
return;
}
length = len;
@@ -339,7 +354,7 @@ struct aiString
/** Append a string to the string */
void Append (const char* app) {
- const size_t len = ::strlen(app);
+ const ai_uint32 len = (ai_uint32) ::strlen(app);
if (!len) {
return;
}
@@ -372,7 +387,7 @@ struct aiString
/** Binary length of the string excluding the terminal 0. This is NOT the
* logical length of strings containing UTF-8 multi-byte sequences! It's
* the number of bytes from the beginning of the string to its end.*/
- size_t length;
+ ai_uint32 length;
/** String buffer. Size limit is MAXLEN */
char data[MAXLEN];
diff --git a/thirdparty/assimp/include/assimp/vector2.h b/thirdparty/assimp/include/assimp/vector2.h
index d5ef001542..c8b1ebbbc2 100644
--- a/thirdparty/assimp/include/assimp/vector2.h
+++ b/thirdparty/assimp/include/assimp/vector2.h
@@ -47,6 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_VECTOR2D_H_INC
#define AI_VECTOR2D_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
# include <cmath>
#else
diff --git a/thirdparty/assimp/include/assimp/vector2.inl b/thirdparty/assimp/include/assimp/vector2.inl
index 3b7a7beabb..4bbf432ff8 100644
--- a/thirdparty/assimp/include/assimp/vector2.inl
+++ b/thirdparty/assimp/include/assimp/vector2.inl
@@ -48,8 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_VECTOR2D_INL_INC
#define AI_VECTOR2D_INL_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
-#include "vector2.h"
+#include <assimp/vector2.h>
#include <cmath>
diff --git a/thirdparty/assimp/include/assimp/vector3.h b/thirdparty/assimp/include/assimp/vector3.h
index 7ff25cf0ad..fffeb12ad7 100644
--- a/thirdparty/assimp/include/assimp/vector3.h
+++ b/thirdparty/assimp/include/assimp/vector3.h
@@ -47,13 +47,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_VECTOR3D_H_INC
#define AI_VECTOR3D_H_INC
+#ifdef __GNUC__
+# pragma GCC system_header
+#endif
+
#ifdef __cplusplus
# include <cmath>
#else
# include <math.h>
#endif
-#include "defs.h"
+#include <assimp/defs.h>
#ifdef __cplusplus
@@ -63,16 +67,13 @@ template<typename TReal> class aiMatrix4x4t;
// ---------------------------------------------------------------------------
/** Represents a three-dimensional vector. */
template <typename TReal>
-class aiVector3t
-{
+class aiVector3t {
public:
aiVector3t() AI_NO_EXCEPT : x(), y(), z() {}
aiVector3t(TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
explicit aiVector3t (TReal _xyz ) : x(_xyz), y(_xyz), z(_xyz) {}
aiVector3t( const aiVector3t& o ) = default;
-public:
-
// combined operators
const aiVector3t& operator += (const aiVector3t& o);
const aiVector3t& operator -= (const aiVector3t& o);
@@ -97,7 +98,6 @@ public:
template <typename TOther>
operator aiVector3t<TOther> () const;
-public:
/** @brief Set the components of a vector
* @param pX X component
* @param pY Y component
diff --git a/thirdparty/assimp/include/assimp/vector3.inl b/thirdparty/assimp/include/assimp/vector3.inl
index 2fce6eddee..6682d3b32c 100644
--- a/thirdparty/assimp/include/assimp/vector3.inl
+++ b/thirdparty/assimp/include/assimp/vector3.inl
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_VECTOR3D_INL_INC
#ifdef __cplusplus
-#include "vector3.h"
+#include <assimp/vector3.h>
#include <cmath>
diff --git a/thirdparty/assimp/include/assimp/version.h b/thirdparty/assimp/include/assimp/version.h
index c62a40e118..2fdd37a43c 100644
--- a/thirdparty/assimp/include/assimp/version.h
+++ b/thirdparty/assimp/include/assimp/version.h
@@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_VERSION_H_INC
#define AI_VERSION_H_INC
-#include "defs.h"
+#include <assimp/defs.h>
#ifdef __cplusplus
extern "C" {