Bladeren bron

Update Assimp from 5.2.3 to 5.2.5

Bloodknight 2 jaren geleden
bovenliggende
commit
16f3710058
100 gewijzigde bestanden met toevoegingen van 1407 en 1415 verwijderingen
  1. 17 0
      Engine/lib/assimp/INSTALL
  2. 3 0
      Engine/lib/assimp/Readme.md
  3. 1 0
      Engine/lib/assimp/code/AssetLib/3DS/3DSConverter.cpp
  4. 1 3
      Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.cpp
  5. 6 7
      Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.cpp
  6. 2 0
      Engine/lib/assimp/code/AssetLib/3MF/3MFXmlTags.h
  7. 2 7
      Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.cpp
  8. 3 0
      Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.cpp
  9. 32 9
      Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.cpp
  10. 7 9
      Engine/lib/assimp/code/AssetLib/AC/ACLoader.cpp
  11. 5 6
      Engine/lib/assimp/code/AssetLib/ASE/ASELoader.cpp
  12. 18 13
      Engine/lib/assimp/code/AssetLib/ASE/ASEParser.cpp
  13. 1 1
      Engine/lib/assimp/code/AssetLib/ASE/ASEParser.h
  14. 9 5
      Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.cpp
  15. 4 0
      Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.cpp
  16. 1 1
      Engine/lib/assimp/code/AssetLib/Assjson/mesh_splitter.cpp
  17. 1 1
      Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.cpp
  18. 5 7
      Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.cpp
  19. 2 2
      Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.cpp
  20. 4 4
      Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.cpp
  21. 2 2
      Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.h
  22. 1 2
      Engine/lib/assimp/code/AssetLib/Blender/BlenderIntermediate.h
  23. 2 2
      Engine/lib/assimp/code/AssetLib/Blender/BlenderLoader.cpp
  24. 1 1
      Engine/lib/assimp/code/AssetLib/Blender/BlenderLoader.h
  25. 3 6
      Engine/lib/assimp/code/AssetLib/Blender/BlenderModifier.cpp
  26. 12 6
      Engine/lib/assimp/code/AssetLib/Blender/BlenderScene.cpp
  27. 12 8
      Engine/lib/assimp/code/AssetLib/Blender/BlenderScene.h
  28. 1 3
      Engine/lib/assimp/code/AssetLib/Blender/BlenderTessellator.cpp
  29. 1 1
      Engine/lib/assimp/code/AssetLib/Blender/BlenderTessellator.h
  30. 7 11
      Engine/lib/assimp/code/AssetLib/COB/COBLoader.cpp
  31. 1 1
      Engine/lib/assimp/code/AssetLib/COB/COBScene.h
  32. 1 2
      Engine/lib/assimp/code/AssetLib/CSM/CSMLoader.cpp
  33. 3 4
      Engine/lib/assimp/code/AssetLib/Collada/ColladaExporter.cpp
  34. 1 1
      Engine/lib/assimp/code/AssetLib/Collada/ColladaExporter.h
  35. 5 0
      Engine/lib/assimp/code/AssetLib/Collada/ColladaHelper.h
  36. 7 6
      Engine/lib/assimp/code/AssetLib/Collada/ColladaLoader.cpp
  37. 1 0
      Engine/lib/assimp/code/AssetLib/Collada/ColladaLoader.h
  38. 10 9
      Engine/lib/assimp/code/AssetLib/Collada/ColladaParser.cpp
  39. 8 11
      Engine/lib/assimp/code/AssetLib/DXF/DXFLoader.cpp
  40. 0 21
      Engine/lib/assimp/code/AssetLib/FBX/FBXAnimation.cpp
  41. 1 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
  42. 2 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXCommon.h
  43. 0 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXCompileConfig.h
  44. 126 75
      Engine/lib/assimp/code/AssetLib/FBX/FBXConverter.cpp
  45. 29 16
      Engine/lib/assimp/code/AssetLib/FBX/FBXConverter.h
  46. 7 27
      Engine/lib/assimp/code/AssetLib/FBX/FBXDeformer.cpp
  47. 2 2
      Engine/lib/assimp/code/AssetLib/FBX/FBXDocument.cpp
  48. 10 10
      Engine/lib/assimp/code/AssetLib/FBX/FBXDocument.h
  49. 3 6
      Engine/lib/assimp/code/AssetLib/FBX/FBXDocumentUtil.cpp
  50. 5 7
      Engine/lib/assimp/code/AssetLib/FBX/FBXDocumentUtil.h
  51. 1 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXExporter.cpp
  52. 6 0
      Engine/lib/assimp/code/AssetLib/FBX/FBXImportSettings.h
  53. 22 25
      Engine/lib/assimp/code/AssetLib/FBX/FBXImporter.cpp
  54. 7 6
      Engine/lib/assimp/code/AssetLib/FBX/FBXImporter.h
  55. 3 9
      Engine/lib/assimp/code/AssetLib/FBX/FBXMaterial.cpp
  56. 33 30
      Engine/lib/assimp/code/AssetLib/FBX/FBXMeshGeometry.cpp
  57. 12 9
      Engine/lib/assimp/code/AssetLib/FBX/FBXMeshGeometry.h
  58. 29 78
      Engine/lib/assimp/code/AssetLib/FBX/FBXNodeAttribute.cpp
  59. 10 24
      Engine/lib/assimp/code/AssetLib/FBX/FBXParser.cpp
  60. 2 2
      Engine/lib/assimp/code/AssetLib/FBX/FBXParser.h
  61. 13 19
      Engine/lib/assimp/code/AssetLib/FBX/FBXProperties.cpp
  62. 1 3
      Engine/lib/assimp/code/AssetLib/FBX/FBXTokenizer.cpp
  63. 1 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXTokenizer.h
  64. 2 6
      Engine/lib/assimp/code/AssetLib/HMP/HMPLoader.cpp
  65. 3 3
      Engine/lib/assimp/code/AssetLib/IFC/IFCBoolean.cpp
  66. 5 3
      Engine/lib/assimp/code/AssetLib/IFC/IFCCurve.cpp
  67. 2 2
      Engine/lib/assimp/code/AssetLib/IFC/IFCGeometry.cpp
  68. 2 3
      Engine/lib/assimp/code/AssetLib/IFC/IFCLoader.cpp
  69. 37 37
      Engine/lib/assimp/code/AssetLib/IFC/IFCOpenings.cpp
  70. 17 17
      Engine/lib/assimp/code/AssetLib/IFC/IFCProfile.cpp
  71. 2 2
      Engine/lib/assimp/code/AssetLib/IFC/IFCUtil.cpp
  72. 1 2
      Engine/lib/assimp/code/AssetLib/IFC/IFCUtil.h
  73. 2 2
      Engine/lib/assimp/code/AssetLib/IQM/IQMImporter.h
  74. 6 8
      Engine/lib/assimp/code/AssetLib/Irr/IRRLoader.cpp
  75. 1 2
      Engine/lib/assimp/code/AssetLib/Irr/IRRLoader.h
  76. 1 1
      Engine/lib/assimp/code/AssetLib/Irr/IRRMeshLoader.cpp
  77. 1 1
      Engine/lib/assimp/code/AssetLib/LWO/LWOBLoader.cpp
  78. 2 8
      Engine/lib/assimp/code/AssetLib/LWO/LWOFileData.h
  79. 9 11
      Engine/lib/assimp/code/AssetLib/LWO/LWOLoader.cpp
  80. 0 2
      Engine/lib/assimp/code/AssetLib/LWO/LWOMaterial.cpp
  81. 10 13
      Engine/lib/assimp/code/AssetLib/LWS/LWSLoader.cpp
  82. 1 1
      Engine/lib/assimp/code/AssetLib/LWS/LWSLoader.h
  83. 1 3
      Engine/lib/assimp/code/AssetLib/M3D/M3DWrapper.h
  84. 1 2
      Engine/lib/assimp/code/AssetLib/MD2/MD2Loader.cpp
  85. 7 7
      Engine/lib/assimp/code/AssetLib/MD3/MD3Loader.cpp
  86. 1 3
      Engine/lib/assimp/code/AssetLib/MD5/MD5Loader.cpp
  87. 10 13
      Engine/lib/assimp/code/AssetLib/MD5/MD5Parser.cpp
  88. 87 100
      Engine/lib/assimp/code/AssetLib/MD5/MD5Parser.h
  89. 4 6
      Engine/lib/assimp/code/AssetLib/MDC/MDCLoader.cpp
  90. 1 2
      Engine/lib/assimp/code/AssetLib/MDL/HalfLife/UniqueNameGenerator.cpp
  91. 1 3
      Engine/lib/assimp/code/AssetLib/MDL/MDLLoader.cpp
  92. 3 0
      Engine/lib/assimp/code/AssetLib/MDL/MDLMaterialLoader.cpp
  93. 35 43
      Engine/lib/assimp/code/AssetLib/MMD/MMDImporter.cpp
  94. 591 548
      Engine/lib/assimp/code/AssetLib/MMD/MMDPmdParser.h
  95. 3 1
      Engine/lib/assimp/code/AssetLib/MMD/MMDPmxParser.h
  96. 2 3
      Engine/lib/assimp/code/AssetLib/MS3D/MS3DLoader.cpp
  97. 8 8
      Engine/lib/assimp/code/AssetLib/NDO/NDOLoader.cpp
  98. 14 14
      Engine/lib/assimp/code/AssetLib/NFF/NFFLoader.cpp
  99. 2 4
      Engine/lib/assimp/code/AssetLib/OFF/OFFLoader.cpp
  100. 4 6
      Engine/lib/assimp/code/AssetLib/Obj/ObjExporter.cpp

+ 17 - 0
Engine/lib/assimp/INSTALL

@@ -0,0 +1,17 @@
+	
+========================================================================
+Open Asset Import Library (assimp) INSTALL 
+========================================================================
+
+------------------------------
+Getting the documentation
+------------------------------
+
+A regularly-updated copy is available at 
+https://assimp-docs.readthedocs.io/en/latest/
+
+------------------------------
+Building Assimp 
+------------------------------
+
+Just check the build-instructions which you can find here: https://github.com/assimp/assimp/blob/master/Build.md

+ 3 - 0
Engine/lib/assimp/Readme.md

@@ -9,9 +9,11 @@ A library to import and export various 3d-model-formats including scene-post-pro
        src="https://scan.coverity.com/projects/5607/badge.svg"/>
 </a>
 [![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
+
 [![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
 [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
 [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
+[![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
 [![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
 <br>
 
@@ -58,6 +60,7 @@ Open Asset Import Library is implemented in C++. The directory structure looks l
 	/code		Source code
 	/contrib	Third-party libraries
 	/doc		Documentation (doxysource and pre-compiled docs)
+	/fuzz           Contains the test-code for the Google-Fuzzer project
 	/include	Public header C and C++ header files
 	/scripts 	Scripts used to generate the loading code for some formats
 	/port		Ports to other languages and scripts to maintain those.

+ 1 - 0
Engine/lib/assimp/code/AssetLib/3DS/3DSConverter.cpp

@@ -262,6 +262,7 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
         unsigned int iWire = 1;
         mat.AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
     }
+    [[fallthrough]];
 
     case D3DS::Discreet3DS::Gouraud:
         eShading = aiShadingMode_Gouraud;

+ 1 - 3
Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.cpp

@@ -209,9 +209,7 @@ Discreet3DSExporter::Discreet3DSExporter(std::shared_ptr<IOStream> &outfile, con
 }
 
 // ------------------------------------------------------------------------------------------------
-Discreet3DSExporter::~Discreet3DSExporter() {
-    // empty
-}
+Discreet3DSExporter::~Discreet3DSExporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 int Discreet3DSExporter::WriteHierarchy(const aiNode &node, int seq, int sibling_level) {

+ 6 - 7
Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.cpp

@@ -105,9 +105,7 @@ Discreet3DSImporter::Discreet3DSImporter() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-Discreet3DSImporter::~Discreet3DSImporter() {
-    // empty
-}
+Discreet3DSImporter::~Discreet3DSImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -319,7 +317,7 @@ void Discreet3DSImporter::ParseObjectChunk() {
     case Discreet3DS::CHUNK_MAT_MATERIAL:
 
         // Add a new material to the list
-        mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + ai_to_string(mScene->mMaterials.size()))));
+        mScene->mMaterials.emplace_back(std::string("UNNAMED_" + ai_to_string(mScene->mMaterials.size())));
         ParseMaterialChunk();
         break;
 
@@ -370,7 +368,7 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
     switch (chunk.Flag) {
     case Discreet3DS::CHUNK_TRIMESH: {
         // this starts a new triangle mesh
-        mScene->mMeshes.push_back(D3DS::Mesh(std::string(name, num)));
+        mScene->mMeshes.emplace_back(std::string(name, num));
 
         // Read mesh chunks
         ParseMeshChunk();
@@ -999,7 +997,7 @@ void Discreet3DSImporter::ParseMeshChunk() {
         mMesh.mFaces.reserve(num);
         while (num-- > 0) {
             // 3DS faces are ALWAYS triangles
-            mMesh.mFaces.push_back(D3DS::Face());
+            mMesh.mFaces.emplace_back();
             D3DS::Face &sFace = mMesh.mFaces.back();
 
             sFace.mIndices[0] = (uint16_t)stream->GetI2();
@@ -1284,7 +1282,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
     switch (chunk.Flag) {
     case Discreet3DS::CHUNK_LINRGBF:
         bGamma = true;
-
+    // fallthrough
     case Discreet3DS::CHUNK_RGBF:
         if (sizeof(float) * 3 > diff) {
             *out = clrError;
@@ -1297,6 +1295,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
 
     case Discreet3DS::CHUNK_LINRGBB:
         bGamma = true;
+            // fallthrough
     case Discreet3DS::CHUNK_RGBB: {
         if (sizeof(char) * 3 > diff) {
             *out = clrError;

+ 2 - 0
Engine/lib/assimp/code/AssetLib/3MF/3MFXmlTags.h

@@ -74,6 +74,8 @@ namespace XmlTag {
     const char* const pid = "pid";
     const char* const pindex = "pindex";
     const char* const p1 = "p1";
+    const char *const p2 = "p2";
+    const char *const p3 = "p3";
     const char* const name = "name";
     const char* const type = "type";
     const char* const build = "build";

+ 2 - 7
Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.cpp

@@ -81,14 +81,9 @@ static const aiImporterDesc desc = {
     "3mf"
 };
 
-D3MFImporter::D3MFImporter() :
-        BaseImporter() {
-    // empty
-}
+D3MFImporter::D3MFImporter() = default;
 
-D3MFImporter::~D3MFImporter() {
-    // empty
-}
+D3MFImporter::~D3MFImporter() = default;
 
 bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
     if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {

+ 3 - 0
Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.cpp

@@ -186,6 +186,9 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
 D3MFOpcPackage::~D3MFOpcPackage() {
     mZipArchive->Close(mRootStream);
     delete mZipArchive;
+    for (auto tex : mEmbeddedTextures) {
+        delete tex;
+    }
 }
 
 IOStream *D3MFOpcPackage::RootStream() const {

+ 32 - 9
Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.cpp

@@ -64,7 +64,7 @@ bool validateColorString(const char *color) {
     return true;
 }
 
-aiFace ReadTriangle(XmlNode &node) {
+aiFace ReadTriangle(XmlNode &node, int &texId0, int &texId1, int &texId2) {
     aiFace face;
 
     face.mNumIndices = 3;
@@ -73,6 +73,11 @@ aiFace ReadTriangle(XmlNode &node) {
     face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
     face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
 
+    texId0 = texId1 = texId2 = -1;
+    XmlParser::getIntAttribute(node, XmlTag::p1, texId0);
+    XmlParser::getIntAttribute(node, XmlTag::p2, texId1);
+    XmlParser::getIntAttribute(node, XmlTag::p3, texId2);
+
     return face;
 }
 
@@ -106,7 +111,7 @@ bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &va
     return false;
 }
 
-aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
+aiMatrix4x4 parseTransformMatrix(const std::string& matrixStr) {
     // split the string
     std::vector<float> numbers;
     std::string currentNumber;
@@ -412,6 +417,9 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
             bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
             bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
 
+            int texId[3];
+            Texture2DGroup *group = nullptr;
+            aiFace face = ReadTriangle(currentNode, texId[0], texId[1], texId[2]);
             if (hasPid && hasP1) {
                 auto it = mResourcesDictionnary.find(pid);
                 if (it != mResourcesDictionnary.end()) {
@@ -420,23 +428,34 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
                         mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
                     } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
                         if (mesh->mTextureCoords[0] == nullptr) {
-                            Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second);
+                            mesh->mNumUVComponents[0] = 2;
+                            for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
+                                mesh->mNumUVComponents[i] = 0;
+                            }
+
+                            group = static_cast<Texture2DGroup *>(it->second);
                             const std::string name = ai_to_string(group->mTexId);
                             for (size_t i = 0; i < mMaterials.size(); ++i) {
                                 if (name == mMaterials[i]->GetName().C_Str()) {
                                     mesh->mMaterialIndex = static_cast<unsigned int>(i);
                                 }
                             }
-                            mesh->mTextureCoords[0] = new aiVector3D[group->mTex2dCoords.size()];
-                            for (unsigned int i = 0; i < group->mTex2dCoords.size(); ++i) {
-                                mesh->mTextureCoords[0][i] = aiVector3D(group->mTex2dCoords[i].x, group->mTex2dCoords[i].y, 0);
-                            }
+                            mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
                         }
                     } 
                 }
             }
 
-            aiFace face = ReadTriangle(currentNode);
+            // Load texture coordinates into mesh, when any
+            if (group != nullptr) {
+                size_t i0 = face.mIndices[0];
+                size_t i1 = face.mIndices[1];
+                size_t i2 = face.mIndices[2];
+                mesh->mTextureCoords[0][i0] = aiVector3D(group->mTex2dCoords[texId[0]].x, group->mTex2dCoords[texId[0]].y, 0.0f);
+                mesh->mTextureCoords[0][i1] = aiVector3D(group->mTex2dCoords[texId[1]].x, group->mTex2dCoords[texId[1]].y, 0.0f);
+                mesh->mTextureCoords[0][i2] = aiVector3D(group->mTex2dCoords[texId[2]].x, group->mTex2dCoords[texId[2]].y, 0.0f);
+            }
+
             faces.push_back(face);
         }
     }
@@ -578,11 +597,15 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater
 }
 
 void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
-    if (nullptr == scene || mMaterials.empty()) {
+    if (nullptr == scene) {
         return;
     }
 
     scene->mNumMaterials = static_cast<unsigned int>(mMaterials.size());
+    if (scene->mNumMaterials == 0) {
+        return;
+    }
+
     scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
     for (size_t i = 0; i < mMaterials.size(); ++i) {
         scene->mMaterials[i] = mMaterials[i];

+ 7 - 9
Engine/lib/assimp/code/AssetLib/AC/ACLoader.cpp

@@ -146,9 +146,7 @@ AC3DImporter::AC3DImporter() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-AC3DImporter::~AC3DImporter() {
-    // nothing to be done here
-}
+AC3DImporter::~AC3DImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -180,7 +178,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
 
     ++mNumMeshes;
 
-    objects.push_back(Object());
+    objects.emplace_back();
     Object &obj = objects.back();
 
     aiLight *light = nullptr;
@@ -267,7 +265,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
                     --buffer; // make sure the line is processed a second time
                     break;
                 }
-                obj.vertices.push_back(aiVector3D());
+                obj.vertices.emplace_back();
                 aiVector3D &v = obj.vertices.back();
                 buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x);
             }
@@ -293,7 +291,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
                     Q3DWorkAround = true;
                 }
                 SkipSpaces(&buffer);
-                obj.surfaces.push_back(Surface());
+                obj.surfaces.emplace_back();
                 Surface &surf = obj.surfaces.back();
                 surf.flags = strtoul_cppstyle(buffer);
 
@@ -324,7 +322,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
                                 ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: surface references are incomplete");
                                 break;
                             }
-                            surf.entries.push_back(Surface::SurfaceEntry());
+                            surf.entries.emplace_back();
                             Surface::SurfaceEntry &entry = surf.entries.back();
 
                             entry.first = strtoul10(buffer, &buffer);
@@ -786,7 +784,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
 
     while (GetNextLine()) {
         if (TokenMatch(buffer, "MATERIAL", 8)) {
-            materials.push_back(Material());
+            materials.emplace_back();
             Material &mat = materials.back();
 
             // manually parse the material ... sscanf would use the buldin atof ...
@@ -813,7 +811,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
     }
     if (materials.empty()) {
         ASSIMP_LOG_WARN("AC3D: No material has been found");
-        materials.push_back(Material());
+        materials.emplace_back();
     }
 
     mNumMeshes += (mNumMeshes >> 2u) + 1;

+ 5 - 6
Engine/lib/assimp/code/AssetLib/ASE/ASELoader.cpp

@@ -89,9 +89,7 @@ ASEImporter::ASEImporter() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-ASEImporter::~ASEImporter() {
-    // empty
-}
+ASEImporter::~ASEImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -265,7 +263,7 @@ void ASEImporter::GenerateDefaultMaterial() {
     }
     if (bHas || mParser->m_vMaterials.empty()) {
         // add a simple material without submaterials to the parser's list
-        mParser->m_vMaterials.push_back(ASE::Material(AI_DEFAULT_MATERIAL_NAME));
+        mParser->m_vMaterials.emplace_back(AI_DEFAULT_MATERIAL_NAME);
         ASE::Material &mat = mParser->m_vMaterials.back();
 
         mat.mDiffuse = aiColor3D(0.6f, 0.6f, 0.6f);
@@ -870,6 +868,7 @@ void ASEImporter::ConvertMaterial(ASE::Material &mat) {
         unsigned int iWire = 1;
         mat.pcInstance->AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
     }
+    // fallthrough
     case D3DS::Discreet3DS::Gouraud:
         eShading = aiShadingMode_Gouraud;
         break;
@@ -1004,8 +1003,8 @@ void ASEImporter::ConvertMeshes(ASE::Mesh &mesh, std::vector<aiMesh *> &avOutMes
                                             blubb != mesh.mBoneVertices[iIndex2].mBoneWeights.end(); ++blubb) {
 
                                         // NOTE: illegal cases have already been filtered out
-                                        avOutputBones[(*blubb).first].push_back(std::pair<unsigned int, float>(
-                                                iBase, (*blubb).second));
+                                        avOutputBones[(*blubb).first].emplace_back(
+                                                iBase, (*blubb).second);
                                     }
                                 }
                             }

+ 18 - 13
Engine/lib/assimp/code/AssetLib/ASE/ASEParser.cpp

@@ -74,7 +74,7 @@ using namespace Assimp::ASE;
             return;                                \
         }                                          \
     }                                              \
-    else if ('\0' == *filePtr) {                   \
+    if ('\0' == *filePtr) {                        \
         return;                                    \
     }                                              \
     if (IsLineEnd(*filePtr) && !bLastWasEndLine) { \
@@ -264,7 +264,7 @@ void Parser::Parse() {
             if (TokenMatch(filePtr, "GEOMOBJECT", 10))
 
             {
-                m_vMeshes.push_back(Mesh("UNNAMED"));
+                m_vMeshes.emplace_back("UNNAMED");
                 ParseLV1ObjectBlock(m_vMeshes.back());
                 continue;
             }
@@ -272,7 +272,7 @@ void Parser::Parse() {
             if (TokenMatch(filePtr, "HELPEROBJECT", 12))
 
             {
-                m_vDummies.push_back(Dummy());
+                m_vDummies.emplace_back();
                 ParseLV1ObjectBlock(m_vDummies.back());
                 continue;
             }
@@ -280,13 +280,13 @@ void Parser::Parse() {
             if (TokenMatch(filePtr, "LIGHTOBJECT", 11))
 
             {
-                m_vLights.push_back(Light("UNNAMED"));
+                m_vLights.emplace_back("UNNAMED");
                 ParseLV1ObjectBlock(m_vLights.back());
                 continue;
             }
             // camera object
             if (TokenMatch(filePtr, "CAMERAOBJECT", 12)) {
-                m_vCameras.push_back(Camera("UNNAMED"));
+                m_vCameras.emplace_back("UNNAMED");
                 ParseLV1ObjectBlock(m_vCameras.back());
                 continue;
             }
@@ -385,7 +385,7 @@ void Parser::ParseLV1SoftSkinBlock() {
                         unsigned int numWeights;
                         ParseLV4MeshLong(numWeights);
 
-                        curMesh->mBoneVertices.push_back(ASE::BoneVertex());
+                        curMesh->mBoneVertices.emplace_back();
                         ASE::BoneVertex &vert = curMesh->mBoneVertices.back();
 
                         // Reserve enough storage
@@ -409,7 +409,7 @@ void Parser::ParseLV1SoftSkinBlock() {
                             if (-1 == me.first) {
                                 // We don't have this bone yet, so add it to the list
                                 me.first = static_cast<int>(curMesh->mBones.size());
-                                curMesh->mBones.push_back(ASE::Bone(bone));
+                                curMesh->mBones.emplace_back(bone);
                             }
                             ParseLV4MeshFloat(me.second);
 
@@ -420,6 +420,8 @@ void Parser::ParseLV1SoftSkinBlock() {
                 }
             }
         }
+        if (*filePtr == '\0')
+            return;
         ++filePtr;
         SkipSpacesAndLineEnd(&filePtr);
     }
@@ -646,10 +648,13 @@ void Parser::ParseLV2MaterialBlock(ASE::Material &mat) {
                 }
 
                 // get a reference to the material
-                Material &sMat = mat.avSubMaterials[iIndex];
+                if (iIndex < mat.avSubMaterials.size()) {
+                    Material &sMat = mat.avSubMaterials[iIndex];
+
+                    // parse the material block
+                    ParseLV2MaterialBlock(sMat);
+                }
 
-                // parse the material block
-                ParseLV2MaterialBlock(sMat);
                 continue;
             }
         }
@@ -1006,7 +1011,7 @@ void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation &anim) {
                 anim.mScalingType = ASE::Animation::TCB;
             }
             if (b) {
-                anim.akeyScaling.push_back(aiVectorKey());
+                anim.akeyScaling.emplace_back();
                 aiVectorKey &key = anim.akeyScaling.back();
                 ParseLV4MeshFloatTriple(&key.mValue.x, iIndex);
                 key.mTime = (double)iIndex;
@@ -1045,7 +1050,7 @@ void Parser::ParseLV3PosAnimationBlock(ASE::Animation &anim) {
                 anim.mPositionType = ASE::Animation::TCB;
             }
             if (b) {
-                anim.akeyPositions.push_back(aiVectorKey());
+                anim.akeyPositions.emplace_back();
                 aiVectorKey &key = anim.akeyPositions.back();
                 ParseLV4MeshFloatTriple(&key.mValue.x, iIndex);
                 key.mTime = (double)iIndex;
@@ -1084,7 +1089,7 @@ void Parser::ParseLV3RotAnimationBlock(ASE::Animation &anim) {
                 anim.mRotationType = ASE::Animation::TCB;
             }
             if (b) {
-                anim.akeyRotations.push_back(aiQuatKey());
+                anim.akeyRotations.emplace_back();
                 aiQuatKey &key = anim.akeyRotations.back();
                 aiVector3D v;
                 ai_real f;

+ 1 - 1
Engine/lib/assimp/code/AssetLib/ASE/ASEParser.h

@@ -116,7 +116,7 @@ struct Material : public D3DS::Material {
         return *this;
     }
 
-    ~Material() {}
+    ~Material() = default;
 
     //! Contains all sub materials of this material
     std::vector<Material> avSubMaterials;

+ 9 - 5
Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.cpp

@@ -130,7 +130,7 @@ inline size_t Write<double>(IOStream *stream, const double &f) {
 // Serialize a vec3
 template <>
 inline size_t Write<aiVector3D>(IOStream *stream, const aiVector3D &v) {
-    size_t t = Write<float>(stream, v.x);
+    size_t t = Write<ai_real>(stream, v.x);
     t += Write<float>(stream, v.y);
     t += Write<float>(stream, v.z);
 
@@ -141,7 +141,7 @@ inline size_t Write<aiVector3D>(IOStream *stream, const aiVector3D &v) {
 // Serialize a color value
 template <>
 inline size_t Write<aiColor3D>(IOStream *stream, const aiColor3D &v) {
-    size_t t = Write<float>(stream, v.r);
+    size_t t = Write<ai_real>(stream, v.r);
     t += Write<float>(stream, v.g);
     t += Write<float>(stream, v.b);
 
@@ -152,7 +152,7 @@ inline size_t Write<aiColor3D>(IOStream *stream, const aiColor3D &v) {
 // Serialize a color value
 template <>
 inline size_t Write<aiColor4D>(IOStream *stream, const aiColor4D &v) {
-    size_t t = Write<float>(stream, v.r);
+    size_t t = Write<ai_real>(stream, v.r);
     t += Write<float>(stream, v.g);
     t += Write<float>(stream, v.b);
     t += Write<float>(stream, v.a);
@@ -164,7 +164,7 @@ inline size_t Write<aiColor4D>(IOStream *stream, const aiColor4D &v) {
 // Serialize a quaternion
 template <>
 inline size_t Write<aiQuaternion>(IOStream *stream, const aiQuaternion &v) {
-    size_t t = Write<float>(stream, v.w);
+    size_t t = Write<ai_real>(stream, v.w);
     t += Write<float>(stream, v.x);
     t += Write<float>(stream, v.y);
     t += Write<float>(stream, v.z);
@@ -190,7 +190,7 @@ template <>
 inline size_t Write<aiMatrix4x4>(IOStream *stream, const aiMatrix4x4 &m) {
     for (unsigned int i = 0; i < 4; ++i) {
         for (unsigned int i2 = 0; i2 < 4; ++i2) {
-            Write<float>(stream, m[i][i2]);
+            Write<ai_real>(stream, m[i][i2]);
         }
     }
 
@@ -642,6 +642,10 @@ protected:
         Write<aiString>(&chunk, l->mName);
         Write<unsigned int>(&chunk, l->mType);
 
+        Write<aiVector3D>(&chunk, l->mPosition);
+        Write<aiVector3D>(&chunk, l->mDirection);
+        Write<aiVector3D>(&chunk, l->mUp);
+
         if (l->mType != aiLightSource_DIRECTIONAL) {
             Write<float>(&chunk, l->mAttenuationConstant);
             Write<float>(&chunk, l->mAttenuationLinear);

+ 4 - 0
Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.cpp

@@ -556,6 +556,10 @@ void AssbinImporter::ReadBinaryLight(IOStream *stream, aiLight *l) {
     l->mName = Read<aiString>(stream);
     l->mType = (aiLightSourceType)Read<unsigned int>(stream);
 
+    l->mPosition = Read<aiVector3D>(stream);
+    l->mDirection = Read<aiVector3D>(stream);
+    l->mUp = Read<aiVector3D>(stream);
+
     if (l->mType != aiLightSource_DIRECTIONAL) {
         l->mAttenuationConstant = Read<float>(stream);
         l->mAttenuationLinear = Read<float>(stream);

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Assjson/mesh_splitter.cpp

@@ -304,7 +304,7 @@ void MeshSplitter :: SplitMesh(unsigned int a, aiMesh* in_mesh, std::vector<std:
 		}
 
 		// add the newly created mesh to the list
-		source_mesh_map.push_back(std::make_pair(out_mesh,a));
+		source_mesh_map.emplace_back(out_mesh,a);
 
 		if (base == in_mesh->mNumFaces) {
 			break;

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.cpp

@@ -365,7 +365,7 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
 
                 ioprintf(io, "\t\t\t<MatProperty key=\"%s\" \n\t\t\ttype=\"%s\" tex_usage=\"%s\" tex_index=\"%u\"",
                         prop->mKey.data, sz,
-                        ::TextureTypeToString((aiTextureType)prop->mSemantic), prop->mIndex);
+                        ::aiTextureTypeToString((aiTextureType)prop->mSemantic), prop->mIndex);
 
                 if (prop->mType == aiPTI_Float) {
                     ioprintf(io, " size=\"%i\">\n\t\t\t\t",

+ 5 - 7
Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.cpp

@@ -88,9 +88,7 @@ void DeleteAllBarePointers(std::vector<T> &x) {
     }
 }
 
-B3DImporter::~B3DImporter() {
-    // empty
-}
+B3DImporter::~B3DImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 bool B3DImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
@@ -479,13 +477,13 @@ void B3DImporter::ReadKEYS(aiNodeAnim *nodeAnim) {
     while (ChunkSize()) {
         int frame = ReadInt();
         if (flags & 1) {
-            trans.push_back(aiVectorKey(frame, ReadVec3()));
+            trans.emplace_back(frame, ReadVec3());
         }
         if (flags & 2) {
-            scale.push_back(aiVectorKey(frame, ReadVec3()));
+            scale.emplace_back(frame, ReadVec3());
         }
         if (flags & 4) {
-            rot.push_back(aiQuatKey(frame, ReadQuat()));
+            rot.emplace_back(frame, ReadQuat());
         }
     }
 
@@ -673,7 +671,7 @@ void B3DImporter::ReadBB3D(aiScene *scene) {
                         int bone = v.bones[k];
                         float weight = v.weights[k];
 
-                        vweights[bone].push_back(aiVertexWeight(vertIdx + faceIndex, weight));
+                        vweights[bone].emplace_back(vertIdx + faceIndex, weight);
                     }
                 }
                 ++face;

+ 2 - 2
Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.cpp

@@ -88,7 +88,7 @@ BVHLoader::BVHLoader() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-BVHLoader::~BVHLoader() {}
+BVHLoader::~BVHLoader() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -186,7 +186,7 @@ aiNode *BVHLoader::ReadNode() {
     std::vector<aiNode *> childNodes;
 
     // and create an bone entry for it
-    mNodes.push_back(Node(node));
+    mNodes.emplace_back(node);
     Node &internNode = mNodes.back();
 
     // now read the node's contents

+ 4 - 4
Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.cpp

@@ -325,10 +325,10 @@ void SectionParser ::Next() {
     stream.SetCurrentPos(current.start + current.size);
 
     const char tmp[] = {
-        (const char)stream.GetI1(),
-        (const char)stream.GetI1(),
-        (const char)stream.GetI1(),
-        (const char)stream.GetI1()
+        (char)stream.GetI1(),
+        (char)stream.GetI1(),
+        (char)stream.GetI1(),
+        (char)stream.GetI1()
     };
     current.id = std::string(tmp, tmp[3] ? 4 : tmp[2] ? 3 : tmp[1] ? 2 : 1);
 

+ 2 - 2
Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.h

@@ -416,10 +416,10 @@ template <>
 struct Structure::_defaultInitializer<ErrorPolicy_Fail> {
 
     template <typename T>
-    void operator()(T & /*out*/, const char * = "") {
+    void operator()(T & /*out*/, const char *message = "") {
         // obviously, it is crucial that _DefaultInitializer is used
         // only from within a catch clause.
-        throw DeadlyImportError("Constructing BlenderDNA Structure encountered an error");
+        throw DeadlyImportError("Constructing BlenderDNA Structure encountered an error: ", message);
     }
 };
 

+ 1 - 2
Engine/lib/assimp/code/AssetLib/Blender/BlenderIntermediate.h

@@ -65,8 +65,7 @@ namespace Blender {
     struct TempArray    {
         typedef TCLASS< T*,std::allocator<T*> > mywrap;
 
-        TempArray() {
-        }
+        TempArray() = default;
 
         ~TempArray () {
             for(T* elem : arr) {

+ 2 - 2
Engine/lib/assimp/code/AssetLib/Blender/BlenderLoader.cpp

@@ -281,7 +281,7 @@ void BlenderImporter::ExtractScene(Scene &out, const FileDatabase &file) {
 }
 
 // ------------------------------------------------------------------------------------------------
-void BlenderImporter::ParseSubCollection(const Blender::Scene &in, aiNode *root, std::shared_ptr<Collection> collection, ConversionData &conv_data) {
+void BlenderImporter::ParseSubCollection(const Blender::Scene &in, aiNode *root, const std::shared_ptr<Collection>& collection, ConversionData &conv_data) {
 
     std::deque<Object *> root_objects;
     // Count number of objects
@@ -986,7 +986,7 @@ void BlenderImporter::ConvertMesh(const Scene & /*in*/, const Object * /*obj*/,
     // key is material number, value is the TextureUVMapping for the material
     typedef std::map<uint32_t, TextureUVMapping> MaterialTextureUVMappings;
     MaterialTextureUVMappings matTexUvMappings;
-    const uint32_t maxMat = static_cast<const uint32_t>(mesh->mat.size());
+    const uint32_t maxMat = static_cast<uint32_t>(mesh->mat.size());
     for (uint32_t m = 0; m < maxMat; ++m) {
         // get material by index
         const std::shared_ptr<Material> pMat = mesh->mat[m];

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Blender/BlenderLoader.h

@@ -117,7 +117,7 @@ protected:
     void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
     void ParseBlendFile(Blender::FileDatabase &out, std::shared_ptr<IOStream> stream);
     void ExtractScene(Blender::Scene &out, const Blender::FileDatabase &file);
-    void ParseSubCollection(const Blender::Scene &in, aiNode *root, std::shared_ptr<Blender::Collection> collection, Blender::ConversionData &conv_data);
+    void ParseSubCollection(const Blender::Scene &in, aiNode *root, const std::shared_ptr<Blender::Collection>& collection, Blender::ConversionData &conv_data);
     void ConvertBlendFile(aiScene *out, const Blender::Scene &in, const Blender::FileDatabase &file);
 
 private:

+ 3 - 6
Engine/lib/assimp/code/AssetLib/Blender/BlenderModifier.cpp

@@ -71,10 +71,6 @@ static const fpCreateModifier creators[] = {
     nullptr // sentinel
 };
 
-// ------------------------------------------------------------------------------------------------
-struct SharedModifierData : ElemBase {
-    ModifierData modifier;
-};
 
 // ------------------------------------------------------------------------------------------------
 void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_data, const Scene &in, const Object &orig_object) {
@@ -157,6 +153,7 @@ void BlenderModifier_Mirror ::DoIt(aiNode &out, ConversionData &conv_data, const
     // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
     const MirrorModifierData &mir = static_cast<const MirrorModifierData &>(orig_modifier);
     ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
+    std::shared_ptr<Object> mirror_ob = mir.mirror_ob.lock();
 
     conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes);
 
@@ -171,8 +168,8 @@ void BlenderModifier_Mirror ::DoIt(aiNode &out, ConversionData &conv_data, const
         const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
         const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f;
 
-        if (mir.mirror_ob) {
-            const aiVector3D center(mir.mirror_ob->obmat[3][0], mir.mirror_ob->obmat[3][1], mir.mirror_ob->obmat[3][2]);
+        if (mirror_ob) {
+            const aiVector3D center(mirror_ob->obmat[3][0], mirror_ob->obmat[3][1], mirror_ob->obmat[3][2]);
             for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
                 aiVector3D &v = mesh->mVertices[j];
 

+ 12 - 6
Engine/lib/assimp/code/AssetLib/Blender/BlenderScene.cpp

@@ -624,7 +624,9 @@ void Structure ::Convert<ListBase>(
         const FileDatabase &db) const {
 
     ReadFieldPtr<ErrorPolicy_Igno>(dest.first, "*first", db);
-    ReadFieldPtr<ErrorPolicy_Igno>(dest.last, "*last", db);
+    std::shared_ptr<ElemBase> last;
+    ReadFieldPtr<ErrorPolicy_Igno>(last, "*last", db);
+    dest.last = last;
 
     db.reader->IncPtr(size);
 }
@@ -648,7 +650,9 @@ void Structure ::Convert<ModifierData>(
         const FileDatabase &db) const {
 
     ReadFieldPtr<ErrorPolicy_Warn>(dest.next, "*next", db);
-    ReadFieldPtr<ErrorPolicy_Warn>(dest.prev, "*prev", db);
+    std::shared_ptr<ElemBase> prev;
+    ReadFieldPtr<ErrorPolicy_Warn>(prev, "*prev", db);
+    dest.prev = prev;
     ReadField<ErrorPolicy_Igno>(dest.type, "type", db);
     ReadField<ErrorPolicy_Igno>(dest.mode, "mode", db);
     ReadFieldArray<ErrorPolicy_Igno>(dest.name, "name", db);
@@ -772,7 +776,9 @@ void Structure ::Convert<MirrorModifierData>(
     ReadField<ErrorPolicy_Igno>(dest.axis, "axis", db);
     ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
     ReadField<ErrorPolicy_Igno>(dest.tolerance, "tolerance", db);
-    ReadFieldPtr<ErrorPolicy_Igno>(dest.mirror_ob, "*mirror_ob", db);
+    std::shared_ptr<Object> mirror_ob;
+    ReadFieldPtr<ErrorPolicy_Igno>(mirror_ob, "*mirror_ob", db);
+    dest.mirror_ob = mirror_ob;
 
     db.reader->IncPtr(size);
 }
@@ -833,9 +839,9 @@ void Structure::Convert<CustomDataLayer>(
     ReadField<ErrorPolicy_Fail>(dest.flag, "flag", db);
     ReadField<ErrorPolicy_Fail>(dest.active, "active", db);
     ReadField<ErrorPolicy_Fail>(dest.active_rnd, "active_rnd", db);
-    ReadField<ErrorPolicy_Fail>(dest.active_clone, "active_clone", db);
-    ReadField<ErrorPolicy_Fail>(dest.active_mask, "active_mask", db);
-    ReadField<ErrorPolicy_Fail>(dest.uid, "uid", db);
+    ReadField<ErrorPolicy_Warn>(dest.active_clone, "active_clone", db);
+    ReadField<ErrorPolicy_Warn>(dest.active_mask, "active_mask", db);
+    ReadField<ErrorPolicy_Warn>(dest.uid, "uid", db);
     ReadFieldArray<ErrorPolicy_Warn>(dest.name, "name", db);
     ReadCustomDataPtr<ErrorPolicy_Fail>(dest.data, dest.type, "*data", db);
 

+ 12 - 8
Engine/lib/assimp/code/AssetLib/Blender/BlenderScene.h

@@ -124,7 +124,7 @@ struct ID : ElemBase {
 // -------------------------------------------------------------------------------
 struct ListBase : ElemBase {
     std::shared_ptr<ElemBase> first;
-    std::shared_ptr<ElemBase> last;
+    std::weak_ptr<ElemBase> last;
 };
 
 // -------------------------------------------------------------------------------
@@ -642,14 +642,21 @@ struct ModifierData : ElemBase {
     };
 
     std::shared_ptr<ElemBase> next WARN;
-    std::shared_ptr<ElemBase> prev WARN;
+    std::weak_ptr<ElemBase> prev WARN;
 
     int type, mode;
     char name[32];
 };
 
+
+// ------------------------------------------------------------------------------------------------
+struct SharedModifierData : ElemBase {
+    ModifierData modifier;
+};
+
+
 // -------------------------------------------------------------------------------
-struct SubsurfModifierData : ElemBase {
+struct SubsurfModifierData : SharedModifierData {
 
     enum Type {
 
@@ -662,7 +669,6 @@ struct SubsurfModifierData : ElemBase {
         FLAGS_SubsurfUV = 1 << 3
     };
 
-    ModifierData modifier FAIL;
     short subdivType WARN;
     short levels FAIL;
     short renderLevels;
@@ -670,7 +676,7 @@ struct SubsurfModifierData : ElemBase {
 };
 
 // -------------------------------------------------------------------------------
-struct MirrorModifierData : ElemBase {
+struct MirrorModifierData : SharedModifierData {
 
     enum Flags {
         Flags_CLIPPING = 1 << 0,
@@ -682,11 +688,9 @@ struct MirrorModifierData : ElemBase {
         Flags_VGROUP = 1 << 6
     };
 
-    ModifierData modifier FAIL;
-
     short axis, flag;
     float tolerance;
-    std::shared_ptr<Object> mirror_ob;
+    std::weak_ptr<Object> mirror_ob;
 };
 
 // -------------------------------------------------------------------------------

+ 1 - 3
Engine/lib/assimp/code/AssetLib/Blender/BlenderTessellator.cpp

@@ -274,9 +274,7 @@ BlenderTessellatorP2T::BlenderTessellatorP2T( BlenderBMeshConverter& converter )
 }
 
 // ------------------------------------------------------------------------------------------------
-BlenderTessellatorP2T::~BlenderTessellatorP2T( )
-{
-}
+
 
 // ------------------------------------------------------------------------------------------------
 void BlenderTessellatorP2T::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Blender/BlenderTessellator.h

@@ -186,7 +186,7 @@ namespace Assimp
     {
     public:
         BlenderTessellatorP2T( BlenderBMeshConverter& converter );
-        ~BlenderTessellatorP2T( );
+        ~BlenderTessellatorP2T( ) = default;
 
         void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
 

+ 7 - 11
Engine/lib/assimp/code/AssetLib/COB/COBLoader.cpp

@@ -91,15 +91,11 @@ static const aiImporterDesc desc = {
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-COBImporter::COBImporter() {
-    // empty
-}
+COBImporter::COBImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-COBImporter::~COBImporter() {
-    // empty
-}
+COBImporter::~COBImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -522,7 +518,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk
         return;
     }
 
-    out.materials.push_back(Material());
+    out.materials.emplace_back();
     Material &mat = out.materials.back();
     mat = nfo;
 
@@ -753,7 +749,7 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
                     ThrowException("Expected Face line");
                 }
 
-                msh.faces.push_back(Face());
+                msh.faces.emplace_back();
                 Face &face = msh.faces.back();
 
                 face.indices.resize(strtoul10(splitter[2]));
@@ -956,7 +952,7 @@ void COBImporter::ReadPolH_Binary(COB::Scene &out, StreamReaderLE &reader, const
                 ThrowException(format("A hole is the first entity in the `PolH` chunk with id ") << nfo.id);
             }
         } else
-            msh.faces.push_back(Face());
+            msh.faces.emplace_back();
         Face &f = msh.faces.back();
 
         const size_t num = reader.GetI2();
@@ -968,7 +964,7 @@ void COBImporter::ReadPolH_Binary(COB::Scene &out, StreamReaderLE &reader, const
         }
 
         for (size_t x = 0; x < num; ++x) {
-            f.indices.push_back(VertexIndex());
+            f.indices.emplace_back();
 
             VertexIndex &v = f.indices.back();
             v.pos_idx = reader.GetI4();
@@ -1008,7 +1004,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const
 
     const chunk_guard cn(nfo, reader);
 
-    out.materials.push_back(Material());
+    out.materials.emplace_back();
     Material &mat = out.materials.back();
     mat = nfo;
 

+ 1 - 1
Engine/lib/assimp/code/AssetLib/COB/COBScene.h

@@ -107,7 +107,7 @@ struct Node : public ChunkInfo
         TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
     };
 
-    virtual ~Node() {}
+    virtual ~Node() = default;
     Node(Type type) : type(type), unit_scale(1.f){}
 
     Type type;

+ 1 - 2
Engine/lib/assimp/code/AssetLib/CSM/CSMLoader.cpp

@@ -85,8 +85,7 @@ CSMImporter::CSMImporter()
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-CSMImporter::~CSMImporter()
-{}
+CSMImporter::~CSMImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.

+ 3 - 4
Engine/lib/assimp/code/AssetLib/Collada/ColladaExporter.cpp

@@ -154,8 +154,7 @@ ColladaExporter::ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, con
 
 // ------------------------------------------------------------------------------------------------
 // Destructor
-ColladaExporter::~ColladaExporter() {
-}
+ColladaExporter::~ColladaExporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Starts writing the contents
@@ -1330,9 +1329,9 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex) {
             std::vector<std::string> names;
             for (size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
                 if (nodeAnim->mPreState == aiAnimBehaviour_DEFAULT || nodeAnim->mPreState == aiAnimBehaviour_LINEAR || nodeAnim->mPreState == aiAnimBehaviour_REPEAT) {
-                    names.push_back("LINEAR");
+                    names.emplace_back("LINEAR");
                 } else if (nodeAnim->mPostState == aiAnimBehaviour_CONSTANT) {
-                    names.push_back("STEP");
+                    names.emplace_back("STEP");
                 }
             }
 

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Collada/ColladaExporter.h

@@ -233,7 +233,7 @@ public:
         Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
         Property shininess, transparency, index_refraction;
 
-        Material() {}
+        Material() = default;
     };
 
     std::map<unsigned int, std::string> textures;

+ 5 - 0
Engine/lib/assimp/code/AssetLib/Collada/ColladaHelper.h

@@ -621,6 +621,11 @@ struct Animation {
 
         for (std::vector<Animation *>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) {
             Animation *anim = *it;
+            // Assign the first animation name to the parent if empty.
+            // This prevents the animation name from being lost when animations are combined
+            if (mName.empty()) {
+              mName = anim->mName;
+            }
             CombineSingleChannelAnimationsRecursively(anim);
 
             if (childrenAnimationsHaveDifferentChannels && anim->mChannels.size() == 1 &&

+ 7 - 6
Engine/lib/assimp/code/AssetLib/Collada/ColladaLoader.cpp

@@ -102,6 +102,7 @@ ColladaLoader::ColladaLoader() :
         mTextures(),
         mAnims(),
         noSkeletonMesh(false),
+        removeEmptyBones(false),
         ignoreUpDirection(false),
         useColladaName(false),
         mNodeNameCounter(0) {
@@ -110,9 +111,7 @@ ColladaLoader::ColladaLoader() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-ColladaLoader::~ColladaLoader() {
-    // empty
-}
+ColladaLoader::~ColladaLoader() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -130,6 +129,7 @@ bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool
 // ------------------------------------------------------------------------------------------------
 void ColladaLoader::SetupProperties(const Importer *pImp) {
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
+    removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0;
     ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
     useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0;
 }
@@ -798,9 +798,10 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
         // count the number of bones which influence vertices of the current submesh
         size_t numRemainingBones = 0;
         for (const auto & dstBone : dstBones) {
-            if (!dstBone.empty()) {
-                ++numRemainingBones;
+            if (dstBone.empty() && removeEmptyBones) {
+                continue;
             }
+            ++numRemainingBones;
         }
 
         // create bone array and copy bone weights one by one
@@ -809,7 +810,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
         size_t boneCount = 0;
         for (size_t a = 0; a < numBones; ++a) {
             // omit bones without weights
-            if (dstBones[a].empty()) {
+            if (dstBones[a].empty() && removeEmptyBones) {
                 continue;
             }
 

+ 1 - 0
Engine/lib/assimp/code/AssetLib/Collada/ColladaLoader.h

@@ -237,6 +237,7 @@ protected:
     std::vector<aiAnimation *> mAnims;
 
     bool noSkeletonMesh;
+    bool removeEmptyBones;
     bool ignoreUpDirection;
     bool useColladaName;
 

+ 10 - 9
Engine/lib/assimp/code/AssetLib/Collada/ColladaParser.cpp

@@ -1616,6 +1616,7 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
                     XmlParser::getValueAsString(currentNode, v);
                     const char *content = v.c_str();
                     vcount.reserve(numPrimitives);
+                    SkipSpacesAndLineEnd(&content);
                     for (unsigned int a = 0; a < numPrimitives; a++) {
                         if (*content == 0) {
                             throw DeadlyImportError("Expected more values while reading <vcount> contents.");
@@ -1928,7 +1929,7 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
     switch (pInput.mType) {
     case IT_Position: // ignore all position streams except 0 - there can be only one position
         if (pInput.mIndex == 0) {
-            pMesh.mPositions.push_back(aiVector3D(obj[0], obj[1], obj[2]));
+            pMesh.mPositions.emplace_back(obj[0], obj[1], obj[2]);
         } else {
             ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
         }
@@ -1940,7 +1941,7 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
 
         // ignore all normal streams except 0 - there can be only one normal
         if (pInput.mIndex == 0) {
-            pMesh.mNormals.push_back(aiVector3D(obj[0], obj[1], obj[2]));
+            pMesh.mNormals.emplace_back(obj[0], obj[1], obj[2]);
         } else {
             ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
         }
@@ -1952,7 +1953,7 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
 
         // ignore all tangent streams except 0 - there can be only one tangent
         if (pInput.mIndex == 0) {
-            pMesh.mTangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
+            pMesh.mTangents.emplace_back(obj[0], obj[1], obj[2]);
         } else {
             ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
         }
@@ -1965,7 +1966,7 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
 
         // ignore all bitangent streams except 0 - there can be only one bitangent
         if (pInput.mIndex == 0) {
-            pMesh.mBitangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
+            pMesh.mBitangents.emplace_back(obj[0], obj[1], obj[2]);
         } else {
             ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
         }
@@ -1978,7 +1979,7 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
                 pMesh.mTexCoords[pInput.mIndex].insert(pMesh.mTexCoords[pInput.mIndex].end(),
                         pMesh.mPositions.size() - pMesh.mTexCoords[pInput.mIndex].size() - 1, aiVector3D(0, 0, 0));
 
-            pMesh.mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2]));
+            pMesh.mTexCoords[pInput.mIndex].emplace_back(obj[0], obj[1], obj[2]);
             if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) {
                 pMesh.mNumUVComponents[pInput.mIndex] = 3;
             }
@@ -2057,7 +2058,7 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
                 XmlParser::getStdStrAttribute(currentNode, "id", child->mID);
             }
             if (XmlParser::hasAttribute(currentNode, "sid")) {
-                XmlParser::getStdStrAttribute(currentNode, "id", child->mSID);
+                XmlParser::getStdStrAttribute(currentNode, "sid", child->mSID);
             }
             if (XmlParser::hasAttribute(currentNode, "name")) {
                 XmlParser::getStdStrAttribute(currentNode, "name", child->mName);
@@ -2112,7 +2113,7 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
                 if (s[0] != '#') {
                     ASSIMP_LOG_ERROR("Collada: Unresolved reference format of node");
                 } else {
-                    pNode->mNodeInstances.push_back(NodeInstance());
+                    pNode->mNodeInstances.emplace_back();
                     pNode->mNodeInstances.back().mNode = s.c_str() + 1;
                 }
             }
@@ -2128,7 +2129,7 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
                     throw DeadlyImportError("Unknown reference format in <instance_light> element");
                 }
 
-                pNode->mLights.push_back(LightInstance());
+                pNode->mLights.emplace_back();
                 pNode->mLights.back().mLight = url.c_str() + 1;
             }
         } else if (currentName == "instance_camera") {
@@ -2139,7 +2140,7 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
                 if (url[0] != '#') {
                     throw DeadlyImportError("Unknown reference format in <instance_camera> element");
                 }
-                pNode->mCameras.push_back(CameraInstance());
+                pNode->mCameras.emplace_back();
                 pNode->mCameras.back().mCamera = url.c_str() + 1;
             }
         }

+ 8 - 11
Engine/lib/assimp/code/AssetLib/DXF/DXFLoader.cpp

@@ -110,16 +110,11 @@ static const aiImporterDesc desc = {
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-DXFImporter::DXFImporter()
-: BaseImporter() {
-    // empty
-}
+DXFImporter::DXFImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-DXFImporter::~DXFImporter() {
-    // empty
-}
+DXFImporter::~DXFImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -368,7 +363,9 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
         // XXX this would be the place to implement recursive expansion if needed.
         const DXF::Block& bl_src = *(*it).second;
 
-        for (std::shared_ptr<const DXF::PolyLine> pl_in : bl_src.lines) {
+        const size_t size = bl_src.lines.size(); // the size may increase in the loop
+        for (size_t i = 0; i < size; ++i) {
+            std::shared_ptr<const DXF::PolyLine> pl_in = bl_src.lines[i];
             if (!pl_in) {
                 ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping.");
                 continue;
@@ -473,7 +470,7 @@ void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) {
 // ------------------------------------------------------------------------------------------------
 void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output) {
     // push a new block onto the stack.
-    output.blocks.push_back( DXF::Block() );
+    output.blocks.emplace_back();
     DXF::Block& block = output.blocks.back();
 
     while( !reader.End() && !reader.Is(0,"ENDBLK")) {
@@ -518,7 +515,7 @@ void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output) {
 // ------------------------------------------------------------------------------------------------
 void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output) {
     // Push a new block onto the stack.
-    output.blocks.push_back( DXF::Block() );
+    output.blocks.emplace_back();
     DXF::Block& block = output.blocks.back();
 
     block.name = AI_DXF_ENTITIES_MAGIC_BLOCK;
@@ -548,7 +545,7 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
 }
 
 void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output) {
-    output.blocks.back().insertions.push_back( DXF::InsertBlock() );
+    output.blocks.back().insertions.emplace_back();
     DXF::InsertBlock& bl = output.blocks.back().insertions.back();
 
     while( !reader.End() && !reader.Is(0)) {

+ 0 - 21
Engine/lib/assimp/code/AssetLib/FBX/FBXAnimation.cpp

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2022, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -87,11 +86,6 @@ AnimationCurve::AnimationCurve(uint64_t id, const Element &element, const std::s
     }
 }
 
-// ------------------------------------------------------------------------------------------------
-AnimationCurve::~AnimationCurve() {
-    // empty
-}
-
 // ------------------------------------------------------------------------------------------------
 AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element &element, const std::string &name,
         const Document &doc, const char *const *target_prop_whitelist /*= nullptr*/,
@@ -147,11 +141,6 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element &element, cons
     props = GetPropertyTable(doc, "AnimationCurveNode.FbxAnimCurveNode", element, sc, false);
 }
 
-// ------------------------------------------------------------------------------------------------
-AnimationCurveNode::~AnimationCurveNode() {
-    // empty
-}
-
 // ------------------------------------------------------------------------------------------------
 const AnimationCurveMap &AnimationCurveNode::Curves() const {
     if (curves.empty()) {
@@ -193,11 +182,6 @@ AnimationLayer::AnimationLayer(uint64_t id, const Element &element, const std::s
     props = GetPropertyTable(doc, "AnimationLayer.FbxAnimLayer", element, sc, true);
 }
 
-// ------------------------------------------------------------------------------------------------
-AnimationLayer::~AnimationLayer() {
-    // empty
-}
-
 // ------------------------------------------------------------------------------------------------
 AnimationCurveNodeList AnimationLayer::Nodes(const char *const *target_prop_whitelist /*= nullptr*/,
         size_t whitelist_size /*= 0*/) const {
@@ -279,11 +263,6 @@ AnimationStack::AnimationStack(uint64_t id, const Element &element, const std::s
     }
 }
 
-// ------------------------------------------------------------------------------------------------
-AnimationStack::~AnimationStack() {
-    // empty
-}
-
 } // namespace FBX
 } // namespace Assimp
 

+ 1 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXBinaryTokenizer.cpp

@@ -472,7 +472,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
     }
     catch (const DeadlyImportError& e)
     {
-        if (!is64bits && (length > std::numeric_limits<std::uint32_t>::max())) {
+        if (!is64bits && (length > std::numeric_limits<uint32_t>::max())) {
             throw DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", ai_to_string(version), ") of the FBX format. (", e.what(), ")");
         }
         throw;

+ 2 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXCommon.h

@@ -50,7 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace FBX {
 
-const std::string NULL_RECORD = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit
+static constexpr size_t NumNullRecords = 25;
+const char NULL_RECORD[NumNullRecords] = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit
     '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
     '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
 }; // who knows why, it looks like two integers 32/64 bit (compressed and uncompressed sizes?) + 1 byte (might be compression type?)

+ 0 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXCompileConfig.h

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2022, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 126 - 75
Engine/lib/assimp/code/AssetLib/FBX/FBXConverter.cpp

@@ -65,12 +65,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <stdlib.h>
 #include <cstdint>
 #include <iomanip>
-#include <iostream>
 #include <iterator>
 #include <memory>
 #include <sstream>
-#include <tuple>
-#include <vector>
 
 namespace Assimp {
 namespace FBX {
@@ -187,8 +184,7 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
 
 /// This struct manages nodes which may or may not end up in the node hierarchy.
 /// When a node becomes a child of another node, that node becomes its owner and mOwnership should be released.
-struct FBXConverter::PotentialNode
-{
+struct FBXConverter::PotentialNode {
     PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
     PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
     aiNode* operator->() { return mNode; }
@@ -231,7 +227,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
         if (nullptr != model) {
             nodes_chain.clear();
             post_nodes_chain.clear();
-
             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
@@ -247,7 +242,7 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
             ai_assert(nodes_chain.size());
 
             if (need_additional_node) {
-                nodes_chain.emplace_back(PotentialNode(node_name));
+                nodes_chain.emplace_back(node_name);
             }
 
             //setup metadata on newest node
@@ -266,8 +261,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
 
                 child->mParent = last_parent;
                 last_parent = child.mNode;
-
-                new_abs_transform *= child->mTransformation;
             }
 
             // attach geometry
@@ -290,8 +283,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
 
                     postnode->mParent = last_parent;
                     last_parent = postnode.mNode;
-
-                    new_abs_transform *= postnode->mTransformation;
                 }
             } else {
                 // free the nodes we allocated as we don't need them
@@ -314,19 +305,16 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
         }
     }
 
-    if (nodes.size()) {
-        parent->mChildren = new aiNode *[nodes.size()]();
-        parent->mNumChildren = static_cast<unsigned int>(nodes.size());
-
-        for (unsigned int i = 0; i < nodes.size(); ++i)
-        {
-            parent->mChildren[i] = nodes[i].mOwnership.release();
-        }
-        nodes.clear();
-    } else {
+    if (nodes.empty()) {
         parent->mNumChildren = 0;
         parent->mChildren = nullptr;
     }
+
+    parent->mChildren = new aiNode *[nodes.size()]();
+    parent->mNumChildren = static_cast<unsigned int>(nodes.size());
+    for (unsigned int i = 0; i < nodes.size(); ++i) {
+        parent->mChildren[i] = nodes[i].mOwnership.release();
+    }
 }
 
 void FBXConverter::ConvertLights(const Model &model, const std::string &orig_name) {
@@ -452,7 +440,7 @@ void FBXConverter::GetUniqueName(const std::string &name, std::string &uniqueNam
     auto it_pair = mNodeNames.insert({ name, 0 }); // duplicate node name instance count
     unsigned int &i = it_pair.first->second;
     while (!it_pair.second) {
-        i++;
+        ++i;
         std::ostringstream ext;
         ext << name << std::setfill('0') << std::setw(3) << i;
         uniqueName = ext.str();
@@ -651,9 +639,8 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
 
 bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
     const PropertyTable &props = model.Props();
-    bool ok;
 
-    const float zero_epsilon = ai_epsilon;
+    const auto zero_epsilon = ai_epsilon;
     const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
     for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
         const TransformationComp comp = static_cast<TransformationComp>(i);
@@ -665,6 +652,7 @@ bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
 
         bool scale_compare = (comp == TransformationComp_GeometricScaling || comp == TransformationComp_Scaling);
 
+        bool ok = true;
         const aiVector3D &v = PropertyGet<aiVector3D>(props, NameTransformationCompProperty(comp), ok);
         if (ok && scale_compare) {
             if ((v - all_ones).SquareLength() > zero_epsilon) {
@@ -899,20 +887,17 @@ void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
     }
 }
 
-void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
-        const aiMatrix4x4 &absolute_transform) {
+void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform) {
     const std::vector<const Geometry *> &geos = model.GetGeometry();
 
     std::vector<unsigned int> meshes;
     meshes.reserve(geos.size());
 
     for (const Geometry *geo : geos) {
-
         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, parent, root_node,
-                    absolute_transform);
+            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, root_node);
@@ -933,8 +918,7 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root
 }
 
 std::vector<unsigned int>
-FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
-        const aiMatrix4x4 &absolute_transform) {
+FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform) {
     std::vector<unsigned int> temp;
 
     MeshMap::const_iterator it = meshes_converted.find(&mesh);
@@ -957,7 +941,7 @@ FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *
         const MatIndexArray::value_type base = mindices[0];
         for (MatIndexArray::value_type index : mindices) {
             if (index != base) {
-                return ConvertMeshMultiMaterial(mesh, model, parent, root_node, absolute_transform);
+                return ConvertMeshMultiMaterial(mesh, model, absolute_transform, parent, root_node);
             }
         }
     }
@@ -1031,9 +1015,36 @@ aiMesh *FBXConverter::SetupEmptyMesh(const Geometry &mesh, aiNode *parent) {
     return out_mesh;
 }
 
-unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
-        const aiMatrix4x4 &absolute_transform, aiNode *parent,
-        aiNode *) {
+static aiSkeleton *createAiSkeleton(SkeletonBoneContainer &sbc) {
+    if (sbc.MeshArray.empty() || sbc.SkeletonBoneToMeshLookup.empty()) {
+        return nullptr;
+    }
+
+    aiSkeleton *skeleton = new aiSkeleton;
+    for (auto *mesh : sbc.MeshArray) {
+        auto it = sbc.SkeletonBoneToMeshLookup.find(mesh);
+        if (it == sbc.SkeletonBoneToMeshLookup.end()) {
+            continue;
+        }
+        SkeletonBoneArray *ba = it->second;
+        if (ba == nullptr) {
+            continue;
+        }
+
+        skeleton->mNumBones = static_cast<unsigned int>(ba->size());
+        skeleton->mBones = new aiSkeletonBone*[skeleton->mNumBones];
+        size_t index = 0;
+        for (auto bone : (* ba)) {
+            skeleton->mBones[index] = bone;
+            ++index;
+        }
+    }
+
+    return skeleton;
+}
+
+unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform,
+        aiNode *parent, aiNode *) {
     const MatIndexArray &mindices = mesh.GetMaterialIndices();
     aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
 
@@ -1151,8 +1162,15 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
         ConvertMaterialForMesh(out_mesh, model, mesh, mindices[0]);
     }
 
-    if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr) {
+    if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr && !doc.Settings().useSkeleton) {
         ConvertWeights(out_mesh, mesh, absolute_transform, parent, NO_MATERIAL_SEPARATION, nullptr);
+    } else if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr && doc.Settings().useSkeleton) {
+        SkeletonBoneContainer sbc;
+        ConvertWeightsToSkeleton(out_mesh, mesh, absolute_transform, parent, NO_MATERIAL_SEPARATION, nullptr, sbc);
+        aiSkeleton *skeleton = createAiSkeleton(sbc);
+        if (skeleton != nullptr) {
+            mSkeletons.emplace_back(skeleton);
+        }
     }
 
     std::vector<aiAnimMesh *> animMeshes;
@@ -1199,9 +1217,8 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
 }
 
 std::vector<unsigned int>
-FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent,
-        aiNode *root_node,
-        const aiMatrix4x4 &absolute_transform) {
+FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform, aiNode *parent,
+        aiNode *root_node) {
     const MatIndexArray &mindices = mesh.GetMaterialIndices();
     ai_assert(mindices.size());
 
@@ -1211,7 +1228,7 @@ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &mo
     for (MatIndexArray::value_type index : mindices) {
         if (had.find(index) == had.end()) {
 
-            indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node, absolute_transform));
+            indices.push_back(ConvertMeshMultiMaterial(mesh, model, absolute_transform, index, parent, root_node));
             had.insert(index);
         }
     }
@@ -1219,10 +1236,8 @@ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &mo
     return indices;
 }
 
-unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model,
-        MatIndexArray::value_type index,
-        aiNode *parent, aiNode *,
-        const aiMatrix4x4 &absolute_transform) {
+unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform,
+        MatIndexArray::value_type index, aiNode *parent, aiNode *) {
     aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
 
     const MatIndexArray &mindices = mesh.GetMaterialIndices();
@@ -1435,20 +1450,47 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
     return static_cast<unsigned int>(mMeshes.size() - 1);
 }
 
-void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo,
-        const aiMatrix4x4 &absolute_transform,
+static void copyBoneToSkeletonBone(aiMesh *mesh, aiBone *bone, aiSkeletonBone *skeletonBone ) {
+    skeletonBone->mNumnWeights = bone->mNumWeights;
+    skeletonBone->mWeights = bone->mWeights;
+    skeletonBone->mOffsetMatrix = bone->mOffsetMatrix;
+    skeletonBone->mMeshId = mesh;
+    skeletonBone->mNode = bone->mNode;
+    skeletonBone->mParent = -1;
+}
+
+void FBXConverter::ConvertWeightsToSkeleton(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, aiNode *parent, unsigned int materialIndex,
+        std::vector<unsigned int> *outputVertStartIndices, SkeletonBoneContainer &skeletonContainer) {
+
+    if (skeletonContainer.SkeletonBoneToMeshLookup.find(out) != skeletonContainer.SkeletonBoneToMeshLookup.end()) {
+        return;
+    }
+
+    ConvertWeights(out, geo, absolute_transform, parent, materialIndex, outputVertStartIndices);
+    skeletonContainer.MeshArray.emplace_back(out);
+    SkeletonBoneArray *ba = new SkeletonBoneArray;
+    for (size_t i = 0; i < out->mNumBones; ++i) {
+        aiBone *bone = out->mBones[i];
+        if (bone == nullptr) {
+            continue;
+        }
+        aiSkeletonBone *skeletonBone = new aiSkeletonBone;
+        copyBoneToSkeletonBone(out, bone, skeletonBone);
+        ba->emplace_back(skeletonBone);
+    }
+    skeletonContainer.SkeletonBoneToMeshLookup[out] = ba;
+}
+
+void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
         aiNode *parent, unsigned int materialIndex,
         std::vector<unsigned int> *outputVertStartIndices) {
     ai_assert(geo.DeformerSkin());
 
-    std::vector<size_t> out_indices;
-    std::vector<size_t> index_out_indices;
-    std::vector<size_t> count_out_indices;
+    std::vector<size_t> out_indices, index_out_indices, count_out_indices;
 
     const Skin &sk = *geo.DeformerSkin();
 
-    std::vector<aiBone *> bones;
-
+    std::vector<aiBone*> bones;
     const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
     ai_assert(no_mat_check || outputVertStartIndices);
 
@@ -1521,26 +1563,20 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo,
         out->mBones = nullptr;
         out->mNumBones = 0;
         return;
-    } else {
-        out->mBones = new aiBone *[bones.size()]();
-        out->mNumBones = static_cast<unsigned int>(bones.size());
-
-        std::swap_ranges(bones.begin(), bones.end(), out->mBones);
-    }
-}
+    } 
 
-const aiNode *GetNodeByName(aiNode *current_node) {
-    aiNode *iter = current_node;
-    //printf("Child count: %d", iter->mNumChildren);
-    return iter;
+    out->mBones = new aiBone *[bones.size()]();
+    out->mNumBones = static_cast<unsigned int>(bones.size());
+    std::swap_ranges(bones.begin(), bones.end(), out->mBones);
 }
 
-void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
+void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const Cluster *cluster,
         std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
-        std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
+        std::vector<size_t> &count_out_indices, const aiMatrix4x4 & /* absolute_transform*/,
         aiNode *) {
-    ai_assert(cl); // make sure cluster valid
-    std::string deformer_name = cl->TargetNode()->Name();
+    ai_assert(cluster != nullptr); // make sure cluster valid
+
+    std::string deformer_name = cluster->TargetNode()->Name();
     aiString bone_name = aiString(FixNodeName(deformer_name));
 
     aiBone *bone = nullptr;
@@ -1553,14 +1589,16 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
         bone = new aiBone();
         bone->mName = bone_name;
 
+        bone->mOffsetMatrix = cluster->Transform();
         // store local transform link for post processing
-        bone->mOffsetMatrix = cl->TransformLink();
+        /*
+        bone->mOffsetMatrix = cluster->TransformLink();
         bone->mOffsetMatrix.Inverse();
 
         aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
 
         bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
-
+        */
         //
         // Now calculate the aiVertexWeights
         //
@@ -1571,7 +1609,7 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
         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 WeightArray &weights = cluster->GetWeights();
 
         const size_t c = index_out_indices.size();
         for (size_t i = 0; i < c; ++i) {
@@ -2161,6 +2199,9 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
     const float ShininessExponent = PropertyGet<float>(props, "ShininessExponent", ok);
     if (ok) {
         out_mat->AddProperty(&ShininessExponent, 1, AI_MATKEY_SHININESS);
+         // Match Blender behavior to extract roughness when only shininess is present
+        const float roughness = 1.0f - (sqrt(ShininessExponent) / 10.0f);
+        out_mat->AddProperty(&roughness, 1, AI_MATKEY_ROUGHNESS_FACTOR);
     }
 
     // TransparentColor / TransparencyFactor... gee thanks FBX :rolleyes:
@@ -2613,7 +2654,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
                 meshMorphAnim->mNumKeys = numKeys;
                 meshMorphAnim->mKeys = new aiMeshMorphKey[numKeys];
                 unsigned int j = 0;
-                for (auto animIt : *animData) {
+                for (auto &animIt : *animData) {
                     morphKeyData *keyData = animIt.second;
                     unsigned int numValuesAndWeights = static_cast<unsigned int>(keyData->values.size());
                     meshMorphAnim->mKeys[j].mNumValuesAndWeights = numValuesAndWeights;
@@ -3188,7 +3229,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
 
     bool ok = false;
     
-    const float zero_epsilon = ai_epsilon;
+    const auto zero_epsilon = ai_epsilon;
 
     const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
     if (ok && preRotation.SquareLength() > zero_epsilon) {
@@ -3275,7 +3316,7 @@ FBXConverter::KeyFrameListList FBXConverter::GetKeyframeList(const std::vector<c
                 }
             }
 
-            inputs.push_back(std::make_tuple(Keys, Values, mapto));
+            inputs.emplace_back(Keys, Values, mapto);
         }
     }
     return inputs; // pray for NRVO :-)
@@ -3326,13 +3367,17 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
                 float vc = curve->GetValues().at(1);
                 for (size_t n = 1; n < count; n++) {
                     while (std::abs(vc - vp) >= 180.0f) {
-                        float step = std::floor(float(tc - tp) / (vc - vp) * 179.0f);
+                        double step = std::floor(double(tc - tp) / std::abs(vc - vp) * 179.0f);
                         int64_t tnew = tp + int64_t(step);
-                        float vnew = vp + (vc - vp) * step / float(tc - tp);
+                        float vnew = vp + (vc - vp) * float(step / (tc - tp));
                         if (tnew >= adj_start && tnew <= adj_stop) {
                             Keys->push_back(tnew);
                             Values->push_back(vnew);
                         }
+                        else {
+                            // Something broke
+                            break;
+                        }
                         tp = tnew;
                         vp = vnew;
                     }
@@ -3348,7 +3393,7 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
                     }
                 }
             }
-            inputs.push_back(std::make_tuple(Keys, Values, mapto));
+            inputs.emplace_back(Keys, Values, mapto);
         }
     }
     return inputs;
@@ -3633,6 +3678,12 @@ void FBXConverter::TransferDataToScene() {
 
         std::swap_ranges(textures.begin(), textures.end(), mSceneOut->mTextures);
     }
+
+    if (!mSkeletons.empty()) {
+        mSceneOut->mSkeletons = new aiSkeleton *[mSkeletons.size()];
+        mSceneOut->mNumSkeletons = static_cast<unsigned int>(mSkeletons.size());
+        std::swap_ranges(mSkeletons.begin(), mSkeletons.end(), mSceneOut->mSkeletons);
+    }
 }
 
 void FBXConverter::ConvertOrphanedEmbeddedTextures() {

+ 29 - 16
Engine/lib/assimp/code/AssetLib/FBX/FBXConverter.h

@@ -75,7 +75,18 @@ typedef std::map<int64_t, morphKeyData*> morphAnimData;
 namespace Assimp {
 namespace FBX {
 
+class MeshGeometry;
+
+using SkeletonBoneArray = std::vector<aiSkeletonBone *>;
+using SkeletonBoneToMesh = std::map<aiMesh*, SkeletonBoneArray*>;
+
+struct SkeletonBoneContainer {
+    std::vector<aiMesh *> MeshArray;
+    SkeletonBoneToMesh SkeletonBoneToMeshLookup;
+};
+
 class Document;
+
 /**
  *  Convert a FBX #Document to #aiScene
  *  @param out Empty scene to be populated
@@ -180,14 +191,12 @@ private:
     void SetupNodeMetadata(const Model& model, aiNode& nd);
 
     // ------------------------------------------------------------------------------------------------
-    void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
-                      const aiMatrix4x4 &absolute_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, aiNode *parent, aiNode *root_node,
-                const aiMatrix4x4 &absolute_transform);
+    ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform);
 
     // ------------------------------------------------------------------------------------------------
     std::vector<unsigned int> ConvertLine(const LineGeometry& line, aiNode *root_node);
@@ -196,18 +205,16 @@ private:
     aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent);
 
     // ------------------------------------------------------------------------------------------------
-    unsigned int ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
-                                           const aiMatrix4x4 &absolute_transform, aiNode *parent,
-                                           aiNode *root_node);
+    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, aiNode *parent, aiNode *root_node,
-                             const aiMatrix4x4 &absolute_transform);
+    ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform, aiNode *parent, aiNode *root_node);
 
     // ------------------------------------------------------------------------------------------------
-    unsigned int ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, MatIndexArray::value_type index,
-                                          aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform);
+    unsigned int ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform, MatIndexArray::value_type index,
+                                          aiNode *parent, aiNode *root_node);
 
     // ------------------------------------------------------------------------------------------------
     static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
@@ -220,15 +227,19 @@ 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 MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
-            aiNode *parent = nullptr, unsigned int materialIndex = NO_MATERIAL_SEPARATION,
+    void ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, aiNode *parent = nullptr,
+            unsigned int materialIndex = NO_MATERIAL_SEPARATION,
             std::vector<unsigned int> *outputVertStartIndices = nullptr);
 
+    // ------------------------------------------------------------------------------------------------
+    void ConvertWeightsToSkeleton(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
+            aiNode *parent, unsigned int materialIndex, std::vector<unsigned int> *outputVertStartIndices,
+            SkeletonBoneContainer &skeletonContainer);
+
     // ------------------------------------------------------------------------------------------------
     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 );
+            std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform, aiNode *parent);
 
     // ------------------------------------------------------------------------------------------------
     void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@@ -301,7 +312,8 @@ private:
     void ConvertAnimationStack(const AnimationStack& st);
 
     // ------------------------------------------------------------------------------------------------
-    void ProcessMorphAnimDatas(std::map<std::string, morphAnimData*>* morphAnimDatas, const BlendShapeChannel* bsc, const AnimationCurveNode* node);
+    void ProcessMorphAnimDatas(std::map<std::string, morphAnimData*>* morphAnimDatas,
+        const BlendShapeChannel* bsc, const AnimationCurveNode* node);
 
     // ------------------------------------------------------------------------------------------------
     void GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims,
@@ -450,6 +462,7 @@ private:
 
     double anim_fps;
 
+    std::vector<aiSkeleton *> mSkeletons;
     aiScene* const mSceneOut;
     const FBX::Document& doc;
     bool mRemoveEmptyBones;

+ 7 - 27
Engine/lib/assimp/code/AssetLib/FBX/FBXDeformer.cpp

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2022, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -58,22 +57,16 @@ namespace FBX {
 using namespace Util;
 
 // ------------------------------------------------------------------------------------------------
-Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name)
-    : Object(id,element,name)
-{
+Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
+        Object(id,element,name) {
     const Scope& sc = GetRequiredScope(element);
 
     const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2));
     props = GetPropertyTable(doc,"Deformer.Fbx" + classname,element,sc,true);
 }
 
-
 // ------------------------------------------------------------------------------------------------
-Deformer::~Deformer()
-{
-
-}
-
+Deformer::~Deformer() = default;
 
 // ------------------------------------------------------------------------------------------------
 Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name)
@@ -122,11 +115,7 @@ Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const
 
 
 // ------------------------------------------------------------------------------------------------
-Cluster::~Cluster()
-{
-
-}
-
+Cluster::~Cluster() = default;
 
 // ------------------------------------------------------------------------------------------------
 Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name)
@@ -155,10 +144,7 @@ Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::
 
 
 // ------------------------------------------------------------------------------------------------
-Skin::~Skin()
-{
-
-}
+Skin::~Skin() = default;
 // ------------------------------------------------------------------------------------------------
 BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name)
     : Deformer(id, element, doc, name)
@@ -174,10 +160,7 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
     }
 }
 // ------------------------------------------------------------------------------------------------
-BlendShape::~BlendShape()
-{
-
-}
+BlendShape::~BlendShape() = default;
 // ------------------------------------------------------------------------------------------------
 BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name)
     : Deformer(id, element, doc, name)
@@ -202,10 +185,7 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
     }
 }
 // ------------------------------------------------------------------------------------------------
-BlendShapeChannel::~BlendShapeChannel()
-{
-
-}
+BlendShapeChannel::~BlendShapeChannel() = default;
 // ------------------------------------------------------------------------------------------------
 }
 }

+ 2 - 2
Engine/lib/assimp/code/AssetLib/FBX/FBXDocument.cpp

@@ -67,7 +67,7 @@ namespace FBX {
 using namespace Util;
 
 // ------------------------------------------------------------------------------------------------
-LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc) : 
+LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc) :
         doc(doc), element(element), id(id), flags() {
     // empty
 }
@@ -544,7 +544,7 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
     ai_assert( count != 0 );
     ai_assert( count <= MAX_CLASSNAMES);
 
-    size_t lengths[MAX_CLASSNAMES];
+    size_t lengths[MAX_CLASSNAMES] = {};
 
     const size_t c = count;
     for (size_t i = 0; i < c; ++i) {

+ 10 - 10
Engine/lib/assimp/code/AssetLib/FBX/FBXDocument.h

@@ -164,7 +164,7 @@ class NodeAttribute : public Object {
 public:
     NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
 
-    virtual ~NodeAttribute();
+    virtual ~NodeAttribute() = default;
 
     const PropertyTable& Props() const {
         ai_assert(props.get());
@@ -180,7 +180,7 @@ class CameraSwitcher : public NodeAttribute {
 public:
     CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
 
-    virtual ~CameraSwitcher();
+    virtual ~CameraSwitcher() = default;
 
     int CameraID() const {
         return cameraId;
@@ -225,7 +225,7 @@ class Camera : public NodeAttribute {
 public:
     Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name);
 
-    virtual  ~Camera();
+    virtual  ~Camera() = default;
 
     fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0))
     fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0))
@@ -250,21 +250,21 @@ public:
 class Null : public NodeAttribute {
 public:
     Null(uint64_t id, const Element& element, const Document& doc, const std::string& name);
-    virtual ~Null();
+    virtual ~Null() = default;
 };
 
 /** DOM base class for FBX limb node markers attached to a node */
 class LimbNode : public NodeAttribute {
 public:
     LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name);
-    virtual ~LimbNode();
+    virtual ~LimbNode() = default;
 };
 
 /** DOM base class for FBX lights attached to a node */
 class Light : public NodeAttribute {
 public:
     Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
-    virtual ~Light();
+    virtual ~Light() = default;
 
     enum Type {
         Type_Point,
@@ -690,7 +690,7 @@ using KeyValueList = std::vector<float>;
 class AnimationCurve : public Object {
 public:
     AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
-    virtual ~AnimationCurve();
+    virtual ~AnimationCurve() = default;
 
     /** get list of keyframe positions (time).
      *  Invariant: |GetKeys()| > 0 */
@@ -731,7 +731,7 @@ public:
     AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
             const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
 
-    virtual ~AnimationCurveNode();
+    virtual ~AnimationCurveNode() = default;
 
     const PropertyTable& Props() const {
         ai_assert(props.get());
@@ -776,7 +776,7 @@ using AnimationCurveNodeList = std::vector<const AnimationCurveNode*>;
 class AnimationLayer : public Object {
 public:
     AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
-    virtual ~AnimationLayer();
+    virtual ~AnimationLayer() = default;
 
     const PropertyTable& Props() const {
         ai_assert(props.get());
@@ -799,7 +799,7 @@ using AnimationLayerList = std::vector<const AnimationLayer*>;
 class AnimationStack : public Object {
 public:
     AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
-    virtual ~AnimationStack();
+    virtual ~AnimationStack() = default;
 
     fbx_simple_property(LocalStart, int64_t, 0L)
     fbx_simple_property(LocalStop, int64_t, 0L)

+ 3 - 6
Engine/lib/assimp/code/AssetLib/FBX/FBXDocumentUtil.cpp

@@ -59,14 +59,12 @@ namespace Util {
 
 // ------------------------------------------------------------------------------------------------
 // signal DOM construction error, this is always unrecoverable. Throws DeadlyImportError.
-void DOMError(const std::string& message, const Token& token)
-{
+void DOMError(const std::string& message, const Token& token) {
     throw DeadlyImportError("FBX-DOM", Util::GetTokenText(&token), message);
 }
 
 // ------------------------------------------------------------------------------------------------
-void DOMError(const std::string& message, const Element* element /*= nullptr*/)
-{
+void DOMError(const std::string& message, const Element* element /*= nullptr*/) {
     if(element) {
         DOMError(message,element->KeyToken());
     }
@@ -76,8 +74,7 @@ void DOMError(const std::string& message, const Element* element /*= nullptr*/)
 
 // ------------------------------------------------------------------------------------------------
 // print warning, do return
-void DOMWarning(const std::string& message, const Token& token)
-{
+void DOMWarning(const std::string& message, const Token& token) {
     if(DefaultLogger::get()) {
         ASSIMP_LOG_WARN("FBX-DOM", Util::GetTokenText(&token), message);
     }

+ 5 - 7
Engine/lib/assimp/code/AssetLib/FBX/FBXDocumentUtil.h

@@ -74,13 +74,11 @@ std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
 
 // ------------------------------------------------------------------------------------------------
 template <typename T>
-inline
-const T* ProcessSimpleConnection(const Connection& con,
-    bool is_object_property_conn,
-    const char* name,
-    const Element& element,
-    const char** propNameOut = nullptr)
-{
+inline const T* ProcessSimpleConnection(const Connection& con,
+        bool is_object_property_conn,
+        const char* name,
+        const Element& element,
+        const char** propNameOut = nullptr) {
     if (is_object_property_conn && !con.PropertyName().length()) {
         DOMWarning("expected incoming " + std::string(name) +
             " link to be an object-object connection, ignoring",

+ 1 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXExporter.cpp

@@ -255,7 +255,7 @@ void FBXExporter::WriteBinaryHeader()
 
 void FBXExporter::WriteBinaryFooter()
 {
-    outfile->Write(NULL_RECORD.c_str(), NULL_RECORD.size(), 1);
+    outfile->Write(NULL_RECORD, NumNullRecords, 1);
 
     outfile->Write(GENERIC_FOOTID.c_str(), GENERIC_FOOTID.size(), 1);
 

+ 6 - 0
Engine/lib/assimp/code/AssetLib/FBX/FBXImportSettings.h

@@ -60,6 +60,7 @@ struct ImportSettings {
             readLights(true),
             readAnimations(true),
             readWeights(true),
+            useSkeleton(false),
             preservePivots(true),
             optimizeEmptyAnimationCurves(true),
             useLegacyEmbeddedTextureNaming(false),
@@ -112,6 +113,11 @@ struct ImportSettings {
      *  Default value is true. */
     bool readWeights;
 
+    /** will convert all animation data into a skeleton (experimental)
+     *  Default value is false.
+     */
+    bool useSkeleton;
+
     /** preserve transformation pivots and offsets. Since these can
      *  not directly be represented in assimp, additional dummy
      *  nodes will be generated. Note that settings this to false

+ 22 - 25
Engine/lib/assimp/code/AssetLib/FBX/FBXImporter.cpp

@@ -90,12 +90,9 @@ static const aiImporterDesc desc = {
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by #Importer
-FBXImporter::FBXImporter() {
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FBXImporter::~FBXImporter() {
+FBXImporter::FBXImporter() :
+        mSettings() {
+    // empty
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -115,20 +112,21 @@ const aiImporterDesc *FBXImporter::GetInfo() const {
 // ------------------------------------------------------------------------------------------------
 // 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.readWeights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_WEIGHTS, 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);
+    mSettings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
+    mSettings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
+    mSettings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
+    mSettings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
+    mSettings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
+    mSettings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
+    mSettings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
+    mSettings.readWeights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_WEIGHTS, true);
+    mSettings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
+    mSettings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
+    mSettings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
+    mSettings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
+    mSettings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
+    mSettings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
+    mSettings.useSkeleton = pImp->GetPropertyBool(AI_CONFIG_FBX_USE_SKELETON_BONE_CONTAINER, false);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -155,7 +153,7 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 	contents[contents.size() - 1] = 0;
 	const char *const begin = &*contents.begin();
 
-	// broadphase tokenizing pass in which we identify the core
+	// broad-phase tokenized pass in which we identify the core
 	// syntax elements of FBX (brackets, commas, key:value mappings)
 	TokenList tokens;
 	try {
@@ -173,15 +171,14 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 		Parser parser(tokens, is_binary);
 
 		// take the raw parse-tree and convert it to a FBX DOM
-		Document doc(parser, settings);
+		Document doc(parser, mSettings);
 
 		// convert the FBX DOM to aiScene
-		ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
+		ConvertToAssimpScene(pScene, doc, mSettings.removeEmptyBones);
 
 		// size relative to cm
 		float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
-        if (size_relative_to_cm == 0.0)
-        {
+        if (size_relative_to_cm == 0.0) {
 			// BaseImporter later asserts that fileScale is non-zero.
 			ThrowException("The UnitScaleFactor must be non-zero");
         }

+ 7 - 6
Engine/lib/assimp/code/AssetLib/FBX/FBXImporter.h

@@ -69,13 +69,14 @@ typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>
 // -------------------------------------------------------------------------------------------
 class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
 public:
+    /// @brief The class constructor.
     FBXImporter();
-    ~FBXImporter() override;
 
-    // --------------------
-    bool CanRead(const std::string &pFile,
-            IOSystem *pIOHandler,
-            bool checkSig) const override;
+    ///	@brief The class destructor, default implementation.
+    ~FBXImporter() override = default;
+
+    /// @brief Will check the file for readability.
+    bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
 
 protected:
     // --------------------
@@ -90,7 +91,7 @@ protected:
             IOSystem *pIOHandler) override;
 
 private:
-    FBX::ImportSettings settings;
+    FBX::ImportSettings mSettings;
 }; // !class FBXImporter
 
 } // end of namespace Assimp

+ 3 - 9
Engine/lib/assimp/code/AssetLib/FBX/FBXMaterial.cpp

@@ -136,9 +136,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
 
 
 // ------------------------------------------------------------------------------------------------
-Material::~Material() {
-    // empty
-}
+Material::~Material() = default;
 
     aiVector2D uvTrans;
     aiVector2D uvScaling;
@@ -255,9 +253,7 @@ Texture::Texture(uint64_t id, const Element& element, const Document& doc, const
 }
 
 
-Texture::~Texture() {
-    // empty
-}
+Texture::~Texture() = default;
 
 LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& /*doc*/, const std::string& name) :
         Object(id,element,name),
@@ -276,9 +272,7 @@ LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Docume
     }
 }
 
-LayeredTexture::~LayeredTexture() {
-    // empty
-}
+LayeredTexture::~LayeredTexture() = default;
 
 void LayeredTexture::fillTexture(const Document& doc) {
     const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());

+ 33 - 30
Engine/lib/assimp/code/AssetLib/FBX/FBXMeshGeometry.cpp

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2022, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -54,18 +53,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXImportSettings.h"
 #include "FBXDocumentUtil.h"
 
-
 namespace Assimp {
 namespace FBX {
 
 using namespace Util;
 
 // ------------------------------------------------------------------------------------------------
-Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
-    : Object(id, element, name)
-    , skin()
-{
-    const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
+Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) :
+        Object(id, element, name), skin() {
+    const std::vector<const Connection*> &conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
     for(const Connection* con : conns) {
         const Skin* const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element);
         if(sk) {
@@ -78,12 +74,6 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
     }
 }
 
-// ------------------------------------------------------------------------------------------------
-Geometry::~Geometry()
-{
-    // empty
-}
-
 // ------------------------------------------------------------------------------------------------
 const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
     return blendShapes;
@@ -183,18 +173,12 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
         if(doc.Settings().readAllLayers || index == 0) {
             const Scope& layer = GetRequiredScope(*(*it).second);
             ReadLayer(layer);
-        }
-        else {
+        } else {
             FBXImporter::LogWarn("ignoring additional geometry layers");
         }
     }
 }
 
-// ------------------------------------------------------------------------------------------------
-MeshGeometry::~MeshGeometry() {
-    // empty
-}
-
 // ------------------------------------------------------------------------------------------------
 const std::vector<aiVector3D>& MeshGeometry::GetVertices() const {
     return m_vertices;
@@ -431,9 +415,11 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
 {
     bool isDirect = ReferenceInformationType == "Direct";
     bool isIndexToDirect = ReferenceInformationType == "IndexToDirect";
+    const bool hasDataElement = HasElement(source, dataElementName);
+    const bool hasIndexDataElement = HasElement(source, indexDataElementName);
 
     // fall-back to direct data if there is no index data element
-    if ( isIndexToDirect && !HasElement( source, indexDataElementName ) ) {
+    if (isIndexToDirect && !hasIndexDataElement) {
         isDirect = true;
         isIndexToDirect = false;
     }
@@ -442,7 +428,8 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
     // deal with this more elegantly and with less redundancy, but right
     // now it seems unavoidable.
     if (MappingInformationType == "ByVertice" && isDirect) {
-        if (!HasElement(source, dataElementName)) {
+        if (!hasDataElement) {
+            FBXImporter::LogWarn("missing data element: ", dataElementName);
             return;
         }
         std::vector<T> tempData;
@@ -464,7 +451,15 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
     }
     else if (MappingInformationType == "ByVertice" && isIndexToDirect) {
 		std::vector<T> tempData;
-		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
+        if (!hasDataElement || !hasIndexDataElement) {
+            if (!hasDataElement)
+                FBXImporter::LogWarn("missing data element: ", dataElementName);
+            if (!hasIndexDataElement)
+                FBXImporter::LogWarn("missing index data element: ", indexDataElementName);
+            return;
+        }
+
+        ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
 
         std::vector<int> uvIndices;
         ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
@@ -489,6 +484,11 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
         }
     }
     else if (MappingInformationType == "ByPolygonVertex" && isDirect) {
+        if (!hasDataElement) {
+            FBXImporter::LogWarn("missing data element: ", dataElementName);
+            return;
+        }
+
 		std::vector<T> tempData;
 		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
 
@@ -503,7 +503,14 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
     }
     else if (MappingInformationType == "ByPolygonVertex" && isIndexToDirect) {
 		std::vector<T> tempData;
-		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
+        if (!hasDataElement || !hasIndexDataElement) {
+            if (!hasDataElement)
+                FBXImporter::LogWarn("missing data element: ", dataElementName);
+            if (!hasIndexDataElement)
+                FBXImporter::LogWarn("missing index data element: ", indexDataElementName);
+            return;
+        }
+        ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
 
         std::vector<int> uvIndices;
         ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
@@ -681,9 +688,7 @@ ShapeGeometry::ShapeGeometry(uint64_t id, const Element& element, const std::str
 }
 
 // ------------------------------------------------------------------------------------------------
-ShapeGeometry::~ShapeGeometry() {
-    // empty
-}
+ShapeGeometry::~ShapeGeometry() = default;
 // ------------------------------------------------------------------------------------------------
 const std::vector<aiVector3D>& ShapeGeometry::GetVertices() const {
     return m_vertices;
@@ -711,9 +716,7 @@ LineGeometry::LineGeometry(uint64_t id, const Element& element, const std::strin
 }
 
 // ------------------------------------------------------------------------------------------------
-LineGeometry::~LineGeometry() {
-    // empty
-}
+LineGeometry::~LineGeometry() = default;
 // ------------------------------------------------------------------------------------------------
 const std::vector<aiVector3D>& LineGeometry::GetVertices() const {
     return m_vertices;

+ 12 - 9
Engine/lib/assimp/code/AssetLib/FBX/FBXMeshGeometry.h

@@ -55,22 +55,25 @@ namespace FBX {
 /**
  *  DOM base class for all kinds of FBX geometry
  */
-class Geometry : public Object
-{
+class Geometry : public Object {
 public:
+    /// @brief The class constructor with all parameters.
+    /// @param id       The id.
+    /// @param element  
+    /// @param name 
+    /// @param doc 
     Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
-    virtual ~Geometry();
+    virtual ~Geometry() = default;
 
-    /** Get the Skin attached to this geometry or nullptr */
+    /// Get the Skin attached to this geometry or nullptr
     const Skin* DeformerSkin() const;
 
-    /** Get the BlendShape attached to this geometry or nullptr */
+    /// Get the BlendShape attached to this geometry or nullptr
     const std::vector<const BlendShape*>& GetBlendShapes() const;
 
 private:
     const Skin* skin;
     std::vector<const BlendShape*> blendShapes;
-
 };
 
 typedef std::vector<int> MatIndexArray;
@@ -79,14 +82,13 @@ typedef std::vector<int> MatIndexArray;
 /**
  *  DOM class for FBX geometry of type "Mesh"
  */
-class MeshGeometry : public Geometry
-{
+class MeshGeometry : public Geometry {
 public:
     /** The class constructor */
     MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
 
     /** The class destructor */
-    virtual ~MeshGeometry();
+    virtual ~MeshGeometry() = default;
 
     /** Get a list of all vertex points, non-unique*/
     const std::vector<aiVector3D>& GetVertices() const;
@@ -130,6 +132,7 @@ public:
     /** Determine the face to which a particular output vertex index belongs.
     *  This mapping is always unique. */
     unsigned int FaceForVertexIndex( unsigned int in_index ) const;
+
 private:
     void ReadLayer( const Scope& layer );
     void ReadLayerElement( const Scope& layerElement );

+ 29 - 78
Engine/lib/assimp/code/AssetLib/FBX/FBXNodeAttribute.cpp

@@ -57,114 +57,65 @@ namespace FBX {
 using namespace Util;
 
 // ------------------------------------------------------------------------------------------------
-NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name)
-: Object(id,element,name)
-, props()
-{
-    const Scope& sc = GetRequiredScope(element);
+NodeAttribute::NodeAttribute(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
+        Object(id, element, name), props() {
+    const Scope &sc = GetRequiredScope(element);
 
-    const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2));
+    const std::string &classname = ParseTokenAsString(GetRequiredToken(element, 2));
 
     // hack on the deriving type but Null/LimbNode attributes are the only case in which
     // the property table is by design absent and no warning should be generated
     // for it.
     const bool is_null_or_limb = !strcmp(classname.c_str(), "Null") || !strcmp(classname.c_str(), "LimbNode");
-    props = GetPropertyTable(doc,"NodeAttribute.Fbx" + classname,element,sc, is_null_or_limb);
+    props = GetPropertyTable(doc, "NodeAttribute.Fbx" + classname, element, sc, is_null_or_limb);
 }
 
-
-// ------------------------------------------------------------------------------------------------
-NodeAttribute::~NodeAttribute()
-{
-    // empty
-}
-
-
 // ------------------------------------------------------------------------------------------------
-CameraSwitcher::CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name)
-    : NodeAttribute(id,element,doc,name)
-{
-    const Scope& sc = GetRequiredScope(element);
-    const Element* const CameraId = sc["CameraId"];
-    const Element* const CameraName = sc["CameraName"];
-    const Element* const CameraIndexName = sc["CameraIndexName"];
-
-    if(CameraId) {
-        cameraId = ParseTokenAsInt(GetRequiredToken(*CameraId,0));
+CameraSwitcher::CameraSwitcher(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
+        NodeAttribute(id, element, doc, name) {
+    const Scope &sc = GetRequiredScope(element);
+    const Element *const CameraId = sc["CameraId"];
+    const Element *const CameraName = sc["CameraName"];
+    const Element *const CameraIndexName = sc["CameraIndexName"];
+
+    if (CameraId) {
+        cameraId = ParseTokenAsInt(GetRequiredToken(*CameraId, 0));
     }
 
-    if(CameraName) {
-        cameraName = GetRequiredToken(*CameraName,0).StringContents();
+    if (CameraName) {
+        cameraName = GetRequiredToken(*CameraName, 0).StringContents();
     }
 
-    if(CameraIndexName && CameraIndexName->Tokens().size()) {
-        cameraIndexName = GetRequiredToken(*CameraIndexName,0).StringContents();
+    if (CameraIndexName && CameraIndexName->Tokens().size()) {
+        cameraIndexName = GetRequiredToken(*CameraIndexName, 0).StringContents();
     }
 }
 
 // ------------------------------------------------------------------------------------------------
-CameraSwitcher::~CameraSwitcher()
-{
+Camera::Camera(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
+        NodeAttribute(id, element, doc, name) {
     // empty
 }
 
 // ------------------------------------------------------------------------------------------------
-Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name)
-: NodeAttribute(id,element,doc,name)
-{
+Light::Light(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
+        NodeAttribute(id, element, doc, name) {
     // empty
 }
 
 // ------------------------------------------------------------------------------------------------
-Camera::~Camera()
-{
+Null::Null(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
+        NodeAttribute(id, element, doc, name) {
     // empty
 }
 
 // ------------------------------------------------------------------------------------------------
-Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& name)
-: NodeAttribute(id,element,doc,name)
-{
+LimbNode::LimbNode(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
+        NodeAttribute(id, element, doc, name) {
     // empty
 }
 
+} // namespace FBX
+} // namespace Assimp
 
-// ------------------------------------------------------------------------------------------------
-Light::~Light()
-{
-}
-
-
-// ------------------------------------------------------------------------------------------------
-Null::Null(uint64_t id, const Element& element, const Document& doc, const std::string& name)
-: NodeAttribute(id,element,doc,name)
-{
-
-}
-
-
-// ------------------------------------------------------------------------------------------------
-Null::~Null()
-{
-
-}
-
-
-// ------------------------------------------------------------------------------------------------
-LimbNode::LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name)
-: NodeAttribute(id,element,doc,name)
-{
-
-}
-
-
-// ------------------------------------------------------------------------------------------------
-LimbNode::~LimbNode()
-{
-
-}
-
-}
-}
-
-#endif
+#endif // ASSIMP_BUILD_NO_FBX_IMPORTER

+ 10 - 24
Engine/lib/assimp/code/AssetLib/FBX/FBXParser.cpp

@@ -162,12 +162,6 @@ Element::Element(const Token& key_token, Parser& parser) : key_token(key_token)
     while(n->Type() != TokenType_KEY && n->Type() != TokenType_CLOSE_BRACKET);
 }
 
-// ------------------------------------------------------------------------------------------------
-Element::~Element()
-{
-     // no need to delete tokens, they are owned by the parser
-}
-
 // ------------------------------------------------------------------------------------------------
 Scope::Scope(Parser& parser,bool topLevel)
 {
@@ -226,12 +220,6 @@ Parser::Parser (const TokenList& tokens, bool is_binary)
     root.reset(new Scope(*this,true));
 }
 
-// ------------------------------------------------------------------------------------------------
-Parser::~Parser()
-{
-    // empty
-}
-
 // ------------------------------------------------------------------------------------------------
 TokenPtr Parser::AdvanceToNextToken()
 {
@@ -631,9 +619,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<ai_real>(d[0]),
+                out.emplace_back(static_cast<ai_real>(d[0]),
                     static_cast<ai_real>(d[1]),
-                    static_cast<ai_real>(d[2])));
+                    static_cast<ai_real>(d[2]));
             }
             // for debugging
             /*for ( size_t i = 0; i < out.size(); i++ ) {
@@ -646,7 +634,7 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
         else if (type == 'f') {
             const float* f = reinterpret_cast<const float*>(&buff[0]);
             for (unsigned int i = 0; i < count3; ++i, f += 3) {
-                out.push_back(aiVector3D(f[0],f[1],f[2]));
+                out.emplace_back(f[0],f[1],f[2]);
             }
         }
 
@@ -720,16 +708,16 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
         if (type == 'd') {
             const double* d = reinterpret_cast<const double*>(&buff[0]);
             for (unsigned int i = 0; i < count4; ++i, d += 4) {
-                out.push_back(aiColor4D(static_cast<float>(d[0]),
+                out.emplace_back(static_cast<float>(d[0]),
                     static_cast<float>(d[1]),
                     static_cast<float>(d[2]),
-                    static_cast<float>(d[3])));
+                    static_cast<float>(d[3]));
             }
         }
         else if (type == 'f') {
             const float* f = reinterpret_cast<const float*>(&buff[0]);
             for (unsigned int i = 0; i < count4; ++i, f += 4) {
-                out.push_back(aiColor4D(f[0],f[1],f[2],f[3]));
+                out.emplace_back(f[0],f[1],f[2],f[3]);
             }
         }
         return;
@@ -801,13 +789,13 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el) {
         if (type == 'd') {
             const double* d = reinterpret_cast<const double*>(&buff[0]);
             for (unsigned int i = 0; i < count2; ++i, d += 2) {
-                out.push_back(aiVector2D(static_cast<float>(d[0]),
-                    static_cast<float>(d[1])));
+                out.emplace_back(static_cast<float>(d[0]),
+                    static_cast<float>(d[1]));
             }
         } else if (type == 'f') {
             const float* f = reinterpret_cast<const float*>(&buff[0]);
             for (unsigned int i = 0; i < count2; ++i, f += 2) {
-                out.push_back(aiVector2D(f[0],f[1]));
+                out.emplace_back(f[0],f[1]);
             }
         }
 
@@ -961,8 +949,7 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
 
 // ------------------------------------------------------------------------------------------------
 // read an array of uints
-void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
-{
+void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el) {
     out.resize( 0 );
     const TokenList& tok = el.Tokens();
     if(tok.empty()) {
@@ -1186,7 +1173,6 @@ aiMatrix4x4 ReadMatrix(const Element& element)
     return result;
 }
 
-
 // ------------------------------------------------------------------------------------------------
 // wrapper around ParseTokenAsString() with ParseError handling
 std::string ParseTokenAsString(const Token& t)

+ 2 - 2
Engine/lib/assimp/code/AssetLib/FBX/FBXParser.h

@@ -87,7 +87,7 @@ class Element
 {
 public:
     Element(const Token& key_token, Parser& parser);
-    ~Element();
+    ~Element() = default;
 
     const Scope* Compound() const {
         return compound.get();
@@ -160,7 +160,7 @@ public:
     /** Parse given a token list. Does not take ownership of the tokens -
      *  the objects must persist during the entire parser lifetime */
     Parser (const TokenList& tokens,bool is_binary);
-    ~Parser();
+    ~Parser() = default;
 
     const Scope& GetRootScope() const {
         return *root.get();

+ 13 - 19
Engine/lib/assimp/code/AssetLib/FBX/FBXProperties.cpp

@@ -60,29 +60,23 @@ namespace FBX {
     using namespace Util;
 
 // ------------------------------------------------------------------------------------------------
-Property::Property()
-{
-}
+    Property::Property() = default;
 
-// ------------------------------------------------------------------------------------------------
-Property::~Property()
-{
-}
+    // ------------------------------------------------------------------------------------------------
+    Property::~Property() = default;
 
-namespace {
+    namespace {
 
-void checkTokenCount(const TokenList& tok, unsigned int expectedCount)
-{
-    ai_assert(expectedCount >= 2);
-    if (tok.size() < expectedCount) {
-        const std::string& s = ParseTokenAsString(*tok[1]);
-        if (tok[1]->IsBinary()) {
-            throw DeadlyImportError("Not enough tokens for property of type ", s, " at offset ", tok[1]->Offset());
-        }
-        else {
-            throw DeadlyImportError("Not enough tokens for property of type ", s, " at line ", tok[1]->Line());
+    void checkTokenCount(const TokenList &tok, unsigned int expectedCount) {
+        ai_assert(expectedCount >= 2);
+        if (tok.size() < expectedCount) {
+            const std::string &s = ParseTokenAsString(*tok[1]);
+            if (tok[1]->IsBinary()) {
+                throw DeadlyImportError("Not enough tokens for property of type ", s, " at offset ", tok[1]->Offset());
+            } else {
+                throw DeadlyImportError("Not enough tokens for property of type ", s, " at line ", tok[1]->Line());
+            }
         }
-    }
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 3
Engine/lib/assimp/code/AssetLib/FBX/FBXTokenizer.cpp

@@ -79,9 +79,7 @@ Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int
 }
 
 // ------------------------------------------------------------------------------------------------
-Token::~Token()
-{
-}
+
 
 namespace {
 

+ 1 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXTokenizer.h

@@ -96,7 +96,7 @@ public:
     /** construct a binary token */
     Token(const char* sbegin, const char* send, TokenType type, size_t offset);
 
-    ~Token();
+    ~Token() = default;
 
 public:
     std::string StringContents() const {

+ 2 - 6
Engine/lib/assimp/code/AssetLib/HMP/HMPLoader.cpp

@@ -72,15 +72,11 @@ static const aiImporterDesc desc = {
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-HMPImporter::HMPImporter() {
-    // nothing to do here
-}
+HMPImporter::HMPImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-HMPImporter::~HMPImporter() {
-    // nothing to do here
-}
+HMPImporter::~HMPImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.

+ 3 - 3
Engine/lib/assimp/code/AssetLib/IFC/IFCBoolean.cpp

@@ -310,7 +310,7 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
                 if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10)
                     continue;
             }
-            intersect_results.push_back(std::make_pair(i, e0));
+            intersect_results.emplace_back(i, e0);
             continue;
         }
 
@@ -324,7 +324,7 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
                 if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10)
                     continue;
             }
-            intersect_results.push_back(std::make_pair(i, p));
+            intersect_results.emplace_back(i, p);
         }
     }
 
@@ -504,7 +504,7 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
                 }
                 // now add them to the list of intersections
                 for (size_t b = 0; b < intersected_boundary.size(); ++b)
-                    intersections.push_back(std::make_tuple(a, proj_inv * intersected_boundary[b].second, intersected_boundary[b].first));
+                    intersections.emplace_back(a, proj_inv * intersected_boundary[b].second, intersected_boundary[b].first);
 
                 // and calculate our new inside/outside state
                 if (intersected_boundary.size() & 1)

+ 5 - 3
Engine/lib/assimp/code/AssetLib/IFC/IFCCurve.cpp

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2022, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -51,7 +50,6 @@ namespace Assimp {
 namespace IFC {
 namespace {
 
-
 // --------------------------------------------------------------------------------
 // Conic is the base class for Circle and Ellipse
 // --------------------------------------------------------------------------------
@@ -226,7 +224,7 @@ public:
                 IFCImporter::LogVerboseDebug("ignoring transition code on composite curve segment, only continuous transitions are supported");
             }
 
-            curves.push_back( CurveEntry(bc,IsTrue(curveSegment.SameSense)) );
+            curves.emplace_back(bc,IsTrue(curveSegment.SameSense) );
             total += bc->GetParametricRangeDelta();
         }
 
@@ -546,8 +544,10 @@ IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, Ifc
         }
     }
 
+#ifndef __INTEL_LLVM_COMPILER
     ai_assert( min_diff[ 0 ] != inf );
     ai_assert( min_diff[ 1 ] != inf );
+#endif // __INTEL_LLVM_COMPILER
     if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
         return min_point[0];
     }
@@ -606,8 +606,10 @@ bool BoundedCurve::IsClosed() const {
 // ------------------------------------------------------------------------------------------------
 void BoundedCurve::SampleDiscrete(TempMesh& out) const {
     const ParamRange& range = GetParametricRange();
+#ifndef __INTEL_LLVM_COMPILER
     ai_assert( range.first != std::numeric_limits<IfcFloat>::infinity() );
     ai_assert( range.second != std::numeric_limits<IfcFloat>::infinity() );
+#endif // __INTEL_LLVM_COMPILER
 
     return SampleDiscrete(out,range.first,range.second);
 }

+ 2 - 2
Engine/lib/assimp/code/AssetLib/IFC/IFCGeometry.cpp

@@ -170,7 +170,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
             continue;
         }
 
-        fake_openings.push_back(TempOpening());
+        fake_openings.emplace_back();
         TempOpening& opening = fake_openings.back();
 
         opening.extrusionDir = master_normal;
@@ -612,7 +612,7 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
             TempMesh& bounds = *t.profileMesh.get();
 
             if( bounds.mVerts.size() <= 2 ) {
-                nors.push_back(IfcVector3());
+                nors.emplace_back();
                 continue;
             }
             auto nor = ((bounds.mVerts[2] - bounds.mVerts[0]) ^ (bounds.mVerts[1] - bounds.mVerts[0])).Normalize();

+ 2 - 3
Engine/lib/assimp/code/AssetLib/IFC/IFCLoader.cpp

@@ -120,12 +120,11 @@ static const aiImporterDesc desc = {
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-IFCImporter::IFCImporter() {}
+IFCImporter::IFCImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-IFCImporter::~IFCImporter() {
-}
+IFCImporter::~IFCImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.

+ 37 - 37
Engine/lib/assimp/code/AssetLib/IFC/IFCOpenings.cpp

@@ -114,9 +114,9 @@ void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField&
     if (!found) {
         // the rectangle [pmin,pend] is opaque, fill it
         out.push_back(pmin);
-        out.push_back(IfcVector2(pmin.x,pmax.y));
+        out.emplace_back(pmin.x,pmax.y);
         out.push_back(pmax);
-        out.push_back(IfcVector2(pmax.x,pmin.y));
+        out.emplace_back(pmax.x,pmin.y);
         return;
     }
 
@@ -126,9 +126,9 @@ void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField&
     // see if there's an offset to fill at the top of our quad
     if (xs - pmin.x) {
         out.push_back(pmin);
-        out.push_back(IfcVector2(pmin.x,pmax.y));
-        out.push_back(IfcVector2(xs,pmax.y));
-        out.push_back(IfcVector2(xs,pmin.y));
+        out.emplace_back(pmin.x,pmax.y);
+        out.emplace_back(xs,pmax.y);
+        out.emplace_back(xs,pmin.y);
     }
 
     // search along the y-axis for all openings that overlap xs and our quad
@@ -159,10 +159,10 @@ void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField&
     }
     if (!found) {
         // the rectangle [pmin,pend] is opaque, fill it
-        out.push_back(IfcVector2(xs,pmin.y));
-        out.push_back(IfcVector2(xs,pmax.y));
-        out.push_back(IfcVector2(xe,pmax.y));
-        out.push_back(IfcVector2(xe,pmin.y));
+        out.emplace_back(xs,pmin.y);
+        out.emplace_back(xs,pmax.y);
+        out.emplace_back(xe,pmax.y);
+        out.emplace_back(xe,pmin.y);
         return;
     }
     if (ylast < pmax.y) {
@@ -342,7 +342,7 @@ void InsertWindowContours(const ContourVector& contours,
                         if ((contour[a] - edge).SquareLength() > diag*diag*0.7) {
                             continue;
                         }
-                        curmesh.mVerts.push_back(IfcVector3(contour[a].x, contour[a].y, 0.0f));
+                        curmesh.mVerts.emplace_back(contour[a].x, contour[a].y, 0.0f);
                     }
 
                     if (edge != contour[last_hit]) {
@@ -363,7 +363,7 @@ void InsertWindowContours(const ContourVector& contours,
                             corner.y = bb.second.y;
                         }
 
-                        curmesh.mVerts.push_back(IfcVector3(corner.x, corner.y, 0.0f));
+                        curmesh.mVerts.emplace_back(corner.x, corner.y, 0.0f);
                     }
                     else if (cnt == 1) {
                         // avoid degenerate polygons (also known as lines or points)
@@ -399,7 +399,7 @@ void MergeWindowContours (const std::vector<IfcVector2>& a,
     ClipperLib::Polygon clip;
 
     for(const IfcVector2& pip : a) {
-        clip.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
+        clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
     }
 
     if (ClipperLib::Orientation(clip)) {
@@ -410,7 +410,7 @@ void MergeWindowContours (const std::vector<IfcVector2>& a,
     clip.clear();
 
     for(const IfcVector2& pip : b) {
-        clip.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
+        clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
     }
 
     if (ClipperLib::Orientation(clip)) {
@@ -433,7 +433,7 @@ void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
     ClipperLib::Polygon clip;
 
     for(const IfcVector2& pip : a) {
-        clip.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
+        clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
     }
 
     if (ClipperLib::Orientation(clip)) {
@@ -444,7 +444,7 @@ void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
     clip.clear();
 
     for(const IfcVector2& pip : b) {
-        clip.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
+        clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
     }
 
     if (ClipperLib::Orientation(clip)) {
@@ -466,7 +466,7 @@ void CleanupWindowContour(ProjectedWindowContour& window)
     ClipperLib::ExPolygons clipped;
 
     for(const IfcVector2& pip : contour) {
-        subject.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
+        subject.emplace_back(to_int64(pip.x), to_int64(pip.y));
     }
 
     clipper.AddPolygon(subject,ClipperLib::ptSubject);
@@ -524,7 +524,7 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
         ClipperLib::Polygon clip;
         clip.reserve(contour_flat.size());
         for(const IfcVector2& pip : contour_flat) {
-            clip.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
+            clip.emplace_back(to_int64(pip.x), to_int64(pip.y));
         }
 
         if (!ClipperLib::Orientation(clip)) {
@@ -544,7 +544,7 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
                     continue;
                 }
             }
-            subject.push_back(ClipperLib::IntPoint(  to_int64(pip.x), to_int64(pip.y) ));
+            subject.emplace_back(to_int64(pip.x), to_int64(pip.y));
             if (--countdown == 0) {
                 if (!ClipperLib::Orientation(subject)) {
                     std::reverse(subject.begin(), subject.end());
@@ -558,10 +558,10 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
                 for(const ClipperLib::ExPolygon& ex : clipped) {
                     iold.push_back(static_cast<unsigned int>(ex.outer.size()));
                     for(const ClipperLib::IntPoint& point : ex.outer) {
-                        vold.push_back(IfcVector3(
+                        vold.emplace_back(
                             from_int64(point.X),
                             from_int64(point.Y),
-                            0.0f));
+                            0.0f);
                     }
                 }
 
@@ -1039,7 +1039,7 @@ void Quadrify(const std::vector< BoundingBox >& bbs, TempMesh& curmesh)
     curmesh.mVertcnt.resize(quads.size()/4,4);
     curmesh.mVerts.reserve(quads.size());
     for(const IfcVector2& v2 : quads) {
-        curmesh.mVerts.push_back(IfcVector3(v2.x, v2.y, static_cast<IfcFloat>(0.0)));
+        curmesh.mVerts.emplace_back(v2.x, v2.y, static_cast<IfcFloat>(0.0));
     }
 }
 
@@ -1095,7 +1095,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
         vmin = std::min(vv, vmin);
         vmax = std::max(vv, vmax);
 
-        out_contour.push_back(IfcVector2(vv.x,vv.y));
+        out_contour.emplace_back(vv.x,vv.y);
     }
 
     zcoord /= in_verts.size();
@@ -1128,7 +1128,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
     for(const IfcVector3& x : in_verts) {
         const IfcVector3& vv = m * x;
 
-        out_contour2.push_back(IfcVector2(vv.x,vv.y));
+        out_contour2.emplace_back(vv.x,vv.y);
         ai_assert(std::fabs(vv.z) < vmax.z + 1e-8);
     }
 
@@ -1378,12 +1378,12 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
 
         if(!temp_contour.empty()) {
             if (generate_connection_geometry) {
-                contours_to_openings.push_back(std::vector<TempOpening*>(
-                    joined_openings.begin(),
-                    joined_openings.end()));
+                contours_to_openings.emplace_back(
+                        joined_openings.begin(),
+                        joined_openings.end());
             }
 
-            contours.push_back(ProjectedWindowContour(temp_contour, bb, is_rectangle));
+            contours.emplace_back(temp_contour, bb, is_rectangle);
         }
     }
 
@@ -1428,7 +1428,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
     return true;
 }
 
-std::vector<IfcVector2> GetContourInPlane2D(std::shared_ptr<TempMesh> mesh,IfcMatrix3 planeSpace,
+std::vector<IfcVector2> GetContourInPlane2D(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
     IfcVector3 planeNor,IfcFloat planeOffset,
     IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first,bool& ok) {
     std::vector<IfcVector2> contour;
@@ -1469,14 +1469,14 @@ std::vector<IfcVector2> GetContourInPlane2D(std::shared_ptr<TempMesh> mesh,IfcMa
 
         // XXX should not be necessary - but it is. Why? For precision reasons?
         vv = is_extruded_side ? vv_extr : vv;
-        contour.push_back(IfcVector2(vv.x,vv.y));
+        contour.emplace_back(vv.x,vv.y);
     }
     ok = true;
 
     return contour;
 }
 
-const float close{ ai_epsilon };
+const ai_real close{ ai_epsilon };
 
 static bool isClose(IfcVector2 first,IfcVector2 second) {
     auto diff = (second - first);
@@ -1491,7 +1491,7 @@ static void logSegment(std::pair<IfcVector2,IfcVector2> segment) {
     IFCImporter::LogInfo(msg2.str().c_str());
 }
 
-std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(std::shared_ptr<TempMesh> mesh,IfcMatrix3 planeSpace,
+std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
     IfcFloat planeOffset) {
 
         {
@@ -1676,7 +1676,7 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(std::shared_ptr<TempMe
             std::stringstream msg;
             msg << "GetContoursInPlane3D: found " << contours.size() << " contours:\n";
 
-            for(auto c : contours) {
+            for(const auto& c : contours) {
                 msg << " Contour: \n";
                 for(auto p : c) {
                     msg << "   " << p.x << " " << p.y << " \n";
@@ -1690,7 +1690,7 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(std::shared_ptr<TempMe
         return contours;
 }
 
-std::vector<std::vector<IfcVector2>> GetContoursInPlane(std::shared_ptr<TempMesh> mesh,IfcMatrix3 planeSpace,
+std::vector<std::vector<IfcVector2>> GetContoursInPlane(const std::shared_ptr<TempMesh>& mesh,IfcMatrix3 planeSpace,
     IfcVector3 planeNor,IfcFloat planeOffset,
     IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first) {
 
@@ -1758,7 +1758,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
         vmin = std::min(IfcVector2(vv.x, vv.y), vmin);
         vmax = std::max(IfcVector2(vv.x, vv.y), vmax);
 
-        contour_flat.push_back(IfcVector2(vv.x,vv.y));
+        contour_flat.emplace_back(vv.x,vv.y);
     }
 
     // With the current code in DerivePlaneCoordinateSpace,
@@ -1791,7 +1791,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
                     pip.x = (pip.x - vmin.x) / vmax.x;
                     pip.y = (pip.y - vmin.y) / vmax.y;
 
-                    hole.push_back(ClipperLib::IntPoint(to_int64(pip.x),to_int64(pip.y)));
+                    hole.emplace_back(to_int64(pip.x), to_int64(pip.y));
                 }
 
                 if(!ClipperLib::Orientation(hole)) {
@@ -1833,7 +1833,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
                 pip.x  = (pip.x - vmin.x) / vmax.x;
                 pip.y  = (pip.y - vmin.y) / vmax.y;
 
-                poly.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) ));
+                poly.emplace_back(to_int64(pip.x), to_int64(pip.y));
             }
 
             if (ClipperLib::Orientation(poly)) {
@@ -1891,7 +1891,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,
         // Build the poly2tri inner contours for all holes we got from ClipperLib
         for(ClipperLib::Polygon& opening : clip.holes) {
 
-            contours.push_back(std::vector<p2t::Point*>());
+            contours.emplace_back();
             std::vector<p2t::Point*>& contour = contours.back();
 
             for(ClipperLib::IntPoint& point : opening) {

+ 17 - 17
Engine/lib/assimp/code/AssetLib/IFC/IFCProfile.cpp

@@ -108,10 +108,10 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
         const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
 
         meshout.mVerts.reserve(meshout.mVerts.size()+4);
-        meshout.mVerts.push_back( IfcVector3( x, y, 0.f ));
-        meshout.mVerts.push_back( IfcVector3(-x, y, 0.f ));
-        meshout.mVerts.push_back( IfcVector3(-x,-y, 0.f ));
-        meshout.mVerts.push_back( IfcVector3( x,-y, 0.f ));
+        meshout.mVerts.emplace_back( x, y, 0.f );
+        meshout.mVerts.emplace_back(-x, y, 0.f );
+        meshout.mVerts.emplace_back(-x,-y, 0.f );
+        meshout.mVerts.emplace_back( x,-y, 0.f );
         meshout.mVertcnt.push_back(4);
     }
     else if( const Schema_2x3::IfcCircleProfileDef* const circle = def.ToPtr<Schema_2x3::IfcCircleProfileDef>()) {
@@ -125,7 +125,7 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
 
         IfcFloat angle = 0.f;
         for(size_t i = 0; i < segments; ++i, angle += delta) {
-            meshout.mVerts.push_back( IfcVector3( std::cos(angle)*radius, std::sin(angle)*radius, 0.f ));
+            meshout.mVerts.emplace_back( std::cos(angle)*radius, std::sin(angle)*radius, 0.f );
         }
 
         meshout.mVertcnt.push_back(static_cast<unsigned int>(segments));
@@ -136,18 +136,18 @@ void ProcessParametrizedProfile(const Schema_2x3::IfcParameterizedProfileDef& de
         const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2;
 
         meshout.mVerts.reserve(12);
-        meshout.mVerts.push_back(IfcVector3(0,0,0));
-        meshout.mVerts.push_back(IfcVector3(0,ishape->FlangeThickness,0));
-        meshout.mVerts.push_back(IfcVector3(offset,ishape->FlangeThickness,0));
-        meshout.mVerts.push_back(IfcVector3(offset,ishape->FlangeThickness + inner_height,0));
-        meshout.mVerts.push_back(IfcVector3(0,ishape->FlangeThickness + inner_height,0));
-        meshout.mVerts.push_back(IfcVector3(0,ishape->OverallDepth,0));
-        meshout.mVerts.push_back(IfcVector3(ishape->OverallWidth,ishape->OverallDepth,0));
-        meshout.mVerts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness + inner_height,0));
-        meshout.mVerts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness + inner_height,0));
-        meshout.mVerts.push_back(IfcVector3(offset+ishape->WebThickness,ishape->FlangeThickness,0));
-        meshout.mVerts.push_back(IfcVector3(ishape->OverallWidth,ishape->FlangeThickness,0));
-        meshout.mVerts.push_back(IfcVector3(ishape->OverallWidth,0,0));
+        meshout.mVerts.emplace_back(0,0,0);
+        meshout.mVerts.emplace_back(0,ishape->FlangeThickness,0);
+        meshout.mVerts.emplace_back(offset,ishape->FlangeThickness,0);
+        meshout.mVerts.emplace_back(offset,ishape->FlangeThickness + inner_height,0);
+        meshout.mVerts.emplace_back(0,ishape->FlangeThickness + inner_height,0);
+        meshout.mVerts.emplace_back(0,ishape->OverallDepth,0);
+        meshout.mVerts.emplace_back(ishape->OverallWidth,ishape->OverallDepth,0);
+        meshout.mVerts.emplace_back(ishape->OverallWidth,ishape->FlangeThickness + inner_height,0);
+        meshout.mVerts.emplace_back(offset+ishape->WebThickness,ishape->FlangeThickness + inner_height,0);
+        meshout.mVerts.emplace_back(offset+ishape->WebThickness,ishape->FlangeThickness,0);
+        meshout.mVerts.emplace_back(ishape->OverallWidth,ishape->FlangeThickness,0);
+        meshout.mVerts.emplace_back(ishape->OverallWidth,0,0);
 
         meshout.mVertcnt.push_back(12);
     }

+ 2 - 2
Engine/lib/assimp/code/AssetLib/IFC/IFCUtil.cpp

@@ -201,7 +201,7 @@ void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
     size_t vidx = std::accumulate(mVertcnt.begin(),begin,0);
     for(iit = begin; iit != end; vidx += *iit++) {
         if (!*iit) {
-            normals.push_back(IfcVector3());
+            normals.emplace_back();
             continue;
         }
         for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) {
@@ -215,7 +215,7 @@ void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
             ++cnt;
         }
 
-        normals.push_back(IfcVector3());
+        normals.emplace_back();
         NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]);
     }
 

+ 1 - 2
Engine/lib/assimp/code/AssetLib/IFC/IFCUtil.h

@@ -344,8 +344,7 @@ protected:
 public:
     typedef std::pair<IfcFloat, IfcFloat> ParamRange;
 
-    virtual ~Curve() {}
-
+    virtual ~Curve() = default;
 
     // check if a curve is closed
     virtual bool IsClosed() const = 0;

+ 2 - 2
Engine/lib/assimp/code/AssetLib/IQM/IQMImporter.h

@@ -56,9 +56,9 @@ class IQMImporter : public BaseImporter {
 public:
 	/// \brief  Default constructor
 	IQMImporter();
-    ~IQMImporter() override {}
+    ~IQMImporter() override = default;
 
-	/// \brief  Returns whether the class can handle the format of the given file.
+    /// \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 override;
 

+ 6 - 8
Engine/lib/assimp/code/AssetLib/Irr/IRRLoader.cpp

@@ -88,9 +88,7 @@ IRRImporter::IRRImporter() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-IRRImporter::~IRRImporter() {
-	// empty
-}
+IRRImporter::~IRRImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -628,7 +626,7 @@ void IRRImporter::GenerateGraph(Node *root, aiNode *rootOut, aiScene *scene,
 				ASSIMP_LOG_ERROR("IRR: Unable to load external file: ", root->meshPath);
 				break;
 			}
-			attach.push_back(AttachmentInfo(localScene, rootOut));
+			attach.emplace_back(localScene, rootOut);
 
 			// Now combine the material we've loaded for this mesh
 			// with the real materials we got from the file. As we
@@ -874,7 +872,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 
 	// Batch loader used to load external models
 	BatchLoader batch(pIOHandler);
-	//  batch.SetBasePath(pFile);
+	//batch.SetBasePath(pFile);
 
 	cameras.reserve(5);
 	lights.reserve(5);
@@ -979,7 +977,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 					// Materials can occur for nearly any type of node
 					if (inMaterials && curNode->type != Node::DUMMY) {
 						//  This is a material description - parse it!
-						curNode->materials.push_back(std::pair<aiMaterial *, unsigned int>());
+						curNode->materials.emplace_back();
 						std::pair<aiMaterial *, unsigned int> &p = curNode->materials.back();
 
 						p.first = ParseMaterial(p.second);
@@ -988,7 +986,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 					} else if (inAnimator) {
 						//  This is an animation path - add a new animator
 						//  to the list.
-						curNode->animators.push_back(Animator());
+						curNode->animators.emplace_back();
 						curAnim = &curNode->animators.back();
 
 						++guessedAnimCnt;
@@ -1015,7 +1013,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 										// here N is the ONE-based index of the point
 										if (prop.name.length() >= 6 && prop.name.substr(0, 5) == "Point") {
 											// Add a new key to the list
-											curAnim->splineKeys.push_back(aiVectorKey());
+											curAnim->splineKeys.emplace_back();
 											aiVectorKey &key = curAnim->splineKeys.back();
 
 											// and parse its properties

+ 1 - 2
Engine/lib/assimp/code/AssetLib/Irr/IRRLoader.h

@@ -206,8 +206,7 @@ private:
      */
     struct SkyboxVertex
     {
-        SkyboxVertex()
-        {}
+        SkyboxVertex() = default;
 
         //! Construction from single vertex components
         SkyboxVertex(ai_real px, ai_real py, ai_real pz,

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Irr/IRRMeshLoader.cpp

@@ -79,7 +79,7 @@ IRRMeshImporter::IRRMeshImporter() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-IRRMeshImporter::~IRRMeshImporter() {}
+IRRMeshImporter::~IRRMeshImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.

+ 1 - 1
Engine/lib/assimp/code/AssetLib/LWO/LWOBLoader.cpp

@@ -218,7 +218,7 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
 // ------------------------------------------------------------------------------------------------
 LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size)
 {
-    list.push_back(LWO::Texture());
+    list.emplace_back();
     LWO::Texture* tex = &list.back();
 
     std::string type;

+ 2 - 8
Engine/lib/assimp/code/AssetLib/LWO/LWOFileData.h

@@ -338,13 +338,7 @@ struct Face : public aiFace {
     uint32_t type;
 
     //! Assignment operator
-    Face &operator=(const LWO::Face &f) {
-        aiFace::operator=(f);
-        surfaceIndex = f.surfaceIndex;
-        smoothGroup = f.smoothGroup;
-        type = f.type;
-        return *this;
-    }
+    Face &operator=(const LWO::Face &f) = default;
 };
 
 // ---------------------------------------------------------------------------
@@ -354,7 +348,7 @@ struct VMapEntry {
     explicit VMapEntry(unsigned int _dims) :
             dims(_dims) {}
 
-    virtual ~VMapEntry() {}
+    virtual ~VMapEntry() = default;
 
     //! allocates memory for the vertex map
     virtual void Allocate(unsigned int num) {

+ 9 - 11
Engine/lib/assimp/code/AssetLib/LWO/LWOLoader.cpp

@@ -100,9 +100,7 @@ LWOImporter::LWOImporter() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-LWOImporter::~LWOImporter() {
-    // empty
-}
+LWOImporter::~LWOImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -287,7 +285,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
             if (UINT_MAX == iDefaultSurface) {
                 pSorted.erase(pSorted.end() - 1);
             }
-            for (unsigned int p = 0, j = 0; j < mSurfaces->size(); ++j) {
+            for (unsigned int j = 0; j < mSurfaces->size(); ++j) {
                 SortedRep &sorted = pSorted[j];
                 if (sorted.empty())
                     continue;
@@ -425,7 +423,6 @@ void LWOImporter::InternReadFile(const std::string &pFile,
                 } else {
                     ASSIMP_LOG_VERBOSE_DEBUG("LWO2: No need to compute normals, they're already there");
                 }
-                ++p;
             }
         }
 
@@ -1098,7 +1095,7 @@ void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly) {
 void LWOImporter::LoadLWO2Clip(unsigned int length) {
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 10);
 
-    mClips.push_back(LWO::Clip());
+    mClips.emplace_back();
     LWO::Clip &clip = mClips.back();
 
     // first - get the index of the clip
@@ -1168,7 +1165,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length) {
 void LWOImporter::LoadLWO3Clip(unsigned int length) {
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 12);
 
-    mClips.push_back(LWO::Clip());
+    mClips.emplace_back();
     LWO::Clip &clip = mClips.back();
 
     // first - get the index of the clip
@@ -1241,7 +1238,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length) {
     LE_NCONST uint8_t *const end = mFileBuffer + length;
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4);
 
-    mEnvelopes.push_back(LWO::Envelope());
+    mEnvelopes.emplace_back();
     LWO::Envelope &envelope = mEnvelopes.back();
 
     // Get the index of the envelope
@@ -1293,7 +1290,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length) {
             case AI_LWO_KEY: {
                 AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, KEY, 8);
 
-                envelope.keys.push_back(LWO::Key());
+                envelope.keys.emplace_back();
                 LWO::Key &key = envelope.keys.back();
 
                 key.time = GetF4();
@@ -1349,7 +1346,7 @@ void LWOImporter::LoadLWO3Envelope(unsigned int length) {
     LE_NCONST uint8_t *const end = mFileBuffer + length;
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4);
 
-    mEnvelopes.push_back(LWO::Envelope());
+    mEnvelopes.emplace_back();
     LWO::Envelope &envelope = mEnvelopes.back();
 
     // Get the index of the envelope
@@ -1391,7 +1388,7 @@ void LWOImporter::LoadLWO3Envelope(unsigned int length) {
             case AI_LWO_KEY: {
                 AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, KEY, 10);
 
-                envelope.keys.push_back(LWO::Key());
+                envelope.keys.emplace_back();
                 LWO::Key &key = envelope.keys.back();
 
                 key.time = GetF4();
@@ -1541,6 +1538,7 @@ void LWOImporter::LoadLWO2File() {
                     break;
                 }
                 // --- intentionally no break here
+                // fallthrough
             case AI_LWO_VMAP: {
                 if (skip)
                     break;

+ 0 - 2
Engine/lib/assimp/code/AssetLib/LWO/LWOMaterial.cpp

@@ -707,12 +707,10 @@ void LWOImporter::LoadNodalBlocks(unsigned int size) {
         if (mFileBuffer + head.length > end) {
             throw DeadlyImportError("LWO3: cannot read length; LoadNodalBlocks");
         }
-        int node_idx = 0;
         uint8_t *const next = mFileBuffer + head.length;
         mFileBuffer += bufOffset;
         switch (head.type) {
         case AI_LWO_NNDS:
-            node_idx++;
             LoadNodes(head.length);
             break;
         }

+ 10 - 13
Engine/lib/assimp/code/AssetLib/LWS/LWSLoader.cpp

@@ -90,7 +90,7 @@ void LWS::Element::Parse(const char *&buffer) {
         } else if (*buffer == '}')
             return;
 
-        children.push_back(Element());
+        children.emplace_back();
 
         // copy data line - read token per token
 
@@ -141,9 +141,7 @@ LWSImporter::LWSImporter() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-LWSImporter::~LWSImporter() {
-    // nothing to do here
-}
+LWSImporter::~LWSImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -199,7 +197,7 @@ void LWSImporter::ReadEnvelope(const LWS::Element &dad, LWO::Envelope &fill) {
         const char *c = (*it).tokens[1].c_str();
 
         if ((*it).tokens[0] == "Key") {
-            fill.keys.push_back(LWO::Key());
+            fill.keys.emplace_back();
             LWO::Key &key = fill.keys.back();
 
             float f;
@@ -262,7 +260,7 @@ void LWSImporter::ReadEnvelope_Old(
     num = strtoul10((*it).tokens[0].c_str());
     for (unsigned int i = 0; i < num; ++i) {
 
-        nodes.channels.push_back(LWO::Envelope());
+        nodes.channels.emplace_back();
         LWO::Envelope &envl = nodes.channels.back();
 
         envl.index = i;
@@ -313,6 +311,9 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
             std::string::size_type t = src.path.substr(s).find_last_of('.');
 
             nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)", src.path.substr(s).substr(0, t).c_str(), combined);
+            if (nd->mName.length > MAXLEN) {
+                nd->mName.length = MAXLEN;
+            }
             return;
         }
     }
@@ -381,7 +382,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<Attachm
 
         //Push attachment, if the object came from an external file
         if (obj) {
-            attach.push_back(AttachmentInfo(obj, nd));
+            attach.emplace_back(obj, nd);
         }
     }
 
@@ -513,7 +514,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
     std::list<LWS::NodeDesc> nodes;
 
     unsigned int cur_light = 0, cur_camera = 0, cur_object = 0;
-    unsigned int num_light = 0, num_camera = 0, num_object = 0;
+    unsigned int num_light = 0, num_camera = 0;
 
     // check magic identifier, 'LWSC'
     bool motion_file = false;
@@ -583,7 +584,6 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
             d.id = batch.AddLoadRequest(path, 0, &props);
 
             nodes.push_back(d);
-            ++num_object;
         } else if ((*it).tokens[0] == "LoadObject") { // 'LoadObject': load a LWO file into the scene-graph
 
             // add node to list
@@ -601,7 +601,6 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 
             d.path = path;
             nodes.push_back(d);
-            ++num_object;
         } else if ((*it).tokens[0] == "AddNullObject") { // 'AddNullObject': add a dummy node to the hierarchy
 
             // add node to list
@@ -615,8 +614,6 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
             }
             d.name = c;
             nodes.push_back(d);
-
-            num_object++;
         }
         // 'NumChannels': Number of envelope channels assigned to last layer
         else if ((*it).tokens[0] == "NumChannels") {
@@ -638,7 +635,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
             }
 
             // important: index of channel
-            nodes.back().channels.push_back(LWO::Envelope());
+            nodes.back().channels.emplace_back();
             LWO::Envelope &env = nodes.back().channels.back();
 
             env.index = strtoul10(c);

+ 1 - 1
Engine/lib/assimp/code/AssetLib/LWS/LWSLoader.h

@@ -69,7 +69,7 @@ namespace LWS {
  */
 class Element {
 public:
-    Element() {}
+    Element() = default;
 
     // first: name, second: rest
     std::string tokens[2];

+ 1 - 3
Engine/lib/assimp/code/AssetLib/M3D/M3DWrapper.h

@@ -57,9 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // Assimp specific M3D configuration. Comment out these defines to remove functionality
 //#define ASSIMP_USE_M3D_READFILECB
 
-// Share stb_image's PNG loader with other importers/exporters instead of bringing our own copy.
-#define STBI_ONLY_PNG
-#include <stb/stb_image.h>
+#include "Common/StbCommon.h"
 
 #include "m3d.h"
 

+ 1 - 2
Engine/lib/assimp/code/AssetLib/MD2/MD2Loader.cpp

@@ -102,8 +102,7 @@ MD2Importer::MD2Importer()
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-MD2Importer::~MD2Importer()
-{}
+MD2Importer::~MD2Importer() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.

+ 7 - 7
Engine/lib/assimp/code/AssetLib/MD3/MD3Loader.cpp

@@ -144,7 +144,7 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
                 if (*buff == '{') {
                     ++buff;
                     // add new map section
-                    curData->maps.push_back(Q3Shader::ShaderMapBlock());
+                    curData->maps.emplace_back();
                     curMap = &curData->maps.back();
 
                     for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
@@ -209,7 +209,7 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
             }
         } else {
             // add new section
-            fill.blocks.push_back(Q3Shader::ShaderDataBlock());
+            fill.blocks.emplace_back();
             curData = &fill.blocks.back();
 
             // get the name of this section
@@ -249,7 +249,7 @@ bool Q3Shader::LoadSkin(SkinData &fill, const std::string &pFile, IOSystem *io)
         if (!::strncmp(&ss[0], "tag_", std::min((size_t)4, ss.length())))
             continue;
 
-        fill.textures.push_back(SkinData::TextureEntry());
+        fill.textures.emplace_back();
         SkinData::TextureEntry &entry = fill.textures.back();
 
         entry.first = ss;
@@ -345,7 +345,7 @@ MD3Importer::MD3Importer() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-MD3Importer::~MD3Importer() {}
+MD3Importer::~MD3Importer() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -584,7 +584,7 @@ bool MD3Importer::ReadMultipartFile() {
 
         // original root
         scene_lower->mRootNode->mName.Set("lower");
-        attach.push_back(AttachmentInfo(scene_lower, nd));
+        attach.emplace_back(scene_lower, nd);
 
         // tag_torso
         tag_torso = scene_lower->mRootNode->FindNode("tag_torso");
@@ -593,7 +593,7 @@ bool MD3Importer::ReadMultipartFile() {
             goto error_cleanup;
         }
         scene_upper->mRootNode->mName.Set("upper");
-        attach.push_back(AttachmentInfo(scene_upper, tag_torso));
+        attach.emplace_back(scene_upper, tag_torso);
 
         // tag_head
         tag_head = scene_upper->mRootNode->FindNode("tag_head");
@@ -602,7 +602,7 @@ bool MD3Importer::ReadMultipartFile() {
             goto error_cleanup;
         }
         scene_head->mRootNode->mName.Set("head");
-        attach.push_back(AttachmentInfo(scene_head, tag_head));
+        attach.emplace_back(scene_head, tag_head);
 
         // Remove tag_head and tag_torso from all other model parts ...
         // this ensures (together with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY)

+ 1 - 3
Engine/lib/assimp/code/AssetLib/MD5/MD5Loader.cpp

@@ -94,9 +94,7 @@ MD5Importer::MD5Importer() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-MD5Importer::~MD5Importer() {
-    // empty
-}
+MD5Importer::~MD5Importer() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.

+ 10 - 13
Engine/lib/assimp/code/AssetLib/MD5/MD5Parser.cpp

@@ -60,14 +60,11 @@ using namespace Assimp::MD5;
 
 // ------------------------------------------------------------------------------------------------
 // Parse the segment structure for an MD5 file
-MD5Parser::MD5Parser(char *_buffer, unsigned int _fileSize) {
+MD5Parser::MD5Parser(char *_buffer, unsigned int _fileSize) : buffer(_buffer), bufferEnd(nullptr), fileSize(_fileSize), lineNumber(0) {
     ai_assert(nullptr != _buffer);
     ai_assert(0 != _fileSize);
 
-    buffer = _buffer;
-    fileSize = _fileSize;
-    lineNumber = 0;
-
+    bufferEnd = buffer + fileSize;
     ASSIMP_LOG_DEBUG("MD5Parser begin");
 
     // parse the file header
@@ -76,7 +73,7 @@ MD5Parser::MD5Parser(char *_buffer, unsigned int _fileSize) {
     // and read all sections until we're finished
     bool running = true;
     while (running) {
-        mSections.push_back(Section());
+        mSections.emplace_back();
         Section &sec = mSections.back();
         if (!ParseSection(sec)) {
             break;
@@ -158,7 +155,7 @@ bool MD5Parser::ParseSection(Section &out) {
                     break;
                 }
 
-                out.mElements.push_back(Element());
+                out.mElements.emplace_back();
                 Element &elem = out.mElements.back();
 
                 elem.iLineNumber = lineNumber;
@@ -253,7 +250,7 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
         } else if ((*iter).mName == "joints") {
             // "origin" -1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 )
             for (const auto &elem : (*iter).mElements) {
-                mJoints.push_back(BoneDesc());
+                mJoints.emplace_back();
                 BoneDesc &desc = mJoints.back();
 
                 const char *sz = elem.szStart;
@@ -267,7 +264,7 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
                 AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
             }
         } else if ((*iter).mName == "mesh") {
-            mMeshes.push_back(MeshDesc());
+            mMeshes.emplace_back();
             MeshDesc &desc = mMeshes.back();
 
             for (const auto &elem : (*iter).mElements) {
@@ -364,7 +361,7 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
         if ((*iter).mName == "hierarchy") {
             // "sheath" 0 63 6
             for (const auto &elem : (*iter).mElements) {
-                mAnimatedBones.push_back(AnimBoneDesc());
+                mAnimatedBones.emplace_back();
                 AnimBoneDesc &desc = mAnimatedBones.back();
 
                 const char *sz = elem.szStart;
@@ -389,7 +386,7 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
             for (const auto &elem : (*iter).mElements) {
                 const char *sz = elem.szStart;
 
-                mBaseFrames.push_back(BaseFrameDesc());
+                mBaseFrames.emplace_back();
                 BaseFrameDesc &desc = mBaseFrames.back();
 
                 AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
@@ -401,7 +398,7 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
                 continue;
             }
 
-            mFrames.push_back(FrameDesc());
+            mFrames.emplace_back();
             FrameDesc &desc = mFrames.back();
             desc.iIndex = strtoul10((*iter).mGlobalValue.c_str());
 
@@ -459,7 +456,7 @@ MD5CameraParser::MD5CameraParser(SectionList &mSections) {
             for (const auto &elem : (*iter).mElements) {
                 const char *sz = elem.szStart;
 
-                frames.push_back(CameraAnimFrameDesc());
+                frames.emplace_back();
                 CameraAnimFrameDesc &cur = frames.back();
                 AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
                 AI_MD5_READ_TRIPLE(cur.vRotationQuat);

+ 87 - 100
Engine/lib/assimp/code/AssetLib/MD5/MD5Parser.h

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 ----------------------------------------------------------------------
 */
-
+#pragma once
 
 /** @file  MD5Parser.h
  *  @brief Definition of the .MD5 parser class.
@@ -51,20 +51,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/types.h>
 #include <assimp/ParsingUtils.h>
 #include <vector>
-#include <stdint.h>
+#include <cstdint>
 
 struct aiFace;
 
-namespace Assimp    {
-namespace MD5           {
+namespace Assimp {
+namespace MD5 {
 
 // ---------------------------------------------------------------------------
 /** Represents a single element in a MD5 file
  *
  *  Elements are always contained in sections.
 */
-struct Element
-{
+struct Element {
     //! Points to the starting point of the element
     //! Whitespace at the beginning and at the end have been removed,
     //! Elements are terminated with \0
@@ -75,15 +74,14 @@ struct Element
     unsigned int iLineNumber;
 };
 
-typedef std::vector< Element > ElementList;
+using ElementList = std::vector<Element>;
 
 // ---------------------------------------------------------------------------
 /** Represents a section of a MD5 file (such as the mesh or the joints section)
  *
  *  A section is always enclosed in { and } brackets.
 */
-struct Section
-{
+struct Section {
     //! Original line number (can be used in error messages
     //! if a parsing error occurs)
     unsigned int iLineNumber;
@@ -99,13 +97,12 @@ struct Section
     std::string mGlobalValue;
 };
 
-typedef std::vector< Section> SectionList;
+using SectionList = std::vector<Section>;
 
 // ---------------------------------------------------------------------------
 /** Basic information about a joint
 */
-struct BaseJointDescription
-{
+struct BaseJointDescription {
     //! Name of the bone
     aiString mName;
 
@@ -116,8 +113,7 @@ struct BaseJointDescription
 // ---------------------------------------------------------------------------
 /** Represents a bone (joint) descriptor in a MD5Mesh file
 */
-struct BoneDesc : BaseJointDescription
-{
+struct BoneDesc : BaseJointDescription {
     //! Absolute position of the bone
     aiVector3D mPositionXYZ;
 
@@ -137,13 +133,12 @@ struct BoneDesc : BaseJointDescription
     unsigned int mMap;
 };
 
-typedef std::vector< BoneDesc > BoneList;
+using BoneList = std::vector<BoneDesc>;
 
 // ---------------------------------------------------------------------------
 /** Represents a bone (joint) descriptor in a MD5Anim file
 */
-struct AnimBoneDesc : BaseJointDescription
-{
+struct AnimBoneDesc : BaseJointDescription {
     //! Flags (AI_MD5_ANIMATION_FLAG_xxx)
     unsigned int iFlags;
 
@@ -151,35 +146,31 @@ struct AnimBoneDesc : BaseJointDescription
     unsigned int iFirstKeyIndex;
 };
 
-typedef std::vector< AnimBoneDesc > AnimBoneList;
-
+using AnimBoneList = std::vector< AnimBoneDesc >;
 
 // ---------------------------------------------------------------------------
 /** Represents a base frame descriptor in a MD5Anim file
 */
-struct BaseFrameDesc
-{
+struct BaseFrameDesc {
     aiVector3D vPositionXYZ;
     aiVector3D vRotationQuat;
 };
 
-typedef std::vector< BaseFrameDesc > BaseFrameList;
+using BaseFrameList = std::vector<BaseFrameDesc>;
 
 // ---------------------------------------------------------------------------
 /** Represents a camera animation frame in a MDCamera file
 */
-struct CameraAnimFrameDesc : BaseFrameDesc
-{
+struct CameraAnimFrameDesc : BaseFrameDesc {
     float fFOV;
 };
 
-typedef std::vector< CameraAnimFrameDesc > CameraFrameList;
+using CameraFrameList = std::vector<CameraAnimFrameDesc>;
 
 // ---------------------------------------------------------------------------
 /** Represents a frame descriptor in a MD5Anim file
 */
-struct FrameDesc
-{
+struct FrameDesc {
     //! Index of the frame
     unsigned int iIndex;
 
@@ -187,15 +178,14 @@ struct FrameDesc
     std::vector< float > mValues;
 };
 
-typedef std::vector< FrameDesc > FrameList;
+using FrameList = std::vector<FrameDesc>;
 
 // ---------------------------------------------------------------------------
 /** Represents a vertex  descriptor in a MD5 file
 */
 struct VertexDesc {
     VertexDesc() AI_NO_EXCEPT
-    : mFirstWeight(0)
-    , mNumWeights(0) {
+    : mFirstWeight(0), mNumWeights(0) {
         // empty
     }
 
@@ -210,13 +200,12 @@ struct VertexDesc {
     unsigned int mNumWeights;
 };
 
-typedef std::vector< VertexDesc > VertexList;
+using VertexList = std::vector<VertexDesc>;
 
 // ---------------------------------------------------------------------------
 /** Represents a vertex weight descriptor in a MD5 file
 */
-struct WeightDesc
-{
+struct WeightDesc {
     //! Index of the bone to which this weight refers
     unsigned int mBone;
 
@@ -228,14 +217,13 @@ struct WeightDesc
     aiVector3D vOffsetPosition;
 };
 
-typedef std::vector< WeightDesc > WeightList;
-typedef std::vector< aiFace > FaceList;
+using WeightList = std::vector<WeightDesc>;
+using FaceList   = std::vector<aiFace>;
 
 // ---------------------------------------------------------------------------
 /** Represents a mesh in a MD5 file
 */
-struct MeshDesc
-{
+struct MeshDesc {
     //! Weights of the mesh
     WeightList mWeights;
 
@@ -249,7 +237,7 @@ struct MeshDesc
     aiString mShader;
 };
 
-typedef std::vector< MeshDesc > MeshList;
+using MeshList = std::vector<MeshDesc>;
 
 // ---------------------------------------------------------------------------
 // Convert a quaternion to its usual representation
@@ -261,9 +249,11 @@ inline void ConvertQuaternion (const aiVector3D& in, aiQuaternion& out) {
 
     const float t = 1.0f - (in.x*in.x) - (in.y*in.y) - (in.z*in.z);
 
-    if (t < 0.0f)
+    if (t < 0.0f) {
         out.w = 0.0f;
-    else out.w = std::sqrt (t);
+    } else {
+        out.w = std::sqrt (t);
+    }
 
     // Assimp convention.
     out.w *= -1.f;
@@ -272,10 +262,8 @@ inline void ConvertQuaternion (const aiVector3D& in, aiQuaternion& out) {
 // ---------------------------------------------------------------------------
 /** Parses the data sections of a MD5 mesh file
 */
-class MD5MeshParser
-{
+class MD5MeshParser {
 public:
-
     // -------------------------------------------------------------------
     /** Constructs a new MD5MeshParser instance from an existing
      *  preparsed list of file sections.
@@ -297,10 +285,8 @@ public:
 // ---------------------------------------------------------------------------
 /** Parses the data sections of a MD5 animation file
 */
-class MD5AnimParser
-{
+class MD5AnimParser {
 public:
-
     // -------------------------------------------------------------------
     /** Constructs a new MD5AnimParser instance from an existing
      *  preparsed list of file sections.
@@ -329,10 +315,8 @@ public:
 // ---------------------------------------------------------------------------
 /** Parses the data sections of a MD5 camera animation file
 */
-class MD5CameraParser
-{
+class MD5CameraParser {
 public:
-
     // -------------------------------------------------------------------
     /** Constructs a new MD5CameraParser instance from an existing
      *  preparsed list of file sections.
@@ -341,7 +325,6 @@ public:
      */
     explicit MD5CameraParser(SectionList& mSections);
 
-
     //! Output frame rate
     float fFrameRate;
 
@@ -356,10 +339,8 @@ public:
 /** Parses the block structure of MD5MESH and MD5ANIM files (but does no
  *  further processing)
 */
-class MD5Parser
-{
+class MD5Parser {
 public:
-
     // -------------------------------------------------------------------
     /** Constructs a new MD5Parser instance from an existing buffer.
      *
@@ -392,13 +373,10 @@ public:
         return ReportWarning(warn, lineNumber);
     }
 
-public:
-
     //! List of all sections which have been read
     SectionList mSections;
 
 private:
-
     // -------------------------------------------------------------------
     /** Parses a file section. The current file pointer must be outside
      *  of a section.
@@ -414,54 +392,63 @@ private:
      */
     void ParseHeader();
 
-
-    // override these functions to make sure the line counter gets incremented
-    // -------------------------------------------------------------------
-    bool SkipLine( const char* in, const char** out)
-    {
-        ++lineNumber;
-        return Assimp::SkipLine(in,out);
-    }
-    // -------------------------------------------------------------------
-    bool SkipLine( )
-    {
-        return SkipLine(buffer,(const char**)&buffer);
-    }
-    // -------------------------------------------------------------------
-    bool SkipSpacesAndLineEnd( const char* in, const char** out)
-    {
-        bool bHad = false;
-        bool running = true;
-        while (running) {
-            if( *in == '\r' || *in == '\n') {
-                 // we open files in binary mode, so there could be \r\n sequences ...
-                if (!bHad)  {
-                    bHad = true;
-                    ++lineNumber;
-                }
-            }
-            else if (*in == '\t' || *in == ' ')bHad = false;
-            else break;
-            in++;
-        }
-        *out = in;
-        return *in != '\0';
-    }
-    // -------------------------------------------------------------------
-    bool SkipSpacesAndLineEnd( )
-    {
-        return SkipSpacesAndLineEnd(buffer,(const char**)&buffer);
-    }
-    // -------------------------------------------------------------------
-    bool SkipSpaces( )
-    {
-        return Assimp::SkipSpaces((const char**)&buffer);
-    }
+    bool SkipLine(const char* in, const char** out);
+    bool SkipLine( );
+    bool SkipSpacesAndLineEnd( const char* in, const char** out);    
+    bool SkipSpacesAndLineEnd();
+    bool SkipSpaces();
 
     char* buffer;
+    char* bufferEnd;
     unsigned int fileSize;
     unsigned int lineNumber;
 };
-}}
+
+// -------------------------------------------------------------------
+inline bool MD5Parser::SkipLine(const char* in, const char** out) {
+    ++lineNumber;
+    return Assimp::SkipLine(in ,out);
+}
+
+// -------------------------------------------------------------------
+inline bool MD5Parser::SkipLine( ) {
+    return SkipLine(buffer,(const char**)&buffer);
+}
+
+// -------------------------------------------------------------------
+inline bool MD5Parser::SkipSpacesAndLineEnd( const char* in, const char** out) {
+    bool bHad = false;
+    bool running = true;
+    while (running) {
+        if( *in == '\r' || *in == '\n') {
+                // we open files in binary mode, so there could be \r\n sequences ...
+            if (!bHad)  {
+                bHad = true;
+                ++lineNumber;
+            }
+        }
+        else if (*in == '\t' || *in == ' ')bHad = false;
+        else break;
+        ++in;
+        if (in == bufferEnd) {
+            break;
+        }
+    }
+    *out = in;
+    return *in != '\0';
+}
+
+// -------------------------------------------------------------------
+inline bool MD5Parser::SkipSpacesAndLineEnd() {
+    return SkipSpacesAndLineEnd(buffer,(const char**)&buffer);
+}
+
+// -------------------------------------------------------------------
+inline bool MD5Parser::SkipSpaces() {
+    return Assimp::SkipSpaces((const char**)&buffer);
+}
+
+} // namespace Assimp
+} // namespace MD5
 
 #endif // AI_MD5PARSER_H_INCLUDED

+ 4 - 6
Engine/lib/assimp/code/AssetLib/MDC/MDCLoader.cpp

@@ -105,9 +105,7 @@ MDCImporter::MDCImporter() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-MDCImporter::~MDCImporter() {
-    // empty
-}
+MDCImporter::~MDCImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -271,13 +269,13 @@ void MDCImporter::InternReadFile(
             pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
 
             // create a new shader
-            aszShaders.push_back(std::string(pcShader->ucName,
-                    ::strnlen(pcShader->ucName, sizeof(pcShader->ucName))));
+            aszShaders.emplace_back(pcShader->ucName,
+                    ::strnlen(pcShader->ucName, sizeof(pcShader->ucName)));
         }
         // need to create a default material
         else if (UINT_MAX == iDefaultMatIndex) {
             pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
-            aszShaders.push_back(std::string());
+            aszShaders.emplace_back();
         }
         // otherwise assign a reference to the default material
         else

+ 1 - 2
Engine/lib/assimp/code/AssetLib/MDL/HalfLife/UniqueNameGenerator.cpp

@@ -68,8 +68,7 @@ UniqueNameGenerator::UniqueNameGenerator(const char *template_name, const char *
     separator_(separator) {
 }
 
-UniqueNameGenerator::~UniqueNameGenerator() {
-}
+UniqueNameGenerator::~UniqueNameGenerator() = default;
 
 void UniqueNameGenerator::make_unique(std::vector<std::string> &names) {
     struct DuplicateInfo {

+ 1 - 3
Engine/lib/assimp/code/AssetLib/MDL/MDLLoader.cpp

@@ -98,9 +98,7 @@ MDLImporter::MDLImporter() :
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-MDLImporter::~MDLImporter() {
-    // empty
-}
+MDLImporter::~MDLImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.

+ 3 - 0
Engine/lib/assimp/code/AssetLib/MDL/MDLMaterialLoader.cpp

@@ -449,6 +449,9 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
         unsigned int iWidth,
         unsigned int iHeight) {
     std::unique_ptr<aiTexture> pcNew;
+    if (szCurrent == nullptr) {
+        return;
+    }
 
     // get the type of the skin
     unsigned int iMasked = (unsigned int)(iType & 0xF);

+ 35 - 43
Engine/lib/assimp/code/AssetLib/MMD/MMDImporter.cpp

@@ -52,9 +52,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/scene.h>
 #include <assimp/Importer.hpp>
 
-#include <fstream>
+
 #include <iomanip>
 #include <memory>
+#include <sstream>
 
 static const aiImporterDesc desc = { "MMD Importer",
     "",
@@ -82,9 +83,7 @@ MMDImporter::MMDImporter() :
 
 // ------------------------------------------------------------------------------------------------
 //  Destructor.
-MMDImporter::~MMDImporter() {
-    // empty
-}
+MMDImporter::~MMDImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 //  Returns true, if file is an pmx file.
@@ -102,26 +101,32 @@ const aiImporterDesc *MMDImporter::GetInfo() const {
 // ------------------------------------------------------------------------------------------------
 //  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, ".");
-    }
+        IOSystem* pIOHandler) {
 
-    std::istream fileStream(&fb);
+    auto streamCloser = [&](IOStream *pStream) {
+        pIOHandler->Close(pStream);
+    };
 
-    // 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);
+    static const std::string mode = "rb";
+    const std::unique_ptr<IOStream, decltype(streamCloser)> fileStream(pIOHandler->Open(file, mode), streamCloser);
 
-    if (fileSize < sizeof(pmx::PmxModel)) {
+    if (fileStream == nullptr) {
+        throw DeadlyImportError("Failed to open file ", file, ".");
+    }
+
+    const size_t fileSize = fileStream->FileSize();
+    if (fileSize < sizeof(pmx::PmxModel))
+    {
         throw DeadlyImportError(file, " is too small.");
     }
 
+    std::vector<char> contents(fileStream->FileSize());
+    fileStream->Read(contents.data(), 1, contents.size());
+
+    std::istringstream iss(std::string(contents.begin(), contents.end()));
+
     pmx::PmxModel model;
-    model.Read(&fileStream);
+    model.Read(&iss);
 
     CreateDataFromImport(&model, pScene);
 }
@@ -264,43 +269,30 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
                 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));
+            bone_vertex_map[vsBDEF1_ptr->bone_index].emplace_back(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));
+            bone_vertex_map[vsBDEF2_ptr->bone_index1].emplace_back(index, vsBDEF2_ptr->bone_weight);
+            bone_vertex_map[vsBDEF2_ptr->bone_index2].emplace_back(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));
+            bone_vertex_map[vsBDEF4_ptr->bone_index1].emplace_back(index, vsBDEF4_ptr->bone_weight1);
+            bone_vertex_map[vsBDEF4_ptr->bone_index2].emplace_back(index, vsBDEF4_ptr->bone_weight2);
+            bone_vertex_map[vsBDEF4_ptr->bone_index3].emplace_back(index, vsBDEF4_ptr->bone_weight3);
+            bone_vertex_map[vsBDEF4_ptr->bone_index4].emplace_back(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));
+            bone_vertex_map[vsSDEF_ptr->bone_index1].emplace_back(index, vsSDEF_ptr->bone_weight);
+            bone_vertex_map[vsSDEF_ptr->bone_index2].emplace_back(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));
+            bone_vertex_map[vsQDEF_ptr->bone_index1].emplace_back(index, vsQDEF_ptr->bone_weight1);
+            bone_vertex_map[vsQDEF_ptr->bone_index2].emplace_back(index, vsQDEF_ptr->bone_weight2);
+            bone_vertex_map[vsQDEF_ptr->bone_index3].emplace_back(index, vsQDEF_ptr->bone_weight3);
+            bone_vertex_map[vsQDEF_ptr->bone_index4].emplace_back(index, vsQDEF_ptr->bone_weight4);
             break;
         }
     }

+ 591 - 548
Engine/lib/assimp/code/AssetLib/MMD/MMDPmdParser.h

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2022, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -48,550 +47,594 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #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 (nullptr == 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 iterations;
-		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 *) &iterations, 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;
-		}
-	};
-}
+namespace pmd {
+
+struct PmdHeader {
+    std::string name;
+    std::string name_english;
+    std::string comment;
+    std::string comment_english;
+
+    PmdHeader() = default;
+    ~PmdHeader() = default;
+
+    bool Read(std::ifstream *stream) {
+        if (stream == nullptr) {
+            return false;
+        }
+        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) {
+        if (stream == nullptr) {
+            return false;
+        }
+
+        char buffer[256] = {};
+        stream->read(buffer, 20);
+        name_english = std::string(buffer);
+        stream->read(buffer, 256);
+        comment_english = std::string(buffer);
+
+        return true;
+    }
+};
+
+struct PmdVertex {
+    float position[3];
+    float normal[3];
+    float uv[2];
+    uint16_t bone_index[2];
+    uint8_t bone_weight;
+    bool edge_invisible;
+
+    PmdVertex() :
+            position{ 0.0f }, normal{ 0.0f }, uv{ 0.0f }, bone_index{ 0 }, bone_weight(0), edge_invisible(false) {}
+
+    ~PmdVertex() = default;
+
+    bool Read(std::ifstream *stream) {
+        if (stream == nullptr) {
+            return false;
+        }
+
+        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;
+    }
+};
+
+struct PmdMaterial {
+    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;
+
+    PmdMaterial() :
+            diffuse{ 0.0f }, power(0.0f), specular{ 0.0f }, ambient{ 0.0f }, toon_index(0), edge_flag(0), index_count(0), texture_filename(), sphere_filename() {}
+
+    ~PmdMaterial() = default;
+
+    bool Read(std::ifstream *stream) {
+        if (stream == nullptr) {
+            return false;
+        }
+        constexpr size_t BufferSize = 20;
+
+        char buffer[BufferSize] = {};
+        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) * BufferSize);
+        char *pstar = strchr(buffer, '*');
+        if (nullptr == 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
+
+};
+
+struct PmdBone {
+    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];
+
+    PmdBone() :
+            name(), name_english(), parent_bone_index(0), tail_pos_bone_index(0), bone_type(BoneType::Unknown), ik_parent_bone_index(0), bone_head_pos{ 0.0f } {}
+
+    ~PmdBone() = default;
+
+    void Read(std::istream *stream) {
+        if (stream == nullptr) {
+            return;
+        }
+        constexpr size_t BufferSize = 20;
+        char buffer[BufferSize] = {};
+        stream->read(buffer, BufferSize);
+        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) {
+        if (stream == nullptr) {
+            return;
+        }
+        constexpr size_t BufferSize = 20;
+        char buffer[BufferSize] = {};
+        stream->read(buffer, BufferSize);
+        name_english = std::string(buffer);
+    }
+};
+
+struct PmdIk {
+    uint16_t ik_bone_index;
+    uint16_t target_bone_index;
+    uint16_t iterations;
+    float angle_limit;
+    std::vector<uint16_t> ik_child_bone_index;
+
+    PmdIk() : ik_bone_index(0), target_bone_index(0), iterations(0), angle_limit(0.0f) {}
+
+    ~PmdIk() = default;
+
+    void Read(std::istream *stream) {
+        if (stream == nullptr) {
+            return;
+        }
+
+        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 *)&iterations, 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));
+        }
+    }
+};
+
+struct PmdFaceVertex {
+    int vertex_index;
+    float position[3];
+
+    PmdFaceVertex() :
+            vertex_index(0), position{ 0.0f } {}
+
+    ~PmdFaceVertex() = default;
+
+    void Read(std::istream *stream) {
+        if (stream == nullptr) {
+            return;
+        }
+        stream->read((char *)&vertex_index, sizeof(int));
+        stream->read((char *)position, sizeof(float) * 3);
+    }
+};
+
+enum class FaceCategory : uint8_t {
+    Base,
+    Eyebrow,
+    Eye,
+    Mouth,
+    Other
+};
+
+struct PmdFace {
+    std::string name;
+    FaceCategory type;
+    std::vector<PmdFaceVertex> vertices;
+    std::string name_english;
+
+    PmdFace() :
+            name(), type(FaceCategory::Other), vertices(), name_english() {}
+
+    ~PmdFace() = default;
+
+    void Read(std::istream *stream) {
+        if (stream == nullptr) {
+            return;
+        }
+        constexpr size_t BufferSize = 20;
+        char buffer[BufferSize];
+        stream->read(buffer, BufferSize);
+        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) {
+        if (stream == nullptr) {
+            return;
+        }
+
+        char buffer[20];
+        stream->read(buffer, 20);
+        name_english = std::string(buffer);
+    }
+};
+
+struct PmdBoneDispName {
+    std::string bone_disp_name;
+    std::string bone_disp_name_english;
+
+    PmdBoneDispName() = default;
+
+    ~PmdBoneDispName() = default;
+
+    void Read(std::istream *stream) {
+        if (stream == nullptr) {
+            return;
+        }
+        char buffer[50];
+        stream->read(buffer, 50);
+        bone_disp_name = std::string(buffer);
+        bone_disp_name_english.clear();
+    }
+
+    void ReadExpantion(std::istream *stream) {
+        if (stream == nullptr) {
+            return;
+        }
+        char buffer[50];
+        stream->read(buffer, 50);
+        bone_disp_name_english = std::string(buffer);
+    }
+};
+
+struct PmdBoneDisp {
+    uint16_t bone_index;
+    uint8_t bone_disp_index;
+
+    PmdBoneDisp() :
+            bone_index(0), bone_disp_index(0) {}
+
+    ~PmdBoneDisp() = default;
+
+    void Read(std::istream *stream) {
+        if (stream == nullptr) {
+            return;
+        }
+
+        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
+};
+
+struct PmdRigidBody {
+    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;
+
+    PmdRigidBody() :
+            name(), related_bone_index(0), group_index(0), mask(0), shape(RigidBodyShape::Box), size{ 0.0f }, position{ 0.0f }, weight(0.0f), linear_damping(0.0f), anglar_damping(0.0f), restitution(0.0f), friction(0.0f), rigid_type(RigidBodyType::BoneConnected) {}
+
+    ~PmdRigidBody() = default;
+
+    void Read(std::istream *stream) {
+        if (stream == nullptr) {
+            return;
+        }
+
+        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));
+    }
+};
+
+struct PmdConstraint {
+    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];
+
+    PmdConstraint() :
+            name(), rigid_body_index_a(0), rigid_body_index_b(0), position{ 0.0f }, orientation{ 0.0f }, linear_lower_limit{ 0.0f }, linear_upper_limit{ 0.0f }, angular_lower_limit{ 0.0f }, angular_upper_limit{ 0.0f }, linear_stiffness{ 0.0f }, angular_stiffness{ 0.0f } {}
+
+    ~PmdConstraint() = default;
+
+    void Read(std::istream *stream) {
+        if (stream == nullptr) {
+            return;
+        }
+
+        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);
+    }
+};
+
+struct PmdModel {
+    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;
+
+    PmdModel() :
+            version(0.0f) {}
+
+    ~PmdModel() = default;
+
+    static std::unique_ptr<PmdModel> LoadFromFile(const char *filename) {
+        if (filename == nullptr) {
+            return nullptr;
+        }
+
+        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;
+    }
+};
+
+} // namespace pmd
+

+ 3 - 1
Engine/lib/assimp/code/AssetLib/MMD/MMDPmxParser.h

@@ -88,7 +88,7 @@ namespace pmx
 	{
 	public:
 		virtual void Read(std::istream *stream, PmxSetting *setting) = 0;
-		virtual ~PmxVertexSkinning() {}
+		virtual ~PmxVertexSkinning() = default;
 	};
 
 	class PmxVertexSkinningBDEF1 : public PmxVertexSkinning
@@ -357,6 +357,8 @@ namespace pmx
 	{
 	public:
 		void virtual Read(std::istream *stream, PmxSetting *setting) = 0;
+
+        virtual ~PmxMorphOffset() = default;
 	};
 
 	class PmxMorphVertexOffset : public PmxMorphOffset

+ 2 - 3
Engine/lib/assimp/code/AssetLib/MS3D/MS3DLoader.cpp

@@ -86,8 +86,7 @@ MS3DImporter::MS3DImporter()
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-MS3DImporter::~MS3DImporter()
-{}
+MS3DImporter::~MS3DImporter() = default;
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
@@ -399,7 +398,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
         // if one of the groups has no material assigned, but there are other
         // groups with materials, a default material needs to be added (
         // scenepreprocessor adds a default material only if nummat==0).
-        materials.push_back(TempMaterial());
+        materials.emplace_back();
         TempMaterial& m = materials.back();
 
         strcpy(m.name,"<MS3D_DefaultMat>");

+ 8 - 8
Engine/lib/assimp/code/AssetLib/NDO/NDOLoader.cpp

@@ -70,13 +70,11 @@ static const aiImporterDesc desc = {
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-NDOImporter::NDOImporter()
-{}
+NDOImporter::NDOImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-NDOImporter::~NDOImporter()
-{}
+NDOImporter::~NDOImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -136,7 +134,9 @@ void NDOImporter::InternReadFile( const std::string& pFile,
         ASSIMP_LOG_INFO("NDO file format is 1.2");
     }
     else {
-        ASSIMP_LOG_WARN( "Unrecognized nendo file format version, continuing happily ... :", (head+6));
+        char buff[4] = {0};
+        memcpy(buff, head+6, 3);
+        ASSIMP_LOG_WARN( "Unrecognized nendo file format version, continuing happily ... :", buff);
     }
 
     reader.IncPtr(2); /* skip flags */
@@ -169,7 +169,7 @@ void NDOImporter::InternReadFile( const std::string& pFile,
         obj.edges.reserve(temp);
         for (unsigned int e = 0; e < temp; ++e) {
 
-            obj.edges.push_back(Edge());
+            obj.edges.emplace_back();
             Edge& edge = obj.edges.back();
 
             for (unsigned int i = 0; i< 8; ++i) {
@@ -186,7 +186,7 @@ void NDOImporter::InternReadFile( const std::string& pFile,
         obj.faces.reserve(temp);
         for (unsigned int e = 0; e < temp; ++e) {
 
-            obj.faces.push_back(Face());
+            obj.faces.emplace_back();
             Face& face = obj.faces.back();
 
             face.elem = file_format >= 12 ? reader.GetU4() : reader.GetU2();
@@ -197,7 +197,7 @@ void NDOImporter::InternReadFile( const std::string& pFile,
         obj.vertices.reserve(temp);
         for (unsigned int e = 0; e < temp; ++e) {
 
-            obj.vertices.push_back(Vertex());
+            obj.vertices.emplace_back();
             Vertex& v = obj.vertices.back();
 
             v.num = file_format >= 12 ? reader.GetU4() : reader.GetU2();

+ 14 - 14
Engine/lib/assimp/code/AssetLib/NFF/NFFLoader.cpp

@@ -73,11 +73,11 @@ static const aiImporterDesc desc = {
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-NFFImporter::NFFImporter() {}
+NFFImporter::NFFImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-NFFImporter::~NFFImporter() {}
+NFFImporter::~NFFImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
@@ -167,7 +167,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo> &output,
         // 'matdef' starts a new material in the file
         else if (TokenMatch(sz, "matdef", 6)) {
             // add a new material to the list
-            output.push_back(ShadingInfo());
+            output.emplace_back();
             curShader = &output.back();
 
             // parse the name of the material
@@ -549,7 +549,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
                         }
                     }
                     if (!mesh) {
-                        meshes.push_back(MeshInfo(PatchType_Simple, false));
+                        meshes.emplace_back(PatchType_Simple, false);
                         mesh = &meshes.back();
                         mesh->matIndex = matIdx;
 
@@ -614,7 +614,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
                     }
 
                     if (!currentMeshWithUVCoords) {
-                        meshesWithUVCoords.push_back(MeshInfo(PatchType_UVAndNormals));
+                        meshesWithUVCoords.emplace_back(PatchType_UVAndNormals);
                         currentMeshWithUVCoords = &meshesWithUVCoords.back();
                         currentMeshWithUVCoords->shader = s;
                     }
@@ -631,7 +631,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
                     }
 
                     if (!currentMeshWithNormals) {
-                        meshesWithNormals.push_back(MeshInfo(PatchType_Normals));
+                        meshesWithNormals.emplace_back(PatchType_Normals);
                         currentMeshWithNormals = &meshesWithNormals.back();
                         currentMeshWithNormals->shader = s;
                     }
@@ -649,7 +649,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
                     }
 
                     if (!currentMesh) {
-                        meshes.push_back(MeshInfo(PatchType_Simple));
+                        meshes.emplace_back(PatchType_Simple);
                         currentMesh = &meshes.back();
                         currentMesh->shader = s;
                     }
@@ -749,7 +749,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
             }
             // 'l' - light source
             else if (TokenMatch(sz, "l", 1)) {
-                lights.push_back(Light());
+                lights.emplace_back();
                 Light &light = lights.back();
 
                 AI_NFF_PARSE_TRIPLE(light.position);
@@ -758,7 +758,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
             }
             // 's' - sphere
             else if (TokenMatch(sz, "s", 1)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
@@ -774,7 +774,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
             }
             // 'dod' - dodecahedron
             else if (TokenMatch(sz, "dod", 3)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
@@ -791,7 +791,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
 
             // 'oct' - octahedron
             else if (TokenMatch(sz, "oct", 3)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
@@ -808,7 +808,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
 
             // 'tet' - tetrahedron
             else if (TokenMatch(sz, "tet", 3)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
@@ -825,7 +825,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
 
             // 'hex' - hexahedron
             else if (TokenMatch(sz, "hex", 3)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_BOX;
@@ -841,7 +841,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
             }
             // 'c' - cone
             else if (TokenMatch(sz, "c", 1)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_CYLINDER;

+ 2 - 4
Engine/lib/assimp/code/AssetLib/OFF/OFFLoader.cpp

@@ -73,13 +73,11 @@ static const aiImporterDesc desc = {
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-OFFImporter::OFFImporter()
-{}
+OFFImporter::OFFImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-OFFImporter::~OFFImporter()
-{}
+OFFImporter::~OFFImporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.

+ 4 - 6
Engine/lib/assimp/code/AssetLib/Obj/ObjExporter.cpp

@@ -137,9 +137,7 @@ ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMt
 }
 
 // ------------------------------------------------------------------------------------------------
-ObjExporter::~ObjExporter() {
-    // empty
-}
+ObjExporter::~ObjExporter() = default;
 
 // ------------------------------------------------------------------------------------------------
 std::string ObjExporter::GetMaterialLibName() {
@@ -271,12 +269,12 @@ void ObjExporter::WriteGeometryFile(bool noMtl) {
     if ( !useVc ) {
         mOutput << "# " << vp.size() << " vertex positions" << endl;
         for ( const vertexData& v : vp ) {
-            mOutput << "v  " << v.vp.x << " " << v.vp.y << " " << v.vp.z << endl;
+            mOutput << "v " << v.vp.x << " " << v.vp.y << " " << v.vp.z << endl;
         }
     } else {
         mOutput << "# " << vp.size() << " vertex positions and colors" << endl;
         for ( const vertexData& v : vp ) {
-            mOutput << "v  " << v.vp.x << " " << v.vp.y << " " << v.vp.z << " " << v.vc.r << " " << v.vc.g << " " << v.vc.b << endl;
+            mOutput << "v " << v.vp.x << " " << v.vp.y << " " << v.vp.z << " " << v.vc.r << " " << v.vc.g << " " << v.vc.b << endl;
         }
     }
     mOutput << endl;
@@ -333,7 +331,7 @@ void ObjExporter::WriteGeometryFile(bool noMtl) {
 
 // ------------------------------------------------------------------------------------------------
 void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) {
-    mMeshes.push_back(MeshInstance() );
+    mMeshes.emplace_back();
     MeshInstance& mesh = mMeshes.back();
 
     if ( nullptr != m->mColors[ 0 ] ) {

Some files were not shown because too many files changed in this diff