Переглянути джерело

Update Assimp from 5.2.3 to 5.2.5

Bloodknight 2 роки тому
батько
коміт
16f3710058
100 змінених файлів з 1407 додано та 1415 видалено
  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"/>
        src="https://scan.coverity.com/projects/5607/badge.svg"/>
 </a>
 </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)
 [![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)
 [![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)
 [![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")
 [![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/)
 [![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>
 <br>
 
 
@@ -58,6 +60,7 @@ Open Asset Import Library is implemented in C++. The directory structure looks l
 	/code		Source code
 	/code		Source code
 	/contrib	Third-party libraries
 	/contrib	Third-party libraries
 	/doc		Documentation (doxysource and pre-compiled docs)
 	/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
 	/include	Public header C and C++ header files
 	/scripts 	Scripts used to generate the loading code for some formats
 	/scripts 	Scripts used to generate the loading code for some formats
 	/port		Ports to other languages and scripts to maintain those.
 	/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;
         unsigned int iWire = 1;
         mat.AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
         mat.AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
     }
     }
+    [[fallthrough]];
 
 
     case D3DS::Discreet3DS::Gouraud:
     case D3DS::Discreet3DS::Gouraud:
         eShading = aiShadingMode_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) {
 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
 // Destructor, private as well
-Discreet3DSImporter::~Discreet3DSImporter() {
-    // empty
-}
+Discreet3DSImporter::~Discreet3DSImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
@@ -319,7 +317,7 @@ void Discreet3DSImporter::ParseObjectChunk() {
     case Discreet3DS::CHUNK_MAT_MATERIAL:
     case Discreet3DS::CHUNK_MAT_MATERIAL:
 
 
         // Add a new material to the list
         // 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();
         ParseMaterialChunk();
         break;
         break;
 
 
@@ -370,7 +368,7 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
     switch (chunk.Flag) {
     switch (chunk.Flag) {
     case Discreet3DS::CHUNK_TRIMESH: {
     case Discreet3DS::CHUNK_TRIMESH: {
         // this starts a new triangle mesh
         // 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
         // Read mesh chunks
         ParseMeshChunk();
         ParseMeshChunk();
@@ -999,7 +997,7 @@ void Discreet3DSImporter::ParseMeshChunk() {
         mMesh.mFaces.reserve(num);
         mMesh.mFaces.reserve(num);
         while (num-- > 0) {
         while (num-- > 0) {
             // 3DS faces are ALWAYS triangles
             // 3DS faces are ALWAYS triangles
-            mMesh.mFaces.push_back(D3DS::Face());
+            mMesh.mFaces.emplace_back();
             D3DS::Face &sFace = mMesh.mFaces.back();
             D3DS::Face &sFace = mMesh.mFaces.back();
 
 
             sFace.mIndices[0] = (uint16_t)stream->GetI2();
             sFace.mIndices[0] = (uint16_t)stream->GetI2();
@@ -1284,7 +1282,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
     switch (chunk.Flag) {
     switch (chunk.Flag) {
     case Discreet3DS::CHUNK_LINRGBF:
     case Discreet3DS::CHUNK_LINRGBF:
         bGamma = true;
         bGamma = true;
-
+    // fallthrough
     case Discreet3DS::CHUNK_RGBF:
     case Discreet3DS::CHUNK_RGBF:
         if (sizeof(float) * 3 > diff) {
         if (sizeof(float) * 3 > diff) {
             *out = clrError;
             *out = clrError;
@@ -1297,6 +1295,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
 
 
     case Discreet3DS::CHUNK_LINRGBB:
     case Discreet3DS::CHUNK_LINRGBB:
         bGamma = true;
         bGamma = true;
+            // fallthrough
     case Discreet3DS::CHUNK_RGBB: {
     case Discreet3DS::CHUNK_RGBB: {
         if (sizeof(char) * 3 > diff) {
         if (sizeof(char) * 3 > diff) {
             *out = clrError;
             *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 pid = "pid";
     const char* const pindex = "pindex";
     const char* const pindex = "pindex";
     const char* const p1 = "p1";
     const char* const p1 = "p1";
+    const char *const p2 = "p2";
+    const char *const p3 = "p3";
     const char* const name = "name";
     const char* const name = "name";
     const char* const type = "type";
     const char* const type = "type";
     const char* const build = "build";
     const char* const build = "build";

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

@@ -81,14 +81,9 @@ static const aiImporterDesc desc = {
     "3mf"
     "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 {
 bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
     if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
     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() {
 D3MFOpcPackage::~D3MFOpcPackage() {
     mZipArchive->Close(mRootStream);
     mZipArchive->Close(mRootStream);
     delete mZipArchive;
     delete mZipArchive;
+    for (auto tex : mEmbeddedTextures) {
+        delete tex;
+    }
 }
 }
 
 
 IOStream *D3MFOpcPackage::RootStream() const {
 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;
     return true;
 }
 }
 
 
-aiFace ReadTriangle(XmlNode &node) {
+aiFace ReadTriangle(XmlNode &node, int &texId0, int &texId1, int &texId2) {
     aiFace face;
     aiFace face;
 
 
     face.mNumIndices = 3;
     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[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()));
     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;
     return face;
 }
 }
 
 
@@ -106,7 +111,7 @@ bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &va
     return false;
     return false;
 }
 }
 
 
-aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
+aiMatrix4x4 parseTransformMatrix(const std::string& matrixStr) {
     // split the string
     // split the string
     std::vector<float> numbers;
     std::vector<float> numbers;
     std::string currentNumber;
     std::string currentNumber;
@@ -412,6 +417,9 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
             bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
             bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
             bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
             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) {
             if (hasPid && hasP1) {
                 auto it = mResourcesDictionnary.find(pid);
                 auto it = mResourcesDictionnary.find(pid);
                 if (it != mResourcesDictionnary.end()) {
                 if (it != mResourcesDictionnary.end()) {
@@ -420,23 +428,34 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
                         mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
                         mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
                     } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
                     } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
                         if (mesh->mTextureCoords[0] == nullptr) {
                         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);
                             const std::string name = ai_to_string(group->mTexId);
                             for (size_t i = 0; i < mMaterials.size(); ++i) {
                             for (size_t i = 0; i < mMaterials.size(); ++i) {
                                 if (name == mMaterials[i]->GetName().C_Str()) {
                                 if (name == mMaterials[i]->GetName().C_Str()) {
                                     mesh->mMaterialIndex = static_cast<unsigned int>(i);
                                     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);
             faces.push_back(face);
         }
         }
     }
     }
@@ -578,11 +597,15 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater
 }
 }
 
 
 void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
 void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
-    if (nullptr == scene || mMaterials.empty()) {
+    if (nullptr == scene) {
         return;
         return;
     }
     }
 
 
     scene->mNumMaterials = static_cast<unsigned int>(mMaterials.size());
     scene->mNumMaterials = static_cast<unsigned int>(mMaterials.size());
+    if (scene->mNumMaterials == 0) {
+        return;
+    }
+
     scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
     scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
     for (size_t i = 0; i < mMaterials.size(); ++i) {
     for (size_t i = 0; i < mMaterials.size(); ++i) {
         scene->mMaterials[i] = mMaterials[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
 // 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.
 // Returns whether the class can handle the format of the given file.
@@ -180,7 +178,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
 
 
     ++mNumMeshes;
     ++mNumMeshes;
 
 
-    objects.push_back(Object());
+    objects.emplace_back();
     Object &obj = objects.back();
     Object &obj = objects.back();
 
 
     aiLight *light = nullptr;
     aiLight *light = nullptr;
@@ -267,7 +265,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
                     --buffer; // make sure the line is processed a second time
                     --buffer; // make sure the line is processed a second time
                     break;
                     break;
                 }
                 }
-                obj.vertices.push_back(aiVector3D());
+                obj.vertices.emplace_back();
                 aiVector3D &v = obj.vertices.back();
                 aiVector3D &v = obj.vertices.back();
                 buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x);
                 buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x);
             }
             }
@@ -293,7 +291,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
                     Q3DWorkAround = true;
                     Q3DWorkAround = true;
                 }
                 }
                 SkipSpaces(&buffer);
                 SkipSpaces(&buffer);
-                obj.surfaces.push_back(Surface());
+                obj.surfaces.emplace_back();
                 Surface &surf = obj.surfaces.back();
                 Surface &surf = obj.surfaces.back();
                 surf.flags = strtoul_cppstyle(buffer);
                 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");
                                 ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: surface references are incomplete");
                                 break;
                                 break;
                             }
                             }
-                            surf.entries.push_back(Surface::SurfaceEntry());
+                            surf.entries.emplace_back();
                             Surface::SurfaceEntry &entry = surf.entries.back();
                             Surface::SurfaceEntry &entry = surf.entries.back();
 
 
                             entry.first = strtoul10(buffer, &buffer);
                             entry.first = strtoul10(buffer, &buffer);
@@ -786,7 +784,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
 
 
     while (GetNextLine()) {
     while (GetNextLine()) {
         if (TokenMatch(buffer, "MATERIAL", 8)) {
         if (TokenMatch(buffer, "MATERIAL", 8)) {
-            materials.push_back(Material());
+            materials.emplace_back();
             Material &mat = materials.back();
             Material &mat = materials.back();
 
 
             // manually parse the material ... sscanf would use the buldin atof ...
             // manually parse the material ... sscanf would use the buldin atof ...
@@ -813,7 +811,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
     }
     }
     if (materials.empty()) {
     if (materials.empty()) {
         ASSIMP_LOG_WARN("AC3D: No material has been found");
         ASSIMP_LOG_WARN("AC3D: No material has been found");
-        materials.push_back(Material());
+        materials.emplace_back();
     }
     }
 
 
     mNumMeshes += (mNumMeshes >> 2u) + 1;
     mNumMeshes += (mNumMeshes >> 2u) + 1;

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

@@ -89,9 +89,7 @@ ASEImporter::ASEImporter() :
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-ASEImporter::~ASEImporter() {
-    // empty
-}
+ASEImporter::~ASEImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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()) {
     if (bHas || mParser->m_vMaterials.empty()) {
         // add a simple material without submaterials to the parser's list
         // 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();
         ASE::Material &mat = mParser->m_vMaterials.back();
 
 
         mat.mDiffuse = aiColor3D(0.6f, 0.6f, 0.6f);
         mat.mDiffuse = aiColor3D(0.6f, 0.6f, 0.6f);
@@ -870,6 +868,7 @@ void ASEImporter::ConvertMaterial(ASE::Material &mat) {
         unsigned int iWire = 1;
         unsigned int iWire = 1;
         mat.pcInstance->AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
         mat.pcInstance->AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
     }
     }
+    // fallthrough
     case D3DS::Discreet3DS::Gouraud:
     case D3DS::Discreet3DS::Gouraud:
         eShading = aiShadingMode_Gouraud;
         eShading = aiShadingMode_Gouraud;
         break;
         break;
@@ -1004,8 +1003,8 @@ void ASEImporter::ConvertMeshes(ASE::Mesh &mesh, std::vector<aiMesh *> &avOutMes
                                             blubb != mesh.mBoneVertices[iIndex2].mBoneWeights.end(); ++blubb) {
                                             blubb != mesh.mBoneVertices[iIndex2].mBoneWeights.end(); ++blubb) {
 
 
                                         // NOTE: illegal cases have already been filtered out
                                         // 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;                                \
             return;                                \
         }                                          \
         }                                          \
     }                                              \
     }                                              \
-    else if ('\0' == *filePtr) {                   \
+    if ('\0' == *filePtr) {                        \
         return;                                    \
         return;                                    \
     }                                              \
     }                                              \
     if (IsLineEnd(*filePtr) && !bLastWasEndLine) { \
     if (IsLineEnd(*filePtr) && !bLastWasEndLine) { \
@@ -264,7 +264,7 @@ void Parser::Parse() {
             if (TokenMatch(filePtr, "GEOMOBJECT", 10))
             if (TokenMatch(filePtr, "GEOMOBJECT", 10))
 
 
             {
             {
-                m_vMeshes.push_back(Mesh("UNNAMED"));
+                m_vMeshes.emplace_back("UNNAMED");
                 ParseLV1ObjectBlock(m_vMeshes.back());
                 ParseLV1ObjectBlock(m_vMeshes.back());
                 continue;
                 continue;
             }
             }
@@ -272,7 +272,7 @@ void Parser::Parse() {
             if (TokenMatch(filePtr, "HELPEROBJECT", 12))
             if (TokenMatch(filePtr, "HELPEROBJECT", 12))
 
 
             {
             {
-                m_vDummies.push_back(Dummy());
+                m_vDummies.emplace_back();
                 ParseLV1ObjectBlock(m_vDummies.back());
                 ParseLV1ObjectBlock(m_vDummies.back());
                 continue;
                 continue;
             }
             }
@@ -280,13 +280,13 @@ void Parser::Parse() {
             if (TokenMatch(filePtr, "LIGHTOBJECT", 11))
             if (TokenMatch(filePtr, "LIGHTOBJECT", 11))
 
 
             {
             {
-                m_vLights.push_back(Light("UNNAMED"));
+                m_vLights.emplace_back("UNNAMED");
                 ParseLV1ObjectBlock(m_vLights.back());
                 ParseLV1ObjectBlock(m_vLights.back());
                 continue;
                 continue;
             }
             }
             // camera object
             // camera object
             if (TokenMatch(filePtr, "CAMERAOBJECT", 12)) {
             if (TokenMatch(filePtr, "CAMERAOBJECT", 12)) {
-                m_vCameras.push_back(Camera("UNNAMED"));
+                m_vCameras.emplace_back("UNNAMED");
                 ParseLV1ObjectBlock(m_vCameras.back());
                 ParseLV1ObjectBlock(m_vCameras.back());
                 continue;
                 continue;
             }
             }
@@ -385,7 +385,7 @@ void Parser::ParseLV1SoftSkinBlock() {
                         unsigned int numWeights;
                         unsigned int numWeights;
                         ParseLV4MeshLong(numWeights);
                         ParseLV4MeshLong(numWeights);
 
 
-                        curMesh->mBoneVertices.push_back(ASE::BoneVertex());
+                        curMesh->mBoneVertices.emplace_back();
                         ASE::BoneVertex &vert = curMesh->mBoneVertices.back();
                         ASE::BoneVertex &vert = curMesh->mBoneVertices.back();
 
 
                         // Reserve enough storage
                         // Reserve enough storage
@@ -409,7 +409,7 @@ void Parser::ParseLV1SoftSkinBlock() {
                             if (-1 == me.first) {
                             if (-1 == me.first) {
                                 // We don't have this bone yet, so add it to the list
                                 // We don't have this bone yet, so add it to the list
                                 me.first = static_cast<int>(curMesh->mBones.size());
                                 me.first = static_cast<int>(curMesh->mBones.size());
-                                curMesh->mBones.push_back(ASE::Bone(bone));
+                                curMesh->mBones.emplace_back(bone);
                             }
                             }
                             ParseLV4MeshFloat(me.second);
                             ParseLV4MeshFloat(me.second);
 
 
@@ -420,6 +420,8 @@ void Parser::ParseLV1SoftSkinBlock() {
                 }
                 }
             }
             }
         }
         }
+        if (*filePtr == '\0')
+            return;
         ++filePtr;
         ++filePtr;
         SkipSpacesAndLineEnd(&filePtr);
         SkipSpacesAndLineEnd(&filePtr);
     }
     }
@@ -646,10 +648,13 @@ void Parser::ParseLV2MaterialBlock(ASE::Material &mat) {
                 }
                 }
 
 
                 // get a reference to the material
                 // 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;
                 continue;
             }
             }
         }
         }
@@ -1006,7 +1011,7 @@ void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation &anim) {
                 anim.mScalingType = ASE::Animation::TCB;
                 anim.mScalingType = ASE::Animation::TCB;
             }
             }
             if (b) {
             if (b) {
-                anim.akeyScaling.push_back(aiVectorKey());
+                anim.akeyScaling.emplace_back();
                 aiVectorKey &key = anim.akeyScaling.back();
                 aiVectorKey &key = anim.akeyScaling.back();
                 ParseLV4MeshFloatTriple(&key.mValue.x, iIndex);
                 ParseLV4MeshFloatTriple(&key.mValue.x, iIndex);
                 key.mTime = (double)iIndex;
                 key.mTime = (double)iIndex;
@@ -1045,7 +1050,7 @@ void Parser::ParseLV3PosAnimationBlock(ASE::Animation &anim) {
                 anim.mPositionType = ASE::Animation::TCB;
                 anim.mPositionType = ASE::Animation::TCB;
             }
             }
             if (b) {
             if (b) {
-                anim.akeyPositions.push_back(aiVectorKey());
+                anim.akeyPositions.emplace_back();
                 aiVectorKey &key = anim.akeyPositions.back();
                 aiVectorKey &key = anim.akeyPositions.back();
                 ParseLV4MeshFloatTriple(&key.mValue.x, iIndex);
                 ParseLV4MeshFloatTriple(&key.mValue.x, iIndex);
                 key.mTime = (double)iIndex;
                 key.mTime = (double)iIndex;
@@ -1084,7 +1089,7 @@ void Parser::ParseLV3RotAnimationBlock(ASE::Animation &anim) {
                 anim.mRotationType = ASE::Animation::TCB;
                 anim.mRotationType = ASE::Animation::TCB;
             }
             }
             if (b) {
             if (b) {
-                anim.akeyRotations.push_back(aiQuatKey());
+                anim.akeyRotations.emplace_back();
                 aiQuatKey &key = anim.akeyRotations.back();
                 aiQuatKey &key = anim.akeyRotations.back();
                 aiVector3D v;
                 aiVector3D v;
                 ai_real f;
                 ai_real f;

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

@@ -116,7 +116,7 @@ struct Material : public D3DS::Material {
         return *this;
         return *this;
     }
     }
 
 
-    ~Material() {}
+    ~Material() = default;
 
 
     //! Contains all sub materials of this material
     //! Contains all sub materials of this material
     std::vector<Material> avSubMaterials;
     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
 // Serialize a vec3
 template <>
 template <>
 inline size_t Write<aiVector3D>(IOStream *stream, const aiVector3D &v) {
 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.y);
     t += Write<float>(stream, v.z);
     t += Write<float>(stream, v.z);
 
 
@@ -141,7 +141,7 @@ inline size_t Write<aiVector3D>(IOStream *stream, const aiVector3D &v) {
 // Serialize a color value
 // Serialize a color value
 template <>
 template <>
 inline size_t Write<aiColor3D>(IOStream *stream, const aiColor3D &v) {
 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.g);
     t += Write<float>(stream, v.b);
     t += Write<float>(stream, v.b);
 
 
@@ -152,7 +152,7 @@ inline size_t Write<aiColor3D>(IOStream *stream, const aiColor3D &v) {
 // Serialize a color value
 // Serialize a color value
 template <>
 template <>
 inline size_t Write<aiColor4D>(IOStream *stream, const aiColor4D &v) {
 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.g);
     t += Write<float>(stream, v.b);
     t += Write<float>(stream, v.b);
     t += Write<float>(stream, v.a);
     t += Write<float>(stream, v.a);
@@ -164,7 +164,7 @@ inline size_t Write<aiColor4D>(IOStream *stream, const aiColor4D &v) {
 // Serialize a quaternion
 // Serialize a quaternion
 template <>
 template <>
 inline size_t Write<aiQuaternion>(IOStream *stream, const aiQuaternion &v) {
 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.x);
     t += Write<float>(stream, v.y);
     t += Write<float>(stream, v.y);
     t += Write<float>(stream, v.z);
     t += Write<float>(stream, v.z);
@@ -190,7 +190,7 @@ template <>
 inline size_t Write<aiMatrix4x4>(IOStream *stream, const aiMatrix4x4 &m) {
 inline size_t Write<aiMatrix4x4>(IOStream *stream, const aiMatrix4x4 &m) {
     for (unsigned int i = 0; i < 4; ++i) {
     for (unsigned int i = 0; i < 4; ++i) {
         for (unsigned int i2 = 0; i2 < 4; ++i2) {
         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<aiString>(&chunk, l->mName);
         Write<unsigned int>(&chunk, l->mType);
         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) {
         if (l->mType != aiLightSource_DIRECTIONAL) {
             Write<float>(&chunk, l->mAttenuationConstant);
             Write<float>(&chunk, l->mAttenuationConstant);
             Write<float>(&chunk, l->mAttenuationLinear);
             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->mName = Read<aiString>(stream);
     l->mType = (aiLightSourceType)Read<unsigned int>(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) {
     if (l->mType != aiLightSource_DIRECTIONAL) {
         l->mAttenuationConstant = Read<float>(stream);
         l->mAttenuationConstant = Read<float>(stream);
         l->mAttenuationLinear = 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
 		// 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) {
 		if (base == in_mesh->mNumFaces) {
 			break;
 			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\"",
                 ioprintf(io, "\t\t\t<MatProperty key=\"%s\" \n\t\t\ttype=\"%s\" tex_usage=\"%s\" tex_index=\"%u\"",
                         prop->mKey.data, sz,
                         prop->mKey.data, sz,
-                        ::TextureTypeToString((aiTextureType)prop->mSemantic), prop->mIndex);
+                        ::aiTextureTypeToString((aiTextureType)prop->mSemantic), prop->mIndex);
 
 
                 if (prop->mType == aiPTI_Float) {
                 if (prop->mType == aiPTI_Float) {
                     ioprintf(io, " size=\"%i\">\n\t\t\t\t",
                     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 {
 bool B3DImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
@@ -479,13 +477,13 @@ void B3DImporter::ReadKEYS(aiNodeAnim *nodeAnim) {
     while (ChunkSize()) {
     while (ChunkSize()) {
         int frame = ReadInt();
         int frame = ReadInt();
         if (flags & 1) {
         if (flags & 1) {
-            trans.push_back(aiVectorKey(frame, ReadVec3()));
+            trans.emplace_back(frame, ReadVec3());
         }
         }
         if (flags & 2) {
         if (flags & 2) {
-            scale.push_back(aiVectorKey(frame, ReadVec3()));
+            scale.emplace_back(frame, ReadVec3());
         }
         }
         if (flags & 4) {
         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];
                         int bone = v.bones[k];
                         float weight = v.weights[k];
                         float weight = v.weights[k];
 
 
-                        vweights[bone].push_back(aiVertexWeight(vertIdx + faceIndex, weight));
+                        vweights[bone].emplace_back(vertIdx + faceIndex, weight);
                     }
                     }
                 }
                 }
                 ++face;
                 ++face;

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

@@ -88,7 +88,7 @@ BVHLoader::BVHLoader() :
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-BVHLoader::~BVHLoader() {}
+BVHLoader::~BVHLoader() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
@@ -186,7 +186,7 @@ aiNode *BVHLoader::ReadNode() {
     std::vector<aiNode *> childNodes;
     std::vector<aiNode *> childNodes;
 
 
     // and create an bone entry for it
     // and create an bone entry for it
-    mNodes.push_back(Node(node));
+    mNodes.emplace_back(node);
     Node &internNode = mNodes.back();
     Node &internNode = mNodes.back();
 
 
     // now read the node's contents
     // 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);
     stream.SetCurrentPos(current.start + current.size);
 
 
     const char tmp[] = {
     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);
     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> {
 struct Structure::_defaultInitializer<ErrorPolicy_Fail> {
 
 
     template <typename T>
     template <typename T>
-    void operator()(T & /*out*/, const char * = "") {
+    void operator()(T & /*out*/, const char *message = "") {
         // obviously, it is crucial that _DefaultInitializer is used
         // obviously, it is crucial that _DefaultInitializer is used
         // only from within a catch clause.
         // 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    {
     struct TempArray    {
         typedef TCLASS< T*,std::allocator<T*> > mywrap;
         typedef TCLASS< T*,std::allocator<T*> > mywrap;
 
 
-        TempArray() {
-        }
+        TempArray() = default;
 
 
         ~TempArray () {
         ~TempArray () {
             for(T* elem : arr) {
             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;
     std::deque<Object *> root_objects;
     // Count number of 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
     // key is material number, value is the TextureUVMapping for the material
     typedef std::map<uint32_t, TextureUVMapping> MaterialTextureUVMappings;
     typedef std::map<uint32_t, TextureUVMapping> MaterialTextureUVMappings;
     MaterialTextureUVMappings matTexUvMappings;
     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) {
     for (uint32_t m = 0; m < maxMat; ++m) {
         // get material by index
         // get material by index
         const std::shared_ptr<Material> pMat = mesh->mat[m];
         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 InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
     void ParseBlendFile(Blender::FileDatabase &out, std::shared_ptr<IOStream> stream);
     void ParseBlendFile(Blender::FileDatabase &out, std::shared_ptr<IOStream> stream);
     void ExtractScene(Blender::Scene &out, const Blender::FileDatabase &file);
     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);
     void ConvertBlendFile(aiScene *out, const Blender::Scene &in, const Blender::FileDatabase &file);
 
 
 private:
 private:

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

@@ -71,10 +71,6 @@ static const fpCreateModifier creators[] = {
     nullptr // sentinel
     nullptr // sentinel
 };
 };
 
 
-// ------------------------------------------------------------------------------------------------
-struct SharedModifierData : ElemBase {
-    ModifierData modifier;
-};
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void BlenderModifierShowcase::ApplyModifiers(aiNode &out, ConversionData &conv_data, const Scene &in, const Object &orig_object) {
 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()
     // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
     const MirrorModifierData &mir = static_cast<const MirrorModifierData &>(orig_modifier);
     const MirrorModifierData &mir = static_cast<const MirrorModifierData &>(orig_modifier);
     ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
     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);
     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 ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
         const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -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) {
             for (unsigned int j = 0; j < mesh->mNumVertices; ++j) {
                 aiVector3D &v = mesh->mVertices[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 {
         const FileDatabase &db) const {
 
 
     ReadFieldPtr<ErrorPolicy_Igno>(dest.first, "*first", db);
     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);
     db.reader->IncPtr(size);
 }
 }
@@ -648,7 +650,9 @@ void Structure ::Convert<ModifierData>(
         const FileDatabase &db) const {
         const FileDatabase &db) const {
 
 
     ReadFieldPtr<ErrorPolicy_Warn>(dest.next, "*next", db);
     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.type, "type", db);
     ReadField<ErrorPolicy_Igno>(dest.mode, "mode", db);
     ReadField<ErrorPolicy_Igno>(dest.mode, "mode", db);
     ReadFieldArray<ErrorPolicy_Igno>(dest.name, "name", 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.axis, "axis", db);
     ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
     ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
     ReadField<ErrorPolicy_Igno>(dest.tolerance, "tolerance", 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);
     db.reader->IncPtr(size);
 }
 }
@@ -833,9 +839,9 @@ void Structure::Convert<CustomDataLayer>(
     ReadField<ErrorPolicy_Fail>(dest.flag, "flag", db);
     ReadField<ErrorPolicy_Fail>(dest.flag, "flag", db);
     ReadField<ErrorPolicy_Fail>(dest.active, "active", db);
     ReadField<ErrorPolicy_Fail>(dest.active, "active", db);
     ReadField<ErrorPolicy_Fail>(dest.active_rnd, "active_rnd", 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);
     ReadFieldArray<ErrorPolicy_Warn>(dest.name, "name", db);
     ReadCustomDataPtr<ErrorPolicy_Fail>(dest.data, dest.type, "*data", 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 {
 struct ListBase : ElemBase {
     std::shared_ptr<ElemBase> first;
     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> next WARN;
-    std::shared_ptr<ElemBase> prev WARN;
+    std::weak_ptr<ElemBase> prev WARN;
 
 
     int type, mode;
     int type, mode;
     char name[32];
     char name[32];
 };
 };
 
 
+
+// ------------------------------------------------------------------------------------------------
+struct SharedModifierData : ElemBase {
+    ModifierData modifier;
+};
+
+
 // -------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------
-struct SubsurfModifierData : ElemBase {
+struct SubsurfModifierData : SharedModifierData {
 
 
     enum Type {
     enum Type {
 
 
@@ -662,7 +669,6 @@ struct SubsurfModifierData : ElemBase {
         FLAGS_SubsurfUV = 1 << 3
         FLAGS_SubsurfUV = 1 << 3
     };
     };
 
 
-    ModifierData modifier FAIL;
     short subdivType WARN;
     short subdivType WARN;
     short levels FAIL;
     short levels FAIL;
     short renderLevels;
     short renderLevels;
@@ -670,7 +676,7 @@ struct SubsurfModifierData : ElemBase {
 };
 };
 
 
 // -------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------
-struct MirrorModifierData : ElemBase {
+struct MirrorModifierData : SharedModifierData {
 
 
     enum Flags {
     enum Flags {
         Flags_CLIPPING = 1 << 0,
         Flags_CLIPPING = 1 << 0,
@@ -682,11 +688,9 @@ struct MirrorModifierData : ElemBase {
         Flags_VGROUP = 1 << 6
         Flags_VGROUP = 1 << 6
     };
     };
 
 
-    ModifierData modifier FAIL;
-
     short axis, flag;
     short axis, flag;
     float tolerance;
     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 )
 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:
     public:
         BlenderTessellatorP2T( BlenderBMeshConverter& converter );
         BlenderTessellatorP2T( BlenderBMeshConverter& converter );
-        ~BlenderTessellatorP2T( );
+        ~BlenderTessellatorP2T( ) = default;
 
 
         void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
         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
 // Constructor to be privately used by Importer
-COBImporter::COBImporter() {
-    // empty
-}
+COBImporter::COBImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-COBImporter::~COBImporter() {
-    // empty
-}
+COBImporter::~COBImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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;
         return;
     }
     }
 
 
-    out.materials.push_back(Material());
+    out.materials.emplace_back();
     Material &mat = out.materials.back();
     Material &mat = out.materials.back();
     mat = nfo;
     mat = nfo;
 
 
@@ -753,7 +749,7 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
                     ThrowException("Expected Face line");
                     ThrowException("Expected Face line");
                 }
                 }
 
 
-                msh.faces.push_back(Face());
+                msh.faces.emplace_back();
                 Face &face = msh.faces.back();
                 Face &face = msh.faces.back();
 
 
                 face.indices.resize(strtoul10(splitter[2]));
                 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);
                 ThrowException(format("A hole is the first entity in the `PolH` chunk with id ") << nfo.id);
             }
             }
         } else
         } else
-            msh.faces.push_back(Face());
+            msh.faces.emplace_back();
         Face &f = msh.faces.back();
         Face &f = msh.faces.back();
 
 
         const size_t num = reader.GetI2();
         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) {
         for (size_t x = 0; x < num; ++x) {
-            f.indices.push_back(VertexIndex());
+            f.indices.emplace_back();
 
 
             VertexIndex &v = f.indices.back();
             VertexIndex &v = f.indices.back();
             v.pos_idx = reader.GetI4();
             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);
     const chunk_guard cn(nfo, reader);
 
 
-    out.materials.push_back(Material());
+    out.materials.emplace_back();
     Material &mat = out.materials.back();
     Material &mat = out.materials.back();
     mat = nfo;
     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
         TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
     };
     };
 
 
-    virtual ~Node() {}
+    virtual ~Node() = default;
     Node(Type type) : type(type), unit_scale(1.f){}
     Node(Type type) : type(type), unit_scale(1.f){}
 
 
     Type type;
     Type type;

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

@@ -85,8 +85,7 @@ CSMImporter::CSMImporter()
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-CSMImporter::~CSMImporter()
-{}
+CSMImporter::~CSMImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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
 // Destructor
-ColladaExporter::~ColladaExporter() {
-}
+ColladaExporter::~ColladaExporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Starts writing the contents
 // Starts writing the contents
@@ -1330,9 +1329,9 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex) {
             std::vector<std::string> names;
             std::vector<std::string> names;
             for (size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
             for (size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
                 if (nodeAnim->mPreState == aiAnimBehaviour_DEFAULT || nodeAnim->mPreState == aiAnimBehaviour_LINEAR || nodeAnim->mPreState == aiAnimBehaviour_REPEAT) {
                 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) {
                 } 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;
         Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
         Property shininess, transparency, index_refraction;
         Property shininess, transparency, index_refraction;
 
 
-        Material() {}
+        Material() = default;
     };
     };
 
 
     std::map<unsigned int, std::string> textures;
     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();) {
         for (std::vector<Animation *>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) {
             Animation *anim = *it;
             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);
             CombineSingleChannelAnimationsRecursively(anim);
 
 
             if (childrenAnimationsHaveDifferentChannels && anim->mChannels.size() == 1 &&
             if (childrenAnimationsHaveDifferentChannels && anim->mChannels.size() == 1 &&

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

@@ -102,6 +102,7 @@ ColladaLoader::ColladaLoader() :
         mTextures(),
         mTextures(),
         mAnims(),
         mAnims(),
         noSkeletonMesh(false),
         noSkeletonMesh(false),
+        removeEmptyBones(false),
         ignoreUpDirection(false),
         ignoreUpDirection(false),
         useColladaName(false),
         useColladaName(false),
         mNodeNameCounter(0) {
         mNodeNameCounter(0) {
@@ -110,9 +111,7 @@ ColladaLoader::ColladaLoader() :
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-ColladaLoader::~ColladaLoader() {
-    // empty
-}
+ColladaLoader::~ColladaLoader() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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) {
 void ColladaLoader::SetupProperties(const Importer *pImp) {
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
     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;
     ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
     useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 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
         // count the number of bones which influence vertices of the current submesh
         size_t numRemainingBones = 0;
         size_t numRemainingBones = 0;
         for (const auto & dstBone : dstBones) {
         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
         // 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;
         size_t boneCount = 0;
         for (size_t a = 0; a < numBones; ++a) {
         for (size_t a = 0; a < numBones; ++a) {
             // omit bones without weights
             // omit bones without weights
-            if (dstBones[a].empty()) {
+            if (dstBones[a].empty() && removeEmptyBones) {
                 continue;
                 continue;
             }
             }
 
 

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

@@ -237,6 +237,7 @@ protected:
     std::vector<aiAnimation *> mAnims;
     std::vector<aiAnimation *> mAnims;
 
 
     bool noSkeletonMesh;
     bool noSkeletonMesh;
+    bool removeEmptyBones;
     bool ignoreUpDirection;
     bool ignoreUpDirection;
     bool useColladaName;
     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);
                     XmlParser::getValueAsString(currentNode, v);
                     const char *content = v.c_str();
                     const char *content = v.c_str();
                     vcount.reserve(numPrimitives);
                     vcount.reserve(numPrimitives);
+                    SkipSpacesAndLineEnd(&content);
                     for (unsigned int a = 0; a < numPrimitives; a++) {
                     for (unsigned int a = 0; a < numPrimitives; a++) {
                         if (*content == 0) {
                         if (*content == 0) {
                             throw DeadlyImportError("Expected more values while reading <vcount> contents.");
                             throw DeadlyImportError("Expected more values while reading <vcount> contents.");
@@ -1928,7 +1929,7 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
     switch (pInput.mType) {
     switch (pInput.mType) {
     case IT_Position: // ignore all position streams except 0 - there can be only one position
     case IT_Position: // ignore all position streams except 0 - there can be only one position
         if (pInput.mIndex == 0) {
         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 {
         } else {
             ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
             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
         // ignore all normal streams except 0 - there can be only one normal
         if (pInput.mIndex == 0) {
         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 {
         } else {
             ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
             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
         // ignore all tangent streams except 0 - there can be only one tangent
         if (pInput.mIndex == 0) {
         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 {
         } else {
             ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
             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
         // ignore all bitangent streams except 0 - there can be only one bitangent
         if (pInput.mIndex == 0) {
         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 {
         } else {
             ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
             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.mTexCoords[pInput.mIndex].insert(pMesh.mTexCoords[pInput.mIndex].end(),
                         pMesh.mPositions.size() - pMesh.mTexCoords[pInput.mIndex].size() - 1, aiVector3D(0, 0, 0));
                         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]) {
             if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) {
                 pMesh.mNumUVComponents[pInput.mIndex] = 3;
                 pMesh.mNumUVComponents[pInput.mIndex] = 3;
             }
             }
@@ -2057,7 +2058,7 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
                 XmlParser::getStdStrAttribute(currentNode, "id", child->mID);
                 XmlParser::getStdStrAttribute(currentNode, "id", child->mID);
             }
             }
             if (XmlParser::hasAttribute(currentNode, "sid")) {
             if (XmlParser::hasAttribute(currentNode, "sid")) {
-                XmlParser::getStdStrAttribute(currentNode, "id", child->mSID);
+                XmlParser::getStdStrAttribute(currentNode, "sid", child->mSID);
             }
             }
             if (XmlParser::hasAttribute(currentNode, "name")) {
             if (XmlParser::hasAttribute(currentNode, "name")) {
                 XmlParser::getStdStrAttribute(currentNode, "name", child->mName);
                 XmlParser::getStdStrAttribute(currentNode, "name", child->mName);
@@ -2112,7 +2113,7 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
                 if (s[0] != '#') {
                 if (s[0] != '#') {
                     ASSIMP_LOG_ERROR("Collada: Unresolved reference format of node");
                     ASSIMP_LOG_ERROR("Collada: Unresolved reference format of node");
                 } else {
                 } else {
-                    pNode->mNodeInstances.push_back(NodeInstance());
+                    pNode->mNodeInstances.emplace_back();
                     pNode->mNodeInstances.back().mNode = s.c_str() + 1;
                     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");
                     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;
                 pNode->mLights.back().mLight = url.c_str() + 1;
             }
             }
         } else if (currentName == "instance_camera") {
         } else if (currentName == "instance_camera") {
@@ -2139,7 +2140,7 @@ void ColladaParser::ReadSceneNode(XmlNode &node, Node *pNode) {
                 if (url[0] != '#') {
                 if (url[0] != '#') {
                     throw DeadlyImportError("Unknown reference format in <instance_camera> element");
                     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;
                 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
 // Constructor to be privately used by Importer
-DXFImporter::DXFImporter()
-: BaseImporter() {
-    // empty
-}
+DXFImporter::DXFImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-DXFImporter::~DXFImporter() {
-    // empty
-}
+DXFImporter::~DXFImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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.
         // XXX this would be the place to implement recursive expansion if needed.
         const DXF::Block& bl_src = *(*it).second;
         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) {
             if (!pl_in) {
                 ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping.");
                 ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping.");
                 continue;
                 continue;
@@ -473,7 +470,7 @@ void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) {
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output) {
 void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output) {
     // push a new block onto the stack.
     // push a new block onto the stack.
-    output.blocks.push_back( DXF::Block() );
+    output.blocks.emplace_back();
     DXF::Block& block = output.blocks.back();
     DXF::Block& block = output.blocks.back();
 
 
     while( !reader.End() && !reader.Is(0,"ENDBLK")) {
     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) {
 void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output) {
     // Push a new block onto the stack.
     // Push a new block onto the stack.
-    output.blocks.push_back( DXF::Block() );
+    output.blocks.emplace_back();
     DXF::Block& block = output.blocks.back();
     DXF::Block& block = output.blocks.back();
 
 
     block.name = AI_DXF_ENTITIES_MAGIC_BLOCK;
     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) {
 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();
     DXF::InsertBlock& bl = output.blocks.back().insertions.back();
 
 
     while( !reader.End() && !reader.Is(0)) {
     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
 Copyright (c) 2006-2022, assimp team
 
 
-
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 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,
 AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element &element, const std::string &name,
         const Document &doc, const char *const *target_prop_whitelist /*= nullptr*/,
         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);
     props = GetPropertyTable(doc, "AnimationCurveNode.FbxAnimCurveNode", element, sc, false);
 }
 }
 
 
-// ------------------------------------------------------------------------------------------------
-AnimationCurveNode::~AnimationCurveNode() {
-    // empty
-}
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 const AnimationCurveMap &AnimationCurveNode::Curves() const {
 const AnimationCurveMap &AnimationCurveNode::Curves() const {
     if (curves.empty()) {
     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);
     props = GetPropertyTable(doc, "AnimationLayer.FbxAnimLayer", element, sc, true);
 }
 }
 
 
-// ------------------------------------------------------------------------------------------------
-AnimationLayer::~AnimationLayer() {
-    // empty
-}
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 AnimationCurveNodeList AnimationLayer::Nodes(const char *const *target_prop_whitelist /*= nullptr*/,
 AnimationCurveNodeList AnimationLayer::Nodes(const char *const *target_prop_whitelist /*= nullptr*/,
         size_t whitelist_size /*= 0*/) const {
         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 FBX
 } // namespace Assimp
 } // 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)
     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 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;
         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 Assimp {
 namespace FBX {
 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', '\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?)
 }; // 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
 Copyright (c) 2006-2022, assimp team
 
 
-
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 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 <stdlib.h>
 #include <cstdint>
 #include <cstdint>
 #include <iomanip>
 #include <iomanip>
-#include <iostream>
 #include <iterator>
 #include <iterator>
 #include <memory>
 #include <memory>
 #include <sstream>
 #include <sstream>
-#include <tuple>
-#include <vector>
 
 
 namespace Assimp {
 namespace Assimp {
 namespace FBX {
 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.
 /// 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.
 /// 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() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
     PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
     PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
     aiNode* operator->() { return mNode; }
     aiNode* operator->() { return mNode; }
@@ -231,7 +227,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
         if (nullptr != model) {
         if (nullptr != model) {
             nodes_chain.clear();
             nodes_chain.clear();
             post_nodes_chain.clear();
             post_nodes_chain.clear();
-
             aiMatrix4x4 new_abs_transform = parent->mTransformation;
             aiMatrix4x4 new_abs_transform = parent->mTransformation;
             std::string node_name = FixNodeName(model->Name());
             std::string node_name = FixNodeName(model->Name());
             // even though there is only a single input node, the design of
             // 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());
             ai_assert(nodes_chain.size());
 
 
             if (need_additional_node) {
             if (need_additional_node) {
-                nodes_chain.emplace_back(PotentialNode(node_name));
+                nodes_chain.emplace_back(node_name);
             }
             }
 
 
             //setup metadata on newest node
             //setup metadata on newest node
@@ -266,8 +261,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
 
 
                 child->mParent = last_parent;
                 child->mParent = last_parent;
                 last_parent = child.mNode;
                 last_parent = child.mNode;
-
-                new_abs_transform *= child->mTransformation;
             }
             }
 
 
             // attach geometry
             // attach geometry
@@ -290,8 +283,6 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
 
 
                     postnode->mParent = last_parent;
                     postnode->mParent = last_parent;
                     last_parent = postnode.mNode;
                     last_parent = postnode.mNode;
-
-                    new_abs_transform *= postnode->mTransformation;
                 }
                 }
             } else {
             } else {
                 // free the nodes we allocated as we don't need them
                 // 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->mNumChildren = 0;
         parent->mChildren = nullptr;
         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) {
 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
     auto it_pair = mNodeNames.insert({ name, 0 }); // duplicate node name instance count
     unsigned int &i = it_pair.first->second;
     unsigned int &i = it_pair.first->second;
     while (!it_pair.second) {
     while (!it_pair.second) {
-        i++;
+        ++i;
         std::ostringstream ext;
         std::ostringstream ext;
         ext << name << std::setfill('0') << std::setw(3) << i;
         ext << name << std::setfill('0') << std::setw(3) << i;
         uniqueName = ext.str();
         uniqueName = ext.str();
@@ -651,9 +639,8 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
 
 
 bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
 bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
     const PropertyTable &props = model.Props();
     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);
     const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
     for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
     for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
         const TransformationComp comp = static_cast<TransformationComp>(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 scale_compare = (comp == TransformationComp_GeometricScaling || comp == TransformationComp_Scaling);
 
 
+        bool ok = true;
         const aiVector3D &v = PropertyGet<aiVector3D>(props, NameTransformationCompProperty(comp), ok);
         const aiVector3D &v = PropertyGet<aiVector3D>(props, NameTransformationCompProperty(comp), ok);
         if (ok && scale_compare) {
         if (ok && scale_compare) {
             if ((v - all_ones).SquareLength() > zero_epsilon) {
             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();
     const std::vector<const Geometry *> &geos = model.GetGeometry();
 
 
     std::vector<unsigned int> meshes;
     std::vector<unsigned int> meshes;
     meshes.reserve(geos.size());
     meshes.reserve(geos.size());
 
 
     for (const Geometry *geo : geos) {
     for (const Geometry *geo : geos) {
-
         const MeshGeometry *const mesh = dynamic_cast<const MeshGeometry *>(geo);
         const MeshGeometry *const mesh = dynamic_cast<const MeshGeometry *>(geo);
         const LineGeometry *const line = dynamic_cast<const LineGeometry *>(geo);
         const LineGeometry *const line = dynamic_cast<const LineGeometry *>(geo);
         if (mesh) {
         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));
             std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
         } else if (line) {
         } else if (line) {
             const std::vector<unsigned int> &indices = ConvertLine(*line, root_node);
             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>
 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;
     std::vector<unsigned int> temp;
 
 
     MeshMap::const_iterator it = meshes_converted.find(&mesh);
     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];
         const MatIndexArray::value_type base = mindices[0];
         for (MatIndexArray::value_type index : mindices) {
         for (MatIndexArray::value_type index : mindices) {
             if (index != base) {
             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;
     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();
     const MatIndexArray &mindices = mesh.GetMaterialIndices();
     aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
     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]);
         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);
         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;
     std::vector<aiAnimMesh *> animMeshes;
@@ -1199,9 +1217,8 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
 }
 }
 
 
 std::vector<unsigned int>
 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();
     const MatIndexArray &mindices = mesh.GetMaterialIndices();
     ai_assert(mindices.size());
     ai_assert(mindices.size());
 
 
@@ -1211,7 +1228,7 @@ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &mo
     for (MatIndexArray::value_type index : mindices) {
     for (MatIndexArray::value_type index : mindices) {
         if (had.find(index) == had.end()) {
         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);
             had.insert(index);
         }
         }
     }
     }
@@ -1219,10 +1236,8 @@ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &mo
     return indices;
     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);
     aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
 
 
     const MatIndexArray &mindices = mesh.GetMaterialIndices();
     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);
     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,
         aiNode *parent, unsigned int materialIndex,
         std::vector<unsigned int> *outputVertStartIndices) {
         std::vector<unsigned int> *outputVertStartIndices) {
     ai_assert(geo.DeformerSkin());
     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();
     const Skin &sk = *geo.DeformerSkin();
 
 
-    std::vector<aiBone *> bones;
-
+    std::vector<aiBone*> bones;
     const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
     const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
     ai_assert(no_mat_check || outputVertStartIndices);
     ai_assert(no_mat_check || outputVertStartIndices);
 
 
@@ -1521,26 +1563,20 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo,
         out->mBones = nullptr;
         out->mBones = nullptr;
         out->mNumBones = 0;
         out->mNumBones = 0;
         return;
         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> &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 *) {
         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));
     aiString bone_name = aiString(FixNodeName(deformer_name));
 
 
     aiBone *bone = nullptr;
     aiBone *bone = nullptr;
@@ -1553,14 +1589,16 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
         bone = new aiBone();
         bone = new aiBone();
         bone->mName = bone_name;
         bone->mName = bone_name;
 
 
+        bone->mOffsetMatrix = cluster->Transform();
         // store local transform link for post processing
         // store local transform link for post processing
-        bone->mOffsetMatrix = cl->TransformLink();
+        /*
+        bone->mOffsetMatrix = cluster->TransformLink();
         bone->mOffsetMatrix.Inverse();
         bone->mOffsetMatrix.Inverse();
 
 
         aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
         aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
 
 
         bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
         bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
-
+        */
         //
         //
         // Now calculate the aiVertexWeights
         // 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()];
         cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
 
 
         const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
         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();
         const size_t c = index_out_indices.size();
         for (size_t i = 0; i < c; ++i) {
         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);
     const float ShininessExponent = PropertyGet<float>(props, "ShininessExponent", ok);
     if (ok) {
     if (ok) {
         out_mat->AddProperty(&ShininessExponent, 1, AI_MATKEY_SHININESS);
         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:
     // TransparentColor / TransparencyFactor... gee thanks FBX :rolleyes:
@@ -2613,7 +2654,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
                 meshMorphAnim->mNumKeys = numKeys;
                 meshMorphAnim->mNumKeys = numKeys;
                 meshMorphAnim->mKeys = new aiMeshMorphKey[numKeys];
                 meshMorphAnim->mKeys = new aiMeshMorphKey[numKeys];
                 unsigned int j = 0;
                 unsigned int j = 0;
-                for (auto animIt : *animData) {
+                for (auto &animIt : *animData) {
                     morphKeyData *keyData = animIt.second;
                     morphKeyData *keyData = animIt.second;
                     unsigned int numValuesAndWeights = static_cast<unsigned int>(keyData->values.size());
                     unsigned int numValuesAndWeights = static_cast<unsigned int>(keyData->values.size());
                     meshMorphAnim->mKeys[j].mNumValuesAndWeights = numValuesAndWeights;
                     meshMorphAnim->mKeys[j].mNumValuesAndWeights = numValuesAndWeights;
@@ -3188,7 +3229,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
 
 
     bool ok = false;
     bool ok = false;
     
     
-    const float zero_epsilon = ai_epsilon;
+    const auto zero_epsilon = ai_epsilon;
 
 
     const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
     const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
     if (ok && preRotation.SquareLength() > zero_epsilon) {
     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 :-)
     return inputs; // pray for NRVO :-)
@@ -3326,13 +3367,17 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
                 float vc = curve->GetValues().at(1);
                 float vc = curve->GetValues().at(1);
                 for (size_t n = 1; n < count; n++) {
                 for (size_t n = 1; n < count; n++) {
                     while (std::abs(vc - vp) >= 180.0f) {
                     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);
                         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) {
                         if (tnew >= adj_start && tnew <= adj_stop) {
                             Keys->push_back(tnew);
                             Keys->push_back(tnew);
                             Values->push_back(vnew);
                             Values->push_back(vnew);
                         }
                         }
+                        else {
+                            // Something broke
+                            break;
+                        }
                         tp = tnew;
                         tp = tnew;
                         vp = vnew;
                         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;
     return inputs;
@@ -3633,6 +3678,12 @@ void FBXConverter::TransferDataToScene() {
 
 
         std::swap_ranges(textures.begin(), textures.end(), mSceneOut->mTextures);
         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() {
 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 Assimp {
 namespace FBX {
 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;
 class Document;
+
 /**
 /**
  *  Convert a FBX #Document to #aiScene
  *  Convert a FBX #Document to #aiScene
  *  @param out Empty scene to be populated
  *  @param out Empty scene to be populated
@@ -180,14 +191,12 @@ private:
     void SetupNodeMetadata(const Model& model, aiNode& nd);
     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
     // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
     std::vector<unsigned int>
     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);
     std::vector<unsigned int> ConvertLine(const LineGeometry& line, aiNode *root_node);
@@ -196,18 +205,16 @@ private:
     aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent);
     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>
     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() */
     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
     *  - outputVertStartIndices is only used when a material index is specified, it gives for
     *    each output vertex the DOM index it maps to.
     *    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);
             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,
     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> &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,
     void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@@ -301,7 +312,8 @@ private:
     void ConvertAnimationStack(const AnimationStack& st);
     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,
     void GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims,
@@ -450,6 +462,7 @@ private:
 
 
     double anim_fps;
     double anim_fps;
 
 
+    std::vector<aiSkeleton *> mSkeletons;
     aiScene* const mSceneOut;
     aiScene* const mSceneOut;
     const FBX::Document& doc;
     const FBX::Document& doc;
     bool mRemoveEmptyBones;
     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
 Copyright (c) 2006-2022, assimp team
 
 
-
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 Redistribution and use of this software in source and binary forms,
@@ -58,22 +57,16 @@ namespace FBX {
 using namespace Util;
 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 Scope& sc = GetRequiredScope(element);
 
 
     const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2));
     const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2));
     props = GetPropertyTable(doc,"Deformer.Fbx" + classname,element,sc,true);
     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)
 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)
 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)
 BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name)
     : Deformer(id, element, doc, 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)
 BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name)
     : Deformer(id, element, doc, 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;
 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() {
         doc(doc), element(element), id(id), flags() {
     // empty
     // empty
 }
 }
@@ -544,7 +544,7 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
     ai_assert( count != 0 );
     ai_assert( count != 0 );
     ai_assert( count <= MAX_CLASSNAMES);
     ai_assert( count <= MAX_CLASSNAMES);
 
 
-    size_t lengths[MAX_CLASSNAMES];
+    size_t lengths[MAX_CLASSNAMES] = {};
 
 
     const size_t c = count;
     const size_t c = count;
     for (size_t i = 0; i < c; ++i) {
     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:
 public:
     NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
 
 
-    virtual ~NodeAttribute();
+    virtual ~NodeAttribute() = default;
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
@@ -180,7 +180,7 @@ class CameraSwitcher : public NodeAttribute {
 public:
 public:
     CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
 
 
-    virtual ~CameraSwitcher();
+    virtual ~CameraSwitcher() = default;
 
 
     int CameraID() const {
     int CameraID() const {
         return cameraId;
         return cameraId;
@@ -225,7 +225,7 @@ class Camera : public NodeAttribute {
 public:
 public:
     Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     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(Position, aiVector3D, aiVector3D(0,0,0))
     fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0))
     fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0))
@@ -250,21 +250,21 @@ public:
 class Null : public NodeAttribute {
 class Null : public NodeAttribute {
 public:
 public:
     Null(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     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 */
 /** DOM base class for FBX limb node markers attached to a node */
 class LimbNode : public NodeAttribute {
 class LimbNode : public NodeAttribute {
 public:
 public:
     LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     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 */
 /** DOM base class for FBX lights attached to a node */
 class Light : public NodeAttribute {
 class Light : public NodeAttribute {
 public:
 public:
     Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
     Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
-    virtual ~Light();
+    virtual ~Light() = default;
 
 
     enum Type {
     enum Type {
         Type_Point,
         Type_Point,
@@ -690,7 +690,7 @@ using KeyValueList = std::vector<float>;
 class AnimationCurve : public Object {
 class AnimationCurve : public Object {
 public:
 public:
     AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
     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).
     /** get list of keyframe positions (time).
      *  Invariant: |GetKeys()| > 0 */
      *  Invariant: |GetKeys()| > 0 */
@@ -731,7 +731,7 @@ public:
     AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
     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);
             const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
 
 
-    virtual ~AnimationCurveNode();
+    virtual ~AnimationCurveNode() = default;
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
@@ -776,7 +776,7 @@ using AnimationCurveNodeList = std::vector<const AnimationCurveNode*>;
 class AnimationLayer : public Object {
 class AnimationLayer : public Object {
 public:
 public:
     AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
     AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
-    virtual ~AnimationLayer();
+    virtual ~AnimationLayer() = default;
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
@@ -799,7 +799,7 @@ using AnimationLayerList = std::vector<const AnimationLayer*>;
 class AnimationStack : public Object {
 class AnimationStack : public Object {
 public:
 public:
     AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
     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(LocalStart, int64_t, 0L)
     fbx_simple_property(LocalStop, 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.
 // 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);
     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) {
     if(element) {
         DOMError(message,element->KeyToken());
         DOMError(message,element->KeyToken());
     }
     }
@@ -76,8 +74,7 @@ void DOMError(const std::string& message, const Element* element /*= nullptr*/)
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // print warning, do return
 // 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()) {
     if(DefaultLogger::get()) {
         ASSIMP_LOG_WARN("FBX-DOM", Util::GetTokenText(&token), message);
         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>
 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()) {
     if (is_object_property_conn && !con.PropertyName().length()) {
         DOMWarning("expected incoming " + std::string(name) +
         DOMWarning("expected incoming " + std::string(name) +
             " link to be an object-object connection, ignoring",
             " 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()
 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);
     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),
             readLights(true),
             readAnimations(true),
             readAnimations(true),
             readWeights(true),
             readWeights(true),
+            useSkeleton(false),
             preservePivots(true),
             preservePivots(true),
             optimizeEmptyAnimationCurves(true),
             optimizeEmptyAnimationCurves(true),
             useLegacyEmbeddedTextureNaming(false),
             useLegacyEmbeddedTextureNaming(false),
@@ -112,6 +113,11 @@ struct ImportSettings {
      *  Default value is true. */
      *  Default value is true. */
     bool readWeights;
     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
     /** preserve transformation pivots and offsets. Since these can
      *  not directly be represented in assimp, additional dummy
      *  not directly be represented in assimp, additional dummy
      *  nodes will be generated. Note that settings this to false
      *  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
 // 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
 // Setup configuration properties for the loader
 void FBXImporter::SetupProperties(const Importer *pImp) {
 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;
 	contents[contents.size() - 1] = 0;
 	const char *const begin = &*contents.begin();
 	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)
 	// syntax elements of FBX (brackets, commas, key:value mappings)
 	TokenList tokens;
 	TokenList tokens;
 	try {
 	try {
@@ -173,15 +171,14 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 		Parser parser(tokens, is_binary);
 		Parser parser(tokens, is_binary);
 
 
 		// take the raw parse-tree and convert it to a FBX DOM
 		// 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
 		// convert the FBX DOM to aiScene
-		ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
+		ConvertToAssimpScene(pScene, doc, mSettings.removeEmptyBones);
 
 
 		// size relative to cm
 		// size relative to cm
 		float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
 		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.
 			// BaseImporter later asserts that fileScale is non-zero.
 			ThrowException("The UnitScaleFactor must be 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> {
 class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
 public:
 public:
+    /// @brief The class constructor.
     FBXImporter();
     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:
 protected:
     // --------------------
     // --------------------
@@ -90,7 +91,7 @@ protected:
             IOSystem *pIOHandler) override;
             IOSystem *pIOHandler) override;
 
 
 private:
 private:
-    FBX::ImportSettings settings;
+    FBX::ImportSettings mSettings;
 }; // !class FBXImporter
 }; // !class FBXImporter
 
 
 } // end of namespace Assimp
 } // 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 uvTrans;
     aiVector2D uvScaling;
     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) :
 LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& /*doc*/, const std::string& name) :
         Object(id,element,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) {
 void LayeredTexture::fillTexture(const Document& doc) {
     const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
     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
 Copyright (c) 2006-2022, assimp team
 
 
-
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 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 "FBXImportSettings.h"
 #include "FBXDocumentUtil.h"
 #include "FBXDocumentUtil.h"
 
 
-
 namespace Assimp {
 namespace Assimp {
 namespace FBX {
 namespace FBX {
 
 
 using namespace Util;
 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) {
     for(const Connection* con : conns) {
         const Skin* const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element);
         const Skin* const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element);
         if(sk) {
         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 {
 const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
     return blendShapes;
     return blendShapes;
@@ -183,18 +173,12 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
         if(doc.Settings().readAllLayers || index == 0) {
         if(doc.Settings().readAllLayers || index == 0) {
             const Scope& layer = GetRequiredScope(*(*it).second);
             const Scope& layer = GetRequiredScope(*(*it).second);
             ReadLayer(layer);
             ReadLayer(layer);
-        }
-        else {
+        } else {
             FBXImporter::LogWarn("ignoring additional geometry layers");
             FBXImporter::LogWarn("ignoring additional geometry layers");
         }
         }
     }
     }
 }
 }
 
 
-// ------------------------------------------------------------------------------------------------
-MeshGeometry::~MeshGeometry() {
-    // empty
-}
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 const std::vector<aiVector3D>& MeshGeometry::GetVertices() const {
 const std::vector<aiVector3D>& MeshGeometry::GetVertices() const {
     return m_vertices;
     return m_vertices;
@@ -431,9 +415,11 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
 {
 {
     bool isDirect = ReferenceInformationType == "Direct";
     bool isDirect = ReferenceInformationType == "Direct";
     bool isIndexToDirect = ReferenceInformationType == "IndexToDirect";
     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
     // fall-back to direct data if there is no index data element
-    if ( isIndexToDirect && !HasElement( source, indexDataElementName ) ) {
+    if (isIndexToDirect && !hasIndexDataElement) {
         isDirect = true;
         isDirect = true;
         isIndexToDirect = false;
         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
     // deal with this more elegantly and with less redundancy, but right
     // now it seems unavoidable.
     // now it seems unavoidable.
     if (MappingInformationType == "ByVertice" && isDirect) {
     if (MappingInformationType == "ByVertice" && isDirect) {
-        if (!HasElement(source, dataElementName)) {
+        if (!hasDataElement) {
+            FBXImporter::LogWarn("missing data element: ", dataElementName);
             return;
             return;
         }
         }
         std::vector<T> tempData;
         std::vector<T> tempData;
@@ -464,7 +451,15 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
     }
     }
     else if (MappingInformationType == "ByVertice" && isIndexToDirect) {
     else if (MappingInformationType == "ByVertice" && isIndexToDirect) {
 		std::vector<T> tempData;
 		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;
         std::vector<int> uvIndices;
         ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
         ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
@@ -489,6 +484,11 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
         }
         }
     }
     }
     else if (MappingInformationType == "ByPolygonVertex" && isDirect) {
     else if (MappingInformationType == "ByPolygonVertex" && isDirect) {
+        if (!hasDataElement) {
+            FBXImporter::LogWarn("missing data element: ", dataElementName);
+            return;
+        }
+
 		std::vector<T> tempData;
 		std::vector<T> tempData;
 		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
 		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
 
 
@@ -503,7 +503,14 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
     }
     }
     else if (MappingInformationType == "ByPolygonVertex" && isIndexToDirect) {
     else if (MappingInformationType == "ByPolygonVertex" && isIndexToDirect) {
 		std::vector<T> tempData;
 		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;
         std::vector<int> uvIndices;
         ParseVectorDataArray(uvIndices,GetRequiredElement(source,indexDataElementName));
         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 {
 const std::vector<aiVector3D>& ShapeGeometry::GetVertices() const {
     return m_vertices;
     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 {
 const std::vector<aiVector3D>& LineGeometry::GetVertices() const {
     return m_vertices;
     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
  *  DOM base class for all kinds of FBX geometry
  */
  */
-class Geometry : public Object
-{
+class Geometry : public Object {
 public:
 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 );
     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;
     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;
     const std::vector<const BlendShape*>& GetBlendShapes() const;
 
 
 private:
 private:
     const Skin* skin;
     const Skin* skin;
     std::vector<const BlendShape*> blendShapes;
     std::vector<const BlendShape*> blendShapes;
-
 };
 };
 
 
 typedef std::vector<int> MatIndexArray;
 typedef std::vector<int> MatIndexArray;
@@ -79,14 +82,13 @@ typedef std::vector<int> MatIndexArray;
 /**
 /**
  *  DOM class for FBX geometry of type "Mesh"
  *  DOM class for FBX geometry of type "Mesh"
  */
  */
-class MeshGeometry : public Geometry
-{
+class MeshGeometry : public Geometry {
 public:
 public:
     /** The class constructor */
     /** The class constructor */
     MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
     MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
 
 
     /** The class destructor */
     /** The class destructor */
-    virtual ~MeshGeometry();
+    virtual ~MeshGeometry() = default;
 
 
     /** Get a list of all vertex points, non-unique*/
     /** Get a list of all vertex points, non-unique*/
     const std::vector<aiVector3D>& GetVertices() const;
     const std::vector<aiVector3D>& GetVertices() const;
@@ -130,6 +132,7 @@ public:
     /** Determine the face to which a particular output vertex index belongs.
     /** Determine the face to which a particular output vertex index belongs.
     *  This mapping is always unique. */
     *  This mapping is always unique. */
     unsigned int FaceForVertexIndex( unsigned int in_index ) const;
     unsigned int FaceForVertexIndex( unsigned int in_index ) const;
+
 private:
 private:
     void ReadLayer( const Scope& layer );
     void ReadLayer( const Scope& layer );
     void ReadLayerElement( const Scope& layerElement );
     void ReadLayerElement( const Scope& layerElement );

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

@@ -57,114 +57,65 @@ namespace FBX {
 using namespace Util;
 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
     // 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
     // the property table is by design absent and no warning should be generated
     // for it.
     // for it.
     const bool is_null_or_limb = !strcmp(classname.c_str(), "Null") || !strcmp(classname.c_str(), "LimbNode");
     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
     // 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
     // empty
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-Camera::~Camera()
-{
+Null::Null(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
+        NodeAttribute(id, element, doc, name) {
     // empty
     // 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
     // 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);
     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)
 Scope::Scope(Parser& parser,bool topLevel)
 {
 {
@@ -226,12 +220,6 @@ Parser::Parser (const TokenList& tokens, bool is_binary)
     root.reset(new Scope(*this,true));
     root.reset(new Scope(*this,true));
 }
 }
 
 
-// ------------------------------------------------------------------------------------------------
-Parser::~Parser()
-{
-    // empty
-}
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 TokenPtr Parser::AdvanceToNextToken()
 TokenPtr Parser::AdvanceToNextToken()
 {
 {
@@ -631,9 +619,9 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
         if (type == 'd') {
         if (type == 'd') {
             const double* d = reinterpret_cast<const double*>(&buff[0]);
             const double* d = reinterpret_cast<const double*>(&buff[0]);
             for (unsigned int i = 0; i < count3; ++i, d += 3) {
             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[1]),
-                    static_cast<ai_real>(d[2])));
+                    static_cast<ai_real>(d[2]));
             }
             }
             // for debugging
             // for debugging
             /*for ( size_t i = 0; i < out.size(); i++ ) {
             /*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') {
         else if (type == 'f') {
             const float* f = reinterpret_cast<const float*>(&buff[0]);
             const float* f = reinterpret_cast<const float*>(&buff[0]);
             for (unsigned int i = 0; i < count3; ++i, f += 3) {
             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') {
         if (type == 'd') {
             const double* d = reinterpret_cast<const double*>(&buff[0]);
             const double* d = reinterpret_cast<const double*>(&buff[0]);
             for (unsigned int i = 0; i < count4; ++i, d += 4) {
             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[1]),
                     static_cast<float>(d[2]),
                     static_cast<float>(d[2]),
-                    static_cast<float>(d[3])));
+                    static_cast<float>(d[3]));
             }
             }
         }
         }
         else if (type == 'f') {
         else if (type == 'f') {
             const float* f = reinterpret_cast<const float*>(&buff[0]);
             const float* f = reinterpret_cast<const float*>(&buff[0]);
             for (unsigned int i = 0; i < count4; ++i, f += 4) {
             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;
         return;
@@ -801,13 +789,13 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el) {
         if (type == 'd') {
         if (type == 'd') {
             const double* d = reinterpret_cast<const double*>(&buff[0]);
             const double* d = reinterpret_cast<const double*>(&buff[0]);
             for (unsigned int i = 0; i < count2; ++i, d += 2) {
             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') {
         } else if (type == 'f') {
             const float* f = reinterpret_cast<const float*>(&buff[0]);
             const float* f = reinterpret_cast<const float*>(&buff[0]);
             for (unsigned int i = 0; i < count2; ++i, f += 2) {
             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
 // 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 );
     out.resize( 0 );
     const TokenList& tok = el.Tokens();
     const TokenList& tok = el.Tokens();
     if(tok.empty()) {
     if(tok.empty()) {
@@ -1186,7 +1173,6 @@ aiMatrix4x4 ReadMatrix(const Element& element)
     return result;
     return result;
 }
 }
 
 
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // wrapper around ParseTokenAsString() with ParseError handling
 // wrapper around ParseTokenAsString() with ParseError handling
 std::string ParseTokenAsString(const Token& t)
 std::string ParseTokenAsString(const Token& t)

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

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

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

@@ -60,29 +60,23 @@ namespace FBX {
     using namespace Util;
     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 {
 namespace {
 
 

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

@@ -96,7 +96,7 @@ public:
     /** construct a binary token */
     /** construct a binary token */
     Token(const char* sbegin, const char* send, TokenType type, size_t offset);
     Token(const char* sbegin, const char* send, TokenType type, size_t offset);
 
 
-    ~Token();
+    ~Token() = default;
 
 
 public:
 public:
     std::string StringContents() const {
     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
 // Constructor to be privately used by Importer
-HMPImporter::HMPImporter() {
-    // nothing to do here
-}
+HMPImporter::HMPImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // 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.
 // 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)
                 if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10)
                     continue;
                     continue;
             }
             }
-            intersect_results.push_back(std::make_pair(i, e0));
+            intersect_results.emplace_back(i, e0);
             continue;
             continue;
         }
         }
 
 
@@ -324,7 +324,7 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
                 if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10)
                 if (IfcVector2(diff.x, diff.y).SquareLength() < 1e-10)
                     continue;
                     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
                 // now add them to the list of intersections
                 for (size_t b = 0; b < intersected_boundary.size(); ++b)
                 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
                 // and calculate our new inside/outside state
                 if (intersected_boundary.size() & 1)
                 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
 Copyright (c) 2006-2022, assimp team
 
 
-
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 Redistribution and use of this software in source and binary forms,
@@ -51,7 +50,6 @@ namespace Assimp {
 namespace IFC {
 namespace IFC {
 namespace {
 namespace {
 
 
-
 // --------------------------------------------------------------------------------
 // --------------------------------------------------------------------------------
 // Conic is the base class for Circle and Ellipse
 // 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");
                 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();
             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[ 0 ] != inf );
     ai_assert( min_diff[ 1 ] != inf );
     ai_assert( min_diff[ 1 ] != inf );
+#endif // __INTEL_LLVM_COMPILER
     if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
     if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
         return min_point[0];
         return min_point[0];
     }
     }
@@ -606,8 +606,10 @@ bool BoundedCurve::IsClosed() const {
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void BoundedCurve::SampleDiscrete(TempMesh& out) const {
 void BoundedCurve::SampleDiscrete(TempMesh& out) const {
     const ParamRange& range = GetParametricRange();
     const ParamRange& range = GetParametricRange();
+#ifndef __INTEL_LLVM_COMPILER
     ai_assert( range.first != std::numeric_limits<IfcFloat>::infinity() );
     ai_assert( range.first != std::numeric_limits<IfcFloat>::infinity() );
     ai_assert( range.second != 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);
     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;
             continue;
         }
         }
 
 
-        fake_openings.push_back(TempOpening());
+        fake_openings.emplace_back();
         TempOpening& opening = fake_openings.back();
         TempOpening& opening = fake_openings.back();
 
 
         opening.extrusionDir = master_normal;
         opening.extrusionDir = master_normal;
@@ -612,7 +612,7 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
             TempMesh& bounds = *t.profileMesh.get();
             TempMesh& bounds = *t.profileMesh.get();
 
 
             if( bounds.mVerts.size() <= 2 ) {
             if( bounds.mVerts.size() <= 2 ) {
-                nors.push_back(IfcVector3());
+                nors.emplace_back();
                 continue;
                 continue;
             }
             }
             auto nor = ((bounds.mVerts[2] - bounds.mVerts[0]) ^ (bounds.mVerts[1] - bounds.mVerts[0])).Normalize();
             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
 // Constructor to be privately used by Importer
-IFCImporter::IFCImporter() {}
+IFCImporter::IFCImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-IFCImporter::~IFCImporter() {
-}
+IFCImporter::~IFCImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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) {
     if (!found) {
         // the rectangle [pmin,pend] is opaque, fill it
         // the rectangle [pmin,pend] is opaque, fill it
         out.push_back(pmin);
         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(pmax);
-        out.push_back(IfcVector2(pmax.x,pmin.y));
+        out.emplace_back(pmax.x,pmin.y);
         return;
         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
     // see if there's an offset to fill at the top of our quad
     if (xs - pmin.x) {
     if (xs - pmin.x) {
         out.push_back(pmin);
         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
     // 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) {
     if (!found) {
         // the rectangle [pmin,pend] is opaque, fill it
         // 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;
         return;
     }
     }
     if (ylast < pmax.y) {
     if (ylast < pmax.y) {
@@ -342,7 +342,7 @@ void InsertWindowContours(const ContourVector& contours,
                         if ((contour[a] - edge).SquareLength() > diag*diag*0.7) {
                         if ((contour[a] - edge).SquareLength() > diag*diag*0.7) {
                             continue;
                             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]) {
                     if (edge != contour[last_hit]) {
@@ -363,7 +363,7 @@ void InsertWindowContours(const ContourVector& contours,
                             corner.y = bb.second.y;
                             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) {
                     else if (cnt == 1) {
                         // avoid degenerate polygons (also known as lines or points)
                         // avoid degenerate polygons (also known as lines or points)
@@ -399,7 +399,7 @@ void MergeWindowContours (const std::vector<IfcVector2>& a,
     ClipperLib::Polygon clip;
     ClipperLib::Polygon clip;
 
 
     for(const IfcVector2& pip : a) {
     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)) {
     if (ClipperLib::Orientation(clip)) {
@@ -410,7 +410,7 @@ void MergeWindowContours (const std::vector<IfcVector2>& a,
     clip.clear();
     clip.clear();
 
 
     for(const IfcVector2& pip : b) {
     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)) {
     if (ClipperLib::Orientation(clip)) {
@@ -433,7 +433,7 @@ void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
     ClipperLib::Polygon clip;
     ClipperLib::Polygon clip;
 
 
     for(const IfcVector2& pip : a) {
     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)) {
     if (ClipperLib::Orientation(clip)) {
@@ -444,7 +444,7 @@ void MakeDisjunctWindowContours (const std::vector<IfcVector2>& a,
     clip.clear();
     clip.clear();
 
 
     for(const IfcVector2& pip : b) {
     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)) {
     if (ClipperLib::Orientation(clip)) {
@@ -466,7 +466,7 @@ void CleanupWindowContour(ProjectedWindowContour& window)
     ClipperLib::ExPolygons clipped;
     ClipperLib::ExPolygons clipped;
 
 
     for(const IfcVector2& pip : contour) {
     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);
     clipper.AddPolygon(subject,ClipperLib::ptSubject);
@@ -524,7 +524,7 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
         ClipperLib::Polygon clip;
         ClipperLib::Polygon clip;
         clip.reserve(contour_flat.size());
         clip.reserve(contour_flat.size());
         for(const IfcVector2& pip : contour_flat) {
         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)) {
         if (!ClipperLib::Orientation(clip)) {
@@ -544,7 +544,7 @@ void CleanupOuterContour(const std::vector<IfcVector2>& contour_flat, TempMesh&
                     continue;
                     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 (--countdown == 0) {
                 if (!ClipperLib::Orientation(subject)) {
                 if (!ClipperLib::Orientation(subject)) {
                     std::reverse(subject.begin(), subject.end());
                     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) {
                 for(const ClipperLib::ExPolygon& ex : clipped) {
                     iold.push_back(static_cast<unsigned int>(ex.outer.size()));
                     iold.push_back(static_cast<unsigned int>(ex.outer.size()));
                     for(const ClipperLib::IntPoint& point : ex.outer) {
                     for(const ClipperLib::IntPoint& point : ex.outer) {
-                        vold.push_back(IfcVector3(
+                        vold.emplace_back(
                             from_int64(point.X),
                             from_int64(point.X),
                             from_int64(point.Y),
                             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.mVertcnt.resize(quads.size()/4,4);
     curmesh.mVerts.reserve(quads.size());
     curmesh.mVerts.reserve(quads.size());
     for(const IfcVector2& v2 : quads) {
     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);
         vmin = std::min(vv, vmin);
         vmax = std::max(vv, vmax);
         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();
     zcoord /= in_verts.size();
@@ -1128,7 +1128,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
     for(const IfcVector3& x : in_verts) {
     for(const IfcVector3& x : in_verts) {
         const IfcVector3& vv = m * x;
         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);
         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(!temp_contour.empty()) {
             if (generate_connection_geometry) {
             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;
     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 planeNor,IfcFloat planeOffset,
     IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first,bool& ok) {
     IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first,bool& ok) {
     std::vector<IfcVector2> contour;
     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?
         // XXX should not be necessary - but it is. Why? For precision reasons?
         vv = is_extruded_side ? vv_extr : vv;
         vv = is_extruded_side ? vv_extr : vv;
-        contour.push_back(IfcVector2(vv.x,vv.y));
+        contour.emplace_back(vv.x,vv.y);
     }
     }
     ok = true;
     ok = true;
 
 
     return contour;
     return contour;
 }
 }
 
 
-const float close{ ai_epsilon };
+const ai_real close{ ai_epsilon };
 
 
 static bool isClose(IfcVector2 first,IfcVector2 second) {
 static bool isClose(IfcVector2 first,IfcVector2 second) {
     auto diff = (second - first);
     auto diff = (second - first);
@@ -1491,7 +1491,7 @@ static void logSegment(std::pair<IfcVector2,IfcVector2> segment) {
     IFCImporter::LogInfo(msg2.str().c_str());
     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) {
     IfcFloat planeOffset) {
 
 
         {
         {
@@ -1676,7 +1676,7 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(std::shared_ptr<TempMe
             std::stringstream msg;
             std::stringstream msg;
             msg << "GetContoursInPlane3D: found " << contours.size() << " contours:\n";
             msg << "GetContoursInPlane3D: found " << contours.size() << " contours:\n";
 
 
-            for(auto c : contours) {
+            for(const auto& c : contours) {
                 msg << " Contour: \n";
                 msg << " Contour: \n";
                 for(auto p : c) {
                 for(auto p : c) {
                     msg << "   " << p.x << " " << p.y << " \n";
                     msg << "   " << p.x << " " << p.y << " \n";
@@ -1690,7 +1690,7 @@ std::vector<std::vector<IfcVector2>> GetContoursInPlane3D(std::shared_ptr<TempMe
         return contours;
         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 planeNor,IfcFloat planeOffset,
     IfcVector3 extrusionDir,IfcVector3& wall_extrusion,bool& first) {
     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);
         vmin = std::min(IfcVector2(vv.x, vv.y), vmin);
         vmax = std::max(IfcVector2(vv.x, vv.y), vmax);
         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,
     // 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.x = (pip.x - vmin.x) / vmax.x;
                     pip.y = (pip.y - vmin.y) / vmax.y;
                     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)) {
                 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.x  = (pip.x - vmin.x) / vmax.x;
                 pip.y  = (pip.y - vmin.y) / vmax.y;
                 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)) {
             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
         // Build the poly2tri inner contours for all holes we got from ClipperLib
         for(ClipperLib::Polygon& opening : clip.holes) {
         for(ClipperLib::Polygon& opening : clip.holes) {
 
 
-            contours.push_back(std::vector<p2t::Point*>());
+            contours.emplace_back();
             std::vector<p2t::Point*>& contour = contours.back();
             std::vector<p2t::Point*>& contour = contours.back();
 
 
             for(ClipperLib::IntPoint& point : opening) {
             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;
         const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
 
 
         meshout.mVerts.reserve(meshout.mVerts.size()+4);
         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);
         meshout.mVertcnt.push_back(4);
     }
     }
     else if( const Schema_2x3::IfcCircleProfileDef* const circle = def.ToPtr<Schema_2x3::IfcCircleProfileDef>()) {
     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;
         IfcFloat angle = 0.f;
         for(size_t i = 0; i < segments; ++i, angle += delta) {
         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));
         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;
         const IfcFloat inner_height = ishape->OverallDepth - ishape->FlangeThickness * 2;
 
 
         meshout.mVerts.reserve(12);
         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);
         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);
     size_t vidx = std::accumulate(mVertcnt.begin(),begin,0);
     for(iit = begin; iit != end; vidx += *iit++) {
     for(iit = begin; iit != end; vidx += *iit++) {
         if (!*iit) {
         if (!*iit) {
-            normals.push_back(IfcVector3());
+            normals.emplace_back();
             continue;
             continue;
         }
         }
         for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) {
         for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) {
@@ -215,7 +215,7 @@ void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
             ++cnt;
             ++cnt;
         }
         }
 
 
-        normals.push_back(IfcVector3());
+        normals.emplace_back();
         NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]);
         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:
 public:
     typedef std::pair<IfcFloat, IfcFloat> ParamRange;
     typedef std::pair<IfcFloat, IfcFloat> ParamRange;
 
 
-    virtual ~Curve() {}
-
+    virtual ~Curve() = default;
 
 
     // check if a curve is closed
     // check if a curve is closed
     virtual bool IsClosed() const = 0;
     virtual bool IsClosed() const = 0;

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

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

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

@@ -206,8 +206,7 @@ private:
      */
      */
     struct SkyboxVertex
     struct SkyboxVertex
     {
     {
-        SkyboxVertex()
-        {}
+        SkyboxVertex() = default;
 
 
         //! Construction from single vertex components
         //! Construction from single vertex components
         SkyboxVertex(ai_real px, ai_real py, ai_real pz,
         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
 // Destructor, private as well
-IRRMeshImporter::~IRRMeshImporter() {}
+IRRMeshImporter::~IRRMeshImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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)
 LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size)
 {
 {
-    list.push_back(LWO::Texture());
+    list.emplace_back();
     LWO::Texture* tex = &list.back();
     LWO::Texture* tex = &list.back();
 
 
     std::string type;
     std::string type;

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

@@ -338,13 +338,7 @@ struct Face : public aiFace {
     uint32_t type;
     uint32_t type;
 
 
     //! Assignment operator
     //! 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) :
     explicit VMapEntry(unsigned int _dims) :
             dims(_dims) {}
             dims(_dims) {}
 
 
-    virtual ~VMapEntry() {}
+    virtual ~VMapEntry() = default;
 
 
     //! allocates memory for the vertex map
     //! allocates memory for the vertex map
     virtual void Allocate(unsigned int num) {
     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
 // Destructor, private as well
-LWOImporter::~LWOImporter() {
-    // empty
-}
+LWOImporter::~LWOImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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) {
             if (UINT_MAX == iDefaultSurface) {
                 pSorted.erase(pSorted.end() - 1);
                 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];
                 SortedRep &sorted = pSorted[j];
                 if (sorted.empty())
                 if (sorted.empty())
                     continue;
                     continue;
@@ -425,7 +423,6 @@ void LWOImporter::InternReadFile(const std::string &pFile,
                 } else {
                 } else {
                     ASSIMP_LOG_VERBOSE_DEBUG("LWO2: No need to compute normals, they're already there");
                     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) {
 void LWOImporter::LoadLWO2Clip(unsigned int length) {
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 10);
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 10);
 
 
-    mClips.push_back(LWO::Clip());
+    mClips.emplace_back();
     LWO::Clip &clip = mClips.back();
     LWO::Clip &clip = mClips.back();
 
 
     // first - get the index of the clip
     // first - get the index of the clip
@@ -1168,7 +1165,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length) {
 void LWOImporter::LoadLWO3Clip(unsigned int length) {
 void LWOImporter::LoadLWO3Clip(unsigned int length) {
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 12);
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, CLIP, 12);
 
 
-    mClips.push_back(LWO::Clip());
+    mClips.emplace_back();
     LWO::Clip &clip = mClips.back();
     LWO::Clip &clip = mClips.back();
 
 
     // first - get the index of the clip
     // 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;
     LE_NCONST uint8_t *const end = mFileBuffer + length;
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4);
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4);
 
 
-    mEnvelopes.push_back(LWO::Envelope());
+    mEnvelopes.emplace_back();
     LWO::Envelope &envelope = mEnvelopes.back();
     LWO::Envelope &envelope = mEnvelopes.back();
 
 
     // Get the index of the envelope
     // Get the index of the envelope
@@ -1293,7 +1290,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length) {
             case AI_LWO_KEY: {
             case AI_LWO_KEY: {
                 AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, KEY, 8);
                 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();
                 LWO::Key &key = envelope.keys.back();
 
 
                 key.time = GetF4();
                 key.time = GetF4();
@@ -1349,7 +1346,7 @@ void LWOImporter::LoadLWO3Envelope(unsigned int length) {
     LE_NCONST uint8_t *const end = mFileBuffer + length;
     LE_NCONST uint8_t *const end = mFileBuffer + length;
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4);
     AI_LWO_VALIDATE_CHUNK_LENGTH(length, ENVL, 4);
 
 
-    mEnvelopes.push_back(LWO::Envelope());
+    mEnvelopes.emplace_back();
     LWO::Envelope &envelope = mEnvelopes.back();
     LWO::Envelope &envelope = mEnvelopes.back();
 
 
     // Get the index of the envelope
     // Get the index of the envelope
@@ -1391,7 +1388,7 @@ void LWOImporter::LoadLWO3Envelope(unsigned int length) {
             case AI_LWO_KEY: {
             case AI_LWO_KEY: {
                 AI_LWO_VALIDATE_CHUNK_LENGTH(head.length, KEY, 10);
                 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();
                 LWO::Key &key = envelope.keys.back();
 
 
                 key.time = GetF4();
                 key.time = GetF4();
@@ -1541,6 +1538,7 @@ void LWOImporter::LoadLWO2File() {
                     break;
                     break;
                 }
                 }
                 // --- intentionally no break here
                 // --- intentionally no break here
+                // fallthrough
             case AI_LWO_VMAP: {
             case AI_LWO_VMAP: {
                 if (skip)
                 if (skip)
                     break;
                     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) {
         if (mFileBuffer + head.length > end) {
             throw DeadlyImportError("LWO3: cannot read length; LoadNodalBlocks");
             throw DeadlyImportError("LWO3: cannot read length; LoadNodalBlocks");
         }
         }
-        int node_idx = 0;
         uint8_t *const next = mFileBuffer + head.length;
         uint8_t *const next = mFileBuffer + head.length;
         mFileBuffer += bufOffset;
         mFileBuffer += bufOffset;
         switch (head.type) {
         switch (head.type) {
         case AI_LWO_NNDS:
         case AI_LWO_NNDS:
-            node_idx++;
             LoadNodes(head.length);
             LoadNodes(head.length);
             break;
             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 == '}')
         } else if (*buffer == '}')
             return;
             return;
 
 
-        children.push_back(Element());
+        children.emplace_back();
 
 
         // copy data line - read token per token
         // copy data line - read token per token
 
 
@@ -141,9 +141,7 @@ LWSImporter::LWSImporter() :
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // 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.
 // 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();
         const char *c = (*it).tokens[1].c_str();
 
 
         if ((*it).tokens[0] == "Key") {
         if ((*it).tokens[0] == "Key") {
-            fill.keys.push_back(LWO::Key());
+            fill.keys.emplace_back();
             LWO::Key &key = fill.keys.back();
             LWO::Key &key = fill.keys.back();
 
 
             float f;
             float f;
@@ -262,7 +260,7 @@ void LWSImporter::ReadEnvelope_Old(
     num = strtoul10((*it).tokens[0].c_str());
     num = strtoul10((*it).tokens[0].c_str());
     for (unsigned int i = 0; i < num; ++i) {
     for (unsigned int i = 0; i < num; ++i) {
 
 
-        nodes.channels.push_back(LWO::Envelope());
+        nodes.channels.emplace_back();
         LWO::Envelope &envl = nodes.channels.back();
         LWO::Envelope &envl = nodes.channels.back();
 
 
         envl.index = i;
         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('.');
             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);
             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;
             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
         //Push attachment, if the object came from an external file
         if (obj) {
         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;
     std::list<LWS::NodeDesc> nodes;
 
 
     unsigned int cur_light = 0, cur_camera = 0, cur_object = 0;
     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'
     // check magic identifier, 'LWSC'
     bool motion_file = false;
     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);
             d.id = batch.AddLoadRequest(path, 0, &props);
 
 
             nodes.push_back(d);
             nodes.push_back(d);
-            ++num_object;
         } else if ((*it).tokens[0] == "LoadObject") { // 'LoadObject': load a LWO file into the scene-graph
         } else if ((*it).tokens[0] == "LoadObject") { // 'LoadObject': load a LWO file into the scene-graph
 
 
             // add node to list
             // add node to list
@@ -601,7 +601,6 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
 
 
             d.path = path;
             d.path = path;
             nodes.push_back(d);
             nodes.push_back(d);
-            ++num_object;
         } else if ((*it).tokens[0] == "AddNullObject") { // 'AddNullObject': add a dummy node to the hierarchy
         } else if ((*it).tokens[0] == "AddNullObject") { // 'AddNullObject': add a dummy node to the hierarchy
 
 
             // add node to list
             // add node to list
@@ -615,8 +614,6 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
             }
             }
             d.name = c;
             d.name = c;
             nodes.push_back(d);
             nodes.push_back(d);
-
-            num_object++;
         }
         }
         // 'NumChannels': Number of envelope channels assigned to last layer
         // 'NumChannels': Number of envelope channels assigned to last layer
         else if ((*it).tokens[0] == "NumChannels") {
         else if ((*it).tokens[0] == "NumChannels") {
@@ -638,7 +635,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
             }
             }
 
 
             // important: index of channel
             // important: index of channel
-            nodes.back().channels.push_back(LWO::Envelope());
+            nodes.back().channels.emplace_back();
             LWO::Envelope &env = nodes.back().channels.back();
             LWO::Envelope &env = nodes.back().channels.back();
 
 
             env.index = strtoul10(c);
             env.index = strtoul10(c);

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

@@ -69,7 +69,7 @@ namespace LWS {
  */
  */
 class Element {
 class Element {
 public:
 public:
-    Element() {}
+    Element() = default;
 
 
     // first: name, second: rest
     // first: name, second: rest
     std::string tokens[2];
     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
 // Assimp specific M3D configuration. Comment out these defines to remove functionality
 //#define ASSIMP_USE_M3D_READFILECB
 //#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"
 #include "m3d.h"
 
 

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

@@ -102,8 +102,7 @@ MD2Importer::MD2Importer()
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-MD2Importer::~MD2Importer()
-{}
+MD2Importer::~MD2Importer() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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 == '{') {
                 if (*buff == '{') {
                     ++buff;
                     ++buff;
                     // add new map section
                     // add new map section
-                    curData->maps.push_back(Q3Shader::ShaderMapBlock());
+                    curData->maps.emplace_back();
                     curMap = &curData->maps.back();
                     curMap = &curData->maps.back();
 
 
                     for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
                     for (; SkipSpacesAndLineEnd(&buff); SkipLine(&buff)) {
@@ -209,7 +209,7 @@ bool Q3Shader::LoadShader(ShaderData &fill, const std::string &pFile, IOSystem *
             }
             }
         } else {
         } else {
             // add new section
             // add new section
-            fill.blocks.push_back(Q3Shader::ShaderDataBlock());
+            fill.blocks.emplace_back();
             curData = &fill.blocks.back();
             curData = &fill.blocks.back();
 
 
             // get the name of this section
             // 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())))
         if (!::strncmp(&ss[0], "tag_", std::min((size_t)4, ss.length())))
             continue;
             continue;
 
 
-        fill.textures.push_back(SkinData::TextureEntry());
+        fill.textures.emplace_back();
         SkinData::TextureEntry &entry = fill.textures.back();
         SkinData::TextureEntry &entry = fill.textures.back();
 
 
         entry.first = ss;
         entry.first = ss;
@@ -345,7 +345,7 @@ MD3Importer::MD3Importer() :
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-MD3Importer::~MD3Importer() {}
+MD3Importer::~MD3Importer() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
@@ -584,7 +584,7 @@ bool MD3Importer::ReadMultipartFile() {
 
 
         // original root
         // original root
         scene_lower->mRootNode->mName.Set("lower");
         scene_lower->mRootNode->mName.Set("lower");
-        attach.push_back(AttachmentInfo(scene_lower, nd));
+        attach.emplace_back(scene_lower, nd);
 
 
         // tag_torso
         // tag_torso
         tag_torso = scene_lower->mRootNode->FindNode("tag_torso");
         tag_torso = scene_lower->mRootNode->FindNode("tag_torso");
@@ -593,7 +593,7 @@ bool MD3Importer::ReadMultipartFile() {
             goto error_cleanup;
             goto error_cleanup;
         }
         }
         scene_upper->mRootNode->mName.Set("upper");
         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
         tag_head = scene_upper->mRootNode->FindNode("tag_head");
         tag_head = scene_upper->mRootNode->FindNode("tag_head");
@@ -602,7 +602,7 @@ bool MD3Importer::ReadMultipartFile() {
             goto error_cleanup;
             goto error_cleanup;
         }
         }
         scene_head->mRootNode->mName.Set("head");
         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 ...
         // Remove tag_head and tag_torso from all other model parts ...
         // this ensures (together with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY)
         // 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
 // Destructor, private as well
-MD5Importer::~MD5Importer() {
-    // empty
-}
+MD5Importer::~MD5Importer() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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
 // 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(nullptr != _buffer);
     ai_assert(0 != _fileSize);
     ai_assert(0 != _fileSize);
 
 
-    buffer = _buffer;
-    fileSize = _fileSize;
-    lineNumber = 0;
-
+    bufferEnd = buffer + fileSize;
     ASSIMP_LOG_DEBUG("MD5Parser begin");
     ASSIMP_LOG_DEBUG("MD5Parser begin");
 
 
     // parse the file header
     // parse the file header
@@ -76,7 +73,7 @@ MD5Parser::MD5Parser(char *_buffer, unsigned int _fileSize) {
     // and read all sections until we're finished
     // and read all sections until we're finished
     bool running = true;
     bool running = true;
     while (running) {
     while (running) {
-        mSections.push_back(Section());
+        mSections.emplace_back();
         Section &sec = mSections.back();
         Section &sec = mSections.back();
         if (!ParseSection(sec)) {
         if (!ParseSection(sec)) {
             break;
             break;
@@ -158,7 +155,7 @@ bool MD5Parser::ParseSection(Section &out) {
                     break;
                     break;
                 }
                 }
 
 
-                out.mElements.push_back(Element());
+                out.mElements.emplace_back();
                 Element &elem = out.mElements.back();
                 Element &elem = out.mElements.back();
 
 
                 elem.iLineNumber = lineNumber;
                 elem.iLineNumber = lineNumber;
@@ -253,7 +250,7 @@ MD5MeshParser::MD5MeshParser(SectionList &mSections) {
         } else if ((*iter).mName == "joints") {
         } else if ((*iter).mName == "joints") {
             // "origin" -1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 )
             // "origin" -1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 )
             for (const auto &elem : (*iter).mElements) {
             for (const auto &elem : (*iter).mElements) {
-                mJoints.push_back(BoneDesc());
+                mJoints.emplace_back();
                 BoneDesc &desc = mJoints.back();
                 BoneDesc &desc = mJoints.back();
 
 
                 const char *sz = elem.szStart;
                 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
                 AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
             }
             }
         } else if ((*iter).mName == "mesh") {
         } else if ((*iter).mName == "mesh") {
-            mMeshes.push_back(MeshDesc());
+            mMeshes.emplace_back();
             MeshDesc &desc = mMeshes.back();
             MeshDesc &desc = mMeshes.back();
 
 
             for (const auto &elem : (*iter).mElements) {
             for (const auto &elem : (*iter).mElements) {
@@ -364,7 +361,7 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
         if ((*iter).mName == "hierarchy") {
         if ((*iter).mName == "hierarchy") {
             // "sheath" 0 63 6
             // "sheath" 0 63 6
             for (const auto &elem : (*iter).mElements) {
             for (const auto &elem : (*iter).mElements) {
-                mAnimatedBones.push_back(AnimBoneDesc());
+                mAnimatedBones.emplace_back();
                 AnimBoneDesc &desc = mAnimatedBones.back();
                 AnimBoneDesc &desc = mAnimatedBones.back();
 
 
                 const char *sz = elem.szStart;
                 const char *sz = elem.szStart;
@@ -389,7 +386,7 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
             for (const auto &elem : (*iter).mElements) {
             for (const auto &elem : (*iter).mElements) {
                 const char *sz = elem.szStart;
                 const char *sz = elem.szStart;
 
 
-                mBaseFrames.push_back(BaseFrameDesc());
+                mBaseFrames.emplace_back();
                 BaseFrameDesc &desc = mBaseFrames.back();
                 BaseFrameDesc &desc = mBaseFrames.back();
 
 
                 AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
                 AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
@@ -401,7 +398,7 @@ MD5AnimParser::MD5AnimParser(SectionList &mSections) {
                 continue;
                 continue;
             }
             }
 
 
-            mFrames.push_back(FrameDesc());
+            mFrames.emplace_back();
             FrameDesc &desc = mFrames.back();
             FrameDesc &desc = mFrames.back();
             desc.iIndex = strtoul10((*iter).mGlobalValue.c_str());
             desc.iIndex = strtoul10((*iter).mGlobalValue.c_str());
 
 
@@ -459,7 +456,7 @@ MD5CameraParser::MD5CameraParser(SectionList &mSections) {
             for (const auto &elem : (*iter).mElements) {
             for (const auto &elem : (*iter).mElements) {
                 const char *sz = elem.szStart;
                 const char *sz = elem.szStart;
 
 
-                frames.push_back(CameraAnimFrameDesc());
+                frames.emplace_back();
                 CameraAnimFrameDesc &cur = frames.back();
                 CameraAnimFrameDesc &cur = frames.back();
                 AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
                 AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
                 AI_MD5_READ_TRIPLE(cur.vRotationQuat);
                 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
 /** @file  MD5Parser.h
  *  @brief Definition of the .MD5 parser class.
  *  @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/types.h>
 #include <assimp/ParsingUtils.h>
 #include <assimp/ParsingUtils.h>
 #include <vector>
 #include <vector>
-#include <stdint.h>
+#include <cstdint>
 
 
 struct aiFace;
 struct aiFace;
 
 
-namespace Assimp    {
-namespace MD5           {
+namespace Assimp {
+namespace MD5 {
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Represents a single element in a MD5 file
 /** Represents a single element in a MD5 file
  *
  *
  *  Elements are always contained in sections.
  *  Elements are always contained in sections.
 */
 */
-struct Element
-{
+struct Element {
     //! Points to the starting point of the element
     //! Points to the starting point of the element
     //! Whitespace at the beginning and at the end have been removed,
     //! Whitespace at the beginning and at the end have been removed,
     //! Elements are terminated with \0
     //! Elements are terminated with \0
@@ -75,15 +74,14 @@ struct Element
     unsigned int iLineNumber;
     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)
 /** Represents a section of a MD5 file (such as the mesh or the joints section)
  *
  *
  *  A section is always enclosed in { and } brackets.
  *  A section is always enclosed in { and } brackets.
 */
 */
-struct Section
-{
+struct Section {
     //! Original line number (can be used in error messages
     //! Original line number (can be used in error messages
     //! if a parsing error occurs)
     //! if a parsing error occurs)
     unsigned int iLineNumber;
     unsigned int iLineNumber;
@@ -99,13 +97,12 @@ struct Section
     std::string mGlobalValue;
     std::string mGlobalValue;
 };
 };
 
 
-typedef std::vector< Section> SectionList;
+using SectionList = std::vector<Section>;
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Basic information about a joint
 /** Basic information about a joint
 */
 */
-struct BaseJointDescription
-{
+struct BaseJointDescription {
     //! Name of the bone
     //! Name of the bone
     aiString mName;
     aiString mName;
 
 
@@ -116,8 +113,7 @@ struct BaseJointDescription
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Represents a bone (joint) descriptor in a MD5Mesh file
 /** Represents a bone (joint) descriptor in a MD5Mesh file
 */
 */
-struct BoneDesc : BaseJointDescription
-{
+struct BoneDesc : BaseJointDescription {
     //! Absolute position of the bone
     //! Absolute position of the bone
     aiVector3D mPositionXYZ;
     aiVector3D mPositionXYZ;
 
 
@@ -137,13 +133,12 @@ struct BoneDesc : BaseJointDescription
     unsigned int mMap;
     unsigned int mMap;
 };
 };
 
 
-typedef std::vector< BoneDesc > BoneList;
+using BoneList = std::vector<BoneDesc>;
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Represents a bone (joint) descriptor in a MD5Anim file
 /** Represents a bone (joint) descriptor in a MD5Anim file
 */
 */
-struct AnimBoneDesc : BaseJointDescription
-{
+struct AnimBoneDesc : BaseJointDescription {
     //! Flags (AI_MD5_ANIMATION_FLAG_xxx)
     //! Flags (AI_MD5_ANIMATION_FLAG_xxx)
     unsigned int iFlags;
     unsigned int iFlags;
 
 
@@ -151,35 +146,31 @@ struct AnimBoneDesc : BaseJointDescription
     unsigned int iFirstKeyIndex;
     unsigned int iFirstKeyIndex;
 };
 };
 
 
-typedef std::vector< AnimBoneDesc > AnimBoneList;
-
+using AnimBoneList = std::vector< AnimBoneDesc >;
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Represents a base frame descriptor in a MD5Anim file
 /** Represents a base frame descriptor in a MD5Anim file
 */
 */
-struct BaseFrameDesc
-{
+struct BaseFrameDesc {
     aiVector3D vPositionXYZ;
     aiVector3D vPositionXYZ;
     aiVector3D vRotationQuat;
     aiVector3D vRotationQuat;
 };
 };
 
 
-typedef std::vector< BaseFrameDesc > BaseFrameList;
+using BaseFrameList = std::vector<BaseFrameDesc>;
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Represents a camera animation frame in a MDCamera file
 /** Represents a camera animation frame in a MDCamera file
 */
 */
-struct CameraAnimFrameDesc : BaseFrameDesc
-{
+struct CameraAnimFrameDesc : BaseFrameDesc {
     float fFOV;
     float fFOV;
 };
 };
 
 
-typedef std::vector< CameraAnimFrameDesc > CameraFrameList;
+using CameraFrameList = std::vector<CameraAnimFrameDesc>;
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Represents a frame descriptor in a MD5Anim file
 /** Represents a frame descriptor in a MD5Anim file
 */
 */
-struct FrameDesc
-{
+struct FrameDesc {
     //! Index of the frame
     //! Index of the frame
     unsigned int iIndex;
     unsigned int iIndex;
 
 
@@ -187,15 +178,14 @@ struct FrameDesc
     std::vector< float > mValues;
     std::vector< float > mValues;
 };
 };
 
 
-typedef std::vector< FrameDesc > FrameList;
+using FrameList = std::vector<FrameDesc>;
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Represents a vertex  descriptor in a MD5 file
 /** Represents a vertex  descriptor in a MD5 file
 */
 */
 struct VertexDesc {
 struct VertexDesc {
     VertexDesc() AI_NO_EXCEPT
     VertexDesc() AI_NO_EXCEPT
-    : mFirstWeight(0)
-    , mNumWeights(0) {
+    : mFirstWeight(0), mNumWeights(0) {
         // empty
         // empty
     }
     }
 
 
@@ -210,13 +200,12 @@ struct VertexDesc {
     unsigned int mNumWeights;
     unsigned int mNumWeights;
 };
 };
 
 
-typedef std::vector< VertexDesc > VertexList;
+using VertexList = std::vector<VertexDesc>;
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Represents a vertex weight descriptor in a MD5 file
 /** Represents a vertex weight descriptor in a MD5 file
 */
 */
-struct WeightDesc
-{
+struct WeightDesc {
     //! Index of the bone to which this weight refers
     //! Index of the bone to which this weight refers
     unsigned int mBone;
     unsigned int mBone;
 
 
@@ -228,14 +217,13 @@ struct WeightDesc
     aiVector3D vOffsetPosition;
     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
 /** Represents a mesh in a MD5 file
 */
 */
-struct MeshDesc
-{
+struct MeshDesc {
     //! Weights of the mesh
     //! Weights of the mesh
     WeightList mWeights;
     WeightList mWeights;
 
 
@@ -249,7 +237,7 @@ struct MeshDesc
     aiString mShader;
     aiString mShader;
 };
 };
 
 
-typedef std::vector< MeshDesc > MeshList;
+using MeshList = std::vector<MeshDesc>;
 
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // Convert a quaternion to its usual representation
 // 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);
     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;
         out.w = 0.0f;
-    else out.w = std::sqrt (t);
+    } else {
+        out.w = std::sqrt (t);
+    }
 
 
     // Assimp convention.
     // Assimp convention.
     out.w *= -1.f;
     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
 /** Parses the data sections of a MD5 mesh file
 */
 */
-class MD5MeshParser
-{
+class MD5MeshParser {
 public:
 public:
-
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Constructs a new MD5MeshParser instance from an existing
     /** Constructs a new MD5MeshParser instance from an existing
      *  preparsed list of file sections.
      *  preparsed list of file sections.
@@ -297,10 +285,8 @@ public:
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Parses the data sections of a MD5 animation file
 /** Parses the data sections of a MD5 animation file
 */
 */
-class MD5AnimParser
-{
+class MD5AnimParser {
 public:
 public:
-
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Constructs a new MD5AnimParser instance from an existing
     /** Constructs a new MD5AnimParser instance from an existing
      *  preparsed list of file sections.
      *  preparsed list of file sections.
@@ -329,10 +315,8 @@ public:
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Parses the data sections of a MD5 camera animation file
 /** Parses the data sections of a MD5 camera animation file
 */
 */
-class MD5CameraParser
-{
+class MD5CameraParser {
 public:
 public:
-
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Constructs a new MD5CameraParser instance from an existing
     /** Constructs a new MD5CameraParser instance from an existing
      *  preparsed list of file sections.
      *  preparsed list of file sections.
@@ -341,7 +325,6 @@ public:
      */
      */
     explicit MD5CameraParser(SectionList& mSections);
     explicit MD5CameraParser(SectionList& mSections);
 
 
-
     //! Output frame rate
     //! Output frame rate
     float fFrameRate;
     float fFrameRate;
 
 
@@ -356,10 +339,8 @@ public:
 /** Parses the block structure of MD5MESH and MD5ANIM files (but does no
 /** Parses the block structure of MD5MESH and MD5ANIM files (but does no
  *  further processing)
  *  further processing)
 */
 */
-class MD5Parser
-{
+class MD5Parser {
 public:
 public:
-
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Constructs a new MD5Parser instance from an existing buffer.
     /** Constructs a new MD5Parser instance from an existing buffer.
      *
      *
@@ -392,13 +373,10 @@ public:
         return ReportWarning(warn, lineNumber);
         return ReportWarning(warn, lineNumber);
     }
     }
 
 
-public:
-
     //! List of all sections which have been read
     //! List of all sections which have been read
     SectionList mSections;
     SectionList mSections;
 
 
 private:
 private:
-
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Parses a file section. The current file pointer must be outside
     /** Parses a file section. The current file pointer must be outside
      *  of a section.
      *  of a section.
@@ -414,54 +392,63 @@ private:
      */
      */
     void ParseHeader();
     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* buffer;
+    char* bufferEnd;
     unsigned int fileSize;
     unsigned int fileSize;
     unsigned int lineNumber;
     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
 #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
 // Destructor, private as well
-MDCImporter::~MDCImporter() {
-    // empty
-}
+MDCImporter::~MDCImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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();
             pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
 
 
             // create a new shader
             // 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
         // need to create a default material
         else if (UINT_MAX == iDefaultMatIndex) {
         else if (UINT_MAX == iDefaultMatIndex) {
             pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
             pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
-            aszShaders.push_back(std::string());
+            aszShaders.emplace_back();
         }
         }
         // otherwise assign a reference to the default material
         // otherwise assign a reference to the default material
         else
         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) {
     separator_(separator) {
 }
 }
 
 
-UniqueNameGenerator::~UniqueNameGenerator() {
-}
+UniqueNameGenerator::~UniqueNameGenerator() = default;
 
 
 void UniqueNameGenerator::make_unique(std::vector<std::string> &names) {
 void UniqueNameGenerator::make_unique(std::vector<std::string> &names) {
     struct DuplicateInfo {
     struct DuplicateInfo {

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

@@ -98,9 +98,7 @@ MDLImporter::MDLImporter() :
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-MDLImporter::~MDLImporter() {
-    // empty
-}
+MDLImporter::~MDLImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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 iWidth,
         unsigned int iHeight) {
         unsigned int iHeight) {
     std::unique_ptr<aiTexture> pcNew;
     std::unique_ptr<aiTexture> pcNew;
+    if (szCurrent == nullptr) {
+        return;
+    }
 
 
     // get the type of the skin
     // get the type of the skin
     unsigned int iMasked = (unsigned int)(iType & 0xF);
     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/scene.h>
 #include <assimp/Importer.hpp>
 #include <assimp/Importer.hpp>
 
 
-#include <fstream>
+
 #include <iomanip>
 #include <iomanip>
 #include <memory>
 #include <memory>
+#include <sstream>
 
 
 static const aiImporterDesc desc = { "MMD Importer",
 static const aiImporterDesc desc = { "MMD Importer",
     "",
     "",
@@ -82,9 +83,7 @@ MMDImporter::MMDImporter() :
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 //  Destructor.
 //  Destructor.
-MMDImporter::~MMDImporter() {
-    // empty
-}
+MMDImporter::~MMDImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 //  Returns true, if file is an pmx file.
 //  Returns true, if file is an pmx file.
@@ -102,26 +101,32 @@ const aiImporterDesc *MMDImporter::GetInfo() const {
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 //  MMD import implementation
 //  MMD import implementation
 void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
 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.");
         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;
     pmx::PmxModel model;
-    model.Read(&fileStream);
+    model.Read(&iss);
 
 
     CreateDataFromImport(&model, pScene);
     CreateDataFromImport(&model, pScene);
 }
 }
@@ -264,43 +269,30 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
                 dynamic_cast<pmx::PmxVertexSkinningSDEF *>(v->skinning.get());
                 dynamic_cast<pmx::PmxVertexSkinningSDEF *>(v->skinning.get());
         switch (v->skinning_type) {
         switch (v->skinning_type) {
         case pmx::PmxVertexSkinningType::BDEF1:
         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;
             break;
         case pmx::PmxVertexSkinningType::BDEF2:
         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;
             break;
         case pmx::PmxVertexSkinningType::BDEF4:
         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;
             break;
         case pmx::PmxVertexSkinningType::SDEF: // TODO: how to use sdef_c, sdef_r0,
         case pmx::PmxVertexSkinningType::SDEF: // TODO: how to use sdef_c, sdef_r0,
                 // sdef_r1?
                 // 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;
             break;
         case pmx::PmxVertexSkinningType::QDEF:
         case pmx::PmxVertexSkinningType::QDEF:
             const auto vsQDEF_ptr =
             const auto vsQDEF_ptr =
                     dynamic_cast<pmx::PmxVertexSkinningQDEF *>(v->skinning.get());
                     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;
             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
 Copyright (c) 2006-2022, assimp team
 
 
-
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 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 <fstream>
 #include "MMDCpp14.h"
 #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:
 	public:
 		virtual void Read(std::istream *stream, PmxSetting *setting) = 0;
 		virtual void Read(std::istream *stream, PmxSetting *setting) = 0;
-		virtual ~PmxVertexSkinning() {}
+		virtual ~PmxVertexSkinning() = default;
 	};
 	};
 
 
 	class PmxVertexSkinningBDEF1 : public PmxVertexSkinning
 	class PmxVertexSkinningBDEF1 : public PmxVertexSkinning
@@ -357,6 +357,8 @@ namespace pmx
 	{
 	{
 	public:
 	public:
 		void virtual Read(std::istream *stream, PmxSetting *setting) = 0;
 		void virtual Read(std::istream *stream, PmxSetting *setting) = 0;
+
+        virtual ~PmxMorphOffset() = default;
 	};
 	};
 
 
 	class PmxMorphVertexOffset : public PmxMorphOffset
 	class PmxMorphVertexOffset : public PmxMorphOffset

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

@@ -86,8 +86,7 @@ MS3DImporter::MS3DImporter()
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-MS3DImporter::~MS3DImporter()
-{}
+MS3DImporter::~MS3DImporter() = default;
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
 bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
 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
         // if one of the groups has no material assigned, but there are other
         // groups with materials, a default material needs to be added (
         // groups with materials, a default material needs to be added (
         // scenepreprocessor adds a default material only if nummat==0).
         // scenepreprocessor adds a default material only if nummat==0).
-        materials.push_back(TempMaterial());
+        materials.emplace_back();
         TempMaterial& m = materials.back();
         TempMaterial& m = materials.back();
 
 
         strcpy(m.name,"<MS3D_DefaultMat>");
         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
 // Constructor to be privately used by Importer
-NDOImporter::NDOImporter()
-{}
+NDOImporter::NDOImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-NDOImporter::~NDOImporter()
-{}
+NDOImporter::~NDOImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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");
         ASSIMP_LOG_INFO("NDO file format is 1.2");
     }
     }
     else {
     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 */
     reader.IncPtr(2); /* skip flags */
@@ -169,7 +169,7 @@ void NDOImporter::InternReadFile( const std::string& pFile,
         obj.edges.reserve(temp);
         obj.edges.reserve(temp);
         for (unsigned int e = 0; e < temp; ++e) {
         for (unsigned int e = 0; e < temp; ++e) {
 
 
-            obj.edges.push_back(Edge());
+            obj.edges.emplace_back();
             Edge& edge = obj.edges.back();
             Edge& edge = obj.edges.back();
 
 
             for (unsigned int i = 0; i< 8; ++i) {
             for (unsigned int i = 0; i< 8; ++i) {
@@ -186,7 +186,7 @@ void NDOImporter::InternReadFile( const std::string& pFile,
         obj.faces.reserve(temp);
         obj.faces.reserve(temp);
         for (unsigned int e = 0; e < temp; ++e) {
         for (unsigned int e = 0; e < temp; ++e) {
 
 
-            obj.faces.push_back(Face());
+            obj.faces.emplace_back();
             Face& face = obj.faces.back();
             Face& face = obj.faces.back();
 
 
             face.elem = file_format >= 12 ? reader.GetU4() : reader.GetU2();
             face.elem = file_format >= 12 ? reader.GetU4() : reader.GetU2();
@@ -197,7 +197,7 @@ void NDOImporter::InternReadFile( const std::string& pFile,
         obj.vertices.reserve(temp);
         obj.vertices.reserve(temp);
         for (unsigned int e = 0; e < temp; ++e) {
         for (unsigned int e = 0; e < temp; ++e) {
 
 
-            obj.vertices.push_back(Vertex());
+            obj.vertices.emplace_back();
             Vertex& v = obj.vertices.back();
             Vertex& v = obj.vertices.back();
 
 
             v.num = file_format >= 12 ? reader.GetU4() : reader.GetU2();
             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
 // Constructor to be privately used by Importer
-NFFImporter::NFFImporter() {}
+NFFImporter::NFFImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-NFFImporter::~NFFImporter() {}
+NFFImporter::~NFFImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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
         // 'matdef' starts a new material in the file
         else if (TokenMatch(sz, "matdef", 6)) {
         else if (TokenMatch(sz, "matdef", 6)) {
             // add a new material to the list
             // add a new material to the list
-            output.push_back(ShadingInfo());
+            output.emplace_back();
             curShader = &output.back();
             curShader = &output.back();
 
 
             // parse the name of the material
             // parse the name of the material
@@ -549,7 +549,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
                         }
                         }
                     }
                     }
                     if (!mesh) {
                     if (!mesh) {
-                        meshes.push_back(MeshInfo(PatchType_Simple, false));
+                        meshes.emplace_back(PatchType_Simple, false);
                         mesh = &meshes.back();
                         mesh = &meshes.back();
                         mesh->matIndex = matIdx;
                         mesh->matIndex = matIdx;
 
 
@@ -614,7 +614,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
                     }
                     }
 
 
                     if (!currentMeshWithUVCoords) {
                     if (!currentMeshWithUVCoords) {
-                        meshesWithUVCoords.push_back(MeshInfo(PatchType_UVAndNormals));
+                        meshesWithUVCoords.emplace_back(PatchType_UVAndNormals);
                         currentMeshWithUVCoords = &meshesWithUVCoords.back();
                         currentMeshWithUVCoords = &meshesWithUVCoords.back();
                         currentMeshWithUVCoords->shader = s;
                         currentMeshWithUVCoords->shader = s;
                     }
                     }
@@ -631,7 +631,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
                     }
                     }
 
 
                     if (!currentMeshWithNormals) {
                     if (!currentMeshWithNormals) {
-                        meshesWithNormals.push_back(MeshInfo(PatchType_Normals));
+                        meshesWithNormals.emplace_back(PatchType_Normals);
                         currentMeshWithNormals = &meshesWithNormals.back();
                         currentMeshWithNormals = &meshesWithNormals.back();
                         currentMeshWithNormals->shader = s;
                         currentMeshWithNormals->shader = s;
                     }
                     }
@@ -649,7 +649,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
                     }
                     }
 
 
                     if (!currentMesh) {
                     if (!currentMesh) {
-                        meshes.push_back(MeshInfo(PatchType_Simple));
+                        meshes.emplace_back(PatchType_Simple);
                         currentMesh = &meshes.back();
                         currentMesh = &meshes.back();
                         currentMesh->shader = s;
                         currentMesh->shader = s;
                     }
                     }
@@ -749,7 +749,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
             }
             }
             // 'l' - light source
             // 'l' - light source
             else if (TokenMatch(sz, "l", 1)) {
             else if (TokenMatch(sz, "l", 1)) {
-                lights.push_back(Light());
+                lights.emplace_back();
                 Light &light = lights.back();
                 Light &light = lights.back();
 
 
                 AI_NFF_PARSE_TRIPLE(light.position);
                 AI_NFF_PARSE_TRIPLE(light.position);
@@ -758,7 +758,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
             }
             }
             // 's' - sphere
             // 's' - sphere
             else if (TokenMatch(sz, "s", 1)) {
             else if (TokenMatch(sz, "s", 1)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
@@ -774,7 +774,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
             }
             }
             // 'dod' - dodecahedron
             // 'dod' - dodecahedron
             else if (TokenMatch(sz, "dod", 3)) {
             else if (TokenMatch(sz, "dod", 3)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
@@ -791,7 +791,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
 
 
             // 'oct' - octahedron
             // 'oct' - octahedron
             else if (TokenMatch(sz, "oct", 3)) {
             else if (TokenMatch(sz, "oct", 3)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
@@ -808,7 +808,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
 
 
             // 'tet' - tetrahedron
             // 'tet' - tetrahedron
             else if (TokenMatch(sz, "tet", 3)) {
             else if (TokenMatch(sz, "tet", 3)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
                 curMesh.shader.mapping = aiTextureMapping_SPHERE;
@@ -825,7 +825,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
 
 
             // 'hex' - hexahedron
             // 'hex' - hexahedron
             else if (TokenMatch(sz, "hex", 3)) {
             else if (TokenMatch(sz, "hex", 3)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_BOX;
                 curMesh.shader.mapping = aiTextureMapping_BOX;
@@ -841,7 +841,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
             }
             }
             // 'c' - cone
             // 'c' - cone
             else if (TokenMatch(sz, "c", 1)) {
             else if (TokenMatch(sz, "c", 1)) {
-                meshesLocked.push_back(MeshInfo(PatchType_Simple, true));
+                meshesLocked.emplace_back(PatchType_Simple, true);
                 MeshInfo &curMesh = meshesLocked.back();
                 MeshInfo &curMesh = meshesLocked.back();
                 curMesh.shader = s;
                 curMesh.shader = s;
                 curMesh.shader.mapping = aiTextureMapping_CYLINDER;
                 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
 // Constructor to be privately used by Importer
-OFFImporter::OFFImporter()
-{}
+OFFImporter::OFFImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
 // Destructor, private as well
-OFFImporter::~OFFImporter()
-{}
+OFFImporter::~OFFImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // 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() {
 std::string ObjExporter::GetMaterialLibName() {
@@ -271,12 +269,12 @@ void ObjExporter::WriteGeometryFile(bool noMtl) {
     if ( !useVc ) {
     if ( !useVc ) {
         mOutput << "# " << vp.size() << " vertex positions" << endl;
         mOutput << "# " << vp.size() << " vertex positions" << endl;
         for ( const vertexData& v : vp ) {
         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 {
     } else {
         mOutput << "# " << vp.size() << " vertex positions and colors" << endl;
         mOutput << "# " << vp.size() << " vertex positions and colors" << endl;
         for ( const vertexData& v : vp ) {
         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;
     mOutput << endl;
@@ -333,7 +331,7 @@ void ObjExporter::WriteGeometryFile(bool noMtl) {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) {
 void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) {
-    mMeshes.push_back(MeshInstance() );
+    mMeshes.emplace_back();
     MeshInstance& mesh = mMeshes.back();
     MeshInstance& mesh = mMeshes.back();
 
 
     if ( nullptr != m->mColors[ 0 ] ) {
     if ( nullptr != m->mColors[ 0 ] ) {

Деякі файли не було показано, через те що забагато файлів було змінено