ソースを参照

Updated assimp to latest

Areloch 6 年 前
コミット
161bf7f83b
100 ファイル変更4247 行追加2750 行削除
  1. 19 17
      Engine/lib/assimp/code/3DSConverter.cpp
  2. 5 4
      Engine/lib/assimp/code/3DSExporter.cpp
  3. 4 3
      Engine/lib/assimp/code/3DSExporter.h
  4. 105 48
      Engine/lib/assimp/code/3DSHelper.h
  5. 62 63
      Engine/lib/assimp/code/3DSLoader.cpp
  6. 4 3
      Engine/lib/assimp/code/3DSLoader.h
  7. 17 2
      Engine/lib/assimp/code/3MFXmlTags.h
  8. 25 24
      Engine/lib/assimp/code/ACLoader.cpp
  9. 3 2
      Engine/lib/assimp/code/ACLoader.h
  10. 4 3
      Engine/lib/assimp/code/AMFImporter.cpp
  11. 68 199
      Engine/lib/assimp/code/AMFImporter.hpp
  12. 2 1
      Engine/lib/assimp/code/AMFImporter_Geometry.cpp
  13. 6 5
      Engine/lib/assimp/code/AMFImporter_Macro.hpp
  14. 61 42
      Engine/lib/assimp/code/AMFImporter_Material.cpp
  15. 64 124
      Engine/lib/assimp/code/AMFImporter_Node.hpp
  16. 10 8
      Engine/lib/assimp/code/AMFImporter_Postprocess.cpp
  17. 20 20
      Engine/lib/assimp/code/ASELoader.cpp
  18. 3 2
      Engine/lib/assimp/code/ASELoader.h
  19. 36 33
      Engine/lib/assimp/code/ASEParser.cpp
  20. 127 103
      Engine/lib/assimp/code/ASEParser.h
  21. 539 516
      Engine/lib/assimp/code/AssbinExporter.cpp
  22. 10 2
      Engine/lib/assimp/code/AssbinExporter.h
  23. 181 188
      Engine/lib/assimp/code/AssbinLoader.cpp
  24. 25 23
      Engine/lib/assimp/code/AssbinLoader.h
  25. 7 6
      Engine/lib/assimp/code/Assimp.cpp
  26. 2 2
      Engine/lib/assimp/code/AssimpCExport.cpp
  27. 13 6
      Engine/lib/assimp/code/AssxmlExporter.cpp
  28. 2 1
      Engine/lib/assimp/code/AssxmlExporter.h
  29. 41 22
      Engine/lib/assimp/code/B3DImporter.cpp
  30. 8 6
      Engine/lib/assimp/code/B3DImporter.h
  31. 79 46
      Engine/lib/assimp/code/BVHLoader.cpp
  32. 7 3
      Engine/lib/assimp/code/BVHLoader.h
  33. 70 55
      Engine/lib/assimp/code/BaseImporter.cpp
  34. 5 4
      Engine/lib/assimp/code/BaseProcess.cpp
  35. 5 8
      Engine/lib/assimp/code/BaseProcess.h
  36. 6 4
      Engine/lib/assimp/code/Bitmap.cpp
  37. 1 1
      Engine/lib/assimp/code/BlenderBMesh.h
  38. 189 0
      Engine/lib/assimp/code/BlenderCustomData.cpp
  39. 89 0
      Engine/lib/assimp/code/BlenderCustomData.h
  40. 15 16
      Engine/lib/assimp/code/BlenderDNA.cpp
  41. 40 6
      Engine/lib/assimp/code/BlenderDNA.h
  42. 107 6
      Engine/lib/assimp/code/BlenderDNA.inl
  43. 8 3
      Engine/lib/assimp/code/BlenderIntermediate.h
  44. 81 29
      Engine/lib/assimp/code/BlenderLoader.cpp
  45. 4 3
      Engine/lib/assimp/code/BlenderLoader.h
  46. 3 30
      Engine/lib/assimp/code/BlenderModifier.cpp
  47. 30 32
      Engine/lib/assimp/code/BlenderModifier.h
  48. 46 2
      Engine/lib/assimp/code/BlenderScene.cpp
  49. 81 2
      Engine/lib/assimp/code/BlenderScene.h
  50. 11 0
      Engine/lib/assimp/code/BlenderSceneGen.h
  51. 2 1
      Engine/lib/assimp/code/BlenderTessellator.cpp
  52. 4 3
      Engine/lib/assimp/code/BlenderTessellator.h
  53. 1 1
      Engine/lib/assimp/code/C4DImporter.cpp
  54. 2 2
      Engine/lib/assimp/code/C4DImporter.h
  55. 2 1
      Engine/lib/assimp/code/CInterfaceIOWrapper.cpp
  56. 2 1
      Engine/lib/assimp/code/CInterfaceIOWrapper.h
  57. 126 71
      Engine/lib/assimp/code/CMakeLists.txt
  58. 36 88
      Engine/lib/assimp/code/COBLoader.cpp
  59. 5 24
      Engine/lib/assimp/code/COBLoader.h
  60. 3 2
      Engine/lib/assimp/code/COBScene.h
  61. 8 7
      Engine/lib/assimp/code/CSMLoader.cpp
  62. 3 2
      Engine/lib/assimp/code/CSMLoader.h
  63. 11 10
      Engine/lib/assimp/code/CalcTangentsProcess.cpp
  64. 2 1
      Engine/lib/assimp/code/CalcTangentsProcess.h
  65. 36 21
      Engine/lib/assimp/code/ColladaExporter.cpp
  66. 4 3
      Engine/lib/assimp/code/ColladaExporter.h
  67. 6 4
      Engine/lib/assimp/code/ColladaHelper.h
  68. 133 103
      Engine/lib/assimp/code/ColladaLoader.cpp
  69. 4 2
      Engine/lib/assimp/code/ColladaLoader.h
  70. 50 34
      Engine/lib/assimp/code/ColladaParser.cpp
  71. 7 3
      Engine/lib/assimp/code/ColladaParser.h
  72. 9 8
      Engine/lib/assimp/code/ComputeUVMappingProcess.cpp
  73. 2 1
      Engine/lib/assimp/code/ComputeUVMappingProcess.h
  74. 111 29
      Engine/lib/assimp/code/ConvertToLHProcess.cpp
  75. 2 1
      Engine/lib/assimp/code/ConvertToLHProcess.h
  76. 1 1
      Engine/lib/assimp/code/CreateAnimMesh.cpp
  77. 78 8
      Engine/lib/assimp/code/D3MFExporter.cpp
  78. 7 4
      Engine/lib/assimp/code/D3MFExporter.h
  79. 234 85
      Engine/lib/assimp/code/D3MFImporter.cpp
  80. 3 2
      Engine/lib/assimp/code/D3MFImporter.h
  81. 44 33
      Engine/lib/assimp/code/D3MFOpcPackage.cpp
  82. 10 7
      Engine/lib/assimp/code/D3MFOpcPackage.h
  83. 28 42
      Engine/lib/assimp/code/DXFHelper.h
  84. 126 127
      Engine/lib/assimp/code/DXFLoader.cpp
  85. 16 21
      Engine/lib/assimp/code/DXFLoader.h
  86. 7 8
      Engine/lib/assimp/code/DeboneProcess.cpp
  87. 2 1
      Engine/lib/assimp/code/DeboneProcess.h
  88. 4 2
      Engine/lib/assimp/code/DefaultIOStream.cpp
  89. 91 33
      Engine/lib/assimp/code/DefaultIOSystem.cpp
  90. 59 70
      Engine/lib/assimp/code/DefaultLogger.cpp
  91. 3 4
      Engine/lib/assimp/code/DefaultProgressHandler.h
  92. 109 0
      Engine/lib/assimp/code/DropFaceNormalsProcess.cpp
  93. 33 57
      Engine/lib/assimp/code/DropFaceNormalsProcess.h
  94. 152 0
      Engine/lib/assimp/code/EmbedTexturesProcess.cpp
  95. 85 0
      Engine/lib/assimp/code/EmbedTexturesProcess.h
  96. 107 61
      Engine/lib/assimp/code/Exporter.cpp
  97. 4 3
      Engine/lib/assimp/code/FBXAnimation.cpp
  98. 35 29
      Engine/lib/assimp/code/FBXBinaryTokenizer.cpp
  99. 86 0
      Engine/lib/assimp/code/FBXCommon.h
  100. 2 1
      Engine/lib/assimp/code/FBXCompileConfig.h

+ 19 - 17
Engine/lib/assimp/code/3DSConverter.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -50,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "TargetAnimation.h"
 #include <assimp/scene.h>
 #include <assimp/DefaultLogger.hpp>
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
 #include <memory>
 #include <cctype>
 
@@ -71,7 +72,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
     unsigned int idx( NotSet );
     for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
     {
-        std::string s = mScene->mMaterials[i].mName;
+        std::string &s = mScene->mMaterials[i].mName;
         for ( std::string::iterator it = s.begin(); it != s.end(); ++it ) {
             *it = static_cast< char >( ::tolower( *it ) );
         }
@@ -119,7 +120,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
             else if ( (*a) >= mScene->mMaterials.size())
             {
                 (*a) = idx;
-                DefaultLogger::get()->warn("Material index overflow in 3DS file. Using default material");
+                ASSIMP_LOG_WARN("Material index overflow in 3DS file. Using default material");
                 ++cnt;
             }
         }
@@ -127,12 +128,11 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
     if (cnt && idx == mScene->mMaterials.size())
     {
         // We need to create our own default material
-        D3DS::Material sMat;
+        D3DS::Material sMat("%%%DEFAULT");
         sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f);
-        sMat.mName = "%%%DEFAULT";
         mScene->mMaterials.push_back(sMat);
 
-        DefaultLogger::get()->info("3DS: Generating default material");
+        ASSIMP_LOG_INFO("3DS: Generating default material");
     }
 }
 
@@ -147,12 +147,12 @@ void Discreet3DSImporter::CheckIndices(D3DS::Mesh& sMesh)
         {
             if ((*i).mIndices[a] >= sMesh.mPositions.size())
             {
-                DefaultLogger::get()->warn("3DS: Vertex index overflow)");
+                ASSIMP_LOG_WARN("3DS: Vertex index overflow)");
                 (*i).mIndices[a] = (uint32_t)sMesh.mPositions.size()-1;
             }
             if ( !sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size())
             {
-                DefaultLogger::get()->warn("3DS: Texture coordinate index overflow)");
+                ASSIMP_LOG_WARN("3DS: Texture coordinate index overflow)");
                 (*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size()-1;
             }
         }
@@ -204,8 +204,9 @@ void CopyTexture(aiMaterial& mat, D3DS::Texture& texture, aiTextureType type)
         mat.AddProperty<ai_real>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
 
     // Setup the texture mapping mode
-    mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
-    mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0));
+    int mapMode = static_cast<int>(texture.mMapMode);
+    mat.AddProperty<int>(&mapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
+    mat.AddProperty<int>(&mapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0));
 
     // Mirroring - double the scaling values
     // FIXME: this is not really correct ...
@@ -313,7 +314,8 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
         case D3DS::Discreet3DS::Blinn :
             eShading = aiShadingMode_Blinn; break;
     }
-    mat.AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
+    int eShading_ = static_cast<int>(eShading);
+    mat.AddProperty<int>(&eShading_, 1, AI_MATKEY_SHADING_MODEL);
 
     // DIFFUSE texture
     if( oldMat.sTexDiffuse.mMapName.length() > 0)
@@ -497,7 +499,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
                         pvCurrent->x *= -1.f;
                         t2->x *= -1.f;
                     }
-                    DefaultLogger::get()->info("3DS: Flipping mesh X-Axis");
+                    ASSIMP_LOG_INFO("3DS: Flipping mesh X-Axis");
                 }
 
                 // Handle pivot point
@@ -573,11 +575,11 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
         pcIn->aTargetPositionKeys.size() > 1)
     {
         aiAnimation* anim = pcSOut->mAnimations[0];
-        ai_assert(NULL != anim);
+        ai_assert(nullptr != anim);
 
         if (pcIn->aCameraRollKeys.size() > 1)
         {
-            DefaultLogger::get()->debug("3DS: Converting camera roll track ...");
+            ASSIMP_LOG_DEBUG("3DS: Converting camera roll track ...");
 
             // Camera roll keys - in fact they're just rotations
             // around the camera's z axis. The angles are given
@@ -597,7 +599,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
 #if 0
         if (pcIn->aTargetPositionKeys.size() > 1)
         {
-            DefaultLogger::get()->debug("3DS: Converting target track ...");
+            ASSIMP_LOG_DEBUG("3DS: Converting target track ...");
 
             // Camera or spot light - need to convert the separate
             // target position channel to our representation
@@ -743,7 +745,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
         //   |       |       |            |         |
         // MESH_0  MESH_1  MESH_2  ...  MESH_N    CAMERA_0 ....
         //
-        DefaultLogger::get()->warn("No hierarchy information has been found in the file. ");
+        ASSIMP_LOG_WARN("No hierarchy information has been found in the file. ");
 
         pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes +
             static_cast<unsigned int>(mScene->mCameras.size() + mScene->mLights.size());

+ 5 - 4
Engine/lib/assimp/code/3DSExporter.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -47,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "3DSHelper.h"
 #include <assimp/SceneCombiner.h>
 #include "SplitLargeMeshes.h"
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/Exporter.hpp>
@@ -183,7 +184,7 @@ void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScen
 } // end of namespace Assimp
 
 // ------------------------------------------------------------------------------------------------
-Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr<IOStream> outfile, const aiScene* scene)
+Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr<IOStream> &outfile, const aiScene* scene)
 : scene(scene)
 , writer(outfile)
 {
@@ -380,7 +381,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type
 
     // TODO: handle embedded textures properly
     if (path.data[0] == '*') {
-        DefaultLogger::get()->error("Ignoring embedded texture for export: " + std::string(path.C_Str()));
+        ASSIMP_LOG_ERROR("Ignoring embedded texture for export: " + std::string(path.C_Str()));
         return;
     }
 

+ 4 - 3
Engine/lib/assimp/code/3DSExporter.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -48,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <map>
 #include <memory>
 
-#include "StreamWriter.h"
+#include <assimp/StreamWriter.h>
 #include <assimp/material.h>
 
 struct aiScene;
@@ -66,7 +67,7 @@ namespace Assimp
 // ------------------------------------------------------------------------------------------------
 class Discreet3DSExporter {
 public:
-    Discreet3DSExporter(std::shared_ptr<IOStream> outfile, const aiScene* pScene);
+    Discreet3DSExporter(std::shared_ptr<IOStream> &outfile, const aiScene* pScene);
     ~Discreet3DSExporter();
 
 private:

+ 105 - 48
Engine/lib/assimp/code/3DSHelper.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -44,10 +45,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_3DSFILEHELPER_H_INC
 #define AI_3DSFILEHELPER_H_INC
 
-#include "SpatialSort.h"
-#include "SmoothingGroups.h"
-#include "StringUtils.h"
-#include "qnan.h"
+#include <assimp/SpatialSort.h>
+#include <assimp/SmoothingGroups.h>
+#include <assimp/StringUtils.h>
+#include <assimp/qnan.h>
 #include <assimp/material.h>
 #include <assimp/camera.h>
 #include <assimp/light.h>
@@ -57,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp    {
 namespace D3DS  {
 
-#include "./../include/assimp/Compiler/pushpack1.h"
+#include <assimp/Compiler/pushpack1.h>
 
 // ---------------------------------------------------------------------------
 /** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
@@ -65,7 +66,7 @@ namespace D3DS  {
 */
 class Discreet3DS {
 private:
-    Discreet3DS() {
+    Discreet3DS() AI_NO_EXCEPT {
         // empty
     }
 
@@ -327,19 +328,17 @@ struct Face : public FaceWithSmoothingGroup
 
 // ---------------------------------------------------------------------------
 /** Helper structure representing a texture */
-struct Texture
-{
+struct Texture {
     //! Default constructor
-    Texture()
-        : mOffsetU  (0.0)
-        , mOffsetV  (0.0)
-        , mScaleU   (1.0)
-        , mScaleV   (1.0)
-        , mRotation (0.0)
-        , mMapMode  (aiTextureMapMode_Wrap)
-        , bPrivate()
-        , iUVSrc    (0)
-    {
+    Texture() AI_NO_EXCEPT
+    : mOffsetU  (0.0)
+    , mOffsetV  (0.0)
+    , mScaleU   (1.0)
+    , mScaleV   (1.0)
+    , mRotation (0.0)
+    , mMapMode  (aiTextureMapMode_Wrap)
+    , bPrivate()
+    , iUVSrc    (0) {
         mTextureBlend = get_qnan();
     }
 
@@ -364,15 +363,20 @@ struct Texture
     int iUVSrc;
 };
 
-#include "./../include/assimp/Compiler/poppack1.h"
+#include <assimp/Compiler/poppack1.h>
 
 // ---------------------------------------------------------------------------
 /** Helper structure representing a 3ds material */
 struct Material
 {
-    //! Default constructor. Builds a default name for the material
-    Material()
-    : mDiffuse            ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
+    //! Default constructor has been deleted
+    Material() = delete;
+
+
+    //! Constructor with explicit name
+    explicit Material(const std::string &name)
+    : mName(name)
+    , mDiffuse            ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
     , mSpecularExponent   ( ai_real( 0.0 ) )
     , mShininessStrength  ( ai_real( 1.0 ) )
     , mShading(Discreet3DS::Gouraud)
@@ -380,13 +384,70 @@ struct Material
     , mBumpHeight         ( ai_real( 1.0 ) )
     , mTwoSided           (false)
     {
-        static int iCnt = 0;
+    }
 
-        char szTemp[128];
-        ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
-        mName = szTemp;
+
+    Material(const Material &other)            = default;
+    Material &operator=(const Material &other) = default;
+
+
+    //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
+    Material(Material &&other) AI_NO_EXCEPT
+    : mName(std::move(other.mName))
+    , mDiffuse(std::move(other.mDiffuse))
+    , mSpecularExponent(std::move(other.mSpecularExponent))
+    , mShininessStrength(std::move(other.mShininessStrength))
+    , mSpecular(std::move(other.mSpecular))
+    , mAmbient(std::move(other.mAmbient))
+    , mShading(std::move(other.mShading))
+    , mTransparency(std::move(other.mTransparency))
+    , sTexDiffuse(std::move(other.sTexDiffuse))
+    , sTexOpacity(std::move(other.sTexOpacity))
+    , sTexSpecular(std::move(other.sTexSpecular))
+    , sTexReflective(std::move(other.sTexReflective))
+    , sTexBump(std::move(other.sTexBump))
+    , sTexEmissive(std::move(other.sTexEmissive))
+    , sTexShininess(std::move(other.sTexShininess))
+    , mBumpHeight(std::move(other.mBumpHeight))
+    , mEmissive(std::move(other.mEmissive))
+    , sTexAmbient(std::move(other.sTexAmbient))
+    , mTwoSided(std::move(other.mTwoSided))
+    {
     }
 
+
+    Material &operator=(Material &&other) AI_NO_EXCEPT {
+        if (this == &other) {
+            return *this;
+        }
+
+        mName = std::move(other.mName);
+        mDiffuse = std::move(other.mDiffuse);
+        mSpecularExponent = std::move(other.mSpecularExponent);
+        mShininessStrength = std::move(other.mShininessStrength),
+        mSpecular = std::move(other.mSpecular);
+        mAmbient = std::move(other.mAmbient);
+        mShading = std::move(other.mShading);
+        mTransparency = std::move(other.mTransparency);
+        sTexDiffuse = std::move(other.sTexDiffuse);
+        sTexOpacity = std::move(other.sTexOpacity);
+        sTexSpecular = std::move(other.sTexSpecular);
+        sTexReflective = std::move(other.sTexReflective);
+        sTexBump = std::move(other.sTexBump);
+        sTexEmissive = std::move(other.sTexEmissive);
+        sTexShininess = std::move(other.sTexShininess);
+        mBumpHeight = std::move(other.mBumpHeight);
+        mEmissive = std::move(other.mEmissive);
+        sTexAmbient = std::move(other.sTexAmbient);
+        mTwoSided = std::move(other.mTwoSided);
+
+        return *this;
+    }
+
+
+    virtual ~Material() {}
+
+
     //! Name of the material
     std::string mName;
     //! Diffuse color of the material
@@ -432,17 +493,16 @@ struct Material
 /** Helper structure to represent a 3ds file mesh */
 struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
 {
-    //! Default constructor
-    Mesh()
-    {
-        static int iCnt = 0;
+    //! Default constructor has been deleted
+    Mesh() = delete;
 
-        // Generate a default name for the mesh
-        char szTemp[128];
-        ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
-        mName = szTemp;
+    //! Constructor with explicit name
+    explicit Mesh(const std::string &name)
+    : mName(name)
+    {
     }
 
+
     //! Name of the mesh
     std::string mName;
 
@@ -488,25 +548,22 @@ struct aiFloatKey
 /** Helper structure to represent a 3ds file node */
 struct Node
 {
-    Node():
-    	mParent(NULL)
-		,	mInstanceNumber(0)
-		,	mHierarchyPos		(0)
-		,	mHierarchyIndex		(0)
-		,	mInstanceCount		(1)
+    Node() = delete;
+
+    explicit Node(const std::string &name)
+    : mParent(NULL)
+    , mName(name)
+    , mInstanceNumber(0)
+    , mHierarchyPos       (0)
+    , mHierarchyIndex     (0)
+    , mInstanceCount      (1)
     {
-        static int iCnt = 0;
-
-        // Generate a default name for the node
-        char szTemp[128];
-        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
-        mName = szTemp;
-
         aRotationKeys.reserve (20);
         aPositionKeys.reserve (20);
         aScalingKeys.reserve  (20);
     }
 
+
     ~Node()
     {
         for (unsigned int i = 0; i < mChildren.size();++i)

+ 62 - 63
Engine/lib/assimp/code/3DSLoader.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -51,12 +52,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // internal headers
 #include "3DSLoader.h"
-#include "Macros.h"
+#include <assimp/Macros.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/scene.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/importerdesc.h>
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
 
 using namespace Assimp;
 
@@ -70,7 +71,7 @@ static const aiImporterDesc desc = {
     0,
     0,
     0,
-    "3ds prj"
+	"3ds prj"
 };
 
 
@@ -105,29 +106,31 @@ static const aiImporterDesc desc = {
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 Discreet3DSImporter::Discreet3DSImporter()
-    : stream(),
-    mLastNodeIndex(),
-    mCurrentNode(),
-    mRootNode(),
-    mScene(),
-    mMasterScale(),
-    bHasBG(),
-    bIsPrj()
-{}
+: stream()
+, mLastNodeIndex()
+, mCurrentNode()
+, mRootNode()
+, mScene()
+, mMasterScale()
+, bHasBG()
+, bIsPrj() {
+    // empty
+}
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-Discreet3DSImporter::~Discreet3DSImporter()
-{}
+Discreet3DSImporter::~Discreet3DSImporter() {
+    // empty
+}
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
-bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
+bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
     std::string extension = GetExtension(pFile);
-    if(extension == "3ds" || extension == "prj" ) {
+	if(extension == "3ds" || extension == "prj") {
         return true;
     }
+
     if (!extension.length() || checkSig) {
         uint16_t token[3];
         token[0] = 0x4d4d;
@@ -158,19 +161,21 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
     aiScene* pScene, IOSystem* pIOHandler)
 {
     StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
-    this->stream = &stream;
 
     // We should have at least one chunk
     if (stream.GetRemainingSize() < 16) {
         throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile);
     }
+    this->stream = &stream;
 
     // Allocate our temporary 3DS representation
-    mScene = new D3DS::Scene();
+    D3DS::Scene _scene;
+    mScene = &_scene;
 
     // Initialize members
+    D3DS::Node _rootNode("UNNAMED");
     mLastNodeIndex             = -1;
-    mCurrentNode               = new D3DS::Node();
+    mCurrentNode               = &_rootNode;
     mRootNode                  = mCurrentNode;
     mRootNode->mHierarchyPos   = -1;
     mRootNode->mHierarchyIndex = -1;
@@ -190,7 +195,6 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
     // file.
     for (auto &mesh : mScene->mMeshes) {
         if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0)  {
-            delete mScene;
             throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile);
         }
         CheckIndices(mesh);
@@ -198,7 +202,7 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
         ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh);
     }
 
-    // Replace all occurrences of the default material with a
+    // Replace all occurences of the default material with a
     // valid material. Generate it if no material containing
     // DEFAULT in its name has been found in the file
     ReplaceDefaultMaterial();
@@ -209,16 +213,14 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
     ConvertScene(pScene);
 
     // Generate the node graph for the scene. This is a little bit
-    // tricky since we'll need to split some meshes into submeshes
+    // tricky since we'll need to split some meshes into sub-meshes
     GenerateNodeGraph(pScene);
 
     // Now apply the master scaling factor to the scene
     ApplyMasterScale(pScene);
 
-    // Delete our internal scene representation and the root
-    // node, so the whole hierarchy will follow
-    delete mRootNode;
-    delete mScene;
+    // Our internal scene representation and the root
+    // node will be automatically deleted, so the whole hierarchy will follow
 
     AI_DEBUG_INVALIDATE_PTR(mRootNode);
     AI_DEBUG_INVALIDATE_PTR(mScene);
@@ -247,16 +249,18 @@ void Discreet3DSImporter::ApplyMasterScale(aiScene* pScene)
 // Reads a new chunk from the file
 void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk* pcOut)
 {
-    ai_assert(pcOut != NULL);
+    ai_assert(pcOut != nullptr);
 
     pcOut->Flag = stream->GetI2();
     pcOut->Size = stream->GetI4();
 
-    if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize())
+    if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize()) {
         throw DeadlyImportError("Chunk is too large");
+    }
 
-    if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit())
-        DefaultLogger::get()->error("3DS: Chunk overflow");
+    if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit()) {
+        ASSIMP_LOG_ERROR("3DS: Chunk overflow");
+    }
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -317,7 +321,7 @@ void Discreet3DSImporter::ParseEditorChunk()
         // print the version number
         char buff[10];
         ASSIMP_itoa10(buff,stream->GetI2());
-        DefaultLogger::get()->info(std::string("3DS file format version: ") + buff);
+        ASSIMP_LOG_INFO_F(std::string("3DS file format version: "), buff);
         }
         break;
     };
@@ -346,7 +350,7 @@ void Discreet3DSImporter::ParseObjectChunk()
     case Discreet3DS::CHUNK_MAT_MATERIAL:
 
         // Add a new material to the list
-        mScene->mMaterials.push_back(D3DS::Material());
+        mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + to_string(mScene->mMaterials.size()))));
         ParseMaterialChunk();
         break;
 
@@ -358,7 +362,7 @@ void Discreet3DSImporter::ParseObjectChunk()
         if (is_qnan(mClrAmbient.r))
         {
             // We failed to read the ambient base color.
-            DefaultLogger::get()->error("3DS: Failed to read ambient base color");
+            ASSIMP_LOG_ERROR("3DS: Failed to read ambient base color");
             mClrAmbient.r = mClrAmbient.g = mClrAmbient.b = 0.0f;
         }
         break;
@@ -402,11 +406,7 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
     case Discreet3DS::CHUNK_TRIMESH:
         {
         // this starts a new triangle mesh
-        mScene->mMeshes.push_back(D3DS::Mesh());
-        D3DS::Mesh& m = mScene->mMeshes.back();
-
-        // Setup the name of the mesh
-        m.mName = std::string(name, num);
+        mScene->mMeshes.push_back(D3DS::Mesh(std::string(name, num)));
 
         // Read mesh chunks
         ParseMeshChunk();
@@ -464,7 +464,7 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
         if (len < 1e-5) {
 
             // There are some files with lookat == position. Don't know why or whether it's ok or not.
-            DefaultLogger::get()->error("3DS: Unable to read proper camera look-at vector");
+            ASSIMP_LOG_ERROR("3DS: Unable to read proper camera look-at vector");
             camera->mLookAt = aiVector3D(0.0,1.0,0.0);
 
         }
@@ -630,9 +630,9 @@ void Discreet3DSImporter::SkipTCBInfo()
     if (!flags) {
         // Currently we can't do anything with these values. They occur
         // quite rare, so it wouldn't be worth the effort implementing
-        // them. 3DS ist not really suitable for complex animations,
+        // them. 3DS is not really suitable for complex animations,
         // so full support is not required.
-        DefaultLogger::get()->warn("3DS: Skipping TCB animation info");
+        ASSIMP_LOG_WARN("3DS: Skipping TCB animation info");
     }
 
     if (flags & Discreet3DS::KEY_USE_TENS) {
@@ -690,8 +690,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
             pcNode->mInstanceCount++;
             instanceNumber = pcNode->mInstanceCount;
         }
-        pcNode = new D3DS::Node();
-        pcNode->mName = name;
+        pcNode = new D3DS::Node(name);
         pcNode->mInstanceNumber = instanceNumber;
 
         // There are two unknown values which we can safely ignore
@@ -734,7 +733,6 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 
             // If object name is DUMMY, take this one instead
             if (mCurrentNode->mName == "$$$DUMMY")  {
-                //DefaultLogger::get()->warn("3DS: Skipping dummy object name for non-dummy object");
                 mCurrentNode->mName = std::string(sz);
                 break;
             }
@@ -745,7 +743,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
 
         if ( Discreet3DS::CHUNK_TRACKINFO != parent)
         {
-            DefaultLogger::get()->warn("3DS: Skipping pivot subchunk for non usual object");
+            ASSIMP_LOG_WARN("3DS: Skipping pivot subchunk for non usual object");
             break;
         }
 
@@ -807,7 +805,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
         {
         // roll keys are accepted for cameras only
         if (parent != Discreet3DS::CHUNK_TRACKCAMERA)   {
-            DefaultLogger::get()->warn("3DS: Ignoring roll track for non-camera object");
+            ASSIMP_LOG_WARN("3DS: Ignoring roll track for non-camera object");
             break;
         }
         bool sortKeys = false;
@@ -847,7 +845,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
         // CAMERA FOV KEYFRAME
     case Discreet3DS::CHUNK_TRACKFOV:
         {
-            DefaultLogger::get()->error("3DS: Skipping FOV animation track. "
+            ASSIMP_LOG_ERROR("3DS: Skipping FOV animation track. "
                 "This is not supported");
         }
         break;
@@ -987,7 +985,7 @@ void Discreet3DSImporter::ParseFaceChunk()
             }
         }
         if (0xcdcdcdcd == idx)  {
-            DefaultLogger::get()->error(std::string("3DS: Unknown material: ") + sz);
+            ASSIMP_LOG_ERROR_F( "3DS: Unknown material: ", sz);
         }
 
         // Now continue and read all material indices
@@ -997,7 +995,7 @@ void Discreet3DSImporter::ParseFaceChunk()
 
             // check range
             if (fidx >= mMesh.mFaceMaterials.size())    {
-                DefaultLogger::get()->error("3DS: Invalid face index in face material list");
+                ASSIMP_LOG_ERROR("3DS: Invalid face index in face material list");
             }
             else mMesh.mFaceMaterials[fidx] = idx;
         }}
@@ -1112,7 +1110,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
 
         if (!cnt)   {
             // This may not be, we use the default name instead
-            DefaultLogger::get()->error("3DS: Empty material name");
+            ASSIMP_LOG_ERROR("3DS: Empty material name");
         }
         else mScene->mMaterials.back().mName = std::string(sz,cnt);
         }
@@ -1125,7 +1123,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
         ParseColorChunk(pc);
         if (is_qnan(pc->r)) {
             // color chunk is invalid. Simply ignore it
-            DefaultLogger::get()->error("3DS: Unable to read DIFFUSE chunk");
+            ASSIMP_LOG_ERROR("3DS: Unable to read DIFFUSE chunk");
             pc->r = pc->g = pc->b = 1.0f;
         }}
         break;
@@ -1137,7 +1135,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
         ParseColorChunk(pc);
         if (is_qnan(pc->r)) {
             // color chunk is invalid. Simply ignore it
-            DefaultLogger::get()->error("3DS: Unable to read SPECULAR chunk");
+            ASSIMP_LOG_ERROR("3DS: Unable to read SPECULAR chunk");
             pc->r = pc->g = pc->b = 1.0f;
         }}
         break;
@@ -1149,7 +1147,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
         ParseColorChunk(pc);
         if (is_qnan(pc->r)) {
             // color chunk is invalid. Simply ignore it
-            DefaultLogger::get()->error("3DS: Unable to read AMBIENT chunk");
+            ASSIMP_LOG_ERROR("3DS: Unable to read AMBIENT chunk");
             pc->r = pc->g = pc->b = 0.0f;
         }}
         break;
@@ -1161,7 +1159,7 @@ void Discreet3DSImporter::ParseMaterialChunk()
         ParseColorChunk(pc);
         if (is_qnan(pc->r)) {
             // color chunk is invalid. Simply ignore it
-            DefaultLogger::get()->error("3DS: Unable to read EMISSIVE chunk");
+            ASSIMP_LOG_ERROR("3DS: Unable to read EMISSIVE chunk");
             pc->r = pc->g = pc->b = 0.0f;
         }}
         break;
@@ -1295,7 +1293,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
         pcOut->mScaleU = stream->GetF4();
         if (0.0f == pcOut->mScaleU)
         {
-            DefaultLogger::get()->warn("Texture coordinate scaling in the x direction is zero. Assuming 1.");
+            ASSIMP_LOG_WARN("Texture coordinate scaling in the x direction is zero. Assuming 1.");
             pcOut->mScaleU = 1.0f;
         }
         break;
@@ -1304,7 +1302,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
         pcOut->mScaleV = stream->GetF4();
         if (0.0f == pcOut->mScaleV)
         {
-            DefaultLogger::get()->warn("Texture coordinate scaling in the y direction is zero. Assuming 1.");
+            ASSIMP_LOG_WARN("Texture coordinate scaling in the y direction is zero. Assuming 1.");
             pcOut->mScaleV = 1.0f;
         }
         break;
@@ -1346,15 +1344,16 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
 
 // ------------------------------------------------------------------------------------------------
 // Read a percentage chunk
-ai_real Discreet3DSImporter::ParsePercentageChunk()
-{
+ai_real Discreet3DSImporter::ParsePercentageChunk() {
     Discreet3DS::Chunk chunk;
     ReadChunk(&chunk);
 
-    if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag)
-        return stream->GetF4();
-    else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag)
+    if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag) {
+        return stream->GetF4() * ai_real(100) / ai_real(0xFFFF);
+    } else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag) {
         return (ai_real)((uint16_t)stream->GetI2()) / (ai_real)0xFFFF;
+    }
+
     return get_qnan();
 }
 

+ 4 - 3
Engine/lib/assimp/code/3DSLoader.h

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -46,13 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_3DSIMPORTER_H_INC
 #define AI_3DSIMPORTER_H_INC
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <assimp/types.h>
 
 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
 
 #include "3DSHelper.h"
-#include "StreamReader.h"
+#include <assimp/StreamReader.h>
 
 struct aiNode;
 

+ 17 - 2
Engine/lib/assimp/code/3MFXmlTags.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -44,6 +45,11 @@ namespace Assimp {
 namespace D3MF {
 
 namespace XmlTag {
+    // Meta-data
+    static const std::string meta = "metadata";
+    static const std::string meta_name = "name";
+
+    // Model-data specific tags
     static const std::string model = "model";
     static const std::string model_unit = "unit";
     static const std::string metadata = "metadata";
@@ -61,6 +67,8 @@ namespace XmlTag {
     static const std::string v2 = "v2";
     static const std::string v3 = "v3";
     static const std::string id = "id";
+    static const std::string pid = "pid";
+    static const std::string p1 = "p1";
     static const std::string name = "name";
     static const std::string type = "type";
     static const std::string build = "build";
@@ -68,6 +76,14 @@ namespace XmlTag {
     static const std::string objectid = "objectid";
     static const std::string transform = "transform";
 
+    // Material definitions
+    static const std::string basematerials = "basematerials";
+    static const std::string basematerials_id = "id";
+    static const std::string basematerials_base = "base";
+    static const std::string basematerials_name = "name";
+    static const std::string basematerials_displaycolor = "displaycolor";
+
+    // Meta info tags
     static const std::string CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
     static const std::string ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
     static const std::string SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
@@ -82,7 +98,6 @@ namespace XmlTag {
     static const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
     static const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
     static const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
-
 }
 
 } // Namespace D3MF

+ 25 - 24
Engine/lib/assimp/code/ACLoader.cpp

@@ -4,7 +4,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -49,11 +50,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // internal headers
 #include "ACLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include "Subdivision.h"
+#include <assimp/ParsingUtils.h>
+#include <assimp/fast_atof.h>
+#include <assimp/Subdivision.h>
 #include "Importer.h"
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <assimp/Importer.hpp>
 #include <assimp/light.h>
 #include <assimp/DefaultLogger.hpp>
@@ -84,7 +85,7 @@ static const aiImporterDesc desc = {
 #define AI_AC_SKIP_TO_NEXT_TOKEN() \
     if (!SkipSpaces(&buffer)) \
     { \
-        DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL"); \
+        ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL"); \
         continue; \
     }
 
@@ -100,7 +101,7 @@ static const aiImporterDesc desc = {
     { \
         if (IsLineEnd( *buffer )) \
         { \
-            DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL in string"); \
+            ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string"); \
             out = "ERROR"; \
             break; \
         } \
@@ -119,7 +120,7 @@ static const aiImporterDesc desc = {
     { \
         if (strncmp(buffer,name,name_length) || !IsSpace(buffer[name_length])) \
         { \
-            DefaultLogger::get()->error("AC3D: Unexpexted token. " name " was expected."); \
+            ASSIMP_LOG_ERROR("AC3D: Unexpexted token. " name " was expected."); \
             continue; \
         } \
         buffer += name_length+1; \
@@ -216,7 +217,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
         light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i",static_cast<unsigned int>(mLights->size())-1);
         obj.name = std::string( light->mName.data );
 
-        DefaultLogger::get()->debug("AC3D: Light source encountered");
+        ASSIMP_LOG_DEBUG("AC3D: Light source encountered");
         obj.type = Object::Light;
     }
     else if (!ASSIMP_strincmp(buffer,"group",5))
@@ -306,12 +307,12 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
             {
                 if (!GetNextLine())
                 {
-                    DefaultLogger::get()->error("AC3D: Unexpected EOF: not all vertices have been parsed yet");
+                    ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet");
                     break;
                 }
                 else if (!IsNumeric(*buffer))
                 {
-                    DefaultLogger::get()->error("AC3D: Unexpected token: not all vertices have been parsed yet");
+                    ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet");
                     --buffer; // make sure the line is processed a second time
                     break;
                 }
@@ -337,8 +338,8 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
                     // example writes no surf chunks
                     if (!Q3DWorkAround)
                     {
-                        DefaultLogger::get()->warn("AC3D: SURF token was expected");
-                        DefaultLogger::get()->debug("Continuing with Quick3D Workaround enabled");
+                        ASSIMP_LOG_WARN("AC3D: SURF token was expected");
+                        ASSIMP_LOG_DEBUG("Continuing with Quick3D Workaround enabled");
                     }
                     --buffer; // make sure the line is processed a second time
                     // break; --- see fix notes above
@@ -383,7 +384,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
                         {
                             if(!GetNextLine())
                             {
-                                DefaultLogger::get()->error("AC3D: Unexpected EOF: surface references are incomplete");
+                                ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: surface references are incomplete");
                                 break;
                             }
                             surf.entries.push_back(Surface::SurfaceEntry());
@@ -404,7 +405,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
             }
         }
     }
-    DefaultLogger::get()->error("AC3D: Unexpected EOF: \'kids\' line was expected");
+    ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: \'kids\' line was expected");
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -477,7 +478,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
                  therefore: if no surfaces are defined return point data only
              */
 
-            DefaultLogger::get()->info("AC3D: No surfaces defined in object definition, "
+            ASSIMP_LOG_INFO("AC3D: No surfaces defined in object definition, "
                 "a point list is returned");
 
             meshes.push_back(new aiMesh());
@@ -518,12 +519,12 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
                 unsigned int idx = (*it).mat;
                 if (idx >= needMat.size())
                 {
-                    DefaultLogger::get()->error("AC3D: material index is out of range");
+                    ASSIMP_LOG_ERROR("AC3D: material index is out of range");
                     idx = 0;
                 }
                 if ((*it).entries.empty())
                 {
-                    DefaultLogger::get()->warn("AC3D: surface her zero vertex references");
+                    ASSIMP_LOG_WARN("AC3D: surface her zero vertex references");
                 }
 
                 // validate all vertex indices to make sure we won't crash here
@@ -532,7 +533,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
                 {
                     if ((*it2).first >= object.vertices.size())
                     {
-                        DefaultLogger::get()->warn("AC3D: Invalid vertex reference");
+                        ASSIMP_LOG_WARN("AC3D: Invalid vertex reference");
                         (*it2).first = 0;
                     }
                 }
@@ -560,7 +561,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
 
                     if ((*it).flags & 0xf)
                     {
-                        DefaultLogger::get()->warn("AC3D: The type flag of a surface is unknown");
+                        ASSIMP_LOG_WARN("AC3D: The type flag of a surface is unknown");
                         (*it).flags &= ~(0xf);
                     }
 
@@ -711,7 +712,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
             if (object.subDiv)  {
                 if (configEvalSubdivision) {
                     std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
-                    DefaultLogger::get()->info("AC3D: Evaluating subdivision surface: "+object.name);
+                    ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: "+object.name);
 
                     std::vector<aiMesh*> cpy(meshes.size()-oldm,NULL);
                     div->Subdivide(&meshes[oldm],cpy.size(),&cpy.front(),object.subDiv,true);
@@ -720,7 +721,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
                     // previous meshes are deleted vy Subdivide().
                 }
                 else {
-                    DefaultLogger::get()->info("AC3D: Letting the subdivision surface untouched due to my configuration: "
+                    ASSIMP_LOG_INFO("AC3D: Letting the subdivision surface untouched due to my configuration: "
                         +object.name);
                 }
             }
@@ -812,7 +813,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
     unsigned int version = HexDigitToDecimal( buffer[4] );
     char msg[3];
     ASSIMP_itoa10(msg,3,version);
-    DefaultLogger::get()->info(std::string("AC3D file format version: ") + msg);
+    ASSIMP_LOG_INFO_F("AC3D file format version: ", msg);
 
     std::vector<Material> materials;
     materials.reserve(5);
@@ -856,7 +857,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
     }
     if (materials.empty())
     {
-        DefaultLogger::get()->warn("AC3D: No material has been found");
+        ASSIMP_LOG_WARN("AC3D: No material has been found");
         materials.push_back(Material());
     }
 

+ 3 - 2
Engine/lib/assimp/code/ACLoader.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -47,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <vector>
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <assimp/types.h>
 
 struct aiNode;

+ 4 - 3
Engine/lib/assimp/code/AMFImporter.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -51,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "AMFImporter.hpp"
 #include "AMFImporter_Macro.hpp"
 
-#include "fast_atof.h"
+#include <assimp/fast_atof.h>
 #include <assimp/DefaultIOSystem.h>
 
 // Header files, stdlib.
@@ -229,7 +230,7 @@ casu_cres:
 	if(!skipped_before[sk_idx])
 	{
 		skipped_before[sk_idx] = true;
-		LogWarning("Skipping node \"" + nn + "\" in " + pParentNodeName + ".");
+        ASSIMP_LOG_WARN_F("Skipping node \"", nn, "\" in ", pParentNodeName, ".");
 	}
 }
 

+ 68 - 199
Engine/lib/assimp/code/AMFImporter.hpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -56,14 +57,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/importerdesc.h>
 #include "assimp/types.h"
-#include "BaseImporter.h"
-#include "irrXMLWrapper.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/irrXMLWrapper.h>
 
 // Header files, stdlib.
 #include <set>
 
-namespace Assimp
-{
+namespace Assimp {
+
 /// \class AMFImporter
 /// Class that holding scene graph which include: geometry, metadata, materials etc.
 ///
@@ -98,100 +99,49 @@ namespace Assimp
 ///            new - <texmap> and children <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>
 ///            old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
 ///
-class AMFImporter : public BaseImporter
-{
-	/***********************************************/
-	/******************** Types ********************/
-	/***********************************************/
-
-private:
-
-	struct SPP_Material;// forward declaration
-
-	/// \struct SPP_Composite
-	/// Data type for postprocessing step. More suitable container for part of material's composition.
-	struct SPP_Composite
-	{
-		SPP_Material* Material;///< Pointer to material - part of composition.
-		std::string Formula;///< Formula for calculating ratio of \ref Material.
-	};
-
-	/// \struct SPP_Material
-	/// Data type for postprocessing step. More suitable container for material.
-	struct SPP_Material
-	{
-		std::string ID;///< Material ID.
-		std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material.
-		CAMFImporter_NodeElement_Color* Color;///< Color of material.
-		std::list<SPP_Composite> Composition;///< List of child materials if current material is composition of few another.
-
-		/// \fn aiColor4D GetColor(const float pX, const float pY, const float pZ) const
-		/// Return color calculated for specified coordinate.
-		/// \param [in] pX - "x" coordinate.
-		/// \param [in] pY - "y" coordinate.
-		/// \param [in] pZ - "z" coordinate.
-		/// \return calculated color.
-		aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
-	};
-
-	/// \struct SPP_Texture
-	/// Data type for post-processing step. More suitable container for texture.
-	struct SPP_Texture
-	{
-		std::string ID;
-		size_t      Width, Height, Depth;
-		bool        Tiled;
-        char        FormatHint[ 9 ];// 8 for string + 1 for terminator.
-		uint8_t    *Data;
-	};
-
-	///	\struct SComplexFace
-	/// Data type for post-processing step. Contain face data.
-	struct SComplexFace
-	{
-		aiFace Face;///< Face vertices.
-		const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face.
-		const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
-	};
-
-
-
-	/***********************************************/
-	/****************** Constants ******************/
-	/***********************************************/
-
+class AMFImporter : public BaseImporter {
 private:
+    struct SPP_Material;// forward declaration
+
+                        /// \struct SPP_Composite
+                        /// Data type for post-processing step. More suitable container for part of material's composition.
+    struct SPP_Composite {
+        SPP_Material* Material;///< Pointer to material - part of composition.
+        std::string Formula;///< Formula for calculating ratio of \ref Material.
+    };
+
+    /// \struct SPP_Material
+    /// Data type for post-processing step. More suitable container for material.
+    struct SPP_Material {
+        std::string ID;///< Material ID.
+        std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material.
+        CAMFImporter_NodeElement_Color* Color;///< Color of material.
+        std::list<SPP_Composite> Composition;///< List of child materials if current material is composition of few another.
+
+        /// Return color calculated for specified coordinate.
+        /// \param [in] pX - "x" coordinate.
+        /// \param [in] pY - "y" coordinate.
+        /// \param [in] pZ - "z" coordinate.
+        /// \return calculated color.
+        aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
+    };
+
+    /// Data type for post-processing step. More suitable container for texture.
+    struct SPP_Texture {
+        std::string ID;
+        size_t      Width, Height, Depth;
+        bool        Tiled;
+        char        FormatHint[9];// 8 for string + 1 for terminator.
+        uint8_t    *Data;
+    };
+
+    /// Data type for post-processing step. Contain face data.
+    struct SComplexFace {
+        aiFace Face;///< Face vertices.
+        const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face.
+        const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
+    };
 
-	static const aiImporterDesc Description;
-
-	/***********************************************/
-	/****************** Variables ******************/
-	/***********************************************/
-
-private:
-
-    CAMFImporter_NodeElement* mNodeElement_Cur;///< Current element.
-    std::list<CAMFImporter_NodeElement*> mNodeElement_List;///< All elements of scene graph.
-	irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
-	std::string mUnit;
-	std::list<SPP_Material> mMaterial_Converted;///< List of converted materials for postprocessing step.
-	std::list<SPP_Texture> mTexture_Converted;///< List of converted textures for postprocessing step.
-
-	/***********************************************/
-	/****************** Functions ******************/
-	/***********************************************/
-
-private:
-
-	/// \fn AMFImporter(const AMFImporter& pScene)
-	/// Disabled copy constructor.
-	AMFImporter(const AMFImporter& pScene);
-
-	/// \fn AMFImporter& operator=(const AMFImporter& pScene)
-	/// Disabled assign operator.
-	AMFImporter& operator=(const AMFImporter& pScene);
-
-	/// \fn void Clear()
 	/// Clear all temporary data.
 	void Clear();
 
@@ -199,7 +149,6 @@ private:
 	/************* Functions: find set *************/
 	/***********************************************/
 
-	/// \fn bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, aiNode** pNode) const
 	/// Find specified node element in node elements list ( \ref mNodeElement_List).
 	/// \param [in] pID - ID(name) of requested node element.
 	/// \param [in] pType - type of node element.
@@ -207,7 +156,6 @@ private:
 	/// \return true - if the node element is found, else - false.
 	bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const;
 
-	/// \fn bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const
 	/// Find requested aiNode in node list.
 	/// \param [in] pID - ID(name) of requested node.
 	/// \param [in] pNodeList - list of nodes where to find the node.
@@ -215,15 +163,13 @@ private:
 	/// \return true - if the node is found, else - false.
 	bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const;
 
-	/// \fn bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const
 	/// Find material in list for converted materials. Use at postprocessing step.
 	/// \param [in] pID - material ID.
 	/// \param [out] pConvertedMaterial - pointer to found converted material (\ref SPP_Material).
 	/// \return true - if the material is found, else - false.
 	bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const;
 
-	/// \fn bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A, uint32_t* pConvertedTextureIndex = nullptr) const
-	/// Find texture in list of converted textures. Use at postprocessing step,
+    /// Find texture in list of converted textures. Use at postprocessing step,
 	/// \param [in] pID_R - ID of source "red" texture.
 	/// \param [in] pID_G - ID of source "green" texture.
 	/// \param [in] pID_B - ID of source "blue" texture.
@@ -234,11 +180,7 @@ private:
 	bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A,
 								uint32_t* pConvertedTextureIndex = nullptr) const;
 
-	/***********************************************/
-	/********* Functions: postprocess set **********/
-	/***********************************************/
 
-	/// \fn void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray, std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const
 	/// Get data stored in <vertices> and place it to arrays.
 	/// \param [in] pNodeElement - reference to node element which kept <object> data.
 	/// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in <vertices>.
@@ -247,7 +189,6 @@ private:
 	void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
 												std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const;
 
-	/// \fn size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A)
 	/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
 	/// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
 	/// to converted textures list.
@@ -259,27 +200,23 @@ private:
 	/// \return index of the texture in array of the converted textures.
 	size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A);
 
-	/// \fn void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> > pOutputList_Separated)
 	/// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc).
 	/// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after
 	/// processing.
 	/// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing.
 	void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated);
 
-	/// \fn void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const
 	/// Check if child elements of node element is metadata and add it to scene node.
 	/// \param [in] pMetadataList - reference to list with collected metadata.
 	/// \param [out] pSceneNode - scene node in which metadata will be added.
 	void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const;
 
-	/// \fn void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)
 	/// To create aiMesh and aiNode for it from <object>.
 	/// \param [in] pNodeElement - reference to node element which kept <object> data.
 	/// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
 	/// \param [out] pSceneNode - pointer to place where new aiNode will be created.
 	void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode);
 
-	/// \fn void Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray, const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor, std::list<aiMesh*>& pMeshList, aiNode& pSceneNode)
 	/// Create mesh for every <volume> in <mesh>.
 	/// \param [in] pNodeElement - reference to node element which kept <mesh> data.
 	/// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all <volume>'s.
@@ -293,27 +230,20 @@ private:
 									const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor,
 									std::list<aiMesh*>& pMeshList, aiNode& pSceneNode);
 
-	/// \fn void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial)
 	/// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material.
 	/// \param [in] pMaterial - source CAMFImporter_NodeElement_Material.
 	void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial);
 
-	/// \fn void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const
 	/// Create and add to aiNode's list new part of scene graph defined by <constellation>.
 	/// \param [in] pConstellation - reference to <constellation> node.
 	/// \param [out] pNodeList - reference to aiNode's list.
 	void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const;
 
-	/// \fn void Postprocess_BuildScene()
 	/// Build Assimp scene graph in aiScene from collected data.
 	/// \param [out] pScene - pointer to aiScene where tree will be built.
 	void Postprocess_BuildScene(aiScene* pScene);
 
-	/***********************************************/
-	/************* Functions: throw set ************/
-	/***********************************************/
 
-	/// \fn void Throw_CloseNotFound(const std::string& pNode)
 	/// Call that function when close tag of node not found and exception must be raised.
 	/// E.g.:
 	/// <amf>
@@ -323,19 +253,16 @@ private:
 	/// \param [in] pNode - node name in which exception happened.
 	void Throw_CloseNotFound(const std::string& pNode);
 
-	/// \fn void Throw_IncorrectAttr(const std::string& pAttrName)
 	/// Call that function when attribute name is incorrect and exception must be raised.
 	/// \param [in] pAttrName - attribute name.
 	/// \throw DeadlyImportError.
 	void Throw_IncorrectAttr(const std::string& pAttrName);
 
-	/// \fn void Throw_IncorrectAttrValue(const std::string& pAttrName)
 	/// Call that function when attribute value is incorrect and exception must be raised.
 	/// \param [in] pAttrName - attribute name.
 	/// \throw DeadlyImportError.
 	void Throw_IncorrectAttrValue(const std::string& pAttrName);
 
-	/// \fn void Throw_MoreThanOnceDefined(const std::string& pNode, const std::string& pDescription)
 	/// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised.
 	/// E.g.:
 	/// <object>
@@ -347,216 +274,158 @@ private:
 	/// \param [in] pDescription - message about error. E.g. what the node defined while exception raised.
 	void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription);
 
-	/// \fn void Throw_ID_NotFound(const std::string& pID) const
 	/// Call that function when referenced element ID are not found in graph and exception must be raised.
 	/// \param [in] pID - ID of of element which not found.
 	/// \throw DeadlyImportError.
 	void Throw_ID_NotFound(const std::string& pID) const;
 
-	/***********************************************/
-	/************** Functions: LOG set *************/
-	/***********************************************/
-
-	/// \fn void LogInfo(const std::string& pMessage)
-	/// Short variant for calling \ref DefaultLogger::get()->info()
-	void LogInfo(const std::string& pMessage) { DefaultLogger::get()->info(pMessage); }
-
-	/// \fn void LogWarning(const std::string& pMessage)
-	/// Short variant for calling \ref DefaultLogger::get()->warn()
-	void LogWarning(const std::string& pMessage) { DefaultLogger::get()->warn(pMessage); }
-
-	/// \fn void LogError(const std::string& pMessage)
-	/// Short variant for calling \ref DefaultLogger::get()->error()
-	void LogError(const std::string& pMessage) { DefaultLogger::get()->error(pMessage); }
-
-	/***********************************************/
-	/************** Functions: XML set *************/
-	/***********************************************/
-
-	/// \fn void XML_CheckNode_MustHaveChildren()
 	/// Check if current node have children: <node>...</node>. If not then exception will throwed.
 	void XML_CheckNode_MustHaveChildren();
 
-	/// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName)
 	/// Check if current node name is equal to pNodeName.
 	/// \param [in] pNodeName - name for checking.
 	/// return true if current node name is equal to pNodeName, else - false.
 	bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
 
-	/// \fn void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
 	/// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node.
 	/// \param [in] pParentNodeName - parent node name. Used for reporting.
 	void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName);
 
-	/// \fn bool XML_SearchNode(const std::string& pNodeName)
 	/// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end.
 	/// \param [in] pNodeName - requested node name.
 	/// return true - if node is found, else - false.
 	bool XML_SearchNode(const std::string& pNodeName);
 
-	/// \fn bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
 	/// Read attribute value.
 	/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
 	/// \return read data.
 	bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx);
 
-	/// \fn float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
 	/// Read attribute value.
 	/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
 	/// \return read data.
 	float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx);
 
-	/// \fn uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx)
 	/// Read attribute value.
 	/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
 	/// \return read data.
 	uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx);
 
-	/// \fn float XML_ReadNode_GetVal_AsFloat()
 	/// Read node value.
 	/// \return read data.
 	float XML_ReadNode_GetVal_AsFloat();
 
-	/// \fn uint32_t XML_ReadNode_GetVal_AsU32()
 	/// Read node value.
 	/// \return read data.
 	uint32_t XML_ReadNode_GetVal_AsU32();
 
-	/// \fn void XML_ReadNode_GetVal_AsString(std::string& pValue)
 	/// Read node value.
 	/// \return read data.
 	void XML_ReadNode_GetVal_AsString(std::string& pValue);
 
-	/***********************************************/
-	/******** Functions: parse set private *********/
-	/***********************************************/
-
-	/// \fn void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode)
 	/// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called.
 	/// \param [in] pNode - new current node.
 	void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode);
 
-	/// \fn void ParseHelper_Group_End()
 	/// This function must be called when exiting from grouping node. \ref ParseHelper_Group_Begin.
 	void ParseHelper_Node_Exit();
 
-	/// \fn void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
 	/// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it
 	/// must be converted to right form - "0.xxx".
 	/// \param [in] pInStr - pointer to input string which can contain incorrect form of values.
 	/// \param [out[ pOutString - output string with right form of values.
 	void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString);
 
-	/// \fn void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const
 	/// Decode Base64-encoded data.
 	/// \param [in] pInputBase64 - reference to input Base64-encoded string.
 	/// \param [out] pOutputData - reference to output array for decoded data.
 	void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const;
 
-	/// \fn void ParseNode_Root()
 	/// Parse <AMF> node of the file.
 	void ParseNode_Root();
 
-	/******** Functions: top nodes *********/
-
-	/// \fn void ParseNode_Constellation()
 	/// Parse <constellation> node of the file.
 	void ParseNode_Constellation();
 
-	/// \fn void ParseNode_Constellation()
 	/// Parse <instance> node of the file.
 	void ParseNode_Instance();
 
-	/// \fn void ParseNode_Material()
 	/// Parse <material> node of the file.
 	void ParseNode_Material();
 
-	/// \fn void ParseNode_Metadata()
 	/// Parse <metadata> node.
 	void ParseNode_Metadata();
 
-	/// \fn void ParseNode_Object()
 	/// Parse <object> node of the file.
 	void ParseNode_Object();
 
-	/// \fn void ParseNode_Texture()
 	/// Parse <texture> node of the file.
 	void ParseNode_Texture();
 
-	/******** Functions: geometry nodes *********/
-
-	/// \fn void ParseNode_Coordinates()
 	/// Parse <coordinates> node of the file.
 	void ParseNode_Coordinates();
 
-	/// \fn void ParseNode_Edge()
 	/// Parse <edge> node of the file.
 	void ParseNode_Edge();
 
-	/// \fn void ParseNode_Mesh()
 	/// Parse <mesh> node of the file.
 	void ParseNode_Mesh();
 
-	/// \fn void ParseNode_Triangle()
 	/// Parse <triangle> node of the file.
 	void ParseNode_Triangle();
 
-	/// \fn void ParseNode_Vertex()
 	/// Parse <vertex> node of the file.
 	void ParseNode_Vertex();
 
-	/// \fn void ParseNode_Vertices()
 	/// Parse <vertices> node of the file.
 	void ParseNode_Vertices();
 
-	/// \fn void ParseNode_Volume()
 	/// Parse <volume> node of the file.
 	void ParseNode_Volume();
 
-	/******** Functions: material nodes *********/
-
-	/// \fn void ParseNode_Color()
 	/// Parse <color> node of the file.
 	void ParseNode_Color();
 
-	/// \fn void ParseNode_TexMap(const bool pUseOldName = false)
 	/// Parse <texmap> of <map> node of the file.
 	/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
 	void ParseNode_TexMap(const bool pUseOldName = false);
 
 public:
-
-	/// \fn AMFImporter()
 	/// Default constructor.
-	AMFImporter()
-		: mNodeElement_Cur(nullptr), mReader(nullptr)
-	{}
+	AMFImporter() AI_NO_EXCEPT
+    : mNodeElement_Cur(nullptr)
+    , mReader(nullptr) {
+        // empty
+    }
 
-	/// \fn ~AMFImporter()
 	/// Default destructor.
 	~AMFImporter();
 
-	/***********************************************/
-	/******** Functions: parse set, public *********/
-	/***********************************************/
-
-	/// \fn void ParseFile(const std::string& pFile, IOSystem* pIOHandler)
 	/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
-	/// Also exception can be throwed if trouble will found.
+	/// Also exception can be thrown if trouble will found.
 	/// \param [in] pFile - name of file to be parsed.
 	/// \param [in] pIOHandler - pointer to IO helper object.
 	void ParseFile(const std::string& pFile, IOSystem* pIOHandler);
 
-	/***********************************************/
-	/********* Functions: BaseImporter set *********/
-	/***********************************************/
-
 	bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const;
 	void GetExtensionList(std::set<std::string>& pExtensionList);
 	void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
 	const aiImporterDesc* GetInfo ()const;
 
-};// class AMFImporter
+    AMFImporter(const AMFImporter& pScene) = delete;
+    AMFImporter& operator=(const AMFImporter& pScene) = delete;
+
+private:
+    static const aiImporterDesc Description;
+
+    CAMFImporter_NodeElement* mNodeElement_Cur;///< Current element.
+    std::list<CAMFImporter_NodeElement*> mNodeElement_List;///< All elements of scene graph.
+    irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
+    std::string mUnit;
+    std::list<SPP_Material> mMaterial_Converted;///< List of converted materials for postprocessing step.
+    std::list<SPP_Texture> mTexture_Converted;///< List of converted textures for postprocessing step.
+
+};
 
 }// namespace Assimp
 

+ 2 - 1
Engine/lib/assimp/code/AMFImporter_Geometry.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.

+ 6 - 5
Engine/lib/assimp/code/AMFImporter_Macro.hpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -70,7 +71,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	}
 
 /// \def MACRO_ATTRREAD_CHECK_REF
-/// Check curent attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
+/// Check current attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
 /// "continue" will called.
 /// \param [in] pAttrName - attribute name.
 /// \param [out] pVarName - output variable name.
@@ -83,7 +84,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	}
 
 /// \def MACRO_ATTRREAD_CHECK_RET
-/// Check curent attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
+/// Check current attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
 /// If result was read then  "continue" will called.
 /// \param [in] pAttrName - attribute name.
 /// \param [out] pVarName - output variable name.
@@ -129,7 +130,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	} while(false)
 
 /// \def MACRO_NODECHECK_READCOMP_F
-/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "float".
+/// Check current node name and if it equal to requested then read value. Result write to output variable of type "float".
 /// If result was read then  "continue" will called. Also check if node data already read then raise exception.
 /// \param [in] pNodeName - node name.
 /// \param [in, out] pReadFlag - read flag.
@@ -146,7 +147,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	}
 
 /// \def MACRO_NODECHECK_READCOMP_U32
-/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
+/// Check current node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
 /// If result was read then  "continue" will called. Also check if node data already read then raise exception.
 /// \param [in] pNodeName - node name.
 /// \param [in, out] pReadFlag - read flag.

+ 61 - 42
Engine/lib/assimp/code/AMFImporter_Material.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -67,10 +68,9 @@ namespace Assimp
 //   Multi elements - No.
 //   Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
 //   values can be specified as constants, or as a formula depending on the coordinates.
-void AMFImporter::ParseNode_Color()
-{
-std::string profile;
-CAMFImporter_NodeElement* ne;
+void AMFImporter::ParseNode_Color() {
+    std::string profile;
+    CAMFImporter_NodeElement* ne;
 
 	// Read attributes for node <color>.
 	MACRO_ATTRREAD_LOOPBEG;
@@ -97,15 +97,19 @@ CAMFImporter_NodeElement* ne;
 		MACRO_NODECHECK_LOOPEND("color");
 		ParseHelper_Node_Exit();
 		// check that all components was defined
-		if(!(read_flag[0] && read_flag[1] && read_flag[2])) throw DeadlyImportError("Not all color components are defined.");
-		// check if <a> is absent. Then manualy add "a == 1".
-		if(!read_flag[3]) als.Color.a = 1;
-
-	}// if(!mReader->isEmptyElement())
+        if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
+            throw DeadlyImportError("Not all color components are defined.");
+        }
+
+        // check if <a> is absent. Then manually add "a == 1".
+        if (!read_flag[3]) {
+            als.Color.a = 1;
+        }
+	}
 	else
 	{
 		mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
-	}// if(!mReader->isEmptyElement()) else
+	}
 
 	als.Composed = false;
 	mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
@@ -118,10 +122,9 @@ CAMFImporter_NodeElement* ne;
 // An available material.
 // Multi elements - Yes.
 // Parent element - <amf>.
-void AMFImporter::ParseNode_Material()
-{
-std::string id;
-CAMFImporter_NodeElement* ne;
+void AMFImporter::ParseNode_Material() {
+    std::string id;
+    CAMFImporter_NodeElement* ne;
 
 	// Read attributes for node <color>.
 	MACRO_ATTRREAD_LOOPBEG;
@@ -130,9 +133,11 @@ CAMFImporter_NodeElement* ne;
 
 	// create new object.
 	ne = new CAMFImporter_NodeElement_Material(mNodeElement_Cur);
-	// and assign read data
+
+    // and assign read data
 	((CAMFImporter_NodeElement_Material*)ne)->ID = id;
-	// Check for child nodes
+
+    // Check for child nodes
 	if(!mReader->isEmptyElement())
 	{
 		bool col_read = false;
@@ -153,11 +158,11 @@ CAMFImporter_NodeElement* ne;
 			if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
 		MACRO_NODECHECK_LOOPEND("material");
 		ParseHelper_Node_Exit();
-	}// if(!mReader->isEmptyElement())
+	}
 	else
 	{
 		mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
-	}// if(!mReader->isEmptyElement()) else
+	}
 
 	mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
 }
@@ -180,14 +185,13 @@ CAMFImporter_NodeElement* ne;
 // Parent element - <amf>.
 void AMFImporter::ParseNode_Texture()
 {
-std::string id;
-uint32_t width = 0;
-uint32_t height = 0;
-uint32_t depth = 1;
-std::string type;
-bool tiled = false;
-std::string enc64_data;
-CAMFImporter_NodeElement* ne;
+    std::string id;
+    uint32_t width = 0;
+    uint32_t height = 0;
+    uint32_t depth = 1;
+    std::string type;
+    bool tiled = false;
+    std::string enc64_data;
 
 	// Read attributes for node <color>.
 	MACRO_ATTRREAD_LOOPBEG;
@@ -200,20 +204,34 @@ CAMFImporter_NodeElement* ne;
 	MACRO_ATTRREAD_LOOPEND;
 
 	// create new texture object.
-	ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur);
+    CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur);
 
 	CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience
 
 	// Check for child nodes
-	if(!mReader->isEmptyElement()) XML_ReadNode_GetVal_AsString(enc64_data);
+    if (!mReader->isEmptyElement()) {
+        XML_ReadNode_GetVal_AsString(enc64_data);
+    }
 
 	// check that all components was defined
-	if(id.empty()) throw DeadlyImportError("ID for texture must be defined.");
-	if(width < 1) Throw_IncorrectAttrValue("width");
-	if(height < 1) Throw_IncorrectAttrValue("height");
-	if(depth < 1) Throw_IncorrectAttrValue("depth");
-	if(type != "grayscale") Throw_IncorrectAttrValue("type");
-	if(enc64_data.empty()) throw DeadlyImportError("Texture data not defined.");
+    if (id.empty()) {
+        throw DeadlyImportError("ID for texture must be defined.");
+    }
+    if (width < 1) {
+        Throw_IncorrectAttrValue("width");
+    }
+    if (height < 1) {
+        Throw_IncorrectAttrValue("height");
+    }
+    if (depth < 1) {
+        Throw_IncorrectAttrValue("depth");
+    }
+    if (type != "grayscale") {
+        Throw_IncorrectAttrValue("type");
+    }
+    if (enc64_data.empty()) {
+        throw DeadlyImportError("Texture data not defined.");
+    }
 	// copy data
 	als.ID = id;
 	als.Width = width;
@@ -221,8 +239,11 @@ CAMFImporter_NodeElement* ne;
 	als.Depth = depth;
 	als.Tiled = tiled;
 	ParseHelper_Decode_Base64(enc64_data, als.Data);
-	// check data size
-	if((width * height * depth) != als.Data.size()) throw DeadlyImportError("Texture has incorrect data size.");
+
+    // check data size
+    if ((width * height * depth) != als.Data.size()) {
+        throw DeadlyImportError("Texture has incorrect data size.");
+    }
 
 	mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
 	mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
@@ -242,10 +263,8 @@ CAMFImporter_NodeElement* ne;
 //   <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>. Old name: <u1>, <u2>, <u3>, <v1>, <v2>, <v3>.
 //   Multi elements - No.
 //   Texture coordinates for every vertex of triangle.
-void AMFImporter::ParseNode_TexMap(const bool pUseOldName)
-{
-std::string rtexid, gtexid, btexid, atexid;
-CAMFImporter_NodeElement* ne;
+void AMFImporter::ParseNode_TexMap(const bool pUseOldName) {
+    std::string rtexid, gtexid, btexid, atexid;
 
 	// Read attributes for node <color>.
 	MACRO_ATTRREAD_LOOPBEG;
@@ -256,7 +275,7 @@ CAMFImporter_NodeElement* ne;
 	MACRO_ATTRREAD_LOOPEND;
 
 	// create new texture coordinates object.
-	ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur);
+    CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur);
 
 	CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience
 	// check data

+ 64 - 124
Engine/lib/assimp/code/AMFImporter_Node.hpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -61,7 +62,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /// \class CAMFImporter_NodeElement
 /// Base class for elements of nodes.
 class CAMFImporter_NodeElement {
-
 public:
 	/// Define what data type contain node element.
 	enum EType {
@@ -95,15 +95,11 @@ public:                                               /// Destructor, virtual..
         // empty
     }
 
-private:
-	/// Disabled copy constructor.
-	CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement);
-
-	/// Disabled assign operator.
-	CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement);
-
-	/// Disabled default constructor.
-	CAMFImporter_NodeElement();
+	/// Disabled copy constructor and co.
+	CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement) = delete;
+    CAMFImporter_NodeElement(CAMFImporter_NodeElement&&) = delete;
+    CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement) = delete;
+	CAMFImporter_NodeElement() = delete;
 
 protected:
 	/// In constructor inheritor must set element type.
@@ -120,9 +116,7 @@ protected:
 
 /// \struct CAMFImporter_NodeElement_Constellation
 /// A collection of objects or constellations with specific relative locations.
-struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement
-{
-	/// \fn CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
+struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement {
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
@@ -133,9 +127,7 @@ struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement
 
 /// \struct CAMFImporter_NodeElement_Instance
 /// Part of constellation.
-struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement
-{
-	/****************** Variables ******************/
+struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement {
 
 	std::string ObjectID;///< ID of object for instantiation.
 	/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
@@ -146,237 +138,185 @@ struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement
 	/// instance of the object in the current constellation. Rotations shall be executed in order of x first, then y, then z.
 	aiVector3D Rotation;
 
-	/****************** Functions ******************/
-
-	/// \fn CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Instance, pParent)
 	{}
-
-};// struct CAMFImporter_NodeElement_Instance
+};
 
 /// \struct CAMFImporter_NodeElement_Metadata
 /// Structure that define metadata node.
-struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement
-{
-	/****************** Variables ******************/
+struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement {
 
-	std::string Type;///< Type of "Value".
+	std::string Type;///< Type of "Value". 
 	std::string Value;///< Value.
 
-	/****************** Functions ******************/
-
-	/// \fn CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Metadata, pParent)
 	{}
-
-};// struct CAMFImporter_NodeElement_Metadata
+};
 
 /// \struct CAMFImporter_NodeElement_Root
 /// Structure that define root node.
-struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement
-{
-	/****************** Variables ******************/
+struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement {
 
 	std::string Unit;///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
 	std::string Version;///< Version of format.
 
-	/****************** Functions ******************/
-
-	/// \fn CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Root, pParent)
 	{}
-
-};// struct CAMFImporter_NodeElement_Root
+};
 
 /// \struct CAMFImporter_NodeElement_Color
 /// Structure that define object node.
-struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement
-{
-	/****************** Variables ******************/
-
-	bool Composed;///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
-	std::string Color_Composed[4];///< By components formulas of composed color. [0..3] => RGBA.
-	aiColor4D Color;///< Constant color.
-	std::string Profile;///< The ICC color space used to interpret the three color channels <r>, <g> and <b>..
-
-	/****************** Functions ******************/
-
-	/// \fn CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
-	/// Constructor.
-	/// \param [in] pParent - pointer to parent node.
+struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement {
+	bool Composed;                  ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
+	std::string Color_Composed[4];  ///< By components formulas of composed color. [0..3] - RGBA.
+	aiColor4D Color;                ///< Constant color.
+	std::string Profile;            ///< The ICC color space used to interpret the three color channels r, g and b..
+
+	/// @brief  Constructor.
+	/// @param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Color, pParent)
-	{}
-
-};// struct CAMFImporter_NodeElement_Color
+	: CAMFImporter_NodeElement(ENET_Color, pParent)
+    , Composed( false )
+    , Color()
+    , Profile() {
+        // empty
+    }
+};
 
 /// \struct CAMFImporter_NodeElement_Material
 /// Structure that define material node.
-struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement
-{
-	/// \fn CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
+struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement {
+	
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Material, pParent)
 	{}
 
-};// struct CAMFImporter_NodeElement_Material
+};
 
 /// \struct CAMFImporter_NodeElement_Object
 /// Structure that define object node.
-struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement
-{
-	/// \fn CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
-	/// Constructor.
+struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement {
+
+    /// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Object, pParent)
 	{}
-
-};// struct CAMFImporter_NodeElement_Object
+};
 
 /// \struct CAMFImporter_NodeElement_Mesh
 /// Structure that define mesh node.
-struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement
-{
-	/// \fn CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
+struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement {
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Mesh, pParent)
 	{}
-
-};// struct CAMFImporter_NodeElement_Mesh
+};
 
 /// \struct CAMFImporter_NodeElement_Vertex
 /// Structure that define vertex node.
-struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement
-{
-	/// \fn CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
+struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement {
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Vertex, pParent)
 	{}
-
-};// struct CAMFImporter_NodeElement_Vertex
+};
 
 /// \struct CAMFImporter_NodeElement_Edge
 /// Structure that define edge node.
-struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement
-{
-	/// \fn CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
+struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement {
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Edge, pParent)
 	{}
 
-};// struct CAMFImporter_NodeElement_Vertex
+};
 
 /// \struct CAMFImporter_NodeElement_Vertices
 /// Structure that define vertices node.
-struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement
-{
-	/// \fn CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
+struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement {
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Vertices, pParent)
 	{}
-
-};// struct CAMFImporter_NodeElement_Vertices
+};
 
 /// \struct CAMFImporter_NodeElement_Volume
 /// Structure that define volume node.
-struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement
-{
-	/****************** Variables ******************/
-
+struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement {
 	std::string MaterialID;///< Which material to use.
 	std::string Type;///< What this volume describes can be “region” or “support”. If none specified, “object” is assumed.
 
-	/****************** Functions ******************/
-
-	/// \fn CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Volume, pParent)
 	{}
-
-};// struct CAMFImporter_NodeElement_Volume
+};
 
 /// \struct CAMFImporter_NodeElement_Coordinates
 /// Structure that define coordinates node.
 struct CAMFImporter_NodeElement_Coordinates : public CAMFImporter_NodeElement
 {
-	/****************** Variables ******************/
-
 	aiVector3D Coordinate;///< Coordinate.
 
-	/****************** Functions ******************/
-
-	/// \fn CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
 		: CAMFImporter_NodeElement(ENET_Coordinates, pParent)
 	{}
 
-};// struct CAMFImporter_NodeElement_Coordinates
+};
 
 /// \struct CAMFImporter_NodeElement_TexMap
 /// Structure that define texture coordinates node.
-struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement
-{
-	/****************** Variables ******************/
-
+struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement {
 	aiVector3D TextureCoordinate[3];///< Texture coordinates.
 	std::string TextureID_R;///< Texture ID for red color component.
 	std::string TextureID_G;///< Texture ID for green color component.
 	std::string TextureID_B;///< Texture ID for blue color component.
 	std::string TextureID_A;///< Texture ID for alpha color component.
 
-	/****************** Functions ******************/
-
-	/// \fn CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_TexMap, pParent)
-	{}
-
-};// struct CAMFImporter_NodeElement_TexMap
+	: CAMFImporter_NodeElement(ENET_TexMap, pParent)
+    , TextureCoordinate{}
+    , TextureID_R()
+    , TextureID_G()
+    , TextureID_B()
+    , TextureID_A()	{
+        // empty
+    }
+};
 
 /// \struct CAMFImporter_NodeElement_Triangle
 /// Structure that define triangle node.
-struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement
-{
-	/****************** Variables ******************/
-
+struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement {
 	size_t V[3];///< Triangle vertices.
 
-	/****************** Functions ******************/
-
-	/// \fn CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
-		: CAMFImporter_NodeElement(ENET_Triangle, pParent)
-	{}
-
-};// struct CAMFImporter_NodeElement_Triangle
+	: CAMFImporter_NodeElement(ENET_Triangle, pParent) {
+        // empty
+    }
+};
 
 /// Structure that define texture node.
 struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement {
@@ -395,6 +335,6 @@ struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement {
     , Tiled( false ){
         // empty
     }
-};// struct CAMFImporter_NodeElement_Texture
+};
 
 #endif // INCLUDED_AI_AMF_IMPORTER_NODE_H

+ 10 - 8
Engine/lib/assimp/code/AMFImporter_Postprocess.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -51,8 +52,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Header files, Assimp.
 #include <assimp/SceneCombiner.h>
-#include "StandardShapes.h"
-#include "StringUtils.h"
+#include <assimp/StandardShapes.h>
+#include <assimp/StringUtils.h>
 
 // Header files, stdlib.
 #include <iterator>
@@ -155,10 +156,11 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
 	TextureConverted_Index = 0;
 	for(const SPP_Texture& tex_convd: mTexture_Converted)
 	{
-		if(tex_convd.ID == TextureConverted_ID)
-			return TextureConverted_Index;
-		else
-			TextureConverted_Index++;
+        if ( tex_convd.ID == TextureConverted_ID ) {
+            return TextureConverted_Index;
+        } else {
+            ++TextureConverted_Index;
+        }
 	}
 
 	//
@@ -768,7 +770,7 @@ std::list<aiNode*> ch_node;
 		// find referenced object
 		if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID);
 
-		// create node for apllying transformation
+		// create node for applying transformation
 		t_node = new aiNode;
 		t_node->mParent = con_node;
 		// apply transformation

+ 20 - 20
Engine/lib/assimp/code/ASELoader.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -50,8 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // internal headers
 #include "ASELoader.h"
-#include "StringComparison.h"
-#include "SkeletonMeshBuilder.h"
+#include <assimp/StringComparison.h>
+#include <assimp/SkeletonMeshBuilder.h>
 #include "TargetAnimation.h"
 #include <assimp/Importer.hpp>
 #include <assimp/IOSystem.hpp>
@@ -62,7 +63,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <memory>
 
 // utilities
-#include "fast_atof.h"
+#include <assimp/fast_atof.h>
 
 using namespace Assimp;
 using namespace Assimp::ASE;
@@ -83,11 +84,11 @@ static const aiImporterDesc desc = {
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 ASEImporter::ASEImporter()
-    : mParser(),
-    mBuffer(),
-    pcScene(),
-    configRecomputeNormals(),
-    noSkeletonMesh()
+: mParser()
+, mBuffer()
+, pcScene()
+, configRecomputeNormals()
+, noSkeletonMesh()
 {}
 
 // ------------------------------------------------------------------------------------------------
@@ -199,7 +200,7 @@ void ASEImporter::InternReadFile( const std::string& pFile,
             ConvertMeshes(*i,avOutMeshes);
         }
         if (tookNormals)    {
-            DefaultLogger::get()->debug("ASE: Taking normals from the file. Use "
+            ASSIMP_LOG_DEBUG("ASE: Taking normals from the file. Use "
                 "the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS setting if you "
                 "experience problems");
         }
@@ -276,14 +277,13 @@ void ASEImporter::GenerateDefaultMaterial()
     }
     if (bHas || mParser->m_vMaterials.empty())  {
         // add a simple material without submaterials to the parser's list
-        mParser->m_vMaterials.push_back ( ASE::Material() );
+        mParser->m_vMaterials.push_back ( ASE::Material(AI_DEFAULT_MATERIAL_NAME) );
         ASE::Material& mat = mParser->m_vMaterials.back();
 
         mat.mDiffuse  = aiColor3D(0.6f,0.6f,0.6f);
         mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
         mat.mAmbient  = aiColor3D(0.05f,0.05f,0.05f);
         mat.mShading  = Discreet3DS::Gouraud;
-        mat.mName     = AI_DEFAULT_MATERIAL_NAME;
     }
 }
 
@@ -297,15 +297,15 @@ void ASEImporter::BuildAnimations(const std::vector<BaseNode*>& nodes)
 
         // TODO: Implement Bezier & TCB support
         if ((*i)->mAnim.mPositionType != ASE::Animation::TRACK) {
-            DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. "
+            ASSIMP_LOG_WARN("ASE: Position controller uses Bezier/TCB keys. "
                 "This is not supported.");
         }
         if ((*i)->mAnim.mRotationType != ASE::Animation::TRACK) {
-            DefaultLogger::get()->warn("ASE: Rotation controller uses Bezier/TCB keys. "
+            ASSIMP_LOG_WARN("ASE: Rotation controller uses Bezier/TCB keys. "
                 "This is not supported.");
         }
         if ((*i)->mAnim.mScalingType != ASE::Animation::TRACK)  {
-            DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. "
+            ASSIMP_LOG_WARN("ASE: Position controller uses Bezier/TCB keys. "
                 "This is not supported.");
         }
 
@@ -583,7 +583,7 @@ void ASEImporter::AddNodes (const std::vector<BaseNode*>& nodes,
         node->mTransformation = mParentAdjust*snode->mTransform;
 
         // Add sub nodes - prevent stack overflow due to recursive parenting
-        if (node->mName != node->mParent->mName) {
+        if (node->mName != node->mParent->mName && node->mName != node->mParent->mParent->mName ) {
             AddNodes(nodes,node,node->mName.data,snode->mTransform);
         }
 
@@ -624,7 +624,7 @@ void ASEImporter::AddNodes (const std::vector<BaseNode*>& nodes,
             node->mNumChildren++;
 
             // What we did is so great, it is at least worth a debug message
-            DefaultLogger::get()->debug("ASE: Generating separate target node ("+snode->mName+")");
+            ASSIMP_LOG_DEBUG("ASE: Generating separate target node ("+snode->mName+")");
         }
     }
 
@@ -947,7 +947,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
     // validate the material index of the mesh
     if (mesh.iMaterialIndex >= mParser->m_vMaterials.size())    {
         mesh.iMaterialIndex = (unsigned int)mParser->m_vMaterials.size()-1;
-        DefaultLogger::get()->warn("Material index is out of range");
+        ASSIMP_LOG_WARN("Material index is out of range");
     }
 
     // If the material the mesh is assigned to is consisting of submeshes, split it
@@ -957,11 +957,11 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
 
         std::vector<unsigned int>* aiSplit = new std::vector<unsigned int>[vSubMaterials.size()];
 
-        // build a list of all faces per submaterial
+        // build a list of all faces per sub-material
         for (unsigned int i = 0; i < mesh.mFaces.size();++i)    {
             // check range
             if (mesh.mFaces[i].iMaterial >= vSubMaterials.size()) {
-                DefaultLogger::get()->warn("Submaterial index is out of range");
+                ASSIMP_LOG_WARN("Submaterial index is out of range");
 
                 // use the last material instead
                 aiSplit[vSubMaterials.size()-1].push_back(i);

+ 3 - 2
Engine/lib/assimp/code/ASELoader.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -45,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_ASELOADER_H_INCLUDED
 #define AI_ASELOADER_H_INCLUDED
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <assimp/types.h>
 #include "ASEParser.h"
 

+ 36 - 33
Engine/lib/assimp/code/ASEParser.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -51,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "TextureTransform.h"
 #include "ASELoader.h"
-#include "fast_atof.h"
+#include <assimp/fast_atof.h>
 #include <assimp/DefaultLogger.hpp>
 
 using namespace Assimp;
@@ -150,7 +151,7 @@ void Parser::LogWarning(const char* szWarn)
 #endif
 
     // output the warning to the logger ...
-    DefaultLogger::get()->warn(szTemp);
+    ASSIMP_LOG_WARN(szTemp);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -166,7 +167,7 @@ void Parser::LogInfo(const char* szWarn)
 #endif
 
     // output the information to the logger ...
-    DefaultLogger::get()->info(szTemp);
+    ASSIMP_LOG_INFO(szTemp);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -266,7 +267,9 @@ void Parser::Parse()
                 // at the file extension (ASE, ASK, ASC)
                 // *************************************************************
 
-                if (fmt)iFileFormat = fmt;
+                if ( fmt ) {
+                    iFileFormat = fmt;
+                }
                 continue;
             }
             // main scene information
@@ -292,7 +295,7 @@ void Parser::Parse()
             if (TokenMatch(filePtr,"GEOMOBJECT",10))
 
             {
-                m_vMeshes.push_back(Mesh());
+                m_vMeshes.push_back(Mesh("UNNAMED"));
                 ParseLV1ObjectBlock(m_vMeshes.back());
                 continue;
             }
@@ -308,14 +311,14 @@ void Parser::Parse()
             if (TokenMatch(filePtr,"LIGHTOBJECT",11))
 
             {
-                m_vLights.push_back(Light());
+                m_vLights.push_back(Light("UNNAMED"));
                 ParseLV1ObjectBlock(m_vLights.back());
                 continue;
             }
             // camera object
             if (TokenMatch(filePtr,"CAMERAOBJECT",12))
             {
-                m_vCameras.push_back(Camera());
+                m_vCameras.push_back(Camera("UNNAMED"));
                 ParseLV1ObjectBlock(m_vCameras.back());
                 continue;
             }
@@ -426,28 +429,25 @@ void Parser::ParseLV1SoftSkinBlock()
                         // Reserve enough storage
                         vert.mBoneWeights.reserve(numWeights);
 
-                        for (unsigned int w = 0; w < numWeights;++w)
-                        {
-                            std::string bone;
+                        std::string bone;
+                        for (unsigned int w = 0; w < numWeights;++w) {
+                            bone.clear();
                             ParseString(bone,"*MESH_SOFTSKINVERTS.Bone");
 
                             // Find the bone in the mesh's list
                             std::pair<int,ai_real> me;
                             me.first = -1;
 
-                            for (unsigned int n = 0; n < curMesh->mBones.size();++n)
-                            {
-                                if (curMesh->mBones[n].mName == bone)
-                                {
+                            for (unsigned int n = 0; n < curMesh->mBones.size();++n) {
+                                if (curMesh->mBones[n].mName == bone) {
                                     me.first = n;
                                     break;
                                 }
                             }
-                            if (-1 == me.first)
-                            {
+                            if (-1 == me.first) {
                                 // We don't have this bone yet, so add it to the list
-                                me.first = (int)curMesh->mBones.size();
-                                curMesh->mBones.push_back(ASE::Bone(bone));
+                                me.first = static_cast<int>( curMesh->mBones.size() );
+                                curMesh->mBones.push_back( ASE::Bone( bone ) );
                             }
                             ParseLV4MeshFloat( me.second );
 
@@ -528,7 +528,7 @@ void Parser::ParseLV1MaterialListBlock()
                 ParseLV4MeshLong(iMaterialCount);
 
                 // now allocate enough storage to hold all materials
-                m_vMaterials.resize(iOldMaterialCount+iMaterialCount);
+                m_vMaterials.resize(iOldMaterialCount+iMaterialCount, Material("INVALID"));
                 continue;
             }
             if (TokenMatch(filePtr,"MATERIAL",8))
@@ -706,7 +706,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
                 ParseLV4MeshLong(iNumSubMaterials);
 
                 // allocate enough storage
-                mat.avSubMaterials.resize(iNumSubMaterials);
+                mat.avSubMaterials.resize(iNumSubMaterials, Material("INVALID SUBMATERIAL"));
             }
             // submaterial chunks
             if (TokenMatch(filePtr,"SUBMATERIAL",11))
@@ -744,6 +744,7 @@ void Parser::ParseLV3MapBlock(Texture& map)
     // empty the texture won't be used later.
     // ***********************************************************
     bool parsePath = true;
+    std::string temp;
     while (true)
     {
         if ('*' == *filePtr)
@@ -752,12 +753,12 @@ void Parser::ParseLV3MapBlock(Texture& map)
             // type of map
             if (TokenMatch(filePtr,"MAP_CLASS" ,9))
             {
-                std::string temp;
+                temp.clear();
                 if(!ParseString(temp,"*MAP_CLASS"))
                     SkipToNextToken();
                 if (temp != "Bitmap" && temp != "Normal Bump")
                 {
-                    DefaultLogger::get()->warn("ASE: Skipping unknown map type: " + temp);
+                    ASSIMP_LOG_WARN_F("ASE: Skipping unknown map type: ", temp);
                     parsePath = false;
                 }
                 continue;
@@ -772,7 +773,7 @@ void Parser::ParseLV3MapBlock(Texture& map)
                 {
                     // Files with 'None' as map name are produced by
                     // an Maja to ASE exporter which name I forgot ..
-                    DefaultLogger::get()->warn("ASE: Skipping invalid map entry");
+                    ASSIMP_LOG_WARN("ASE: Skipping invalid map entry");
                     map.mMapName = "";
                 }
 
@@ -1071,7 +1072,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
                         ( mesh.mType != BaseNode::Light  || ((ASE::Light&)mesh).mLightType   != ASE::Light::TARGET))
                     {
 
-                        DefaultLogger::get()->error("ASE: Found target animation channel "
+                        ASSIMP_LOG_ERROR("ASE: Found target animation channel "
                             "but the node is neither a camera nor a spot light");
                         anim = NULL;
                     }
@@ -1097,7 +1098,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
                 if (!anim || anim == &mesh.mTargetAnim)
                 {
                     // Target animation channels may have no rotation channels
-                    DefaultLogger::get()->error("ASE: Ignoring scaling channel in target animation");
+                    ASSIMP_LOG_ERROR("ASE: Ignoring scaling channel in target animation");
                     SkipSection();
                 }
                 else ParseLV3ScaleAnimationBlock(*anim);
@@ -1111,7 +1112,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
                 if (!anim || anim == &mesh.mTargetAnim)
                 {
                     // Target animation channels may have no rotation channels
-                    DefaultLogger::get()->error("ASE: Ignoring rotation channel in target animation");
+                    ASSIMP_LOG_ERROR("ASE: Ignoring rotation channel in target animation");
                     SkipSection();
                 }
                 else ParseLV3RotAnimationBlock(*anim);
@@ -1294,12 +1295,14 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode& mesh)
                     {
                         mode = 2;
                     }
-                    else DefaultLogger::get()->error("ASE: Ignoring target transform, "
-                        "this is no spot light or target camera");
+                    else {
+                        ASSIMP_LOG_ERROR("ASE: Ignoring target transform, "
+                            "this is no spot light or target camera");
+                    }
                 }
                 else
                 {
-                    DefaultLogger::get()->error("ASE: Unknown node transformation: " + temp);
+                    ASSIMP_LOG_ERROR("ASE: Unknown node transformation: " + temp);
                     // mode = 0
                 }
                 continue;
@@ -1553,7 +1556,7 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
 void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh)
 {
     AI_ASE_PARSER_INIT();
-    mesh.mBones.resize(iNumBones);
+    mesh.mBones.resize(iNumBones, Bone("UNNAMED"));
     while (true)
     {
         if ('*' == *filePtr)
@@ -1915,7 +1918,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
                 else if (index == face.mIndices[2])
                     index = 2;
                 else    {
-                    DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_VERTEXNORMAL section");
+                    ASSIMP_LOG_ERROR("ASE: Invalid vertex index in MESH_VERTEXNORMAL section");
                     continue;
                 }
                 // We'll renormalize later
@@ -1927,7 +1930,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
                 ParseLV4MeshFloatTriple(&vNormal.x,faceIdx);
 
                 if (faceIdx >= sMesh.mFaces.size()) {
-                    DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_FACENORMAL section");
+                    ASSIMP_LOG_ERROR("ASE: Invalid vertex index in MESH_FACENORMAL section");
                     continue;
                 }
 

+ 127 - 103
Engine/lib/assimp/code/ASEParser.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -52,8 +53,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
 
 // for some helper routines like IsSpace()
-#include "ParsingUtils.h"
-#include "qnan.h"
+#include <assimp/ParsingUtils.h>
+#include <assimp/qnan.h>
 
 // ASE is quite similar to 3ds. We can reuse some structures
 #include "3DSLoader.h"
@@ -67,9 +68,51 @@ using namespace D3DS;
 /** Helper structure representing an ASE material */
 struct Material : public D3DS::Material
 {
-    //! Default constructor
-    Material() : pcInstance(NULL), bNeed (false)
-    {}
+    //! Default constructor has been deleted
+    Material() = delete;
+
+    //! Constructor with explicit name
+    explicit Material(const std::string &name)
+    : D3DS::Material(name)
+    , pcInstance(NULL)
+    , bNeed (false) {
+        // empty
+    }
+
+    Material(const Material &other)            = default;
+    Material &operator=(const Material &other) = default;
+
+
+    //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
+    Material(Material &&other) AI_NO_EXCEPT
+    : D3DS::Material(std::move(other))
+    , avSubMaterials(std::move(other.avSubMaterials))
+    , pcInstance(std::move(other.pcInstance))
+    , bNeed(std::move(other.bNeed))
+    {
+        other.pcInstance = nullptr;
+    }
+
+
+    Material &operator=(Material &&other) AI_NO_EXCEPT {
+        if (this == &other) {
+            return *this;
+        }
+
+        D3DS::Material::operator=(std::move(other));
+
+        avSubMaterials = std::move(other.avSubMaterials);
+        pcInstance = std::move(other.pcInstance);
+        bNeed = std::move(other.bNeed);
+
+        other.pcInstance = nullptr;
+
+        return *this;
+    }
+
+
+    ~Material() {}
+
 
     //! Contains all sub materials of this material
     std::vector<Material> avSubMaterials;
@@ -83,19 +126,12 @@ struct Material : public D3DS::Material
 
 // ---------------------------------------------------------------------------
 /** Helper structure to represent an ASE file face */
-struct Face : public FaceWithSmoothingGroup
-{
+struct Face : public FaceWithSmoothingGroup {
     //! Default constructor. Initializes everything with 0
-    Face()
-    {
-        mColorIndices[0] = mColorIndices[1] = mColorIndices[2] = 0;
-        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
-        {
-            amUVIndices[i][0] = amUVIndices[i][1] = amUVIndices[i][2] = 0;
-        }
-
-        iMaterial = DEFAULT_MATINDEX;
-        iFace = 0;
+    Face() AI_NO_EXCEPT
+    : iMaterial(DEFAULT_MATINDEX)
+    , iFace(0) {
+        // empty
     }
 
     //! special value to indicate that no material index has
@@ -103,8 +139,6 @@ struct Face : public FaceWithSmoothingGroup
     //! will replace this value later.
     static const unsigned int DEFAULT_MATINDEX = 0xFFFFFFFF;
 
-
-
     //! Indices into each list of texture coordinates
     unsigned int amUVIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS][3];
 
@@ -122,23 +156,15 @@ struct Face : public FaceWithSmoothingGroup
 
 // ---------------------------------------------------------------------------
 /** Helper structure to represent an ASE file bone */
-struct Bone
-{
+struct Bone {
     //! Constructor
-    Bone()
-    {
-        static int iCnt = 0;
-
-        // Generate a default name for the bone
-        char szTemp[128];
-        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
-        mName = szTemp;
-    }
+    Bone() = delete;
 
     //! Construction from an existing name
     explicit Bone( const std::string& name)
-        :   mName   (name)
-    {}
+    : mName(name) {
+        // empty
+    }
 
     //! Name of the bone
     std::string mName;
@@ -146,29 +172,22 @@ struct Bone
 
 // ---------------------------------------------------------------------------
 /** Helper structure to represent an ASE file bone vertex */
-struct BoneVertex
-{
+struct BoneVertex {
     //! Bone and corresponding vertex weight.
     //! -1 for unrequired bones ....
     std::vector<std::pair<int,float> > mBoneWeights;
-
-    //! Position of the bone vertex.
-    //! MUST be identical to the vertex position
-    //aiVector3D mPosition;
 };
 
 // ---------------------------------------------------------------------------
 /** Helper structure to represent an ASE file animation */
-struct Animation
-{
-    enum Type
-    {
+struct Animation {
+    enum Type {
         TRACK   = 0x0,
         BEZIER  = 0x1,
         TCB     = 0x2
     } mRotationType, mScalingType, mPositionType;
 
-    Animation()
+    Animation() AI_NO_EXCEPT
         :   mRotationType   (TRACK)
         ,   mScalingType    (TRACK)
         ,   mPositionType   (TRACK)
@@ -182,19 +201,16 @@ struct Animation
 
     //! List of track scaling keyframes
     std::vector< aiVectorKey > akeyScaling;
-
 };
 
 // ---------------------------------------------------------------------------
 /** Helper structure to represent the inheritance information of an ASE node */
-struct InheritanceInfo
-{
+struct InheritanceInfo {
     //! Default constructor
-    InheritanceInfo()
-    {
-        // set the inheritance flag for all axes by default to true
-        for (unsigned int i = 0; i < 3;++i)
+    InheritanceInfo() AI_NO_EXCEPT {
+        for ( size_t i=0; i<3; ++i ) {
             abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
+        }
     }
 
     //! Inherit the parent's position?, axis order is x,y,z
@@ -209,26 +225,25 @@ struct InheritanceInfo
 
 // ---------------------------------------------------------------------------
 /** Represents an ASE file node. Base class for mesh, light and cameras */
-struct BaseNode
-{
-    enum Type {Light, Camera, Mesh, Dummy} mType;
-
-    //! Constructor. Creates a default name for the node
-    explicit BaseNode(Type _mType)
-        : mType         (_mType)
-        , mProcessed    (false)
-    {
-        // generate a default name for the  node
-        static int iCnt = 0;
-        char szTemp[128]; // should be sufficiently large
-        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
-        mName = szTemp;
+struct BaseNode {
+    enum Type {
+        Light, 
+        Camera, 
+        Mesh, 
+        Dummy
+    } mType;
 
+    //! Construction from an existing name
+    BaseNode(Type _mType, const std::string &name)
+    : mType         (_mType)
+    , mName         (name)
+    , mProcessed    (false) {
         // Set mTargetPosition to qnan
         const ai_real qnan = get_qnan();
         mTargetPosition.x = qnan;
     }
 
+
     //! Name of the mesh
     std::string mName;
 
@@ -258,19 +273,21 @@ struct BaseNode
 
 // ---------------------------------------------------------------------------
 /** Helper structure to represent an ASE file mesh */
-struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode
-{
-    //! Constructor.
-    Mesh()
-        : BaseNode  (BaseNode::Mesh)
-        , bSkip     (false)
-    {
-        // use 2 texture vertex components by default
-        for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
-            this->mNumUVComponents[c] = 2;
+struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode {
+    //! Default constructor has been deleted
+    Mesh() = delete;
 
-        // setup the default material index by default
-        iMaterialIndex = Face::DEFAULT_MATINDEX;
+    //! Construction from an existing name
+    explicit Mesh(const std::string &name)
+    : BaseNode( BaseNode::Mesh, name )
+    , mVertexColors()
+    , mBoneVertices()
+    , mBones()
+    , iMaterialIndex(Face::DEFAULT_MATINDEX)
+    , bSkip     (false) {
+        for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
+            this->mNumUVComponents[c] = 2;
+        }
     }
 
     //! List of all texture coordinate sets
@@ -307,17 +324,21 @@ struct Light : public BaseNode
         DIRECTIONAL
     };
 
-    //! Constructor.
-    Light()
-        : BaseNode   (BaseNode::Light)
-        , mLightType (OMNI)
-        , mColor     (1.f,1.f,1.f)
-        , mIntensity (1.f) // light is white by default
-        , mAngle     (45.f)
-        , mFalloff   (0.f)
+    //! Default constructor has been deleted
+    Light() = delete;
+
+    //! Construction from an existing name
+    explicit Light(const std::string &name)
+    : BaseNode   (BaseNode::Light, name)
+    , mLightType (OMNI)
+    , mColor     (1.f,1.f,1.f)
+    , mIntensity (1.f) // light is white by default
+    , mAngle     (45.f)
+    , mFalloff   (0.f)
     {
     }
 
+
     LightType mLightType;
     aiColor3D mColor;
     ai_real mIntensity;
@@ -335,28 +356,32 @@ struct Camera : public BaseNode
         TARGET
     };
 
-    //! Constructor
-    Camera()
-        : BaseNode    (BaseNode::Camera)
-        , mFOV        (0.75f)   // in radians
-        , mNear       (0.1f)
-        , mFar        (1000.f)  // could be zero
-        , mCameraType (FREE)
+    //! Default constructor has been deleted
+    Camera() = delete;
+
+
+    //! Construction from an existing name
+    explicit Camera(const std::string &name)
+    : BaseNode    (BaseNode::Camera, name)
+    , mFOV        (0.75f)   // in radians
+    , mNear       (0.1f)
+    , mFar        (1000.f)  // could be zero
+    , mCameraType (FREE)
     {
     }
 
+
     ai_real mFOV, mNear, mFar;
     CameraType mCameraType;
 };
 
 // ---------------------------------------------------------------------------
 /** Helper structure to represent an ASE helper object (dummy) */
-struct Dummy : public BaseNode
-{
+struct Dummy : public BaseNode {
     //! Constructor
-    Dummy()
-        : BaseNode  (BaseNode::Dummy)
-    {
+    Dummy() AI_NO_EXCEPT
+    : BaseNode  (BaseNode::Dummy, "DUMMY") {
+        // empty
     }
 };
 
@@ -371,18 +396,17 @@ struct Dummy : public BaseNode
 // -------------------------------------------------------------------------------
 /** \brief Class to parse ASE files
  */
-class Parser
-{
-
+class Parser {
 private:
-
-    Parser() {}
+    Parser() AI_NO_EXCEPT {
+        // empty
+    }
 
 public:
 
     // -------------------------------------------------------------------
     //! Construct a parser from a given input file which is
-    //! guaranted to be terminated with zero.
+    //! guaranteed to be terminated with zero.
     //! @param szFile Input file
     //! @param fileFormatDefault Assumed file format version. If the
     //!   file format is specified in the file the new value replaces

+ 539 - 516
Engine/lib/assimp/code/AssbinExporter.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -41,13 +42,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file  AssbinExporter.cpp
  *  ASSBIN exporter main code
  */
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
+
 #include "assbin_chunks.h"
 #include <assimp/version.h>
 #include <assimp/IOStream.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/Exporter.hpp>
 #include "ProcessHelper.h"
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 
 #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
 #   include <zlib.h>
@@ -57,152 +62,154 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <time.h>
 
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
-
-using namespace Assimp;
-
-namespace Assimp    {
+namespace Assimp {
 
 template <typename T>
-size_t Write(IOStream * stream, const T& v)
-{
+size_t Write(IOStream * stream, const T& v) {
     return stream->Write( &v, sizeof(T), 1 );
 }
 
-
 // -----------------------------------------------------------------------------------
 // Serialize an aiString
 template <>
-inline size_t Write<aiString>(IOStream * stream, const aiString& s)
-{
+inline
+size_t Write<aiString>(IOStream * stream, const aiString& s) {
     const size_t s2 = (uint32_t)s.length;
     stream->Write(&s,4,1);
     stream->Write(s.data,s2,1);
+
     return s2+4;
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize an unsigned int as uint32_t
 template <>
-inline size_t Write<unsigned int>(IOStream * stream, const unsigned int& w)
-{
+inline
+size_t Write<unsigned int>(IOStream * stream, const unsigned int& w) {
     const uint32_t t = (uint32_t)w;
     if (w > t) {
         // this shouldn't happen, integers in Assimp data structures never exceed 2^32
-        throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion");
+        throw DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion");
     }
 
     stream->Write(&t,4,1);
+
     return 4;
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize an unsigned int as uint16_t
 template <>
-inline size_t Write<uint16_t>(IOStream * stream, const uint16_t& w)
-{
+inline
+size_t Write<uint16_t>(IOStream * stream, const uint16_t& w) {
     static_assert(sizeof(uint16_t)==2, "sizeof(uint16_t)==2");
     stream->Write(&w,2,1);
+
     return 2;
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize a float
 template <>
-inline size_t Write<float>(IOStream * stream, const float& f)
-{
+inline
+size_t Write<float>(IOStream * stream, const float& f) {
     static_assert(sizeof(float)==4, "sizeof(float)==4");
     stream->Write(&f,4,1);
+
     return 4;
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize a double
 template <>
-inline size_t Write<double>(IOStream * stream, const double& f)
-{
+inline
+size_t Write<double>(IOStream * stream, const double& f) {
     static_assert(sizeof(double)==8, "sizeof(double)==8");
     stream->Write(&f,8,1);
+
     return 8;
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize a vec3
 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);
     t += Write<float>(stream,v.y);
     t += Write<float>(stream,v.z);
+
     return t;
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize a color value
 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);
     t += Write<float>(stream,v.g);
     t += Write<float>(stream,v.b);
+
     return t;
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize a color value
 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);
     t += Write<float>(stream,v.g);
     t += Write<float>(stream,v.b);
     t += Write<float>(stream,v.a);
+
     return t;
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize a quaternion
 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);
     t += Write<float>(stream,v.x);
     t += Write<float>(stream,v.y);
     t += Write<float>(stream,v.z);
     ai_assert(t == 16);
+
     return 16;
 }
 
-
 // -----------------------------------------------------------------------------------
 // Serialize a vertex weight
 template <>
-inline size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v)
-{
+inline
+size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v) {
     size_t t = Write<unsigned int>(stream,v.mVertexId);
+
     return t+Write<float>(stream,v.mWeight);
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize a mat4x4
 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 i2 = 0; i2 < 4;++i2) {
             Write<float>(stream,m[i][i2]);
         }
     }
+
     return 64;
 }
 
 // -----------------------------------------------------------------------------------
 // Serialize an aiVectorKey
 template <>
-inline size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v)
-{
+inline
+size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v) {
     const size_t t = Write<double>(stream,v.mTime);
     return t + Write<aiVector3D>(stream,v.mValue);
 }
@@ -210,16 +217,16 @@ inline size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v)
 // -----------------------------------------------------------------------------------
 // Serialize an aiQuatKey
 template <>
-inline size_t Write<aiQuatKey>(IOStream * stream, const aiQuatKey& v)
-{
+inline
+size_t Write<aiQuatKey>(IOStream * stream, const aiQuatKey& v) {
     const size_t t = Write<double>(stream,v.mTime);
     return t + Write<aiQuaternion>(stream,v.mValue);
 }
 
 template <typename T>
-inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size)
-{
-    T minc,maxc;
+inline
+size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) {
+    T minc, maxc;
     ArrayBounds(in,size,minc,maxc);
 
     const size_t t = Write<T>(stream,minc);
@@ -229,590 +236,606 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size)
 // We use this to write out non-byte arrays so that we write using the specializations.
 // This way we avoid writing out extra bytes that potentially come from struct alignment.
 template <typename T>
-inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
-{
+inline
+size_t WriteArray(IOStream * stream, const T* in, unsigned int size) {
     size_t n = 0;
     for (unsigned int i=0; i<size; i++) n += Write<T>(stream,in[i]);
+
     return n;
 }
 
-    // ----------------------------------------------------------------------------------
-    /** @class  AssbinChunkWriter
-     *  @brief  Chunk writer mechanism for the .assbin file structure
-     *
-     *  This is a standard in-memory IOStream (most of the code is based on BlobIOStream),
-     *  the difference being that this takes another IOStream as a "container" in the
-     *  constructor, and when it is destroyed, it appends the magic number, the chunk size,
-     *  and the chunk contents to the container stream. This allows relatively easy chunk
-     *  chunk construction, even recursively.
-     */
-    class AssbinChunkWriter : public IOStream
-    {
-    private:
+// ----------------------------------------------------------------------------------
+/** @class  AssbinChunkWriter
+ *  @brief  Chunk writer mechanism for the .assbin file structure
+ *
+ *  This is a standard in-memory IOStream (most of the code is based on BlobIOStream),
+ *  the difference being that this takes another IOStream as a "container" in the
+ *  constructor, and when it is destroyed, it appends the magic number, the chunk size,
+ *  and the chunk contents to the container stream. This allows relatively easy chunk
+ *  chunk construction, even recursively.
+ */
+class AssbinChunkWriter : public IOStream
+{
+private:
 
-        uint8_t* buffer;
-        uint32_t magic;
-        IOStream * container;
-        size_t cur_size, cursor, initial;
+    uint8_t* buffer;
+    uint32_t magic;
+    IOStream * container;
+    size_t cur_size, cursor, initial;
 
-    private:
-        // -------------------------------------------------------------------
-        void Grow(size_t need = 0)
-        {
-            size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
-
-            const uint8_t* const old = buffer;
-            buffer = new uint8_t[new_size];
+private:
+    // -------------------------------------------------------------------
+    void Grow(size_t need = 0)
+    {
+        size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
 
-            if (old) {
-                memcpy(buffer,old,cur_size);
-                delete[] old;
-            }
+        const uint8_t* const old = buffer;
+        buffer = new uint8_t[new_size];
 
-            cur_size = new_size;
+        if (old) {
+            memcpy(buffer,old,cur_size);
+            delete[] old;
         }
 
-    public:
+        cur_size = new_size;
+    }
 
-        AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096)
-            : buffer(NULL), magic(magic), container(container), cur_size(0), cursor(0), initial(initial)
-        {
-        }
+public:
 
-        virtual ~AssbinChunkWriter()
-        {
-            if (container) {
-                container->Write( &magic, sizeof(uint32_t), 1 );
-                container->Write( &cursor, sizeof(uint32_t), 1 );
-                container->Write( buffer, 1, cursor );
-            }
-            if (buffer) delete[] buffer;
+    AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096)
+        : buffer(NULL), magic(magic), container(container), cur_size(0), cursor(0), initial(initial)
+    {
+    }
+
+    virtual ~AssbinChunkWriter()
+    {
+        if (container) {
+            container->Write( &magic, sizeof(uint32_t), 1 );
+            container->Write( &cursor, sizeof(uint32_t), 1 );
+            container->Write( buffer, 1, cursor );
         }
+        if (buffer) delete[] buffer;
+    }
 
-        void * GetBufferPointer() { return buffer; }
+    void * GetBufferPointer() { return buffer; }
+
+    // -------------------------------------------------------------------
+    virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) {
+        return 0;
+    }
+    virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) {
+        return aiReturn_FAILURE;
+    }
+    virtual size_t Tell() const {
+        return cursor;
+    }
+    virtual void Flush() {
+        // not implemented
+    }
 
-        // -------------------------------------------------------------------
-        virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { return 0; }
-        virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { return aiReturn_FAILURE; }
-        virtual size_t Tell() const { return cursor; }
-        virtual void Flush() { }
+    virtual size_t FileSize() const {
+        return cursor;
+    }
 
-        virtual size_t FileSize() const
-        {
-            return cursor;
+    // -------------------------------------------------------------------
+    virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) {
+        pSize *= pCount;
+        if (cursor + pSize > cur_size) {
+            Grow(cursor + pSize);
         }
 
-        // -------------------------------------------------------------------
-        virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount)
-        {
-            pSize *= pCount;
-            if (cursor + pSize > cur_size) {
-                Grow(cursor + pSize);
-            }
+        memcpy(buffer+cursor, pvBuffer, pSize);
+        cursor += pSize;
 
-            memcpy(buffer+cursor, pvBuffer, pSize);
-            cursor += pSize;
+        return pCount;
+    }
 
-            return pCount;
-        }
+};
 
-    };
+// ----------------------------------------------------------------------------------
+/** @class  AssbinExport
+ *  @brief  Assbin exporter class
+ *
+ *  This class performs the .assbin exporting, and is responsible for the file layout.
+ */
+class AssbinExport
+{
+private:
+    bool shortened;
+    bool compressed;
 
-    // ----------------------------------------------------------------------------------
-    /** @class  AssbinExport
-     *  @brief  Assbin exporter class
-     *
-     *  This class performs the .assbin exporting, and is responsible for the file layout.
-     */
-    class AssbinExport
+protected:
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryNode( IOStream * container, const aiNode* node)
     {
-    private:
-        bool shortened;
-        bool compressed;
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE );
 
-    protected:
+        unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
 
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryNode( IOStream * container, const aiNode* node)
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE );
+        Write<aiString>(&chunk,node->mName);
+        Write<aiMatrix4x4>(&chunk,node->mTransformation);
+        Write<unsigned int>(&chunk,node->mNumChildren);
+        Write<unsigned int>(&chunk,node->mNumMeshes);
+        Write<unsigned int>(&chunk,nb_metadata);
 
-			unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
+        for (unsigned int i = 0; i < node->mNumMeshes;++i) {
+            Write<unsigned int>(&chunk,node->mMeshes[i]);
+        }
 
-            Write<aiString>(&chunk,node->mName);
-            Write<aiMatrix4x4>(&chunk,node->mTransformation);
-            Write<unsigned int>(&chunk,node->mNumChildren);
-            Write<unsigned int>(&chunk,node->mNumMeshes);
-			Write<unsigned int>(&chunk,nb_metadata);
+        for (unsigned int i = 0; i < node->mNumChildren;++i) {
+            WriteBinaryNode( &chunk, node->mChildren[i] );
+        }
 
-            for (unsigned int i = 0; i < node->mNumMeshes;++i) {
-                Write<unsigned int>(&chunk,node->mMeshes[i]);
-            }
+        for (unsigned int i = 0; i < nb_metadata; ++i) {
+            const aiString& key = node->mMetaData->mKeys[i];
+            aiMetadataType type = node->mMetaData->mValues[i].mType;
+            void* value = node->mMetaData->mValues[i].mData;
 
-            for (unsigned int i = 0; i < node->mNumChildren;++i) {
-                WriteBinaryNode( &chunk, node->mChildren[i] );
-            }
+            Write<aiString>(&chunk, key);
+            Write<uint16_t>(&chunk, type);
 
-			for (unsigned int i = 0; i < nb_metadata; ++i) {
-				const aiString& key = node->mMetaData->mKeys[i];
-				aiMetadataType type = node->mMetaData->mValues[i].mType;
-				void* value = node->mMetaData->mValues[i].mData;
-
-				Write<aiString>(&chunk, key);
-				Write<uint16_t>(&chunk, type);
-				
-				switch (type) {
-                    case AI_BOOL:
-                        Write<bool>(&chunk, *((bool*) value));
-                        break;
-                    case AI_INT32:
-                        Write<int32_t>(&chunk, *((int32_t*) value));
-                        break;
-                    case AI_UINT64:
-                        Write<uint64_t>(&chunk, *((uint64_t*) value));
-                        break;
-                    case AI_FLOAT:
-                        Write<float>(&chunk, *((float*) value));
-                        break;
-                    case AI_DOUBLE:
-                        Write<double>(&chunk, *((double*) value));
-                        break;
-                    case AI_AISTRING:
-                        Write<aiString>(&chunk, *((aiString*) value));
-                        break;
-                    case AI_AIVECTOR3D:
-                        Write<aiVector3D>(&chunk, *((aiVector3D*) value));
-                        break;
+            switch (type) {
+                case AI_BOOL:
+                    Write<bool>(&chunk, *((bool*) value));
+                    break;
+                case AI_INT32:
+                    Write<int32_t>(&chunk, *((int32_t*) value));
+                    break;
+                case AI_UINT64:
+                    Write<uint64_t>(&chunk, *((uint64_t*) value));
+                    break;
+                case AI_FLOAT:
+                    Write<float>(&chunk, *((float*) value));
+                    break;
+                case AI_DOUBLE:
+                    Write<double>(&chunk, *((double*) value));
+                    break;
+                case AI_AISTRING:
+                    Write<aiString>(&chunk, *((aiString*) value));
+                    break;
+                case AI_AIVECTOR3D:
+                    Write<aiVector3D>(&chunk, *((aiVector3D*) value));
+                    break;
 #ifdef SWIG
-                    case FORCE_32BIT:
+                case FORCE_32BIT:
 #endif // SWIG
-                    default:
-                        break;
-				}
-			}
+                default:
+                    break;
+            }
         }
+    }
 
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryTexture(IOStream * container, const aiTexture* tex)
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE );
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryTexture(IOStream * container, const aiTexture* tex)
+    {
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE );
 
-            Write<unsigned int>(&chunk,tex->mWidth);
-            Write<unsigned int>(&chunk,tex->mHeight);
-            chunk.Write( tex->achFormatHint, sizeof(char), 4 );
+        Write<unsigned int>(&chunk,tex->mWidth);
+        Write<unsigned int>(&chunk,tex->mHeight);
+        chunk.Write( tex->achFormatHint, sizeof(char), 4 );
 
-            if(!shortened) {
-                if (!tex->mHeight) {
-                    chunk.Write(tex->pcData,1,tex->mWidth);
-                }
-                else {
-                    chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4);
-                }
+        if(!shortened) {
+            if (!tex->mHeight) {
+                chunk.Write(tex->pcData,1,tex->mWidth);
+            }
+            else {
+                chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4);
             }
-
         }
 
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryBone(IOStream * container, const aiBone* b)
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE );
+    }
 
-            Write<aiString>(&chunk,b->mName);
-            Write<unsigned int>(&chunk,b->mNumWeights);
-            Write<aiMatrix4x4>(&chunk,b->mOffsetMatrix);
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryBone(IOStream * container, const aiBone* b)
+    {
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE );
+
+        Write<aiString>(&chunk,b->mName);
+        Write<unsigned int>(&chunk,b->mNumWeights);
+        Write<aiMatrix4x4>(&chunk,b->mOffsetMatrix);
+
+        // for the moment we write dumb min/max values for the bones, too.
+        // maybe I'll add a better, hash-like solution later
+        if (shortened) {
+            WriteBounds(&chunk,b->mWeights,b->mNumWeights);
+        } // else write as usual
+        else WriteArray<aiVertexWeight>(&chunk,b->mWeights,b->mNumWeights);
+    }
 
-            // for the moment we write dumb min/max values for the bones, too.
-            // maybe I'll add a better, hash-like solution later
-            if (shortened) {
-                WriteBounds(&chunk,b->mWeights,b->mNumWeights);
-            } // else write as usual
-            else WriteArray<aiVertexWeight>(&chunk,b->mWeights,b->mNumWeights);
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryMesh(IOStream * container, const aiMesh* mesh)
+    {
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH );
+
+        Write<unsigned int>(&chunk,mesh->mPrimitiveTypes);
+        Write<unsigned int>(&chunk,mesh->mNumVertices);
+        Write<unsigned int>(&chunk,mesh->mNumFaces);
+        Write<unsigned int>(&chunk,mesh->mNumBones);
+        Write<unsigned int>(&chunk,mesh->mMaterialIndex);
+
+        // first of all, write bits for all existent vertex components
+        unsigned int c = 0;
+        if (mesh->mVertices) {
+            c |= ASSBIN_MESH_HAS_POSITIONS;
         }
-
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryMesh(IOStream * container, const aiMesh* mesh)
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH );
-
-            Write<unsigned int>(&chunk,mesh->mPrimitiveTypes);
-            Write<unsigned int>(&chunk,mesh->mNumVertices);
-            Write<unsigned int>(&chunk,mesh->mNumFaces);
-            Write<unsigned int>(&chunk,mesh->mNumBones);
-            Write<unsigned int>(&chunk,mesh->mMaterialIndex);
-
-            // first of all, write bits for all existent vertex components
-            unsigned int c = 0;
-            if (mesh->mVertices) {
-                c |= ASSBIN_MESH_HAS_POSITIONS;
-            }
-            if (mesh->mNormals) {
-                c |= ASSBIN_MESH_HAS_NORMALS;
-            }
-            if (mesh->mTangents && mesh->mBitangents) {
-                c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS;
-            }
-            for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
-                if (!mesh->mTextureCoords[n]) {
-                    break;
-                }
-                c |= ASSBIN_MESH_HAS_TEXCOORD(n);
-            }
-            for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
-                if (!mesh->mColors[n]) {
-                    break;
-                }
-                c |= ASSBIN_MESH_HAS_COLOR(n);
-            }
-            Write<unsigned int>(&chunk,c);
-
-            aiVector3D minVec, maxVec;
-            if (mesh->mVertices) {
-                if (shortened) {
-                    WriteBounds(&chunk,mesh->mVertices,mesh->mNumVertices);
-                } // else write as usual
-                else WriteArray<aiVector3D>(&chunk,mesh->mVertices,mesh->mNumVertices);
-            }
-            if (mesh->mNormals) {
-                if (shortened) {
-                    WriteBounds(&chunk,mesh->mNormals,mesh->mNumVertices);
-                } // else write as usual
-                else WriteArray<aiVector3D>(&chunk,mesh->mNormals,mesh->mNumVertices);
+        if (mesh->mNormals) {
+            c |= ASSBIN_MESH_HAS_NORMALS;
+        }
+        if (mesh->mTangents && mesh->mBitangents) {
+            c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS;
+        }
+        for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
+            if (!mesh->mTextureCoords[n]) {
+                break;
             }
-            if (mesh->mTangents && mesh->mBitangents) {
-                if (shortened) {
-                    WriteBounds(&chunk,mesh->mTangents,mesh->mNumVertices);
-                    WriteBounds(&chunk,mesh->mBitangents,mesh->mNumVertices);
-                } // else write as usual
-                else {
-                    WriteArray<aiVector3D>(&chunk,mesh->mTangents,mesh->mNumVertices);
-                    WriteArray<aiVector3D>(&chunk,mesh->mBitangents,mesh->mNumVertices);
-                }
+            c |= ASSBIN_MESH_HAS_TEXCOORD(n);
+        }
+        for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
+            if (!mesh->mColors[n]) {
+                break;
             }
-            for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
-                if (!mesh->mColors[n])
-                    break;
+            c |= ASSBIN_MESH_HAS_COLOR(n);
+        }
+        Write<unsigned int>(&chunk,c);
 
-                if (shortened) {
-                    WriteBounds(&chunk,mesh->mColors[n],mesh->mNumVertices);
-                } // else write as usual
-                else WriteArray<aiColor4D>(&chunk,mesh->mColors[n],mesh->mNumVertices);
+        aiVector3D minVec, maxVec;
+        if (mesh->mVertices) {
+            if (shortened) {
+                WriteBounds(&chunk,mesh->mVertices,mesh->mNumVertices);
+            } // else write as usual
+            else WriteArray<aiVector3D>(&chunk,mesh->mVertices,mesh->mNumVertices);
+        }
+        if (mesh->mNormals) {
+            if (shortened) {
+                WriteBounds(&chunk,mesh->mNormals,mesh->mNumVertices);
+            } // else write as usual
+            else WriteArray<aiVector3D>(&chunk,mesh->mNormals,mesh->mNumVertices);
+        }
+        if (mesh->mTangents && mesh->mBitangents) {
+            if (shortened) {
+                WriteBounds(&chunk,mesh->mTangents,mesh->mNumVertices);
+                WriteBounds(&chunk,mesh->mBitangents,mesh->mNumVertices);
+            } // else write as usual
+            else {
+                WriteArray<aiVector3D>(&chunk,mesh->mTangents,mesh->mNumVertices);
+                WriteArray<aiVector3D>(&chunk,mesh->mBitangents,mesh->mNumVertices);
             }
-            for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
-                if (!mesh->mTextureCoords[n])
-                    break;
+        }
+        for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
+            if (!mesh->mColors[n])
+                break;
 
-                // write number of UV components
-                Write<unsigned int>(&chunk,mesh->mNumUVComponents[n]);
+            if (shortened) {
+                WriteBounds(&chunk,mesh->mColors[n],mesh->mNumVertices);
+            } // else write as usual
+            else WriteArray<aiColor4D>(&chunk,mesh->mColors[n],mesh->mNumVertices);
+        }
+        for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
+            if (!mesh->mTextureCoords[n])
+                break;
 
-                if (shortened) {
-                    WriteBounds(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
-                } // else write as usual
-                else WriteArray<aiVector3D>(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
-            }
+            // write number of UV components
+            Write<unsigned int>(&chunk,mesh->mNumUVComponents[n]);
 
-            // write faces. There are no floating-point calculations involved
-            // in these, so we can write a simple hash over the face data
-            // to the dump file. We generate a single 32 Bit hash for 512 faces
-            // using Assimp's standard hashing function.
             if (shortened) {
-                unsigned int processed = 0;
-                for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) {
-
-                    uint32_t hash = 0;
-                    for (unsigned int a = 0; a < job;++a) {
+                WriteBounds(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
+            } // else write as usual
+            else WriteArray<aiVector3D>(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
+        }
 
-                        const aiFace& f = mesh->mFaces[processed+a];
-                        uint32_t tmp = f.mNumIndices;
+        // write faces. There are no floating-point calculations involved
+        // in these, so we can write a simple hash over the face data
+        // to the dump file. We generate a single 32 Bit hash for 512 faces
+        // using Assimp's standard hashing function.
+        if (shortened) {
+            unsigned int processed = 0;
+            for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) {
+
+                uint32_t hash = 0;
+                for (unsigned int a = 0; a < job;++a) {
+
+                    const aiFace& f = mesh->mFaces[processed+a];
+                    uint32_t tmp = f.mNumIndices;
+                    hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
+                    for (unsigned int i = 0; i < f.mNumIndices; ++i) {
+                        static_assert(AI_MAX_VERTICES <= 0xffffffff, "AI_MAX_VERTICES <= 0xffffffff");
+                        tmp = static_cast<uint32_t>( f.mIndices[i] );
                         hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
-                        for (unsigned int i = 0; i < f.mNumIndices; ++i) {
-                            static_assert(AI_MAX_VERTICES <= 0xffffffff, "AI_MAX_VERTICES <= 0xffffffff");
-                            tmp = static_cast<uint32_t>( f.mIndices[i] );
-                            hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
-                        }
                     }
-                    Write<unsigned int>(&chunk,hash);
                 }
+                Write<unsigned int>(&chunk,hash);
             }
-            else // else write as usual
-            {
-                // if there are less than 2^16 vertices, we can simply use 16 bit integers ...
-                for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
-                    const aiFace& f = mesh->mFaces[i];
-
-                    static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
-                    Write<uint16_t>(&chunk,f.mNumIndices);
-
-                    for (unsigned int a = 0; a < f.mNumIndices;++a) {
-                        if (mesh->mNumVertices < (1u<<16)) {
-                            Write<uint16_t>(&chunk,f.mIndices[a]);
-                        }
-                        else Write<unsigned int>(&chunk,f.mIndices[a]);
+        }
+        else // else write as usual
+        {
+            // if there are less than 2^16 vertices, we can simply use 16 bit integers ...
+            for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
+                const aiFace& f = mesh->mFaces[i];
+
+                static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
+                Write<uint16_t>(&chunk,f.mNumIndices);
+
+                for (unsigned int a = 0; a < f.mNumIndices;++a) {
+                    if (mesh->mNumVertices < (1u<<16)) {
+                        Write<uint16_t>(&chunk,f.mIndices[a]);
                     }
+                    else Write<unsigned int>(&chunk,f.mIndices[a]);
                 }
             }
+        }
 
-            // write bones
-            if (mesh->mNumBones) {
-                for (unsigned int a = 0; a < mesh->mNumBones;++a) {
-                    const aiBone* b = mesh->mBones[a];
-                    WriteBinaryBone(&chunk,b);
-                }
+        // write bones
+        if (mesh->mNumBones) {
+            for (unsigned int a = 0; a < mesh->mNumBones;++a) {
+                const aiBone* b = mesh->mBones[a];
+                WriteBinaryBone(&chunk,b);
             }
         }
+    }
 
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop)
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY );
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop)
+    {
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY );
 
-            Write<aiString>(&chunk,prop->mKey);
-            Write<unsigned int>(&chunk,prop->mSemantic);
-            Write<unsigned int>(&chunk,prop->mIndex);
+        Write<aiString>(&chunk,prop->mKey);
+        Write<unsigned int>(&chunk,prop->mSemantic);
+        Write<unsigned int>(&chunk,prop->mIndex);
 
-            Write<unsigned int>(&chunk,prop->mDataLength);
-            Write<unsigned int>(&chunk,(unsigned int)prop->mType);
-            chunk.Write(prop->mData,1,prop->mDataLength);
-        }
+        Write<unsigned int>(&chunk,prop->mDataLength);
+        Write<unsigned int>(&chunk,(unsigned int)prop->mType);
+        chunk.Write(prop->mData,1,prop->mDataLength);
+    }
 
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat)
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL);
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat)
+    {
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL);
 
-            Write<unsigned int>(&chunk,mat->mNumProperties);
-            for (unsigned int i = 0; i < mat->mNumProperties;++i) {
-                WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]);
-            }
+        Write<unsigned int>(&chunk,mat->mNumProperties);
+        for (unsigned int i = 0; i < mat->mNumProperties;++i) {
+            WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]);
         }
+    }
 
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd)
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM );
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd)
+    {
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM );
 
-            Write<aiString>(&chunk,nd->mNodeName);
-            Write<unsigned int>(&chunk,nd->mNumPositionKeys);
-            Write<unsigned int>(&chunk,nd->mNumRotationKeys);
-            Write<unsigned int>(&chunk,nd->mNumScalingKeys);
-            Write<unsigned int>(&chunk,nd->mPreState);
-            Write<unsigned int>(&chunk,nd->mPostState);
+        Write<aiString>(&chunk,nd->mNodeName);
+        Write<unsigned int>(&chunk,nd->mNumPositionKeys);
+        Write<unsigned int>(&chunk,nd->mNumRotationKeys);
+        Write<unsigned int>(&chunk,nd->mNumScalingKeys);
+        Write<unsigned int>(&chunk,nd->mPreState);
+        Write<unsigned int>(&chunk,nd->mPostState);
 
-            if (nd->mPositionKeys) {
-                if (shortened) {
-                    WriteBounds(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);
+        if (nd->mPositionKeys) {
+            if (shortened) {
+                WriteBounds(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);
 
-                } // else write as usual
-                else WriteArray<aiVectorKey>(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);
-            }
-            if (nd->mRotationKeys) {
-                if (shortened) {
-                    WriteBounds(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);
+            } // else write as usual
+            else WriteArray<aiVectorKey>(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);
+        }
+        if (nd->mRotationKeys) {
+            if (shortened) {
+                WriteBounds(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);
 
-                } // else write as usual
-                else WriteArray<aiQuatKey>(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);
-            }
-            if (nd->mScalingKeys) {
-                if (shortened) {
-                    WriteBounds(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);
+            } // else write as usual
+            else WriteArray<aiQuatKey>(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);
+        }
+        if (nd->mScalingKeys) {
+            if (shortened) {
+                WriteBounds(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);
 
-                } // else write as usual
-                else WriteArray<aiVectorKey>(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);
-            }
+            } // else write as usual
+            else WriteArray<aiVectorKey>(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);
         }
+    }
 
 
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryAnim( IOStream * container, const aiAnimation* anim )
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION );
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryAnim( IOStream * container, const aiAnimation* anim )
+    {
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION );
 
-            Write<aiString>(&chunk,anim->mName);
-            Write<double>(&chunk,anim->mDuration);
-            Write<double>(&chunk,anim->mTicksPerSecond);
-            Write<unsigned int>(&chunk,anim->mNumChannels);
+        Write<aiString>(&chunk,anim->mName);
+        Write<double>(&chunk,anim->mDuration);
+        Write<double>(&chunk,anim->mTicksPerSecond);
+        Write<unsigned int>(&chunk,anim->mNumChannels);
 
-            for (unsigned int a = 0; a < anim->mNumChannels;++a) {
-                const aiNodeAnim* nd = anim->mChannels[a];
-                WriteBinaryNodeAnim(&chunk,nd);
-            }
+        for (unsigned int a = 0; a < anim->mNumChannels;++a) {
+            const aiNodeAnim* nd = anim->mChannels[a];
+            WriteBinaryNodeAnim(&chunk,nd);
         }
+    }
 
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryLight( IOStream * container, const aiLight* l )
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT );
-
-            Write<aiString>(&chunk,l->mName);
-            Write<unsigned int>(&chunk,l->mType);
-
-            if (l->mType != aiLightSource_DIRECTIONAL) {
-                Write<float>(&chunk,l->mAttenuationConstant);
-                Write<float>(&chunk,l->mAttenuationLinear);
-                Write<float>(&chunk,l->mAttenuationQuadratic);
-            }
-
-            Write<aiColor3D>(&chunk,l->mColorDiffuse);
-            Write<aiColor3D>(&chunk,l->mColorSpecular);
-            Write<aiColor3D>(&chunk,l->mColorAmbient);
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryLight( IOStream * container, const aiLight* l )
+    {
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT );
 
-            if (l->mType == aiLightSource_SPOT) {
-                Write<float>(&chunk,l->mAngleInnerCone);
-                Write<float>(&chunk,l->mAngleOuterCone);
-            }
+        Write<aiString>(&chunk,l->mName);
+        Write<unsigned int>(&chunk,l->mType);
 
+        if (l->mType != aiLightSource_DIRECTIONAL) {
+            Write<float>(&chunk,l->mAttenuationConstant);
+            Write<float>(&chunk,l->mAttenuationLinear);
+            Write<float>(&chunk,l->mAttenuationQuadratic);
         }
 
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryCamera( IOStream * container, const aiCamera* cam )
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA );
+        Write<aiColor3D>(&chunk,l->mColorDiffuse);
+        Write<aiColor3D>(&chunk,l->mColorSpecular);
+        Write<aiColor3D>(&chunk,l->mColorAmbient);
 
-            Write<aiString>(&chunk,cam->mName);
-            Write<aiVector3D>(&chunk,cam->mPosition);
-            Write<aiVector3D>(&chunk,cam->mLookAt);
-            Write<aiVector3D>(&chunk,cam->mUp);
-            Write<float>(&chunk,cam->mHorizontalFOV);
-            Write<float>(&chunk,cam->mClipPlaneNear);
-            Write<float>(&chunk,cam->mClipPlaneFar);
-            Write<float>(&chunk,cam->mAspect);
+        if (l->mType == aiLightSource_SPOT) {
+            Write<float>(&chunk,l->mAngleInnerCone);
+            Write<float>(&chunk,l->mAngleOuterCone);
         }
 
-        // -----------------------------------------------------------------------------------
-        void WriteBinaryScene( IOStream * container, const aiScene* scene)
-        {
-            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE );
-
-            // basic scene information
-            Write<unsigned int>(&chunk,scene->mFlags);
-            Write<unsigned int>(&chunk,scene->mNumMeshes);
-            Write<unsigned int>(&chunk,scene->mNumMaterials);
-            Write<unsigned int>(&chunk,scene->mNumAnimations);
-            Write<unsigned int>(&chunk,scene->mNumTextures);
-            Write<unsigned int>(&chunk,scene->mNumLights);
-            Write<unsigned int>(&chunk,scene->mNumCameras);
-
-            // write node graph
-            WriteBinaryNode( &chunk, scene->mRootNode );
-
-            // write all meshes
-            for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
-                const aiMesh* mesh = scene->mMeshes[i];
-                WriteBinaryMesh( &chunk,mesh);
-            }
+    }
 
-            // write materials
-            for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
-                const aiMaterial* mat = scene->mMaterials[i];
-                WriteBinaryMaterial(&chunk,mat);
-            }
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryCamera( IOStream * container, const aiCamera* cam )
+    {
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA );
+
+        Write<aiString>(&chunk,cam->mName);
+        Write<aiVector3D>(&chunk,cam->mPosition);
+        Write<aiVector3D>(&chunk,cam->mLookAt);
+        Write<aiVector3D>(&chunk,cam->mUp);
+        Write<float>(&chunk,cam->mHorizontalFOV);
+        Write<float>(&chunk,cam->mClipPlaneNear);
+        Write<float>(&chunk,cam->mClipPlaneFar);
+        Write<float>(&chunk,cam->mAspect);
+    }
 
-            // write all animations
-            for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
-                const aiAnimation* anim = scene->mAnimations[i];
-                WriteBinaryAnim(&chunk,anim);
-            }
+    // -----------------------------------------------------------------------------------
+    void WriteBinaryScene( IOStream * container, const aiScene* scene)
+    {
+        AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE );
+
+        // basic scene information
+        Write<unsigned int>(&chunk,scene->mFlags);
+        Write<unsigned int>(&chunk,scene->mNumMeshes);
+        Write<unsigned int>(&chunk,scene->mNumMaterials);
+        Write<unsigned int>(&chunk,scene->mNumAnimations);
+        Write<unsigned int>(&chunk,scene->mNumTextures);
+        Write<unsigned int>(&chunk,scene->mNumLights);
+        Write<unsigned int>(&chunk,scene->mNumCameras);
+
+        // write node graph
+        WriteBinaryNode( &chunk, scene->mRootNode );
+
+        // write all meshes
+        for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
+            const aiMesh* mesh = scene->mMeshes[i];
+            WriteBinaryMesh( &chunk,mesh);
+        }
 
+        // write materials
+        for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
+            const aiMaterial* mat = scene->mMaterials[i];
+            WriteBinaryMaterial(&chunk,mat);
+        }
 
-            // write all textures
-            for (unsigned int i = 0; i < scene->mNumTextures;++i) {
-                const aiTexture* mesh = scene->mTextures[i];
-                WriteBinaryTexture(&chunk,mesh);
-            }
+        // write all animations
+        for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
+            const aiAnimation* anim = scene->mAnimations[i];
+            WriteBinaryAnim(&chunk,anim);
+        }
 
-            // write lights
-            for (unsigned int i = 0; i < scene->mNumLights;++i) {
-                const aiLight* l = scene->mLights[i];
-                WriteBinaryLight(&chunk,l);
-            }
 
-            // write cameras
-            for (unsigned int i = 0; i < scene->mNumCameras;++i) {
-                const aiCamera* cam = scene->mCameras[i];
-                WriteBinaryCamera(&chunk,cam);
-            }
+        // write all textures
+        for (unsigned int i = 0; i < scene->mNumTextures;++i) {
+            const aiTexture* mesh = scene->mTextures[i];
+            WriteBinaryTexture(&chunk,mesh);
+        }
 
+        // write lights
+        for (unsigned int i = 0; i < scene->mNumLights;++i) {
+            const aiLight* l = scene->mLights[i];
+            WriteBinaryLight(&chunk,l);
         }
 
-    public:
-        AssbinExport()
-            : shortened(false), compressed(false) // temporary settings until properties are introduced for exporters
-        {
+        // write cameras
+        for (unsigned int i = 0; i < scene->mNumCameras;++i) {
+            const aiCamera* cam = scene->mCameras[i];
+            WriteBinaryCamera(&chunk,cam);
         }
 
-        // -----------------------------------------------------------------------------------
-        // Write a binary model dump
-        void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
-        {
-            IOStream * out = pIOSystem->Open( pFile, "wb" );
-            if (!out) return;
+    }
+
+public:
+    AssbinExport()
+        : shortened(false), compressed(false) // temporary settings until properties are introduced for exporters
+    {
+    }
 
-            time_t tt = time(NULL);
-            tm* p     = gmtime(&tt);
+    // -----------------------------------------------------------------------------------
+    // Write a binary model dump
+    void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
+    {
+        IOStream * out = pIOSystem->Open( pFile, "wb" );
+        if (!out) return;
 
-            // header
-            char s[64];
-            memset( s, 0, 64 );
-#if _MSC_VER >= 1400
-            sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p));
+        time_t tt = time(NULL);
+#if _WIN32
+        tm* p     = gmtime(&tt);
 #else
-            ai_snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
+        struct tm now;
+        tm* p = gmtime_r(&tt, &now);
 #endif
-            out->Write( s, 44, 1 );
-            // == 44 bytes
-
-            Write<unsigned int>( out, ASSBIN_VERSION_MAJOR );
-            Write<unsigned int>( out, ASSBIN_VERSION_MINOR );
-            Write<unsigned int>( out, aiGetVersionRevision() );
-            Write<unsigned int>( out, aiGetCompileFlags() );
-            Write<uint16_t>( out, shortened );
-            Write<uint16_t>( out, compressed );
-            // ==  20 bytes
-
-            char buff[256];
-            strncpy(buff,pFile,256);
-            out->Write(buff,sizeof(char),256);
-
-            char cmd[] = "\0";
-            strncpy(buff,cmd,128);
-            out->Write(buff,sizeof(char),128);
-
-            // leave 64 bytes free for future extensions
-            memset(buff,0xcd,64);
-            out->Write(buff,sizeof(char),64);
-            // == 435 bytes
-
-            // ==== total header size: 512 bytes
-            ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH );
-
-            // Up to here the data is uncompressed. For compressed files, the rest
-            // is compressed using standard DEFLATE from zlib.
-            if (compressed)
-            {
-                AssbinChunkWriter uncompressedStream( NULL, 0 );
-                WriteBinaryScene( &uncompressedStream, pScene );
-
-                uLongf uncompressedSize = static_cast<uLongf>(uncompressedStream.Tell());
-                uLongf compressedSize = (uLongf)(uncompressedStream.Tell() * 1.001 + 12.);
-                uint8_t* compressedBuffer = new uint8_t[ compressedSize ];
 
-                compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 );
+        // header
+        char s[64];
+        memset( s, 0, 64 );
+#if _MSC_VER >= 1400
+        sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p));
+#else
+        ai_snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
+#endif
+        out->Write( s, 44, 1 );
+        // == 44 bytes
+
+        Write<unsigned int>( out, ASSBIN_VERSION_MAJOR );
+        Write<unsigned int>( out, ASSBIN_VERSION_MINOR );
+        Write<unsigned int>( out, aiGetVersionRevision() );
+        Write<unsigned int>( out, aiGetCompileFlags() );
+        Write<uint16_t>( out, shortened );
+        Write<uint16_t>( out, compressed );
+        // ==  20 bytes
+
+        char buff[256];
+        strncpy(buff,pFile,256);
+        out->Write(buff,sizeof(char),256);
+
+        char cmd[] = "\0";
+        strncpy(buff,cmd,128);
+        out->Write(buff,sizeof(char),128);
+
+        // leave 64 bytes free for future extensions
+        memset(buff,0xcd,64);
+        out->Write(buff,sizeof(char),64);
+        // == 435 bytes
+
+        // ==== total header size: 512 bytes
+        ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH );
+
+        // Up to here the data is uncompressed. For compressed files, the rest
+        // is compressed using standard DEFLATE from zlib.
+        if (compressed)
+        {
+            AssbinChunkWriter uncompressedStream( NULL, 0 );
+            WriteBinaryScene( &uncompressedStream, pScene );
 
-                out->Write( &uncompressedSize, sizeof(uint32_t), 1 );
-                out->Write( compressedBuffer, sizeof(char), compressedSize );
+            uLongf uncompressedSize = static_cast<uLongf>(uncompressedStream.Tell());
+            uLongf compressedSize = (uLongf)compressBound(uncompressedSize);
+            uint8_t* compressedBuffer = new uint8_t[ compressedSize ];
 
-                delete[] compressedBuffer;
-            }
-            else
+            int res = compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 );
+            if(res != Z_OK)
             {
-                WriteBinaryScene( out, pScene );
+                delete [] compressedBuffer;
+                pIOSystem->Close(out);
+                throw DeadlyExportError("Compression failed.");
             }
 
-            pIOSystem->Close( out );
+            out->Write( &uncompressedSize, sizeof(uint32_t), 1 );
+            out->Write( compressedBuffer, sizeof(char), compressedSize );
+
+            delete[] compressedBuffer;
+        }
+        else
+        {
+            WriteBinaryScene( out, pScene );
         }
-    };
 
-void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
-{
+        pIOSystem->Close( out );
+    }
+};
+
+void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) {
     AssbinExport exporter;
     exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
 }

+ 10 - 2
Engine/lib/assimp/code/AssbinExporter.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -45,6 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_ASSBINEXPORTER_H_INC
 #define AI_ASSBINEXPORTER_H_INC
 
+#include <assimp/defs.h>
+
 // nothing really needed here - reserved for future use like properties
+namespace Assimp {
+
+void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/);
+
+}
 
-#endif
+#endif // AI_ASSBINEXPORTER_H_INC

+ 181 - 188
Engine/lib/assimp/code/AssbinLoader.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -51,11 +52,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "AssbinLoader.h"
 #include "assbin_chunks.h"
-#include "MemoryIOWrapper.h"
+#include <assimp/MemoryIOWrapper.h>
 #include <assimp/mesh.h>
 #include <assimp/anim.h>
 #include <assimp/scene.h>
 #include <assimp/importerdesc.h>
+#include <memory>
 
 #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
 #   include <zlib.h>
@@ -78,16 +80,17 @@ static const aiImporterDesc desc = {
     "assbin"
 };
 
-const aiImporterDesc* AssbinImporter::GetInfo() const
-{
+// -----------------------------------------------------------------------------------
+const aiImporterDesc* AssbinImporter::GetInfo() const {
     return &desc;
 }
 
-bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const
-{
+// -----------------------------------------------------------------------------------
+bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const {
     IOStream * in = pIOHandler->Open(pFile);
-    if (!in)
+    if (nullptr == in) {
         return false;
+    }
 
     char s[32];
     in->Read( s, sizeof(char), 32 );
@@ -97,17 +100,19 @@ bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bo
     return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0;
 }
 
+// -----------------------------------------------------------------------------------
 template <typename T>
-T Read(IOStream * stream)
-{
+T Read(IOStream * stream) {
     T t;
-    stream->Read( &t, sizeof(T), 1 );
+    size_t res = stream->Read( &t, sizeof(T), 1 );
+    if(res != 1)
+        throw DeadlyImportError("Unexpected EOF");
     return t;
 }
 
+// -----------------------------------------------------------------------------------
 template <>
-aiVector3D Read<aiVector3D>(IOStream * stream)
-{
+aiVector3D Read<aiVector3D>(IOStream * stream) {
     aiVector3D v;
     v.x = Read<float>(stream);
     v.y = Read<float>(stream);
@@ -115,9 +120,9 @@ aiVector3D Read<aiVector3D>(IOStream * stream)
     return v;
 }
 
+// -----------------------------------------------------------------------------------
 template <>
-aiColor4D Read<aiColor4D>(IOStream * stream)
-{
+aiColor4D Read<aiColor4D>(IOStream * stream) {
     aiColor4D c;
     c.r = Read<float>(stream);
     c.g = Read<float>(stream);
@@ -126,9 +131,9 @@ aiColor4D Read<aiColor4D>(IOStream * stream)
     return c;
 }
 
+// -----------------------------------------------------------------------------------
 template <>
-aiQuaternion Read<aiQuaternion>(IOStream * stream)
-{
+aiQuaternion Read<aiQuaternion>(IOStream * stream) {
     aiQuaternion v;
     v.w = Read<float>(stream);
     v.x = Read<float>(stream);
@@ -137,28 +142,29 @@ aiQuaternion Read<aiQuaternion>(IOStream * stream)
     return v;
 }
 
+// -----------------------------------------------------------------------------------
 template <>
-aiString Read<aiString>(IOStream * stream)
-{
+aiString Read<aiString>(IOStream * stream) {
     aiString s;
     stream->Read(&s.length,4,1);
-    stream->Read(s.data,s.length,1);
+    if(s.length)
+        stream->Read(s.data,s.length,1);
     s.data[s.length] = 0;
     return s;
 }
 
+// -----------------------------------------------------------------------------------
 template <>
-aiVertexWeight Read<aiVertexWeight>(IOStream * stream)
-{
+aiVertexWeight Read<aiVertexWeight>(IOStream * stream) {
     aiVertexWeight w;
     w.mVertexId = Read<unsigned int>(stream);
     w.mWeight = Read<float>(stream);
     return w;
 }
 
+// -----------------------------------------------------------------------------------
 template <>
-aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
-{
+aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream) {
     aiMatrix4x4 m;
     for (unsigned int i = 0; i < 4;++i) {
         for (unsigned int i2 = 0; i2 < 4;++i2) {
@@ -168,76 +174,85 @@ aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
     return m;
 }
 
+// -----------------------------------------------------------------------------------
 template <>
-aiVectorKey Read<aiVectorKey>(IOStream * stream)
-{
+aiVectorKey Read<aiVectorKey>(IOStream * stream) {
     aiVectorKey v;
     v.mTime = Read<double>(stream);
     v.mValue = Read<aiVector3D>(stream);
     return v;
 }
 
+// -----------------------------------------------------------------------------------
 template <>
-aiQuatKey Read<aiQuatKey>(IOStream * stream)
-{
+aiQuatKey Read<aiQuatKey>(IOStream * stream) {
     aiQuatKey v;
     v.mTime = Read<double>(stream);
     v.mValue = Read<aiQuaternion>(stream);
     return v;
 }
 
+// -----------------------------------------------------------------------------------
 template <typename T>
-void ReadArray(IOStream * stream, T * out, unsigned int size)
-{
-    for (unsigned int i=0; i<size; i++) out[i] = Read<T>(stream);
+void ReadArray( IOStream *stream, T * out, unsigned int size) {
+    ai_assert( nullptr != stream );
+    ai_assert( nullptr != out );
+
+    for (unsigned int i=0; i<size; i++) {
+        out[i] = Read<T>(stream);
+    }
 }
 
-template <typename T> void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n )
-{
+// -----------------------------------------------------------------------------------
+template <typename T>
+void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n ) {
     // not sure what to do here, the data isn't really useful.
     stream->Seek( sizeof(T) * n, aiOrigin_CUR );
 }
 
-void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) {
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AINODE);
+// -----------------------------------------------------------------------------------
+void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** onode, aiNode* parent ) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AINODE)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
-    *node = new aiNode();
+    std::unique_ptr<aiNode> node(new aiNode());
 
-    (*node)->mName = Read<aiString>(stream);
-    (*node)->mTransformation = Read<aiMatrix4x4>(stream);
-    (*node)->mNumChildren = Read<unsigned int>(stream);
-    (*node)->mNumMeshes = Read<unsigned int>(stream);
+    node->mName = Read<aiString>(stream);
+    node->mTransformation = Read<aiMatrix4x4>(stream);
+    unsigned numChildren = Read<unsigned int>(stream);
+    unsigned numMeshes = Read<unsigned int>(stream);
 	unsigned int nb_metadata = Read<unsigned int>(stream);
 
     if(parent) {
-        (*node)->mParent = parent;
+        node->mParent = parent;
     }
 
-    if ((*node)->mNumMeshes) {
-        (*node)->mMeshes = new unsigned int[(*node)->mNumMeshes];
-        for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) {
-            (*node)->mMeshes[i] = Read<unsigned int>(stream);
+    if (numMeshes)
+    {
+        node->mMeshes = new unsigned int[numMeshes];
+        for (unsigned int i = 0; i < numMeshes; ++i) {
+            node->mMeshes[i] = Read<unsigned int>(stream);
+            node->mNumMeshes++;
         }
     }
 
-    if ((*node)->mNumChildren) {
-        (*node)->mChildren = new aiNode*[(*node)->mNumChildren];
-        for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) {
-            ReadBinaryNode( stream, &(*node)->mChildren[i], *node );
+    if (numChildren) {
+        node->mChildren = new aiNode*[numChildren];
+        for (unsigned int i = 0; i < numChildren; ++i) {
+            ReadBinaryNode( stream, &node->mChildren[i], node.get() );
+            node->mNumChildren++;
         }
     }
 
     if ( nb_metadata > 0 ) {
-        (*node)->mMetaData = aiMetadata::Alloc(nb_metadata);
+        node->mMetaData = aiMetadata::Alloc(nb_metadata);
         for (unsigned int i = 0; i < nb_metadata; ++i) {
-            (*node)->mMetaData->mKeys[i] = Read<aiString>(stream);
-            (*node)->mMetaData->mValues[i].mType = (aiMetadataType) Read<uint16_t>(stream);
-            void* data( nullptr );
+            node->mMetaData->mKeys[i] = Read<aiString>(stream);
+            node->mMetaData->mValues[i].mType = (aiMetadataType) Read<uint16_t>(stream);
+            void* data = nullptr;
 
-            switch ((*node)->mMetaData->mValues[i].mType) {
+            switch (node->mMetaData->mValues[i].mType) {
                 case AI_BOOL:
                     data = new bool(Read<bool>(stream));
                     break;
@@ -266,17 +281,16 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* p
                     break;
             }
 
-			(*node)->mMetaData->mValues[i].mData = data;
+			node->mMetaData->mValues[i].mData = data;
 		}
 	}
+    *onode = node.release();
 }
 
 // -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
-{
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
+void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIBONE)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
     b->mName = Read<aiString>(stream);
@@ -285,23 +299,23 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
 
     // for the moment we write dumb min/max values for the bones, too.
     // maybe I'll add a better, hash-like solution later
-    if (shortened)
-    {
+    if (shortened) {
         ReadBounds(stream,b->mWeights,b->mNumWeights);
-    } // else write as usual
-    else
-    {
+    } else {
+        // else write as usual
         b->mWeights = new aiVertexWeight[b->mNumWeights];
         ReadArray<aiVertexWeight>(stream,b->mWeights,b->mNumWeights);
     }
 }
 
-
-void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
-{
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
+// -----------------------------------------------------------------------------------
+static bool fitsIntoUI16(unsigned int mNumVertices) {
+    return ( mNumVertices < (1u<<16) );
+}
+// -----------------------------------------------------------------------------------
+void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMESH)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
     mesh->mPrimitiveTypes = Read<unsigned int>(stream);
@@ -313,70 +327,61 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
     // first of all, write bits for all existent vertex components
     unsigned int c = Read<unsigned int>(stream);
 
-    if (c & ASSBIN_MESH_HAS_POSITIONS)
-    {
+    if (c & ASSBIN_MESH_HAS_POSITIONS) {
         if (shortened) {
             ReadBounds(stream,mesh->mVertices,mesh->mNumVertices);
-        } // else write as usual
-        else
-        {
+        }  else {
+            // else write as usual
             mesh->mVertices = new aiVector3D[mesh->mNumVertices];
             ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices);
         }
     }
-    if (c & ASSBIN_MESH_HAS_NORMALS)
-    {
+    if (c & ASSBIN_MESH_HAS_NORMALS) {
         if (shortened) {
             ReadBounds(stream,mesh->mNormals,mesh->mNumVertices);
-        } // else write as usual
-        else
-        {
+        }  else {
+            // else write as usual
             mesh->mNormals = new aiVector3D[mesh->mNumVertices];
             ReadArray<aiVector3D>(stream,mesh->mNormals,mesh->mNumVertices);
         }
     }
-    if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS)
-    {
+    if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) {
         if (shortened) {
             ReadBounds(stream,mesh->mTangents,mesh->mNumVertices);
             ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices);
-        } // else write as usual
-        else
-        {
+        }  else {
+            // else write as usual
             mesh->mTangents = new aiVector3D[mesh->mNumVertices];
             ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices);
             mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
             ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices);
         }
     }
-    for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n)
-    {
-        if (!(c & ASSBIN_MESH_HAS_COLOR(n)))
+    for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
+        if (!(c & ASSBIN_MESH_HAS_COLOR(n))) {
             break;
+        }
 
-        if (shortened)
-        {
+        if (shortened) {
             ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices);
-        } // else write as usual
-        else
-        {
+        }  else {
+            // else write as usual
             mesh->mColors[n] = new aiColor4D[mesh->mNumVertices];
             ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices);
         }
     }
-    for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
-    {
-        if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n)))
+    for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
+        if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n))) {
             break;
+        }
 
         // write number of UV components
         mesh->mNumUVComponents[n] = Read<unsigned int>(stream);
 
         if (shortened) {
             ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
-        } // else write as usual
-        else
-        {
+        }  else {
+            // else write as usual
             mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
             ReadArray<aiVector3D>(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
         }
@@ -388,9 +393,8 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
     // using Assimp's standard hashing function.
     if (shortened) {
         Read<unsigned int>(stream);
-    }
-    else // else write as usual
-    {
+    } else  {
+        // else write as usual
         // if there are less than 2^16 vertices, we can simply use 16 bit integers ...
         mesh->mFaces = new aiFace[mesh->mNumFaces];
         for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
@@ -401,12 +405,10 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
             f.mIndices = new unsigned int[f.mNumIndices];
 
             for (unsigned int a = 0; a < f.mNumIndices;++a) {
-                if (mesh->mNumVertices < (1u<<16))
-                {
+                // Check if unsigned  short ( 16 bit  ) are big enought for the indices
+                if ( fitsIntoUI16( mesh->mNumVertices ) ) {
                     f.mIndices[a] = Read<uint16_t>(stream);
-                }
-                else
-                {
+                } else {
                     f.mIndices[a] = Read<unsigned int>(stream);
                 }
             }
@@ -423,11 +425,10 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
     }
 }
 
-void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop)
-{
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
+// -----------------------------------------------------------------------------------
+void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMATERIALPROPERTY)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
     prop->mKey = Read<aiString>(stream);
@@ -441,11 +442,9 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro
 }
 
 // -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
-{
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
+void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMATERIAL)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
     mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream);
@@ -464,11 +463,9 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
 }
 
 // -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
-{
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
+void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AINODEANIM)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
     nd->mNodeName = Read<aiString>(stream);
@@ -492,9 +489,8 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
         if (shortened) {
             ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys);
 
-        } // else write as usual
-        else
-        {
+        }  else {
+            // else write as usual
             nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
             ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys);
         }
@@ -503,22 +499,18 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
         if (shortened) {
             ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys);
 
-        } // else write as usual
-        else
-        {
+        }  else {
+            // else write as usual
             nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
             ReadArray<aiVectorKey>(stream,nd->mScalingKeys,nd->mNumScalingKeys);
         }
     }
 }
 
-
 // -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
-{
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
+void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIANIMATION)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
     anim->mName = Read<aiString> (stream);
@@ -526,8 +518,7 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
     anim->mTicksPerSecond = Read<double> (stream);
     anim->mNumChannels = Read<unsigned int>(stream);
 
-    if (anim->mNumChannels)
-    {
+    if (anim->mNumChannels) {
         anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ];
         for (unsigned int a = 0; a < anim->mNumChannels;++a) {
             anim->mChannels[a] = new aiNodeAnim();
@@ -536,11 +527,10 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
     }
 }
 
-void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
-{
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
+// -----------------------------------------------------------------------------------
+void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AITEXTURE)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
     tex->mWidth = Read<unsigned int>(stream);
@@ -551,21 +541,17 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
         if (!tex->mHeight) {
             tex->pcData = new aiTexel[ tex->mWidth ];
             stream->Read(tex->pcData,1,tex->mWidth);
-        }
-        else {
+        } else {
             tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ];
             stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4);
         }
     }
-
 }
 
 // -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
-{
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
+void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AILIGHT)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
     l->mName = Read<aiString>(stream);
@@ -585,15 +571,12 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
         l->mAngleInnerCone = Read<float>(stream);
         l->mAngleOuterCone = Read<float>(stream);
     }
-
 }
 
 // -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
-{
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
+void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AICAMERA)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
     cam->mName = Read<aiString>(stream);
@@ -606,11 +589,10 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
     cam->mAspect = Read<float>(stream);
 }
 
-void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
-{
-    uint32_t chunkID = Read<uint32_t>(stream);
-    (void)(chunkID);
-    ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
+// -----------------------------------------------------------------------------------
+void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
+    if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AISCENE)
+        throw DeadlyImportError("Magic chunk identifiers are wrong!");
     /*uint32_t size =*/ Read<uint32_t>(stream);
 
     scene->mFlags         = Read<unsigned int>(stream);
@@ -622,13 +604,13 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
     scene->mNumCameras    = Read<unsigned int>(stream);
 
     // Read node graph
-    scene->mRootNode = new aiNode[1];
+    //scene->mRootNode = new aiNode[1];
     ReadBinaryNode( stream, &scene->mRootNode, (aiNode*)NULL );
 
     // Read all meshes
-    if (scene->mNumMeshes)
-    {
+    if (scene->mNumMeshes) {
         scene->mMeshes = new aiMesh*[scene->mNumMeshes];
+        memset(scene->mMeshes, 0, scene->mNumMeshes*sizeof(aiMesh*));
         for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
             scene->mMeshes[i] = new aiMesh();
             ReadBinaryMesh( stream,scene->mMeshes[i]);
@@ -636,9 +618,9 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
     }
 
     // Read materials
-    if (scene->mNumMaterials)
-    {
+    if (scene->mNumMaterials) {
         scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
+        memset(scene->mMaterials, 0, scene->mNumMaterials*sizeof(aiMaterial*));
         for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
             scene->mMaterials[i] = new aiMaterial();
             ReadBinaryMaterial(stream,scene->mMaterials[i]);
@@ -646,9 +628,9 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
     }
 
     // Read all animations
-    if (scene->mNumAnimations)
-    {
+    if (scene->mNumAnimations) {
         scene->mAnimations = new aiAnimation*[scene->mNumAnimations];
+        memset(scene->mAnimations, 0, scene->mNumAnimations*sizeof(aiAnimation*));
         for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
             scene->mAnimations[i] = new aiAnimation();
             ReadBinaryAnim(stream,scene->mAnimations[i]);
@@ -656,9 +638,9 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
     }
 
     // Read all textures
-    if (scene->mNumTextures)
-    {
+    if (scene->mNumTextures) {
         scene->mTextures = new aiTexture*[scene->mNumTextures];
+        memset(scene->mTextures, 0, scene->mNumTextures*sizeof(aiTexture*));
         for (unsigned int i = 0; i < scene->mNumTextures;++i) {
             scene->mTextures[i] = new aiTexture();
             ReadBinaryTexture(stream,scene->mTextures[i]);
@@ -666,9 +648,9 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
     }
 
     // Read lights
-    if (scene->mNumLights)
-    {
+    if (scene->mNumLights) {
         scene->mLights = new aiLight*[scene->mNumLights];
+        memset(scene->mLights, 0, scene->mNumLights*sizeof(aiLight*));
         for (unsigned int i = 0; i < scene->mNumLights;++i) {
             scene->mLights[i] = new aiLight();
             ReadBinaryLight(stream,scene->mLights[i]);
@@ -676,9 +658,9 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
     }
 
     // Read cameras
-    if (scene->mNumCameras)
-    {
+    if (scene->mNumCameras) {
         scene->mCameras = new aiCamera*[scene->mNumCameras];
+        memset(scene->mCameras, 0, scene->mNumCameras*sizeof(aiCamera*));
         for (unsigned int i = 0; i < scene->mNumCameras;++i) {
             scene->mCameras[i] = new aiCamera();
             ReadBinaryCamera(stream,scene->mCameras[i]);
@@ -687,16 +669,22 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
 
 }
 
-void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler )
-{
+// -----------------------------------------------------------------------------------
+void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) {
     IOStream * stream = pIOHandler->Open(pFile,"rb");
-    if (!stream)
+    if (nullptr == stream) {
         return;
+    }
 
-    stream->Seek( 44, aiOrigin_CUR ); // signature
+    // signature
+    stream->Seek( 44, aiOrigin_CUR );
+
+    unsigned int versionMajor = Read<unsigned int>(stream);
+    unsigned int versionMinor = Read<unsigned int>(stream);
+    if (versionMinor != ASSBIN_VERSION_MINOR || versionMajor != ASSBIN_VERSION_MAJOR) {
+        throw DeadlyImportError( "Invalid version, data format not compatible!" );
+    }
 
-    /*unsigned int versionMajor =*/ Read<unsigned int>(stream);
-    /*unsigned int versionMinor =*/ Read<unsigned int>(stream);
     /*unsigned int versionRevision =*/ Read<unsigned int>(stream);
     /*unsigned int compileFlags =*/ Read<unsigned int>(stream);
 
@@ -710,17 +698,24 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
     stream->Seek( 128, aiOrigin_CUR ); // options
     stream->Seek( 64, aiOrigin_CUR ); // padding
 
-    if (compressed)
-    {
+    if (compressed) {
         uLongf uncompressedSize = Read<uint32_t>(stream);
         uLongf compressedSize = static_cast<uLongf>(stream->FileSize() - stream->Tell());
 
         unsigned char * compressedData = new unsigned char[ compressedSize ];
-        stream->Read( compressedData, 1, compressedSize );
+        size_t len = stream->Read( compressedData, 1, compressedSize );
+        ai_assert(len == compressedSize);
 
         unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
 
-        uncompress( uncompressedData, &uncompressedSize, compressedData, compressedSize );
+        int res = uncompress( uncompressedData, &uncompressedSize, compressedData, len );
+        if(res != Z_OK)
+        {
+            delete [] uncompressedData;
+            delete [] compressedData;
+            pIOHandler->Close(stream);
+            throw DeadlyImportError("Zlib decompression failed.");
+        }
 
         MemoryIOStream io( uncompressedData, uncompressedSize );
 
@@ -728,9 +723,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
 
         delete[] uncompressedData;
         delete[] compressedData;
-    }
-    else
-    {
+    } else {
         ReadBinaryScene(stream,pScene);
     }
 

+ 25 - 23
Engine/lib/assimp/code/AssbinLoader.h

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -46,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_ASSBINIMPORTER_H_INC
 #define AI_ASSBINIMPORTER_H_INC
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 
 struct aiMesh;
 struct aiNode;
@@ -69,32 +70,33 @@ namespace Assimp    {
 class AssbinImporter : public BaseImporter
 {
 private:
-  bool shortened;
-  bool compressed;
+    bool shortened;
+    bool compressed;
 
 public:
-  virtual bool CanRead(
-    const std::string& pFile,
-    IOSystem* pIOHandler,
-    bool checkSig
+    virtual bool CanRead(
+        const std::string& pFile,
+        IOSystem* pIOHandler,
+        bool checkSig
     ) const;
-  virtual const aiImporterDesc* GetInfo() const;
-  virtual void InternReadFile(
+    virtual const aiImporterDesc* GetInfo() const;
+    virtual void InternReadFile(
     const std::string& pFile,
-    aiScene* pScene,
-    IOSystem* pIOHandler
+        aiScene* pScene,
+        IOSystem* pIOHandler
     );
-  void ReadBinaryScene( IOStream * stream, aiScene* pScene );
-  void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );
-  void ReadBinaryMesh( IOStream * stream, aiMesh* mesh );
-  void ReadBinaryBone( IOStream * stream, aiBone* bone );
-  void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat);
-  void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop);
-  void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd);
-  void ReadBinaryAnim( IOStream * stream, aiAnimation* anim );
-  void ReadBinaryTexture(IOStream * stream, aiTexture* tex);
-  void ReadBinaryLight( IOStream * stream, aiLight* l );
-  void ReadBinaryCamera( IOStream * stream, aiCamera* cam );
+    void ReadHeader();
+    void ReadBinaryScene( IOStream * stream, aiScene* pScene );
+    void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );
+    void ReadBinaryMesh( IOStream * stream, aiMesh* mesh );
+    void ReadBinaryBone( IOStream * stream, aiBone* bone );
+    void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat);
+    void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop);
+    void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd);
+    void ReadBinaryAnim( IOStream * stream, aiAnimation* anim );
+    void ReadBinaryTexture(IOStream * stream, aiTexture* tex);
+    void ReadBinaryLight( IOStream * stream, aiLight* l );
+    void ReadBinaryCamera( IOStream * stream, aiCamera* cam );
 };
 
 } // end of namespace Assimp

+ 7 - 6
Engine/lib/assimp/code/Assimp.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -49,13 +50,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/Importer.hpp>
 #include <assimp/importerdesc.h>
 #include <assimp/scene.h>
+#include <assimp/GenericProperty.h>
+#include <assimp/Exceptional.h>
+#include <assimp/BaseImporter.h>
 
-#include "GenericProperty.h"
 #include "CInterfaceIOWrapper.h"
 #include "Importer.h"
-#include "Exceptional.h"
 #include "ScenePrivate.h"
-#include "BaseImporter.h"
+
 #include <list>
 
 // ------------------------------------------------------------------------------------------------
@@ -106,7 +108,6 @@ namespace Assimp {
 static std::mutex gLogStreamMutex;
 #endif
 
-
 // ------------------------------------------------------------------------------------------------
 // Custom LogStream implementation for the C-API
 class LogToCallbackRedirector : public LogStream {
@@ -145,7 +146,7 @@ private:
 
 // ------------------------------------------------------------------------------------------------
 void ReportSceneNotFoundError() {
-    DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
+    ASSIMP_LOG_ERROR("Unable to find the Assimp::Importer for this aiScene. "
         "The C-API does not accept scenes produced by the C++ API and vice versa");
 
     ai_assert(false);

+ 2 - 2
Engine/lib/assimp/code/AssimpCExport.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -59,7 +60,6 @@ ASSIMP_API size_t aiGetExportFormatCount(void)
     return Exporter().GetExportFormatCount();
 }
 
-
 // ------------------------------------------------------------------------------------------------
 ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index)
 {

+ 13 - 6
Engine/lib/assimp/code/AssxmlExporter.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -41,6 +42,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file  AssxmlExporter.cpp
  *  ASSXML exporter main code
  */
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
+
 #include <stdarg.h>
 #include <assimp/version.h>
 #include "ProcessHelper.h"
@@ -57,9 +62,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <time.h>
 #include <stdio.h>
 
-#ifndef ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
-
 using namespace Assimp;
 
 namespace Assimp    {
@@ -182,8 +184,13 @@ static std::string encodeXML(const std::string& data) {
 static
 void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
     time_t tt = ::time( NULL );
-    tm* p     = ::gmtime( &tt );
-    ai_assert( nullptr != p );
+#if _WIN32
+    tm* p = gmtime(&tt);
+#else
+    struct tm now;
+    tm* p = gmtime_r(&tt, &now);
+#endif
+    ai_assert(nullptr != p);
 
     // write header
     std::string header(

+ 2 - 1
Engine/lib/assimp/code/AssxmlExporter.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 

+ 41 - 22
Engine/lib/assimp/code/B3DImporter.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -51,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "B3DImporter.h"
 #include "TextureTransform.h"
 #include "ConvertToLHProcess.h"
-#include "StringUtils.h"
+#include <assimp/StringUtils.h>
 #include <memory>
 #include <assimp/IOSystem.hpp>
 #include <assimp/anim.h>
@@ -93,7 +94,6 @@ void DeleteAllBarePointers(std::vector<T>& x)
 
 B3DImporter::~B3DImporter()
 {
-    DeleteAllBarePointers(_animations);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -267,6 +267,21 @@ T *B3DImporter::to_array( const vector<T> &v ){
     return p;
 }
 
+
+// ------------------------------------------------------------------------------------------------
+template<class T>
+T **unique_to_array( vector<std::unique_ptr<T> > &v ){
+    if( v.empty() ) {
+        return 0;
+    }
+    T **p = new T*[ v.size() ];
+    for( size_t i = 0; i < v.size(); ++i ){
+        p[i] = v[i].release();
+    }
+    return p;
+}
+
+
 // ------------------------------------------------------------------------------------------------
 void B3DImporter::ReadTEXS(){
     while( ChunkSize() ){
@@ -295,8 +310,7 @@ void B3DImporter::ReadBRUS(){
         /*int blend=**/ReadInt();
         int fx=ReadInt();
 
-        aiMaterial *mat=new aiMaterial;
-        _materials.push_back( mat );
+        std::unique_ptr<aiMaterial> mat(new aiMaterial);
 
         // Name
         aiString ainame( name );
@@ -333,6 +347,7 @@ void B3DImporter::ReadBRUS(){
                 mat->AddProperty( &texname,AI_MATKEY_TEXTURE_DIFFUSE(0) );
             }
         }
+        _materials.emplace_back( std::move(mat) );
     }
 }
 
@@ -386,8 +401,7 @@ void B3DImporter::ReadTRIS( int v0 ){
         Fail( "Bad material id" );
     }
 
-    aiMesh *mesh=new aiMesh;
-    _meshes.push_back( mesh );
+    std::unique_ptr<aiMesh> mesh(new aiMesh);
 
     mesh->mMaterialIndex=matid;
     mesh->mNumFaces=0;
@@ -415,6 +429,8 @@ void B3DImporter::ReadTRIS( int v0 ){
         ++mesh->mNumFaces;
         ++face;
     }
+
+    _meshes.emplace_back( std::move(mesh) );
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -500,11 +516,11 @@ void B3DImporter::ReadANIM(){
     int frames=ReadInt();
     float fps=ReadFloat();
 
-    aiAnimation *anim=new aiAnimation;
-    _animations.push_back( anim );
+    std::unique_ptr<aiAnimation> anim(new aiAnimation);
 
     anim->mDuration=frames;
     anim->mTicksPerSecond=fps;
+    _animations.emplace_back( std::move(anim) );
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -531,7 +547,7 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
     node->mParent=parent;
     node->mTransformation=tform;
 
-    aiNodeAnim *nodeAnim=0;
+    std::unique_ptr<aiNodeAnim> nodeAnim;
     vector<unsigned> meshes;
     vector<aiNode*> children;
 
@@ -549,11 +565,10 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
             ReadANIM();
         }else if( t=="KEYS" ){
             if( !nodeAnim ){
-                nodeAnim=new aiNodeAnim;
-                _nodeAnims.push_back( nodeAnim );
+                nodeAnim.reset(new aiNodeAnim);
                 nodeAnim->mNodeName=node->mName;
             }
-            ReadKEYS( nodeAnim );
+            ReadKEYS( nodeAnim.get() );
         }else if( t=="NODE" ){
             aiNode *child=ReadNODE( node );
             children.push_back( child );
@@ -561,6 +576,10 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
         ExitChunk();
     }
 
+    if (nodeAnim) {
+        _nodeAnims.emplace_back( std::move(nodeAnim) );
+    }
+
     node->mNumMeshes= static_cast<unsigned int>(meshes.size());
     node->mMeshes=to_array( meshes );
 
@@ -586,7 +605,6 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
 
     _nodeAnims.clear();
 
-    DeleteAllBarePointers(_animations);
     _animations.clear();
 
     string t=ReadChunk();
@@ -596,7 +614,7 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
         if (!DefaultLogger::isNullLogger()) {
             char dmp[128];
             ai_snprintf(dmp, 128, "B3D file format version: %i",version);
-            DefaultLogger::get()->info(dmp);
+            ASSIMP_LOG_INFO(dmp);
         }
 
         while( ChunkSize() ){
@@ -622,7 +640,7 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
         aiNode *node=_nodes[i];
 
         for( size_t j=0;j<node->mNumMeshes;++j ){
-            aiMesh *mesh=_meshes[node->mMeshes[j]];
+            aiMesh *mesh = _meshes[node->mMeshes[j]].get();
 
             int n_tris=mesh->mNumFaces;
             int n_verts=mesh->mNumVertices=n_tris * 3;
@@ -685,27 +703,28 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
 
     //nodes
     scene->mRootNode=_nodes[0];
+    _nodes.clear();  // node ownership now belongs to scene
 
     //material
     if( !_materials.size() ){
-        _materials.push_back( new aiMaterial );
+        _materials.emplace_back( std::unique_ptr<aiMaterial>(new aiMaterial) );
     }
     scene->mNumMaterials= static_cast<unsigned int>(_materials.size());
-    scene->mMaterials=to_array( _materials );
+    scene->mMaterials = unique_to_array( _materials );
 
     //meshes
     scene->mNumMeshes= static_cast<unsigned int>(_meshes.size());
-    scene->mMeshes=to_array( _meshes );
+    scene->mMeshes = unique_to_array( _meshes );
 
     //animations
     if( _animations.size()==1 && _nodeAnims.size() ){
 
-        aiAnimation *anim=_animations.back();
+        aiAnimation *anim = _animations.back().get();
         anim->mNumChannels=static_cast<unsigned int>(_nodeAnims.size());
-        anim->mChannels=to_array( _nodeAnims );
+        anim->mChannels = unique_to_array( _nodeAnims );
 
         scene->mNumAnimations=static_cast<unsigned int>(_animations.size());
-        scene->mAnimations=to_array( _animations );
+        scene->mAnimations=unique_to_array( _animations );
     }
 
     // convert to RH

+ 8 - 6
Engine/lib/assimp/code/B3DImporter.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -47,8 +48,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/types.h>
 #include <assimp/mesh.h>
 #include <assimp/material.h>
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 
+#include <memory>
 #include <vector>
 
 struct aiNodeAnim;
@@ -116,15 +118,15 @@ private:
     std::vector<unsigned> _stack;
 
     std::vector<std::string> _textures;
-    std::vector<aiMaterial*> _materials;
+    std::vector<std::unique_ptr<aiMaterial> > _materials;
 
     int _vflags,_tcsets,_tcsize;
     std::vector<Vertex> _vertices;
 
     std::vector<aiNode*> _nodes;
-    std::vector<aiMesh*> _meshes;
-    std::vector<aiNodeAnim*> _nodeAnims;
-    std::vector<aiAnimation*> _animations;
+    std::vector<std::unique_ptr<aiMesh> > _meshes;
+    std::vector<std::unique_ptr<aiNodeAnim> > _nodeAnims;
+    std::vector<std::unique_ptr<aiAnimation> > _animations;
 };
 
 }

+ 79 - 46
Engine/lib/assimp/code/BVHLoader.cpp

@@ -4,7 +4,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -45,14 +46,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
 
 #include "BVHLoader.h"
-#include "fast_atof.h"
-#include "SkeletonMeshBuilder.h"
+#include <assimp/fast_atof.h>
+#include <assimp/SkeletonMeshBuilder.h>
 #include <assimp/Importer.hpp>
 #include <memory>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/scene.h>
 #include <assimp/importerdesc.h>
+#include <map>
 
 using namespace Assimp;
 using namespace Assimp::Formatter;
@@ -198,6 +200,7 @@ aiNode* BVHLoader::ReadNode()
     Node& internNode = mNodes.back();
 
     // now read the node's contents
+    std::string siteToken;
     while( 1)
     {
         std::string token = GetNextToken();
@@ -217,7 +220,8 @@ aiNode* BVHLoader::ReadNode()
         else if( token == "End")
         {
             // The real symbol is "End Site". Second part comes in a separate token
-            std::string siteToken = GetNextToken();
+            siteToken.clear();
+            siteToken = GetNextToken();
             if( siteToken != "Site")
                 ThrowException( format() << "Expected \"End Site\" keyword, but found \"" << token << " " << siteToken << "\"." );
 
@@ -261,21 +265,18 @@ aiNode* BVHLoader::ReadEndSite( const std::string& pParentName)
     aiNode* node = new aiNode( "EndSite_" + pParentName);
 
     // now read the node's contents. Only possible entry is "OFFSET"
-    while( 1)
-    {
-        std::string token = GetNextToken();
+    std::string token;
+    while( 1) {
+        token.clear();
+        token = GetNextToken();
 
         // end node's offset
-        if( token == "OFFSET")
-        {
+        if( token == "OFFSET") {
             ReadNodeOffset( node);
-        }
-        else if( token == "}")
-        {
+        } else if( token == "}") {
             // we're done with the end node
             break;
-        } else
-        {
+        } else {
             // everything else is a parse error
             ThrowException( format() << "Unknown keyword \"" << token << "\"." );
         }
@@ -295,8 +296,10 @@ void BVHLoader::ReadNodeOffset( aiNode* pNode)
     offset.z = GetNextTokenAsFloat();
 
     // build a transformation matrix from it
-    pNode->mTransformation = aiMatrix4x4( 1.0f, 0.0f, 0.0f, offset.x, 0.0f, 1.0f, 0.0f, offset.y,
-        0.0f, 0.0f, 1.0f, offset.z, 0.0f, 0.0f, 0.0f, 1.0f);
+    pNode->mTransformation = aiMatrix4x4( 1.0f, 0.0f, 0.0f, offset.x,
+                                          0.0f, 1.0f, 0.0f, offset.y,
+                                          0.0f, 0.0f, 1.0f, offset.z,
+                                          0.0f, 0.0f, 0.0f, 1.0f);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -459,6 +462,13 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
         aiNodeAnim* nodeAnim = new aiNodeAnim;
         anim->mChannels[a] = nodeAnim;
         nodeAnim->mNodeName.Set( nodeName);
+		std::map<BVHLoader::ChannelType, int> channelMap;
+
+		//Build map of channels 
+		for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel)
+		{
+			channelMap[node.mChannels[channel]] = channel;
+		}
 
         // translational part, if given
         if( node.mChannels.size() == 6)
@@ -470,16 +480,32 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
             {
                 poskey->mTime = double( fr);
 
-                // Now compute all translations in the right order
-                for( unsigned int channel = 0; channel < 3; ++channel)
+                // Now compute all translations 
+                for(BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel +1))
                 {
-                    switch( node.mChannels[channel])
-                    {
-                    case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
-                    case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
-                    case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
-                    default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
-                    }
+					//Find channel in node
+					std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
+
+					if (mapIter == channelMap.end())
+						throw DeadlyImportError("Missing position channel in node " + nodeName);
+					else {
+						int channelIdx = mapIter->second;
+						switch (channel) {
+						    case Channel_PositionX: 
+                                poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channelIdx]; 
+                                break;
+						    case Channel_PositionY: 
+                                poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channelIdx]; 
+                                break;
+						    case Channel_PositionZ: 
+                                poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channelIdx]; 
+                                break;
+                                
+                            default:
+                                break;
+						}
+
+					}
                 }
                 ++poskey;
             }
@@ -495,12 +521,6 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
 
         // rotation part. Always present. First find value offsets
         {
-            unsigned int rotOffset  = 0;
-            if( node.mChannels.size() == 6)
-            {
-                // Offset all further calculations
-                rotOffset = 3;
-            }
 
             // Then create the number of rotation keys
             nodeAnim->mNumRotationKeys = mAnimNumFrames;
@@ -510,20 +530,33 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
             {
                 aiMatrix4x4 temp;
                 aiMatrix3x3 rotMatrix;
-
-                for( unsigned int channel = 0; channel < 3; ++channel)
-                {
-                    // translate ZXY euler angels into a quaternion
-                    const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
-
-                    // Compute rotation transformations in the right order
-                    switch (node.mChannels[rotOffset+channel])
-                    {
-                    case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
-                    case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp);  break;
-                    case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
-                    default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
-                    }
+				for (BVHLoader::ChannelType channel = Channel_RotationX; channel <= Channel_RotationZ; channel = (BVHLoader::ChannelType)(channel + 1))
+				{
+					//Find channel in node
+					std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
+
+					if (mapIter == channelMap.end())
+						throw DeadlyImportError("Missing rotation channel in node " + nodeName);
+					else {
+						int channelIdx = mapIter->second;
+						// translate ZXY euler angels into a quaternion
+						const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
+
+						// Compute rotation transformations in the right order
+						switch (channel)
+						{
+							case Channel_RotationX: 
+                                aiMatrix4x4::RotationX(angle, temp); rotMatrix *= aiMatrix3x3(temp); 
+                                break;
+							case Channel_RotationY: 
+                                aiMatrix4x4::RotationY(angle, temp); rotMatrix *= aiMatrix3x3(temp);  
+                                break;
+							case Channel_RotationZ: aiMatrix4x4::RotationZ(angle, temp); rotMatrix *= aiMatrix3x3(temp); 
+                                break;
+                            default:
+                                break;
+						}
+					}
                 }
 
                 rotkey->mTime = double( fr);

+ 7 - 3
Engine/lib/assimp/code/BVHLoader.h

@@ -4,7 +4,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -48,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_BVHLOADER_H_INC
 #define AI_BVHLOADER_H_INC
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 
 struct aiNode;
 
@@ -83,7 +84,10 @@ class BVHLoader : public BaseImporter
         std::vector<ChannelType> mChannels;
         std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
 
-        Node() { }
+        Node()
+        : mNode(nullptr)
+        { }
+
         explicit Node( const aiNode* pNode) : mNode( pNode) { }
     };
 

+ 70 - 55
Engine/lib/assimp/code/BaseImporter.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -44,14 +45,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *  @brief Implementation of BaseImporter
  */
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/ParsingUtils.h>
 #include "FileSystemFilter.h"
 #include "Importer.h"
-#include "ByteSwapper.h"
+#include <assimp/ByteSwapper.h>
 #include <assimp/scene.h>
 #include <assimp/Importer.hpp>
 #include <assimp/postprocess.h>
 #include <assimp/importerdesc.h>
+
 #include <ios>
 #include <list>
 #include <memory>
@@ -62,24 +65,25 @@ using namespace Assimp;
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-BaseImporter::BaseImporter()
-: m_progress()
-{
+BaseImporter::BaseImporter() AI_NO_EXCEPT
+: m_progress() {
     // nothing to do here
 }
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-BaseImporter::~BaseImporter()
-{
+BaseImporter::~BaseImporter() {
     // nothing to do here
 }
 
 // ------------------------------------------------------------------------------------------------
 // Imports the given file and returns the imported data.
-aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler)
-{
+aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler) {
     m_progress = pImp->GetProgressHandler();
+    if (nullptr == m_progress) {
+        return nullptr;
+    }
+
     ai_assert(m_progress);
 
     // Gather configuration properties for this run
@@ -99,8 +103,8 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
     } catch( const std::exception& err )    {
         // extract error description
         m_ErrorText = err.what();
-        DefaultLogger::get()->error(m_ErrorText);
-        return NULL;
+        ASSIMP_LOG_ERROR(m_ErrorText);
+        return nullptr;
     }
 
     // return what we gathered from the import.
@@ -114,13 +118,12 @@ void BaseImporter::SetupProperties(const Importer* /*pImp*/)
 }
 
 // ------------------------------------------------------------------------------------------------
-void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
-{
+void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
     const aiImporterDesc* desc = GetInfo();
-    ai_assert(desc != NULL);
+    ai_assert(desc != nullptr);
 
     const char* ext = desc->mFileExtensions;
-    ai_assert(ext != NULL);
+    ai_assert(ext != nullptr );
 
     const char* last = ext;
     do {
@@ -142,31 +145,29 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
     const char**        tokens,
     unsigned int        numTokens,
     unsigned int        searchBytes /* = 200 */,
-    bool                tokensSol /* false */)
+    bool                tokensSol /* false */,
+    bool                noAlphaBeforeTokens /* false */)
 {
-    ai_assert( NULL != tokens );
+    ai_assert( nullptr != tokens );
     ai_assert( 0 != numTokens );
     ai_assert( 0 != searchBytes);
 
-    if (!pIOHandler)
+    if ( nullptr == pIOHandler ) {
         return false;
+    }
 
     std::unique_ptr<IOStream> pStream (pIOHandler->Open(pFile));
     if (pStream.get() ) {
         // read 200 characters from the file
         std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]);
-        char* buffer = _buffer.get();
-        if( NULL == buffer ) {
-            return false;
-        }
-
-        const size_t read = pStream->Read(buffer,1,searchBytes);
-        if( !read ) {
+        char *buffer( _buffer.get() );
+        const size_t read( pStream->Read(buffer,1,searchBytes) );
+        if( 0 == read ) {
             return false;
         }
 
         for( size_t i = 0; i < read; ++i ) {
-            buffer[ i ] = ::tolower( buffer[ i ] );
+            buffer[ i ] = static_cast<char>( ::tolower( buffer[ i ] ) );
         }
 
         // It is not a proper handling of unicode files here ...
@@ -180,16 +181,29 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
         }
         *cur2 = '\0';
 
-        for (unsigned int i = 0; i < numTokens;++i) {
-            ai_assert(NULL != tokens[i]);
-            const char* r = strstr(buffer,tokens[i]);
+        std::string token;
+        for (unsigned int i = 0; i < numTokens; ++i ) {
+            ai_assert( nullptr != tokens[i] );
+            const size_t len( strlen( tokens[ i ] ) );
+            token.clear();
+            const char *ptr( tokens[ i ] );
+            for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) {
+                token.push_back( static_cast<char>( tolower( *ptr ) ) );
+                ++ptr;
+            }
+            const char* r = strstr( buffer, token.c_str() );
             if( !r ) {
                 continue;
             }
+            // We need to make sure that we didn't accidentially identify the end of another token as our token,
+            // e.g. in a previous version the "gltf " present in some gltf files was detected as "f "
+            if (noAlphaBeforeTokens && (r != buffer && isalpha(r[-1]))) {
+                continue;
+            }
             // We got a match, either we don't care where it is, or it happens to
             // be in the beginning of the file / line
             if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
-                DefaultLogger::get()->debug(std::string("Found positive match for header keyword: ") + tokens[i]);
+                ASSIMP_LOG_DEBUG_F( "Found positive match for header keyword: ", tokens[i] );
                 return true;
             }
         }
@@ -227,16 +241,19 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
 
 // ------------------------------------------------------------------------------------------------
 // Get file extension from path
-/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile)
-{
-    std::string::size_type pos = pFile.find_last_of('.');
+std::string BaseImporter::GetExtension( const std::string& file ) {
+    std::string::size_type pos = file.find_last_of('.');
 
     // no file extension at all
-    if( pos == std::string::npos)
+    if (pos == std::string::npos) {
         return "";
+    }
+
+
+    // thanks to Andy Maloney for the hint
+    std::string ret = file.substr( pos + 1 );
+    std::transform( ret.begin(), ret.end(), ret.begin(), ToLower<char>);
 
-    std::string ret = pFile.substr(pos+1);
-    std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
     return ret;
 }
 
@@ -245,7 +262,8 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
 /* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile,
     const void* _magic, unsigned int num, unsigned int offset, unsigned int size)
 {
-    ai_assert(size <= 16 && _magic);
+    ai_assert( size <= 16 );
+    ai_assert( _magic );
 
     if (!pIOHandler) {
         return false;
@@ -315,7 +333,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
 
     // UTF 8 with BOM
     if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) {
-        DefaultLogger::get()->debug("Found UTF-8 BOM ...");
+        ASSIMP_LOG_DEBUG("Found UTF-8 BOM ...");
 
         std::copy(data.begin()+3,data.end(),data.begin());
         data.resize(data.size()-3);
@@ -334,7 +352,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
 
     // UTF 32 LE with BOM
     if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
-        DefaultLogger::get()->debug("Found UTF-32 BOM ...");
+        ASSIMP_LOG_DEBUG("Found UTF-32 BOM ...");
 
         std::vector<char> output;
         int *ptr = (int*)&data[ 0 ];
@@ -354,7 +372,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
 
     // UTF 16 LE with BOM
     if(*((uint16_t*)&data.front()) == 0xFEFF) {
-        DefaultLogger::get()->debug("Found UTF-16 BOM ...");
+        ASSIMP_LOG_DEBUG("Found UTF-16 BOM ...");
 
         std::vector<unsigned char> output;
         utf8::utf16to8(data.begin(), data.end(), back_inserter(output));
@@ -379,16 +397,14 @@ void BaseImporter::ConvertUTF8toISO8859_1(std::string& data)
                 data[j] = ((unsigned char) data[++i] + 0x40);
             } else {
                 std::stringstream stream;
-
                 stream << "UTF8 code " << std::hex << data[i] << data[i + 1] << " can not be converted into ISA-8859-1.";
-
-                DefaultLogger::get()->error(stream.str());
+                ASSIMP_LOG_ERROR( stream.str() );
 
                 data[j++] = data[i++];
                 data[j] = data[i];
             }
         } else {
-            DefaultLogger::get()->error("UTF8 code but only one character remaining");
+            ASSIMP_LOG_ERROR("UTF8 code but only one character remaining");
 
             data[j] = data[i];
         }
@@ -404,7 +420,7 @@ void BaseImporter::TextFileToBuffer(IOStream* stream,
     std::vector<char>& data,
     TextFileMode mode)
 {
-    ai_assert(NULL != stream);
+    ai_assert(nullptr != stream);
 
     const size_t fileSize = stream->FileSize();
     if (mode == FORBID_EMPTY) {
@@ -465,14 +481,14 @@ struct Assimp::BatchData {
     , pImporter( nullptr )
     , next_id(0xffff)
     , validate( validate ) {
-        ai_assert( NULL != pIO );
+        ai_assert( nullptr != pIO );
         
         pImporter = new Importer();
         pImporter->SetIOHandler( pIO );
     }
 
     ~BatchData() {
-        pImporter->SetIOHandler( NULL ); /* get pointer back into our possession */
+        pImporter->SetIOHandler( nullptr ); /* get pointer back into our possession */
         delete pImporter;
     }
 
@@ -498,9 +514,8 @@ struct Assimp::BatchData {
 typedef std::list<LoadRequest>::iterator LoadReqIt;
 
 // ------------------------------------------------------------------------------------------------
-BatchLoader::BatchLoader(IOSystem* pIO, bool validate )
-{
-    ai_assert(NULL != pIO);
+BatchLoader::BatchLoader(IOSystem* pIO, bool validate ) {
+    ai_assert(nullptr != pIO);
 
     m_data = new BatchData( pIO, validate );
 }
@@ -566,7 +581,7 @@ aiScene* BatchLoader::GetImport( unsigned int which )
             return sc;
         }
     }
-    return NULL;
+    return nullptr;
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -589,13 +604,13 @@ void BatchLoader::LoadAll()
 
         if (!DefaultLogger::isNullLogger())
         {
-            DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
-            DefaultLogger::get()->info("File: " + (*it).file);
+            ASSIMP_LOG_INFO("%%% BEGIN EXTERNAL FILE %%%");
+            ASSIMP_LOG_INFO_F("File: ", (*it).file);
         }
         m_data->pImporter->ReadFile((*it).file,pp);
         (*it).scene = m_data->pImporter->GetOrphanedScene();
         (*it).loaded = true;
 
-        DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
+        ASSIMP_LOG_INFO("%%% END EXTERNAL FILE %%%");
     }
 }

+ 5 - 4
Engine/lib/assimp/code/BaseProcess.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -42,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /** @file Implementation of BaseProcess */
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include "BaseProcess.h"
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/scene.h>
@@ -52,7 +53,7 @@ using namespace Assimp;
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
-BaseProcess::BaseProcess()
+BaseProcess::BaseProcess() AI_NO_EXCEPT
 : shared()
 , progress()
 {
@@ -84,7 +85,7 @@ void BaseProcess::ExecuteOnScene( Importer* pImp)
 
         // extract error description
         pImp->Pimpl()->mErrorString = err.what();
-        DefaultLogger::get()->error(pImp->Pimpl()->mErrorString);
+        ASSIMP_LOG_ERROR(pImp->Pimpl()->mErrorString);
 
         // and kill the partially imported data
         delete pImp->Pimpl()->mScene;

+ 5 - 8
Engine/lib/assimp/code/BaseProcess.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -44,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INCLUDED_AI_BASEPROCESS_H
 
 #include <map>
-#include "GenericProperty.h"
+#include <assimp/GenericProperty.h>
 
 struct aiScene;
 
@@ -210,20 +211,16 @@ private:
  * should be executed. If the function returns true, the class' Execute()
  * function is called subsequently.
  */
-class ASSIMP_API_WINONLY BaseProcess
-{
+class ASSIMP_API_WINONLY BaseProcess {
     friend class Importer;
 
 public:
-
     /** Constructor to be privately used by Importer */
-    BaseProcess();
+    BaseProcess() AI_NO_EXCEPT;
 
     /** Destructor, private as well */
     virtual ~BaseProcess();
 
-public:
-
     // -------------------------------------------------------------------
     /** Returns whether the processing step is present in the given flag.
      * @param pFlags The processing flags the importer was called with. A

+ 6 - 4
Engine/lib/assimp/code/Bitmap.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -47,10 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 
-#include "Bitmap.h"
+#include <assimp/Bitmap.h>
 #include <assimp/texture.h>
 #include <assimp/IOStream.hpp>
-#include "ByteSwapper.h"
+#include <assimp/ByteSwapper.h>
 
 namespace Assimp {
 
@@ -84,7 +85,8 @@ namespace Assimp {
     }
 
     template<typename T>
-    inline std::size_t Copy(uint8_t* data, T& field) {
+    inline 
+    std::size_t Copy(uint8_t* data, const T &field) {
 #ifdef AI_BUILD_BIG_ENDIAN
         T field_swapped=AI_BE(field);
         std::memcpy(data, &field_swapped, sizeof(field)); return sizeof(field);

+ 1 - 1
Engine/lib/assimp/code/BlenderBMesh.h

@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_BLEND_BMESH_H
 #define INCLUDED_AI_BLEND_BMESH_H
 
-#include "LogAux.h"
+#include <assimp/LogAux.h>
 
 namespace Assimp
 {

+ 189 - 0
Engine/lib/assimp/code/BlenderCustomData.cpp

@@ -0,0 +1,189 @@
+#include "BlenderCustomData.h"
+#include "BlenderDNA.h"
+#include <array>
+#include <functional>
+
+namespace Assimp {
+    namespace Blender {
+        /**
+        *   @brief  read/convert of Structure array to memory
+        */
+        template<typename T>
+        bool read(const Structure &s, T *p, const size_t cnt, const FileDatabase &db) {
+            for (size_t i = 0; i < cnt; ++i) {
+                T read;
+                s.Convert(read, db);
+                *p = read;
+                p++;
+            }
+            return true;
+        }
+
+        /**
+        *   @brief  pointer to function read memory for n CustomData types
+        */
+        typedef bool        (*PRead)(ElemBase *pOut, const size_t cnt, const FileDatabase &db);
+        typedef ElemBase *  (*PCreate)(const size_t cnt);
+        typedef void(*PDestroy)(ElemBase *);
+
+#define IMPL_STRUCT_READ(ty)                                                    \
+        bool read##ty(ElemBase *v, const size_t cnt, const FileDatabase &db) {  \
+        ty *ptr = dynamic_cast<ty*>(v);                                         \
+        if (nullptr == ptr) {                                                   \
+            return false;                                                       \
+        }                                                                       \
+        return read<ty>(db.dna[#ty], ptr, cnt, db);                             \
+        }
+
+#define IMPL_STRUCT_CREATE(ty)                                                  \
+        ElemBase *create##ty(const size_t cnt) {                                \
+            return new ty[cnt];                                                 \
+        }
+
+#define IMPL_STRUCT_DESTROY(ty)                                                 \
+        void destroy##ty(ElemBase *pE) {                                        \
+            ty *p = dynamic_cast<ty *>(pE);                                     \
+            delete[]p;                                                          \
+        }
+
+        /**
+        *   @brief  helper macro to define Structure functions
+        */
+#define IMPL_STRUCT(ty)                                                         \
+        IMPL_STRUCT_READ(ty)                                                    \
+        IMPL_STRUCT_CREATE(ty)                                                  \
+        IMPL_STRUCT_DESTROY(ty)
+
+        // supported structures for CustomData
+        IMPL_STRUCT(MVert)
+        IMPL_STRUCT(MEdge)
+        IMPL_STRUCT(MFace)
+        IMPL_STRUCT(MTFace)
+        IMPL_STRUCT(MTexPoly)
+        IMPL_STRUCT(MLoopUV)
+        IMPL_STRUCT(MLoopCol)
+        IMPL_STRUCT(MPoly)
+        IMPL_STRUCT(MLoop)
+
+        /**
+        *   @brief  describes the size of data and the read function to be used for single CustomerData.type
+        */
+        struct CustomDataTypeDescription {
+            PRead Read;                         ///< function to read one CustomData type element
+            PCreate Create;                       ///< function to allocate n type elements
+            PDestroy Destroy;
+
+            CustomDataTypeDescription(PRead read, PCreate create, PDestroy destroy)
+                : Read(read)
+                , Create(create)
+                , Destroy(destroy)
+            {}
+        };
+
+
+        /**
+        *   @brief  helper macro to define Structure type specific CustomDataTypeDescription
+        *   @note   IMPL_STRUCT_READ for same ty must be used earlier to implement the typespecific read function
+        */
+#define DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(ty)           \
+        CustomDataTypeDescription{&read##ty, &create##ty, &destroy##ty}
+
+        /**
+        *   @brief  helper macro to define CustomDataTypeDescription for UNSUPPORTED type
+        */
+#define DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION          \
+        CustomDataTypeDescription{nullptr, nullptr, nullptr}
+
+        /**
+        *   @brief  descriptors for data pointed to from CustomDataLayer.data
+        *   @note   some of the CustomData uses already well defined Structures
+        *           other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
+        *           use a special readfunction for that cases
+        */
+        std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
+            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
+            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MFace),
+            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTFace),
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTexPoly),
+            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopUV),
+            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopCol),
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MPoly),
+            DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoop),
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+            DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION
+        }};
+
+
+        bool isValidCustomDataType(const int cdtype) {
+            return cdtype >= 0 && cdtype < CD_NUMTYPES;
+        }
+
+        bool readCustomData(std::shared_ptr<ElemBase> &out, const int cdtype, const size_t cnt, const FileDatabase &db) {
+            if (!isValidCustomDataType(cdtype)) {
+                throw Error((Formatter::format(), "CustomData.type ", cdtype, " out of index"));
+            }
+
+            const CustomDataTypeDescription cdtd = customDataTypeDescriptions[cdtype];
+            if (cdtd.Read && cdtd.Create && cdtd.Destroy && cnt > 0) {
+                // allocate cnt elements and parse them from file
+                out.reset(cdtd.Create(cnt), cdtd.Destroy);
+                return cdtd.Read(out.get(), cnt, db);
+            }
+            return false;
+        }
+
+        std::shared_ptr<CustomDataLayer> getCustomDataLayer(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) {
+            for (auto it = customdata.layers.begin(); it != customdata.layers.end(); ++it) {
+                if (it->get()->type == cdtype && name == it->get()->name) {
+                    return *it;
+                }
+            }
+            return nullptr;
+        }
+
+        const ElemBase * getCustomDataLayerData(const CustomData &customdata, const CustomDataType cdtype, const std::string &name)
+        {
+            const std::shared_ptr<CustomDataLayer> pLayer = getCustomDataLayer(customdata, cdtype, name);
+            if (pLayer && pLayer->data) {
+                return pLayer->data.get();
+            }
+            return nullptr;
+        }
+    }
+}

+ 89 - 0
Engine/lib/assimp/code/BlenderCustomData.h

@@ -0,0 +1,89 @@
+#pragma once
+
+#include "BlenderDNA.h"
+#include "BlenderScene.h"
+#include <memory>
+
+namespace Assimp {
+    namespace Blender {
+        /* CustomData.type from Blender (2.79b) */
+        enum CustomDataType {
+            CD_AUTO_FROM_NAME = -1,
+            CD_MVERT = 0,
+#ifdef DNA_DEPRECATED
+            CD_MSTICKY = 1,  /* DEPRECATED */
+#endif
+            CD_MDEFORMVERT = 2,
+            CD_MEDGE = 3,
+            CD_MFACE = 4,
+            CD_MTFACE = 5,
+            CD_MCOL = 6,
+            CD_ORIGINDEX = 7,
+            CD_NORMAL = 8,
+            /*	CD_POLYINDEX        = 9, */
+            CD_PROP_FLT = 10,
+            CD_PROP_INT = 11,
+            CD_PROP_STR = 12,
+            CD_ORIGSPACE = 13,  /* for modifier stack face location mapping */
+            CD_ORCO = 14,
+            CD_MTEXPOLY = 15,
+            CD_MLOOPUV = 16,
+            CD_MLOOPCOL = 17,
+            CD_TANGENT = 18,
+            CD_MDISPS = 19,
+            CD_PREVIEW_MCOL = 20,  /* for displaying weightpaint colors */
+            /*	CD_ID_MCOL          = 21, */
+            CD_TEXTURE_MLOOPCOL = 22,
+            CD_CLOTH_ORCO = 23,
+            CD_RECAST = 24,
+
+            /* BMESH ONLY START */
+            CD_MPOLY = 25,
+            CD_MLOOP = 26,
+            CD_SHAPE_KEYINDEX = 27,
+            CD_SHAPEKEY = 28,
+            CD_BWEIGHT = 29,
+            CD_CREASE = 30,
+            CD_ORIGSPACE_MLOOP = 31,
+            CD_PREVIEW_MLOOPCOL = 32,
+            CD_BM_ELEM_PYPTR = 33,
+            /* BMESH ONLY END */
+
+            CD_PAINT_MASK = 34,
+            CD_GRID_PAINT_MASK = 35,
+            CD_MVERT_SKIN = 36,
+            CD_FREESTYLE_EDGE = 37,
+            CD_FREESTYLE_FACE = 38,
+            CD_MLOOPTANGENT = 39,
+            CD_TESSLOOPNORMAL = 40,
+            CD_CUSTOMLOOPNORMAL = 41,
+
+            CD_NUMTYPES = 42
+        };
+
+        /**
+        *   @brief  check if given cdtype is valid (ie >= 0 and < CD_NUMTYPES)
+        *   @param[in]  cdtype to check
+        *   @return true when valid
+        */
+        bool isValidCustomDataType(const int cdtype);
+
+        /**
+        *   @brief  returns CustomDataLayer ptr for given cdtype and name
+        *   @param[in]  customdata CustomData to search for wanted layer
+        *   @param[in]  cdtype to search for
+        *   @param[in]  name to search for
+        *   @return CustomDataLayer * or nullptr if not found
+        */
+        std::shared_ptr<CustomDataLayer> getCustomDataLayer(const CustomData &customdata, CustomDataType cdtype, const std::string &name);
+
+        /**
+        *   @brief  returns CustomDataLayer data ptr for given cdtype and name
+        *   @param[in]  customdata CustomData to search for wanted layer
+        *   @param[in]  cdtype to search for
+        *   @param[in]  name to search for
+        *   @return * to struct data or nullptr if not found
+        */
+        const ElemBase * getCustomDataLayerData(const CustomData &customdata, CustomDataType cdtype, const std::string &name);
+    }
+}

+ 15 - 16
Engine/lib/assimp/code/BlenderDNA.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -47,9 +48,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 #include "BlenderDNA.h"
-#include "StreamReader.h"
-#include "fast_atof.h"
-#include "TinyFormatter.h"
+#include <assimp/StreamReader.h>
+#include <assimp/fast_atof.h>
+#include <assimp/TinyFormatter.h>
 
 using namespace Assimp;
 using namespace Assimp::Blender;
@@ -57,12 +58,11 @@ using namespace Assimp::Formatter;
 
 static bool match4(StreamReaderAny& stream, const char* string) {
     ai_assert( nullptr != string );
-    char tmp[] = {
-        (const char)(stream).GetI1(),
-        (const char)(stream).GetI1(),
-        (const char)(stream).GetI1(),
-        (const char)(stream).GetI1()
-    };
+    char tmp[4];
+    tmp[ 0 ] = ( stream ).GetI1();
+    tmp[ 1 ] = ( stream ).GetI1();
+    tmp[ 2 ] = ( stream ).GetI1();
+    tmp[ 3 ] = ( stream ).GetI1();
     return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
 }
 
@@ -210,8 +210,7 @@ void DNAParser::Parse ()
         s.size = offset;
     }
 
-    DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(),
-        " structures with totally ",fields," fields"));
+    ASSIMP_LOG_DEBUG_F( "BlenderDNA: Got ", dna.structures.size()," structures with totally ",fields," fields");
 
 #ifdef ASSIMP_BUILD_BLENDER_DEBUG
     dna.DumpToFile();
@@ -228,12 +227,12 @@ void DNAParser::Parse ()
 // ------------------------------------------------------------------------------------------------
 void DNA :: DumpToFile()
 {
-    // we dont't bother using the VFS here for this is only for debugging.
+    // we don't bother using the VFS here for this is only for debugging.
     // (and all your bases are belong to us).
 
     std::ofstream f("dna.txt");
     if (f.fail()) {
-        DefaultLogger::get()->error("Could not dump dna to dna.txt");
+        ASSIMP_LOG_ERROR("Could not dump dna to dna.txt");
         return;
     }
     f << "Field format: type name offset size" << "\n";
@@ -248,7 +247,7 @@ void DNA :: DumpToFile()
     }
     f << std::flush;
 
-    DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt");
+    ASSIMP_LOG_INFO("BlenderDNA: Dumped dna to dna.txt");
 }
 #endif
 
@@ -367,7 +366,7 @@ void SectionParser :: Next()
     }
 
 #ifdef ASSIMP_BUILD_BLENDER_DEBUG
-    DefaultLogger::get()->debug(current.id);
+    ASSIMP_LOG_DEBUG(current.id);
 #endif
 }
 

+ 40 - 6
Engine/lib/assimp/code/BlenderDNA.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -46,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_BLEND_DNA_H
 #define INCLUDED_AI_BLEND_DNA_H
 
-#include "BaseImporter.h"
-#include "StreamReader.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/StreamReader.h>
 #include <assimp/DefaultLogger.hpp>
 #include <stdint.h>
 #include <memory>
@@ -204,7 +205,7 @@ enum ErrorPolicy {
 
 // -------------------------------------------------------------------------------
 /** Represents a data structure in a BLEND file. A Structure defines n fields
- *  and their locatios and encodings the input stream. Usually, every
+ *  and their locations and encodings the input stream. Usually, every
  *  Structure instance pertains to one equally-named data structure in the
  *  BlenderScene.h header. This class defines various utilities to map a
  *  binary `blob` read from the file to such a structure instance with
@@ -308,6 +309,28 @@ public:
     void ReadField(T& out, const char* name,
         const FileDatabase& db) const;
 
+    // --------------------------------------------------------
+    /**
+    *   @brief  field parsing for dynamic vectors
+    *   @param[in]  out vector of struct to be filled
+    *   @param[in]  name of field
+    *   @param[in]  db to access the file, dna, ...
+    *   @return true when read was successful
+    */
+    template <int error_policy, template <typename> class TOUT, typename T>
+    bool ReadFieldPtrVector(vector<TOUT<T>>&out, const char* name, const FileDatabase& db) const;
+
+    /**
+    *   @brief  parses raw customdata
+    *   @param[in]  out shared_ptr to be filled
+    *   @param[in]  cdtype customdata type to read
+    *   @param[in]  name of field ptr
+    *   @param[in]  db to access the file, dna, ...
+    *   @return true when read was successful
+    */
+    template <int error_policy>
+    bool ReadCustomDataPtr(std::shared_ptr<ElemBase>&out, int cdtype, const char* name, const FileDatabase& db) const;
+
 private:
 
     // --------------------------------------------------------
@@ -380,7 +403,7 @@ template <>  struct Structure :: _defaultInitializer<ErrorPolicy_Warn> {
 
     template <typename T>
     void operator ()(T& out, const char* reason = "<add reason>") {
-        DefaultLogger::get()->warn(reason);
+        ASSIMP_LOG_WARN(reason);
 
         // ... and let the show go on
         _defaultInitializer<0 /*ErrorPolicy_Igno*/>()(out);
@@ -662,7 +685,7 @@ public:
     /** Check whether a specific item is in the cache.
      *  @param s Data type of the item
      *  @param out Output pointer. Unchanged if the
-     *   cache doens't know the item yet.
+     *   cache doesn't know the item yet.
      *  @param ptr Item address to look for. */
     template <typename T> void get (
         const Structure& s,
@@ -802,6 +825,17 @@ private:
     FileDatabase& db;
 };
 
+/**
+*   @brief  read CustomData's data to ptr to mem
+*   @param[out] out memory ptr to set
+*   @param[in]  cdtype  to read
+*   @param[in]  cnt cnt of elements to read
+*   @param[in]  db to read elements from
+*   @return true when ok
+*/
+bool readCustomData(std::shared_ptr<ElemBase> &out, int cdtype, size_t cnt, const FileDatabase &db);
+
+
     } // end Blend
 } // end Assimp
 

+ 107 - 6
Engine/lib/assimp/code/BlenderDNA.inl

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -47,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INCLUDED_AI_BLEND_DNA_INL
 
 #include <memory>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 
 namespace Assimp {
 namespace Blender {
@@ -306,6 +307,108 @@ void Structure :: ReadField(T& out, const char* name, const FileDatabase& db) co
 }
 
 
+//--------------------------------------------------------------------------------
+// field parsing for raw untyped data (like CustomDataLayer.data)
+template <int error_policy>
+bool Structure::ReadCustomDataPtr(std::shared_ptr<ElemBase>&out, int cdtype, const char* name, const FileDatabase& db) const {
+
+	const StreamReaderAny::pos old = db.reader->GetCurrentPos();
+
+	Pointer ptrval;
+	const Field* f;
+	try	{
+		f = &(*this)[name];
+
+		// sanity check, should never happen if the genblenddna script is right
+		if (!(f->flags & FieldFlag_Pointer)) {
+			throw Error((Formatter::format(), "Field `", name, "` of structure `",
+				this->name, "` ought to be a pointer"));
+		}
+
+		db.reader->IncPtr(f->offset);
+		Convert(ptrval, db);
+		// actually it is meaningless on which Structure the Convert is called
+		// because the `Pointer` argument triggers a special implementation.
+	}
+	catch (const Error& e) {
+		_defaultInitializer<error_policy>()(out, e.what());
+		out.reset();
+	}
+
+	bool readOk = true;
+	if (ptrval.val)	{
+		// get block for ptr
+		const FileBlockHead* block = LocateFileBlockForAddress(ptrval, db);
+		db.reader->SetCurrentPos(block->start + static_cast<size_t>((ptrval.val - block->address.val)));
+		// read block->num instances of given type to out
+		readOk = readCustomData(out, cdtype, block->num, db);
+	}
+
+	// and recover the previous stream position
+	db.reader->SetCurrentPos(old);
+
+#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
+	++db.stats().fields_read;
+#endif
+
+	return readOk;
+}
+
+//--------------------------------------------------------------------------------
+template <int error_policy, template <typename> class TOUT, typename T>
+bool Structure::ReadFieldPtrVector(vector<TOUT<T>>&out, const char* name, const FileDatabase& db) const {
+	out.clear();
+
+	const StreamReaderAny::pos old = db.reader->GetCurrentPos();
+
+	Pointer ptrval;
+	const Field* f;
+	try	{
+		f = &(*this)[name];
+
+		// sanity check, should never happen if the genblenddna script is right
+		if (!(f->flags & FieldFlag_Pointer)) {
+			throw Error((Formatter::format(), "Field `", name, "` of structure `",
+				this->name, "` ought to be a pointer"));
+		}
+
+		db.reader->IncPtr(f->offset);
+		Convert(ptrval, db);
+		// actually it is meaningless on which Structure the Convert is called
+		// because the `Pointer` argument triggers a special implementation.
+	}
+	catch (const Error& e) {
+		_defaultInitializer<error_policy>()(out, e.what());
+		out.clear();
+		return false;
+	}
+
+
+	if (ptrval.val)	{
+		// find the file block the pointer is pointing to
+		const FileBlockHead* block = LocateFileBlockForAddress(ptrval, db);
+		db.reader->SetCurrentPos(block->start + static_cast<size_t>((ptrval.val - block->address.val)));
+		// FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
+		// I really ought to improve StreamReader to work with 64 bit indices exclusively.
+
+		const Structure& s = db.dna[f->type];
+		for (size_t i = 0; i < block->num; ++i)	{
+			TOUT<T> p(new T);
+			s.Convert(*p, db);
+			out.push_back(p);
+		}
+	}
+
+	db.reader->SetCurrentPos(old);
+
+#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
+	++db.stats().fields_read;
+#endif
+
+	return true;
+}
+
+
 //--------------------------------------------------------------------------------
 template <template <typename> class TOUT, typename T>
 bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db,
@@ -467,9 +570,7 @@ template <> bool Structure :: ResolvePointer<std::shared_ptr,ElemBase>(std::shar
         // this might happen if DNA::RegisterConverters hasn't been called so far
         // or if the target type is not contained in `our` DNA.
         out.reset();
-        DefaultLogger::get()->warn((Formatter::format(),
-            "Failed to find a converter for the `",s.name,"` structure"
-            ));
+        ASSIMP_LOG_WARN_F( "Failed to find a converter for the `",s.name,"` structure" );
         return false;
     }
 
@@ -501,7 +602,7 @@ const FileBlockHead* Structure :: LocateFileBlockForAddress(const Pointer & ptrv
 {
     // the file blocks appear in list sorted by
     // with ascending base addresses so we can run a
-    // binary search to locate the pointee quickly.
+    // binary search to locate the pointer quickly.
 
     // NOTE: Blender seems to distinguish between side-by-side
     // data (stored in the same data block) and far pointers,

+ 8 - 3
Engine/lib/assimp/code/BlenderIntermediate.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -121,9 +122,11 @@ namespace Blender {
 #   pragma warning(disable:4351)
 #endif
 
+    // As counter-intuitive as it may seem, a comparator must return false for equal values.
+    // The C++ standard defines and expects this behavior: true if lhs < rhs, false otherwise.
     struct ObjectCompare {
         bool operator() (const Object* left, const Object* right) const {
-            return ::strncmp(left->id.name, right->id.name, strlen( left->id.name ) ) == 0;
+            return ::strncmp(left->id.name, right->id.name, strlen( left->id.name ) ) < 0;
         }
     };
 
@@ -142,9 +145,11 @@ namespace Blender {
             , db(db)
         {}
 
+        // As counter-intuitive as it may seem, a comparator must return false for equal values.
+        // The C++ standard defines and expects this behavior: true if lhs < rhs, false otherwise.
         struct ObjectCompare {
             bool operator() (const Object* left, const Object* right) const {
-                return ::strncmp( left->id.name, right->id.name, strlen( left->id.name ) ) == 0;
+                return ::strncmp( left->id.name, right->id.name, strlen( left->id.name ) ) < 0;
             }
         };
 

+ 81 - 29
Engine/lib/assimp/code/BlenderLoader.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -53,13 +54,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "BlenderIntermediate.h"
 #include "BlenderModifier.h"
 #include "BlenderBMesh.h"
-#include "StringUtils.h"
+#include "BlenderCustomData.h"
+#include <assimp/StringUtils.h>
 #include <assimp/scene.h>
 #include <assimp/importerdesc.h>
 
-#include "StringComparison.h"
-#include "StreamReader.h"
-#include "MemoryIOWrapper.h"
+#include <assimp/StringComparison.h>
+#include <assimp/StreamReader.h>
+#include <assimp/MemoryIOWrapper.h>
 
 #include <cctype>
 
@@ -153,14 +155,6 @@ void BlenderImporter::SetupProperties(const Importer* /*pImp*/)
     // nothing to be done for the moment
 }
 
-struct free_it {
-    free_it(void* free) : free(free) {}
-    ~free_it() {
-        ::free(this->free);
-    }
-
-    void* free;
-};
 
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure.
@@ -168,8 +162,7 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
     aiScene* pScene, IOSystem* pIOHandler)
 {
 #ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
-    Bytef* dest = NULL;
-    free_it free_it_really(dest);
+    std::vector<Bytef> uncompressed;
 #endif
 
 
@@ -217,6 +210,7 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
 
         size_t total = 0l;
 
+        // TODO: be smarter about this, decompress directly into heap buffer
         // and decompress the data .... do 1k chunks in the hope that we won't kill the stack
 #define MYBLOCK 1024
         Bytef block[MYBLOCK];
@@ -231,8 +225,8 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
             }
             const size_t have = MYBLOCK - zstream.avail_out;
             total += have;
-            dest = reinterpret_cast<Bytef*>( realloc(dest,total) );
-            memcpy(dest + total - have,block,have);
+            uncompressed.resize(total);
+            memcpy(uncompressed.data() + total - have,block,have);
         }
         while (ret != Z_STREAM_END);
 
@@ -240,7 +234,7 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
         inflateEnd(&zstream);
 
         // replace the input stream with a memory stream
-        stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(dest),total));
+        stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(uncompressed.data()),total));
 
         // .. and retry
         stream->Read(magic,7,1);
@@ -334,12 +328,12 @@ void BlenderImporter::ExtractScene(Scene& out, const FileDatabase& file)
     ss.Convert(out,file);
 
 #ifndef ASSIMP_BUILD_BLENDER_NO_STATS
-    DefaultLogger::get()->info((format(),
+    ASSIMP_LOG_INFO_F(
         "(Stats) Fields read: " ,file.stats().fields_read,
         ", pointers resolved: " ,file.stats().pointers_resolved,
         ", cache hits: "        ,file.stats().cache_hits,
         ", cached objects: "    ,file.stats().cached_objects
-    ));
+    );
 #endif
 }
 
@@ -1028,6 +1022,34 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
         }
     }
 
+    // TODO should we create the TextureUVMapping map in Convert<Material> to prevent redundant processing?
+
+    // create texture <-> uvname mapping for all materials
+    // key is texture number, value is data *
+    typedef std::map<uint32_t, const MLoopUV *> TextureUVMapping;
+    // key is material number, value is the TextureUVMapping for the material
+    typedef std::map<uint32_t, TextureUVMapping> MaterialTextureUVMappings;
+    MaterialTextureUVMappings matTexUvMappings;
+    const uint32_t maxMat = static_cast<const uint32_t>(mesh->mat.size());
+    for (uint32_t m = 0; m < maxMat; ++m) {
+        // get material by index
+        const std::shared_ptr<Material> pMat = mesh->mat[m];
+        TextureUVMapping texuv;
+        const uint32_t maxTex = sizeof(pMat->mtex) / sizeof(pMat->mtex[0]);
+        for (uint32_t t = 0; t < maxTex; ++t) {
+            if (pMat->mtex[t] && pMat->mtex[t]->uvname[0]) {
+                // get the CustomData layer for given uvname and correct type
+                const ElemBase *pLoop = getCustomDataLayerData(mesh->ldata, CD_MLOOPUV, pMat->mtex[t]->uvname);
+                if (pLoop) {
+                    texuv.insert(std::make_pair(t, dynamic_cast<const MLoopUV *>(pLoop)));
+                }
+            }
+        }
+        if (texuv.size()) {
+            matTexUvMappings.insert(std::make_pair(m, texuv));
+        }
+    }
+
     // collect texture coordinates, they're stored in a separate per-face buffer
     if (mesh->mtface || mesh->mloopuv) {
         if (mesh->totface > static_cast<int> ( mesh->mtface.size())) {
@@ -1035,8 +1057,17 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
         }
         for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
             ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
-
-            (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
+            const auto itMatTexUvMapping = matTexUvMappings.find((*it)->mMaterialIndex);
+            if (itMatTexUvMapping == matTexUvMappings.end()) {
+                // default behaviour like before
+                (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
+            }
+            else {
+                // create texture coords for every mapped tex
+                for (uint32_t i = 0; i < itMatTexUvMapping->second.size(); ++i) {
+                    (*it)->mTextureCoords[i] = new aiVector3D[(*it)->mNumVertices];
+                }
+            }
             (*it)->mNumFaces = (*it)->mNumVertices = 0;
         }
 
@@ -1058,13 +1089,34 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
             aiMesh* const out = temp[ mat_num_to_mesh_idx[ v.mat_nr ] ];
             const aiFace& f = out->mFaces[out->mNumFaces++];
 
-            aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
-            for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
-                const MLoopUV& uv = mesh->mloopuv[v.loopstart + j];
-                vo->x = uv.uv[0];
-                vo->y = uv.uv[1];
+            const auto itMatTexUvMapping = matTexUvMappings.find(v.mat_nr);
+            if (itMatTexUvMapping == matTexUvMappings.end()) {
+                // old behavior
+                aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
+                for (unsigned int j = 0; j < f.mNumIndices; ++j, ++vo, ++out->mNumVertices) {
+                    const MLoopUV& uv = mesh->mloopuv[v.loopstart + j];
+                    vo->x = uv.uv[0];
+                    vo->y = uv.uv[1];
+                }
+            }
+            else {
+                // create textureCoords for every mapped tex
+                for (uint32_t m = 0; m < itMatTexUvMapping->second.size(); ++m) {
+                    const MLoopUV *tm = itMatTexUvMapping->second[m];
+                    aiVector3D* vo = &out->mTextureCoords[m][out->mNumVertices];
+                    uint32_t j = 0;
+                    for (; j < f.mNumIndices; ++j, ++vo) {
+                        const MLoopUV& uv = tm[v.loopstart + j];
+                        vo->x = uv.uv[0];
+                        vo->y = uv.uv[1];
+                    }
+                    // only update written mNumVertices in last loop
+                    // TODO why must the numVertices be incremented here?
+                    if (m == itMatTexUvMapping->second.size() - 1) {
+                        out->mNumVertices += j;
+                    }
+                }
             }
-
         }
     }
 
@@ -1154,7 +1206,7 @@ aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj,
     out->mUp = aiVector3D(0.f, 1.f, 0.f);
     out->mLookAt = aiVector3D(0.f, 0.f, -1.f);
     if (cam->sensor_x && cam->lens) {
-        out->mHorizontalFOV = std::atan2(cam->sensor_x,  2.f * cam->lens);
+        out->mHorizontalFOV = 2.f * std::atan2(cam->sensor_x,  2.f * cam->lens);
     }
     out->mClipPlaneNear = cam->clipsta;
     out->mClipPlaneFar = cam->clipend;

+ 4 - 3
Engine/lib/assimp/code/BlenderLoader.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -45,8 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_BLEND_LOADER_H
 #define INCLUDED_AI_BLEND_LOADER_H
 
-#include "BaseImporter.h"
-#include "LogAux.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/LogAux.h>
 #include <memory>
 
 struct aiNode;

+ 3 - 30
Engine/lib/assimp/code/BlenderModifier.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -47,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "BlenderModifier.h"
 #include <assimp/SceneCombiner.h>
-#include "Subdivision.h"
+#include <assimp/Subdivision.h>
 #include <assimp/scene.h>
 #include <memory>
 
@@ -69,34 +70,6 @@ static const fpCreateModifier creators[] = {
         NULL // sentinel
 };
 
-// ------------------------------------------------------------------------------------------------
-// just testing out some new macros to simplify logging
-#define ASSIMP_LOG_WARN_F(string,...)\
-    DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
-
-#define ASSIMP_LOG_ERROR_F(string,...)\
-    DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
-
-#define ASSIMP_LOG_DEBUG_F(string,...)\
-    DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
-
-#define ASSIMP_LOG_INFO_F(string,...)\
-    DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
-
-
-#define ASSIMP_LOG_WARN(string)\
-    DefaultLogger::get()->warn(string)
-
-#define ASSIMP_LOG_ERROR(string)\
-    DefaultLogger::get()->error(string)
-
-#define ASSIMP_LOG_DEBUG(string)\
-    DefaultLogger::get()->debug(string)
-
-#define ASSIMP_LOG_INFO(string)\
-    DefaultLogger::get()->info(string)
-
-
 // ------------------------------------------------------------------------------------------------
 struct SharedModifierData : ElemBase
 {

+ 30 - 32
Engine/lib/assimp/code/BlenderModifier.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -46,53 +47,57 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INCLUDED_AI_BLEND_MODIFIER_H
 
 #include "BlenderIntermediate.h"
-#include "TinyFormatter.h"
 
 namespace Assimp {
 namespace Blender {
 
 // -------------------------------------------------------------------------------------------
-/** Dummy base class for all blender modifiers. Modifiers are reused between imports, so
- *  they should be stateless and not try to cache model data. */
+/** 
+ *  Dummy base class for all blender modifiers. Modifiers are reused between imports, so
+ *  they should be stateless and not try to cache model data. 
+ */
 // -------------------------------------------------------------------------------------------
-class BlenderModifier
-{
+class BlenderModifier {
 public:
+    /**
+     *  The class destructor, virtual.
+     */
     virtual ~BlenderModifier() {
         // empty
     }
 
-public:
-
     // --------------------
-    /** Check if *this* modifier is active, given a ModifierData& block.*/
+    /** 
+     *  Check if *this* modifier is active, given a ModifierData& block.
+     */
     virtual bool IsActive( const ModifierData& /*modin*/) {
         return false;
     }
 
     // --------------------
-    /** Apply the modifier to a given output node. The original data used
+    /** 
+     *  Apply the modifier to a given output node. The original data used
      *  to construct the node is given as well. Not called unless IsActive()
-     *  was called and gave positive response. */
+     *  was called and gave positive response. 
+     */
     virtual void DoIt(aiNode& /*out*/,
         ConversionData& /*conv_data*/,
         const ElemBase& orig_modifier,
         const Scene& /*in*/,
         const Object& /*orig_object*/
     ) {
-        DefaultLogger::get()->warn((Formatter::format("This modifier is not supported, skipping: "),orig_modifier.dna_type));
+        ASSIMP_LOG_INFO_F("This modifier is not supported, skipping: ",orig_modifier.dna_type );
         return;
     }
 };
 
-
 // -------------------------------------------------------------------------------------------
-/** Manage all known modifiers and instance and apply them if necessary */
+/** 
+ *  Manage all known modifiers and instance and apply them if necessary 
+ */
 // -------------------------------------------------------------------------------------------
-class BlenderModifierShowcase
-{
+class BlenderModifierShowcase {
 public:
-
     // --------------------
     /** Apply all requested modifiers provided we support them. */
     void ApplyModifiers(aiNode& out,
@@ -102,25 +107,18 @@ public:
     );
 
 private:
-
     TempArray< std::vector,BlenderModifier > cached_modifiers;
 };
 
-
-
-
-
-// MODIFIERS
-
-
+// MODIFIERS /////////////////////////////////////////////////////////////////////////////////
 
 // -------------------------------------------------------------------------------------------
-/** Mirror modifier. Status: implemented. */
+/** 
+ *  Mirror modifier. Status: implemented. 
+ */
 // -------------------------------------------------------------------------------------------
-class BlenderModifier_Mirror : public BlenderModifier
-{
+class BlenderModifier_Mirror : public BlenderModifier {
 public:
-
     // --------------------
     virtual bool IsActive( const ModifierData& modin);
 
@@ -136,8 +134,7 @@ public:
 // -------------------------------------------------------------------------------------------
 /** Subdivision modifier. Status: dummy. */
 // -------------------------------------------------------------------------------------------
-class BlenderModifier_Subdivision : public BlenderModifier
-{
+class BlenderModifier_Subdivision : public BlenderModifier {
 public:
 
     // --------------------
@@ -152,6 +149,7 @@ public:
     ) ;
 };
 
+}
+}
 
-}}
 #endif // !INCLUDED_AI_BLEND_MODIFIER_H

+ 46 - 2
Engine/lib/assimp/code/BlenderScene.cpp

@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "BlenderScene.h"
 #include "BlenderSceneGen.h"
 #include "BlenderDNA.h"
+#include "BlenderCustomData.h"
 
 using namespace Assimp;
 using namespace Assimp::Blender;
@@ -116,7 +117,7 @@ template <> void Structure :: Convert<MTex> (
     ReadField<ErrorPolicy_Igno>(temp,"projy",db);
     dest.projy = static_cast<Assimp::Blender::MTex::Projection>(temp);
     ReadField<ErrorPolicy_Igno>(temp,"projz",db);
-    dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
+    dest.projz = static_cast<Assimp::Blender::MTex::Projection>(temp);
     ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
     ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
     ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
@@ -202,7 +203,7 @@ template <> void Structure :: Convert<Lamp> (
     int temp = 0;
     ReadField<ErrorPolicy_Fail>(temp,"type",db);
     dest.type = static_cast<Assimp::Blender::Lamp::Type>(temp);
-    ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
+    ReadField<ErrorPolicy_Igno>(dest.flags,"flag",db);
     ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
     ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
     ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
@@ -481,6 +482,12 @@ template <> void Structure :: Convert<Mesh> (
     ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db);
     ReadFieldPtr<ErrorPolicy_Fail>(dest.mat,"**mat",db);
 
+    ReadField<ErrorPolicy_Igno>(dest.vdata, "vdata", db);
+    ReadField<ErrorPolicy_Igno>(dest.edata, "edata", db);
+    ReadField<ErrorPolicy_Igno>(dest.fdata, "fdata", db);
+    ReadField<ErrorPolicy_Igno>(dest.pdata, "pdata", db);
+    ReadField<ErrorPolicy_Warn>(dest.ldata, "ldata", db);
+
     db.reader->IncPtr(size);
 }
 
@@ -786,6 +793,41 @@ template <> void Structure :: Convert<Image> (
     db.reader->IncPtr(size);
 }
 
+//--------------------------------------------------------------------------------
+template <> void Structure::Convert<CustomData>(
+    CustomData& dest,
+    const FileDatabase& db
+    ) const
+{
+    ReadFieldArray<ErrorPolicy_Warn>(dest.typemap, "typemap", db);
+    ReadField<ErrorPolicy_Warn>(dest.totlayer, "totlayer", db);
+    ReadField<ErrorPolicy_Warn>(dest.maxlayer, "maxlayer", db);
+    ReadField<ErrorPolicy_Warn>(dest.totsize, "totsize", db);
+    ReadFieldPtrVector<ErrorPolicy_Warn>(dest.layers, "*layers", db);
+
+    db.reader->IncPtr(size);
+}
+
+//--------------------------------------------------------------------------------
+template <> void Structure::Convert<CustomDataLayer>(
+    CustomDataLayer& dest,
+    const FileDatabase& db
+    ) const
+{
+    ReadField<ErrorPolicy_Fail>(dest.type, "type", db);
+    ReadField<ErrorPolicy_Fail>(dest.offset, "offset", db);
+    ReadField<ErrorPolicy_Fail>(dest.flag, "flag", db);
+    ReadField<ErrorPolicy_Fail>(dest.active, "active", db);
+    ReadField<ErrorPolicy_Fail>(dest.active_rnd, "active_rnd", db);
+    ReadField<ErrorPolicy_Fail>(dest.active_clone, "active_clone", db);
+    ReadField<ErrorPolicy_Fail>(dest.active_mask, "active_mask", db);
+    ReadField<ErrorPolicy_Fail>(dest.uid, "uid", db);
+    ReadFieldArray<ErrorPolicy_Warn>(dest.name, "name", db);
+    ReadCustomDataPtr<ErrorPolicy_Fail>(dest.data, dest.type, "*data", db);
+
+    db.reader->IncPtr(size);
+}
+
 //--------------------------------------------------------------------------------
 void DNA::RegisterConverters() {
 
@@ -822,6 +864,8 @@ void DNA::RegisterConverters() {
     converters["Camera"] = DNA::FactoryPair( &Structure::Allocate<Camera>, &Structure::Convert<Camera> );
     converters["MirrorModifierData"] = DNA::FactoryPair( &Structure::Allocate<MirrorModifierData>, &Structure::Convert<MirrorModifierData> );
     converters["Image"] = DNA::FactoryPair( &Structure::Allocate<Image>, &Structure::Convert<Image> );
+    converters["CustomData"] = DNA::FactoryPair(&Structure::Allocate<CustomData>, &Structure::Convert<CustomData>);
+    converters["CustomDataLayer"] = DNA::FactoryPair(&Structure::Allocate<CustomDataLayer>, &Structure::Convert<CustomDataLayer>);
 }
 
 #endif // ASSIMP_BUILD_NO_BLEND_IMPORTER

+ 81 - 2
Engine/lib/assimp/code/BlenderScene.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -156,10 +157,16 @@ struct World : ElemBase {
 // -------------------------------------------------------------------------------
 struct MVert : ElemBase {
     float co[3] FAIL;
-    float no[3] FAIL;
+    float no[3] FAIL;       // readed as short and divided through / 32767.f
     char flag;
     int mat_nr WARN;
     int bweight;
+
+    MVert() : ElemBase()
+        , flag(0)
+        , mat_nr(0)
+        , bweight(0)
+    {}
 };
 
 // -------------------------------------------------------------------------------
@@ -368,6 +375,72 @@ struct Material : ElemBase {
     std::shared_ptr<MTex> mtex[18];
 };
 
+/*
+CustomDataLayer 104
+
+    int type 0 4
+    int offset 4 4
+    int flag 8 4
+    int active 12 4
+    int active_rnd 16 4
+    int active_clone 20 4
+    int active_mask 24 4
+    int uid 28 4
+    char name 32 64
+    void *data 96 8
+*/
+struct CustomDataLayer : ElemBase {
+    int type;
+    int offset;
+    int flag;
+    int active;
+    int active_rnd;
+    int active_clone;
+    int active_mask;
+    int uid;
+    char name[64];
+    std::shared_ptr<ElemBase> data;     // must be converted to real type according type member
+
+    CustomDataLayer()
+        : ElemBase()
+        , type(0)
+        , offset(0)
+        , flag(0)
+        , active(0)
+        , active_rnd(0)
+        , active_clone(0)
+        , active_mask(0)
+        , uid(0)
+        , data(nullptr)
+    {
+        memset(name, 0, sizeof name);
+    }
+};
+
+/*
+CustomData 208
+
+    CustomDataLayer *layers 0 8
+    int typemap 8 168
+    int pad_i1 176 4
+    int totlayer 180 4
+    int maxlayer 184 4
+    int totsize 188 4
+    BLI_mempool *pool 192 8
+    CustomDataExternal *external 200 8
+*/
+struct CustomData : ElemBase {
+    vector<std::shared_ptr<struct CustomDataLayer> > layers;
+    int typemap[42];    // CD_NUMTYPES
+    int totlayer;
+    int maxlayer;
+    int totsize;
+    /*
+    std::shared_ptr<BLI_mempool> pool;
+    std::shared_ptr<CustomDataExternal> external;
+    */
+};
+
 // -------------------------------------------------------------------------------
 struct Mesh : ElemBase {
     ID id FAIL;
@@ -397,6 +470,12 @@ struct Mesh : ElemBase {
     vector<MCol> mcol;
 
     vector< std::shared_ptr<Material> > mat FAIL;
+
+    struct CustomData vdata;
+    struct CustomData edata;
+    struct CustomData fdata;
+    struct CustomData pdata;
+    struct CustomData ldata;
 };
 
 // -------------------------------------------------------------------------------

+ 11 - 0
Engine/lib/assimp/code/BlenderSceneGen.h

@@ -248,6 +248,17 @@ template <> void Structure :: Convert<Image> (
     ) const
 ;
 
+template <> void Structure::Convert<CustomData>(
+    CustomData& dest,
+    const FileDatabase& db
+    ) const
+    ;
+
+template <> void Structure::Convert<CustomDataLayer>(
+    CustomDataLayer& dest,
+    const FileDatabase& db
+    ) const
+    ;
 
     }
 }

+ 2 - 1
Engine/lib/assimp/code/BlenderTessellator.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 

+ 4 - 3
Engine/lib/assimp/code/BlenderTessellator.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -46,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INCLUDED_AI_BLEND_TESSELLATOR_H
 
 // Use these to toggle between GLU Tessellate or poly2tri
-// Note (acg) keep GLU Tesselate disabled by default - if it is turned on,
+// Note (acg) keep GLU Tessellate disabled by default - if it is turned on,
 // assimp needs to be linked against GLU, which is currently not yet
 // made configurable in CMake and potentially not wanted by most users
 // as it requires a Gl environment.
@@ -58,7 +59,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #   define ASSIMP_BLEND_WITH_POLY_2_TRI 1
 #endif
 
-#include "LogAux.h"
+#include <assimp/LogAux.h>
 
 #if ASSIMP_BLEND_WITH_GLU_TESSELLATE
 

+ 1 - 1
Engine/lib/assimp/code/C4DImporter.cpp

@@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "C4DImporter.h"
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 #include <memory>
 #include <assimp/IOSystem.hpp>
 #include <assimp/scene.h>

+ 2 - 2
Engine/lib/assimp/code/C4DImporter.h

@@ -44,8 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_CINEMA_4D_LOADER_H
 #define INCLUDED_AI_CINEMA_4D_LOADER_H
 
-#include "BaseImporter.h"
-#include "LogAux.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/LogAux.h>
 
 #include <map>
 struct aiNode;

+ 2 - 1
Engine/lib/assimp/code/CInterfaceIOWrapper.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.

+ 2 - 1
Engine/lib/assimp/code/CInterfaceIOWrapper.h

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.

+ 126 - 71
Engine/lib/assimp/code/CMakeLists.txt

@@ -1,7 +1,8 @@
 # Open Asset Import Library (assimp)
 # ----------------------------------------------------------------------
 #
-# Copyright (c) 2006-2017, assimp team
+# Copyright (c) 2006-2019, assimp team
+
 
 # All rights reserved.
 #
@@ -46,6 +47,11 @@
 cmake_minimum_required( VERSION 2.6 )
 SET( HEADER_PATH ../include/assimp )
 
+if(NOT ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
+    message(WARNING "Requesting Android JNI I/O-System in non-Android toolchain. Resetting ASSIMP_ANDROID_JNIIOSYSTEM to OFF.")
+    set(ASSIMP_ANDROID_JNIIOSYSTEM OFF)
+endif(NOT ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
+
 SET( COMPILER_HEADERS
   ${HEADER_PATH}/Compiler/pushpack1.h
   ${HEADER_PATH}/Compiler/poppack1.h
@@ -71,6 +77,7 @@ SET( PUBLIC_HEADERS
   ${HEADER_PATH}/matrix4x4.h
   ${HEADER_PATH}/matrix4x4.inl
   ${HEADER_PATH}/mesh.h
+  ${HEADER_PATH}/pbrmaterial.h
   ${HEADER_PATH}/postprocess.h
   ${HEADER_PATH}/quaternion.h
   ${HEADER_PATH}/quaternion.inl
@@ -98,6 +105,40 @@ SET( PUBLIC_HEADERS
   ${HEADER_PATH}/DefaultIOStream.h
   ${HEADER_PATH}/DefaultIOSystem.h
   ${HEADER_PATH}/SceneCombiner.h
+  ${HEADER_PATH}/fast_atof.h
+  ${HEADER_PATH}/qnan.h
+  ${HEADER_PATH}/BaseImporter.h
+  ${HEADER_PATH}/Hash.h
+  ${HEADER_PATH}/MemoryIOWrapper.h
+  ${HEADER_PATH}/ParsingUtils.h
+  ${HEADER_PATH}/StreamReader.h
+  ${HEADER_PATH}/StreamWriter.h
+  ${HEADER_PATH}/StringComparison.h
+  ${HEADER_PATH}/StringUtils.h
+  ${HEADER_PATH}/SGSpatialSort.h
+  ${HEADER_PATH}/GenericProperty.h
+  ${HEADER_PATH}/SpatialSort.h
+  ${HEADER_PATH}/SkeletonMeshBuilder.h
+  ${HEADER_PATH}/SmoothingGroups.h
+  ${HEADER_PATH}/SmoothingGroups.inl
+  ${HEADER_PATH}/StandardShapes.h
+  ${HEADER_PATH}/RemoveComments.h
+  ${HEADER_PATH}/Subdivision.h
+  ${HEADER_PATH}/Vertex.h
+  ${HEADER_PATH}/LineSplitter.h
+  ${HEADER_PATH}/TinyFormatter.h
+  ${HEADER_PATH}/Profiler.h
+  ${HEADER_PATH}/LogAux.h
+  ${HEADER_PATH}/Bitmap.h
+  ${HEADER_PATH}/XMLTools.h
+  ${HEADER_PATH}/IOStreamBuffer.h
+  ${HEADER_PATH}/CreateAnimMesh.h
+  ${HEADER_PATH}/irrXMLWrapper.h
+  ${HEADER_PATH}/BlobIOSystem.h
+  ${HEADER_PATH}/MathFunctions.h
+  ${HEADER_PATH}/Macros.h
+  ${HEADER_PATH}/Exceptional.h
+  ${HEADER_PATH}/ByteSwapper.h
 )
 
 SET( Core_SRCS
@@ -117,72 +158,52 @@ SET( Logging_SRCS
 SOURCE_GROUP(Logging FILES ${Logging_SRCS})
 
 SET( Common_SRCS
-  fast_atof.h
-  qnan.h
   BaseImporter.cpp
-  BaseImporter.h
   BaseProcess.cpp
   BaseProcess.h
   Importer.h
   ScenePrivate.h
   PostStepRegistry.cpp
   ImporterRegistry.cpp
-  ByteSwapper.h
   DefaultProgressHandler.h
   DefaultIOStream.cpp
   DefaultIOSystem.cpp
   CInterfaceIOWrapper.cpp
   CInterfaceIOWrapper.h
-  Hash.h
   Importer.cpp
   IFF.h
-  MemoryIOWrapper.h
-  ParsingUtils.h
-  StreamReader.h
-  StreamWriter.h
-  StringComparison.h
-  StringUtils.h
   SGSpatialSort.cpp
-  SGSpatialSort.h
   VertexTriangleAdjacency.cpp
   VertexTriangleAdjacency.h
-  GenericProperty.h
   SpatialSort.cpp
-  SpatialSort.h
   SceneCombiner.cpp
   ScenePreprocessor.cpp
   ScenePreprocessor.h
   SkeletonMeshBuilder.cpp
-  SkeletonMeshBuilder.h
   SplitByBoneCountProcess.cpp
   SplitByBoneCountProcess.h
-  ScaleProcess.cpp
-  ScaleProcess.h
-  SmoothingGroups.h
   StandardShapes.cpp
-  StandardShapes.h
   TargetAnimation.cpp
   TargetAnimation.h
   RemoveComments.cpp
-  RemoveComments.h
   Subdivision.cpp
-  Subdivision.h
   scene.cpp
-  Vertex.h
-  LineSplitter.h
-  TinyFormatter.h
-  Profiler.h
-  LogAux.h
   Bitmap.cpp
-  Bitmap.h
-  XMLTools.h
   Version.cpp
-  IOStreamBuffer.h
-  CreateAnimMesh.h
   CreateAnimMesh.cpp
+  simd.h
+  simd.cpp
 )
 SOURCE_GROUP(Common FILES ${Common_SRCS})
 
+SET( STEPParser_SRCS
+  Importer/STEPParser/STEPFileReader.h
+  Importer/STEPParser/STEPFileReader.cpp
+  Importer/STEPParser/STEPFileEncoding.cpp
+  Importer/STEPParser/STEPFileEncoding.h
+)
+SOURCE_GROUP(STEPParser FILES ${STEPParser_SRCS})
+
 IF ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER )
   SET( C4D_SRCS
     C4DImporter.cpp
@@ -200,8 +221,15 @@ OPTION(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT "default value of all ASSIMP_BUILD_
 # macro to add the CMake Option ADD_ASSIMP_IMPORTER_<name> which enables compile of loader
 # this way selective loaders can be compiled (reduces filesize + compile time)
 MACRO(ADD_ASSIMP_IMPORTER name)
-  OPTION(ASSIMP_BUILD_${name}_IMPORTER "build the ${name} importer" ${ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT})
-  IF(ASSIMP_BUILD_${name}_IMPORTER)
+  IF (ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT)
+    set(ASSIMP_IMPORTER_ENABLED TRUE)
+    IF (DEFINED ASSIMP_BUILD_${name}_IMPORTER AND NOT ASSIMP_BUILD_${name}_IMPORTER)
+      set(ASSIMP_IMPORTER_ENABLED FALSE)
+    ENDIF ()
+  ELSE ()
+    set(ASSIMP_IMPORTER_ENABLED ${ASSIMP_BUILD_${name}_IMPORTER})
+  ENDIF ()
+  IF (ASSIMP_IMPORTER_ENABLED)
     LIST(APPEND ASSIMP_LOADER_SRCS ${ARGN})
     SET(ASSIMP_IMPORTERS_ENABLED "${ASSIMP_IMPORTERS_ENABLED} ${name}")
     SET(${name}_SRCS ${ARGN})
@@ -454,33 +482,31 @@ ADD_ASSIMP_IMPORTER( BLEND
   BlenderBMesh.cpp
   BlenderTessellator.h
   BlenderTessellator.cpp
+  BlenderCustomData.h
+  BlenderCustomData.cpp
 )
 
 ADD_ASSIMP_IMPORTER( IFC
-  IFCLoader.cpp
-  IFCLoader.h
-  IFCReaderGen1.cpp
-  IFCReaderGen2.cpp
-  IFCReaderGen.h
-  IFCUtil.h
-  IFCUtil.cpp
-  IFCGeometry.cpp
-  IFCMaterial.cpp
-  IFCProfile.cpp
-  IFCCurve.cpp
-  IFCBoolean.cpp
-  IFCOpenings.cpp
-  STEPFile.h
-  STEPFileReader.h
-  STEPFileReader.cpp
-  STEPFileEncoding.cpp
-  STEPFileEncoding.h
+  Importer/IFC/IFCLoader.cpp
+  Importer/IFC/IFCLoader.h
+  Importer/IFC/IFCReaderGen1_2x3.cpp
+  Importer/IFC/IFCReaderGen2_2x3.cpp
+  Importer/IFC/IFCReaderGen_2x3.h
+  Importer/IFC/IFCUtil.h
+  Importer/IFC/IFCUtil.cpp
+  Importer/IFC/IFCGeometry.cpp
+  Importer/IFC/IFCMaterial.cpp
+  Importer/IFC/IFCProfile.cpp
+  Importer/IFC/IFCCurve.cpp
+  Importer/IFC/IFCBoolean.cpp
+  Importer/IFC/IFCOpenings.cpp
 )
+
 if (ASSIMP_BUILD_IFC_IMPORTER)
   if (MSVC)
-    set_source_files_properties(IFCReaderGen1.cpp IFCReaderGen2.cpp PROPERTIES COMPILE_FLAGS "/bigobj")
+    set_source_files_properties(Importer/IFC/IFCReaderGen1_2x3.cpp Importer/IFC/IFCReaderGen2_2x3.cpp PROPERTIES COMPILE_FLAGS "/bigobj")
   elseif(CMAKE_COMPILER_IS_MINGW)
-    set_source_files_properties(IFCReaderGen1.cpp IFCReaderGen2.cpp PROPERTIES COMPILE_FLAGS "-O2 -Wa,-mbig-obj")
+    set_source_files_properties(Importer/IFC/IFCReaderGen1_2x3.cpp Importer/IFC/IFCReaderGen2_2x3.cpp PROPERTIES COMPILE_FLAGS "-O2 -Wa,-mbig-obj")
   endif()
 endif (ASSIMP_BUILD_IFC_IMPORTER)
 
@@ -489,7 +515,6 @@ ADD_ASSIMP_IMPORTER( XGL
   XGLLoader.h
 )
 
-
 ADD_ASSIMP_IMPORTER( FBX
   FBXImporter.cpp
   FBXCompileConfig.h
@@ -516,6 +541,13 @@ ADD_ASSIMP_IMPORTER( FBX
   FBXDeformer.cpp
   FBXBinaryTokenizer.cpp
   FBXDocumentUtil.cpp
+  FBXExporter.h
+  FBXExporter.cpp
+  FBXExportNode.h
+  FBXExportNode.cpp
+  FBXExportProperty.h
+  FBXExportProperty.cpp
+  FBXCommon.h
 )
 
 SET( PostProcessing_SRCS
@@ -525,6 +557,8 @@ SET( PostProcessing_SRCS
   ComputeUVMappingProcess.h
   ConvertToLHProcess.cpp
   ConvertToLHProcess.h
+  EmbedTexturesProcess.cpp
+  EmbedTexturesProcess.h
   FindDegenerates.cpp
   FindDegenerates.h
   FindInstancesProcess.cpp
@@ -533,6 +567,8 @@ SET( PostProcessing_SRCS
   FindInvalidDataProcess.h
   FixNormalsStep.cpp
   FixNormalsStep.h
+  DropFaceNormalsProcess.cpp
+  DropFaceNormalsProcess.h
   GenFaceNormalsProcess.cpp
   GenFaceNormalsProcess.h
   GenVertexNormalsProcess.cpp
@@ -570,10 +606,12 @@ SET( PostProcessing_SRCS
   PolyTools.h
   MakeVerboseFormat.cpp
   MakeVerboseFormat.h
+  ScaleProcess.cpp
+  ScaleProcess.h
 )
 SOURCE_GROUP( PostProcessing FILES ${PostProcessing_SRCS})
 
-SET( IrrXML_SRCS irrXMLWrapper.h )
+SET( IrrXML_SRCS ${HEADER_PATH}/irrXMLWrapper.h )
 SOURCE_GROUP( IrrXML FILES ${IrrXML_SRCS})
 
 ADD_ASSIMP_IMPORTER( Q3D
@@ -633,7 +671,7 @@ ADD_ASSIMP_IMPORTER( X
   XFileExporter.cpp
 )
 
-ADD_ASSIMP_IMPORTER(X3D
+ADD_ASSIMP_IMPORTER( X3D
   X3DExporter.cpp
   X3DExporter.hpp
   X3DImporter.cpp
@@ -694,16 +732,22 @@ ADD_ASSIMP_IMPORTER( MMD
   MMDVmdParser.h
 )
 
-SET( Step_SRCS
-  StepExporter.h
-  StepExporter.cpp
+ADD_ASSIMP_IMPORTER( STEP
+    STEPFile.h
+    Importer/StepFile/StepFileImporter.h
+    Importer/StepFile/StepFileImporter.cpp
+    Importer/StepFile/StepFileGen1.cpp
+    Importer/StepFile/StepFileGen2.cpp
+    Importer/StepFile/StepFileGen3.cpp
+    Importer/StepFile/StepReaderGen.h
+    StepExporter.h
+    StepExporter.cpp
 )
-SOURCE_GROUP( Step FILES ${Step_SRCS})
 
 SET( Exporter_SRCS
   Exporter.cpp
   AssimpCExport.cpp
-  BlobIOSystem.h
+  ${HEADER_PATH}/BlobIOSystem.h
 )
 SOURCE_GROUP( Exporter FILES ${Exporter_SRCS})
 
@@ -850,7 +894,8 @@ SET( assimp_src
   ${Exporter_SRCS}
   ${PostProcessing_SRCS}
   ${MaterialSystem_SRCS}
-  ${Step_SRCS}
+  ${STEPParser_SRCS}
+#  ${Step_SRCS} check if we need a different approach
 
   # Model Support
   ${ASSIMP_LOADER_SRCS}
@@ -882,14 +927,21 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
 ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
 
 ADD_LIBRARY( assimp ${assimp_src} )
+ADD_LIBRARY(assimp::assimp ALIAS assimp)
+
+TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC
+  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
+  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/../include>
+  $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
+)
 
 TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} ${IRRXML_LIBRARY} )
 
-if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
+if(ASSIMP_ANDROID_JNIIOSYSTEM)
   set(ASSIMP_ANDROID_JNIIOSYSTEM_PATH port/AndroidJNI)
   add_subdirectory(../${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/ ../${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/)
   target_link_libraries(assimp android_jniiosystem)
-endif(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
+endif(ASSIMP_ANDROID_JNIIOSYSTEM)
 
 IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
   TARGET_LINK_LIBRARIES(assimp optimized ${C4D_RELEASE_LIBRARIES})
@@ -919,6 +971,9 @@ if( MSVC )
   set(LIBRARY_SUFFIX "${ASSIMP_LIBRARY_SUFFIX}-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library")
 endif()
 
+if (${CMAKE_SYSTEM_NAME} MATCHES "WindowsStore")
+    set(WindowsStore TRUE)
+endif()
 SET_TARGET_PROPERTIES( assimp PROPERTIES
   VERSION ${ASSIMP_VERSION}
   SOVERSION ${ASSIMP_SOVERSION} # use full version
@@ -940,13 +995,13 @@ if (APPLE)
 
     # PUBLIC_HEADER option does not support directory structure creation
     # add ./Compiler/*.h to assimp.framework via copy command
-    ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD 
-      COMMAND "${CMAKE_COMMAND}" -E copy_directory 
+    ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD
+      COMMAND "${CMAKE_COMMAND}" -E copy_directory
          "../${HEADER_PATH}/Compiler"
          assimp.framework/Headers/Compiler
       COMMENT "Copying public ./Compiler/ header files to framework bundle's Headers/Compiler/")
-  endif(BUILD_FRAMEWORK)
-endif(APPLE)
+  ENDIF(BUILD_FRAMEWORK)
+ENDIF(APPLE)
 
 # Build against external unzip, or add ../contrib/unzip so
 # assimp can #include "unzip.h"
@@ -975,7 +1030,7 @@ if (ASSIMP_ANDROID_JNIIOSYSTEM)
   INSTALL(FILES ${HEADER_PATH}/${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/AndroidJNIIOSystem.h
     DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}
     COMPONENT assimp-dev)
-endif(ASSIMP_ANDROID_JNIIOSYSTEM)
+ENDIF(ASSIMP_ANDROID_JNIIOSYSTEM)
 
 if(MSVC AND ASSIMP_INSTALL_PDB)
   IF(CMAKE_GENERATOR MATCHES "^Visual Studio")
@@ -997,7 +1052,7 @@ if(MSVC AND ASSIMP_INSTALL_PDB)
       CONFIGURATIONS RelWithDebInfo
     )
   ENDIF()
-endif ()
+ENDIF ()
 
 if (ASSIMP_COVERALLS)
     include(Coveralls)
@@ -1009,4 +1064,4 @@ if (ASSIMP_COVERALLS)
         "${COVERAGE_SRCS}" # The source files.
         ON                 # If we should upload.
         "${PROJECT_SOURCE_DIR}/cmake-modules/") # (Optional) Alternate project cmake module path.
-endif()
+ENDIF()

+ 36 - 88
Engine/lib/assimp/code/COBLoader.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -46,13 +47,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_COB_IMPORTER
 #include "COBLoader.h"
 #include "COBScene.h"
-
-#include "StreamReader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-#include "LineSplitter.h"
-#include "TinyFormatter.h"
+#include "ConvertToLHProcess.h"
+#include <assimp/StreamReader.h>
+#include <assimp/ParsingUtils.h>
+#include <assimp/fast_atof.h>
+#include <assimp/LineSplitter.h>
+#include <assimp/TinyFormatter.h>
 #include <memory>
 #include <assimp/IOSystem.hpp>
 #include <assimp/DefaultLogger.hpp>
@@ -104,7 +104,7 @@ COBImporter::~COBImporter()
 bool COBImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
 {
     const std::string& extension = GetExtension(pFile);
-    if (extension == "cob" || extension == "scn") {
+    if (extension == "cob" || extension == "scn" || extension == "COB" || extension == "SCN") {
         return true;
     }
 
@@ -137,9 +137,7 @@ void COBImporter::SetupProperties(const Importer* /*pImp*/)
 
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure.
-void COBImporter::InternReadFile( const std::string& pFile,
-    aiScene* pScene, IOSystem* pIOHandler)
-{
+void COBImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
     COB::Scene scene;
     std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) );
 
@@ -150,7 +148,7 @@ void COBImporter::InternReadFile( const std::string& pFile,
         ThrowException("Could not found magic id: `Caligari`");
     }
 
-    DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
+    ASSIMP_LOG_INFO_F("File format tag: ",std::string(head+9,6));
     if (head[16]!='L') {
         ThrowException("File is big-endian, which is not supported");
     }
@@ -224,6 +222,9 @@ void COBImporter::InternReadFile( const std::string& pFile,
     }
 
     pScene->mRootNode = BuildNodes(*root.get(),scene,pScene);
+	//flip normals after import
+    FlipWindingOrderProcess flip;
+    flip.Execute( pScene );
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -300,7 +301,7 @@ aiNode* COBImporter::BuildNodes(const Node& root,const Scene& scin,aiScene* fill
                     }
                     std::unique_ptr<const Material> defmat;
                     if(!min) {
-                        DefaultLogger::get()->debug(format()<<"Could not resolve material index "
+                        ASSIMP_LOG_DEBUG(format()<<"Could not resolve material index "
                             <<reflist.first<<" - creating default material for this slot");
 
                         defmat.reset(min=new Material());
@@ -472,7 +473,7 @@ void COBImporter::UnsupportedChunk_Ascii(LineSplitter& splitter, const ChunkInfo
 
     // we can recover if the chunk size was specified.
     if(nfo.size != static_cast<unsigned int>(-1)) {
-        DefaultLogger::get()->error(error);
+        ASSIMP_LOG_ERROR(error);
 
         // (HACK) - our current position in the stream is the beginning of the
         // head line of the next chunk. That's fine, but the caller is going
@@ -484,46 +485,6 @@ void COBImporter::UnsupportedChunk_Ascii(LineSplitter& splitter, const ChunkInfo
     else ThrowException(error);
 }
 
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogWarn_Ascii(const LineSplitter& splitter, const format& message)    {
-    LogWarn_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogError_Ascii(const LineSplitter& splitter, const format& message)   {
-    LogError_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogInfo_Ascii(const LineSplitter& splitter, const format& message)    {
-    LogInfo_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogDebug_Ascii(const LineSplitter& splitter, const format& message)   {
-    LogDebug_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogWarn_Ascii(const Formatter::format& message)   {
-    DefaultLogger::get()->warn(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogError_Ascii(const Formatter::format& message)  {
-    DefaultLogger::get()->error(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogInfo_Ascii(const Formatter::format& message)   {
-    DefaultLogger::get()->info(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogDebug_Ascii(const Formatter::format& message)  {
-    DefaultLogger::get()->debug(std::string("COB: ")+=message);
-}
-
 // ------------------------------------------------------------------------------------------------
 void COBImporter::ReadBasicNodeInfo_Ascii(Node& msh, LineSplitter& splitter, const ChunkInfo& /*nfo*/)
 {
@@ -573,8 +534,7 @@ void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const Chunk
 
     ++splitter;
     if (!splitter.match_start("mat# ")) {
-        LogWarn_Ascii(splitter,format()<<
-            "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
+        ASSIMP_LOG_WARN_F( "Expected `mat#` line in `Mat1` chunk ", nfo.id );
         return;
     }
 
@@ -586,8 +546,7 @@ void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const Chunk
     ++splitter;
 
     if (!splitter.match_start("shader: ")) {
-        LogWarn_Ascii(splitter,format()<<
-            "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
+        ASSIMP_LOG_WARN_F( "Expected `mat#` line in `Mat1` chunk ", nfo.id);
         return;
     }
     std::string shader = std::string(splitter[1]);
@@ -600,14 +559,12 @@ void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const Chunk
         mat.shader = Material::PHONG;
     }
     else if (shader != "flat") {
-        LogWarn_Ascii(splitter,format()<<
-            "Unknown value for `shader` in `Mat1` chunk "<<nfo.id);
+        ASSIMP_LOG_WARN_F( "Unknown value for `shader` in `Mat1` chunk ", nfo.id );
     }
 
     ++splitter;
     if (!splitter.match_start("rgb ")) {
-        LogWarn_Ascii(splitter,format()<<
-            "Expected `rgb` line in `Mat1` chunk "<<nfo.id);
+        ASSIMP_LOG_WARN_F( "Expected `rgb` line in `Mat1` chunk ", nfo.id);
     }
 
     const char* rgb = splitter[1];
@@ -615,8 +572,7 @@ void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const Chunk
 
     ++splitter;
     if (!splitter.match_start("alpha ")) {
-        LogWarn_Ascii(splitter,format()<<
-            "Expected `alpha` line in `Mat1` chunk "<<nfo.id);
+        ASSIMP_LOG_WARN_F( "Expected `alpha` line in `Mat1` chunk ", nfo.id);
     }
 
     const char* tokens[10];
@@ -637,8 +593,7 @@ void COBImporter::ReadUnit_Ascii(Scene& out, LineSplitter& splitter, const Chunk
     }
     ++splitter;
     if (!splitter.match_start("Units ")) {
-        LogWarn_Ascii(splitter,format()<<
-            "Expected `Units` line in `Unit` chunk "<<nfo.id);
+        ASSIMP_LOG_WARN_F( "Expected `Units` line in `Unit` chunk ", nfo.id);
         return;
     }
 
@@ -649,13 +604,12 @@ void COBImporter::ReadUnit_Ascii(Scene& out, LineSplitter& splitter, const Chunk
             const unsigned int t=strtoul10(splitter[1]);
 
             nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
-                LogWarn_Ascii(splitter,format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
+                ASSIMP_LOG_WARN_F(t, " is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id)
                 ,1.f):units[t];
             return;
         }
     }
-    LogWarn_Ascii(splitter,format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
-        <<nfo.parent_id<<" which does not exist");
+    ASSIMP_LOG_WARN_F( "`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -689,15 +643,13 @@ void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const Chunk
         msh.ltype = Light::SPOT;
     }
     else {
-        LogWarn_Ascii(splitter,format()<<
-            "Unknown kind of light source in `Lght` chunk "<<nfo.id<<" : "<<*splitter);
+        ASSIMP_LOG_WARN_F( "Unknown kind of light source in `Lght` chunk ", nfo.id, " : ", *splitter );
         msh.ltype = Light::SPOT;
     }
 
     ++splitter;
     if (!splitter.match_start("color ")) {
-        LogWarn_Ascii(splitter,format()<<
-            "Expected `color` line in `Lght` chunk "<<nfo.id);
+        ASSIMP_LOG_WARN_F( "Expected `color` line in `Lght` chunk ", nfo.id );
     }
 
     const char* rgb = splitter[1];
@@ -705,16 +657,14 @@ void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const Chunk
 
     SkipSpaces(&rgb);
     if (strncmp(rgb,"cone angle",10)) {
-        LogWarn_Ascii(splitter,format()<<
-            "Expected `cone angle` entity in `color` line in `Lght` chunk "<<nfo.id);
+        ASSIMP_LOG_WARN_F( "Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id );
     }
     SkipSpaces(rgb+10,&rgb);
     msh.angle = fast_atof(&rgb);
 
     SkipSpaces(&rgb);
     if (strncmp(rgb,"inner angle",11)) {
-        LogWarn_Ascii(splitter,format()<<
-            "Expected `inner angle` entity in `color` line in `Lght` chunk "<<nfo.id);
+        ASSIMP_LOG_WARN_F( "Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
     }
     SkipSpaces(rgb+11,&rgb);
     msh.inner_angle = fast_atof(&rgb);
@@ -825,7 +775,7 @@ void COBImporter::ReadPolH_Ascii(Scene& out, LineSplitter& splitter, const Chunk
 
             for(unsigned int cur = 0; cur < cnt && ++splitter ;++cur) {
                 if (splitter.match_start("Hole")) {
-                    LogWarn_Ascii(splitter,"Skipping unsupported `Hole` line");
+                    ASSIMP_LOG_WARN( "Skipping unsupported `Hole` line" );
                     continue;
                 }
 
@@ -885,7 +835,7 @@ void COBImporter::ReadBitM_Ascii(Scene& /*out*/, LineSplitter& splitter, const C
 
     const unsigned int head = strtoul10((++splitter)[1]);
     if (head != sizeof(Bitmap::BitmapHeader)) {
-        LogWarn_Ascii(splitter,"Unexpected ThumbNailHdrSize, skipping this chunk");
+        ASSIMP_LOG_WARN("Unexpected ThumbNailHdrSize, skipping this chunk");
         return;
     }
 
@@ -932,7 +882,7 @@ void COBImporter::UnsupportedChunk_Binary( StreamReaderLE& reader, const ChunkIn
 
     // we can recover if the chunk size was specified.
     if(nfo.size != static_cast<unsigned int>(-1)) {
-        DefaultLogger::get()->error(error);
+        ASSIMP_LOG_ERROR(error);
         reader.IncPtr(nfo.size);
     }
     else ThrowException(error);
@@ -1139,7 +1089,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const
             mat.type = Material::METAL;
             break;
         default:
-            LogError_Ascii(format("Unrecognized shader type in `Mat1` chunk with id ")<<nfo.id);
+            ASSIMP_LOG_ERROR_F( "Unrecognized shader type in `Mat1` chunk with id ", nfo.id );
             mat.type = Material::FLAT;
     }
 
@@ -1154,7 +1104,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const
             mat.autofacet = Material::SMOOTH;
             break;
         default:
-            LogError_Ascii(format("Unrecognized faceting mode in `Mat1` chunk with id ")<<nfo.id);
+            ASSIMP_LOG_ERROR_F( "Unrecognized faceting mode in `Mat1` chunk with id ", nfo.id );
             mat.autofacet = Material::FACETED;
     }
     mat.autofacet_angle = static_cast<float>(reader.GetI1());
@@ -1286,15 +1236,13 @@ void COBImporter::ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const
         if (nd->id == nfo.parent_id) {
             const unsigned int t=reader.GetI2();
             nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
-                LogWarn_Ascii(format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
+                ASSIMP_LOG_WARN_F(t," is not a valid value for `Units` attribute in `Unit chunk` ", nfo.id)
                 ,1.f):units[t];
 
             return;
         }
     }
-    LogWarn_Ascii(format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
-        <<nfo.parent_id<<" which does not exist");
+    ASSIMP_LOG_WARN_F( "`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
 }
 
-
-#endif
+#endif // ASSIMP_BUILD_NO_COB_IMPORTER

+ 5 - 24
Engine/lib/assimp/code/COBLoader.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -45,8 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_COB_LOADER_H
 #define INCLUDED_AI_COB_LOADER_H
 
-#include "BaseImporter.h"
-#include "StreamReader.h"
+#include <assimp/BaseImporter.h>
+#include <assimp/StreamReader.h>
 
 struct aiNode;
 
@@ -76,10 +77,7 @@ class COBImporter : public BaseImporter
 public:
     COBImporter();
     ~COBImporter();
-
-
-public:
-
+    
     // --------------------
     bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
         bool checkSig) const;
@@ -114,15 +112,11 @@ private:
      *  @param stream Stream to read from.  */
     void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
 
-
-private:
-
     // Conversion to Assimp output format
 
     aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
 
 private:
-
     // ASCII file support
 
     void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
@@ -141,19 +135,6 @@ private:
     void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
 
 
-    // ASCII file logging stuff to add proper line numbers to messages
-
-    static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message);
-    static void LogError_Ascii(const LineSplitter& splitter, const Formatter::format& message);
-    static void LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message);
-    static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message);
-
-    static void LogWarn_Ascii  (const Formatter::format& message);
-    static void LogError_Ascii (const Formatter::format& message);
-    static void LogInfo_Ascii  (const Formatter::format& message);
-    static void LogDebug_Ascii (const Formatter::format& message);
-
-
     // Binary file support
 
     void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);

+ 3 - 2
Engine/lib/assimp/code/COBScene.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -49,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <deque>
 #include <map>
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <assimp/material.h>
 
 namespace Assimp {

+ 8 - 7
Engine/lib/assimp/code/CSMLoader.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -49,9 +50,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
 
 #include "CSMLoader.h"
-#include "SkeletonMeshBuilder.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
+#include <assimp/SkeletonMeshBuilder.h>
+#include <assimp/ParsingUtils.h>
+#include <assimp/fast_atof.h>
 #include <assimp/Importer.hpp>
 #include <memory>
 #include <assimp/IOSystem.hpp>
@@ -135,7 +136,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
     TextFileToBuffer(file.get(),mBuffer2);
     const char* buffer = &mBuffer2[0];
 
-    aiAnimation* anim = new aiAnimation();
+    std::unique_ptr<aiAnimation> anim(new aiAnimation());
     int first = 0, last = 0x00ffffff;
 
     // now process the file and look out for '$' sections
@@ -232,7 +233,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
 
                         if (TokenMatchI(buffer, "DROPOUT", 7))  {
                             // seems this is invalid marker data; at least the doc says it's possible
-                            DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)");
+                            ASSIMP_LOG_WARN("CSM: Encountered invalid marker data (DROPOUT)");
                         }
                         else    {
                             aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
@@ -293,8 +294,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
 
     // Store the one and only animation in the scene
     pScene->mAnimations    = new aiAnimation*[pScene->mNumAnimations=1];
-    pScene->mAnimations[0] = anim;
     anim->mName.Set("$CSM_MasterAnim");
+    pScene->mAnimations[0] = anim.release();
 
     // mark the scene as incomplete and run SkeletonMeshBuilder on it
     pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;

+ 3 - 2
Engine/lib/assimp/code/CSMLoader.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -45,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_AI_CSM_LOADER_H
 #define INCLUDED_AI_CSM_LOADER_H
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 
 namespace Assimp    {
 

+ 11 - 10
Engine/lib/assimp/code/CalcTangentsProcess.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -47,8 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // internal headers
 #include "CalcTangentsProcess.h"
 #include "ProcessHelper.h"
-#include "TinyFormatter.h"
-#include "qnan.h"
+#include <assimp/TinyFormatter.h>
+#include <assimp/qnan.h>
 
 using namespace Assimp;
 
@@ -94,7 +95,7 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
 {
     ai_assert( NULL != pScene );
 
-    DefaultLogger::get()->debug("CalcTangentsProcess begin");
+    ASSIMP_LOG_DEBUG("CalcTangentsProcess begin");
 
     bool bHas = false;
     for ( unsigned int a = 0; a < pScene->mNumMeshes; a++ ) {
@@ -102,9 +103,9 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
     }
 
     if ( bHas ) {
-        DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated");
+        ASSIMP_LOG_INFO("CalcTangentsProcess finished. Tangents have been calculated");
     } else {
-        DefaultLogger::get()->debug("CalcTangentsProcess finished");
+        ASSIMP_LOG_DEBUG("CalcTangentsProcess finished");
     }
 }
 
@@ -125,19 +126,19 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
     // are undefined.
     if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
     {
-        DefaultLogger::get()->info("Tangents are undefined for line and point meshes");
+        ASSIMP_LOG_INFO("Tangents are undefined for line and point meshes");
         return false;
     }
 
     // what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement
     if( pMesh->mNormals == NULL)
     {
-        DefaultLogger::get()->error("Failed to compute tangents; need normals");
+        ASSIMP_LOG_ERROR("Failed to compute tangents; need normals");
         return false;
     }
     if( configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV] )
     {
-        DefaultLogger::get()->error((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV));
+        ASSIMP_LOG_ERROR((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV));
         return false;
     }
 
@@ -189,7 +190,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
         float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y;
         float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;
         // when t1, t2, t3 in same position in UV space, just use default UV direction.
-        if ( 0 == sx && 0 ==sy && 0 == tx && 0 == ty ) {
+        if (  sx * ty == sy * tx ) {
             sx = 0.0; sy = 1.0;
             tx = 1.0; ty = 0.0;
         }

+ 2 - 1
Engine/lib/assimp/code/CalcTangentsProcess.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 

+ 36 - 21
Engine/lib/assimp/code/ColladaExporter.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -43,17 +44,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
 
 #include "ColladaExporter.h"
-#include "Bitmap.h"
-#include "fast_atof.h"
+#include <assimp/Bitmap.h>
+#include <assimp/fast_atof.h>
 #include <assimp/SceneCombiner.h>
-#include "StringUtils.h"
-#include "XMLTools.h"
+#include <assimp/StringUtils.h>
+#include <assimp/XMLTools.h>
 #include <assimp/DefaultIOSystem.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/Exporter.hpp>
 #include <assimp/scene.h>
 
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 
 #include <memory>
 #include <ctime>
@@ -1268,7 +1269,8 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
 	
 	mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
 	PushTag();
-	
+
+    std::string node_idstr;
 	for (size_t a = 0; a < anim->mNumChannels; ++a) {
 		const aiNodeAnim * nodeAnim = anim->mChannels[a];
 		
@@ -1276,7 +1278,9 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
 		if ( nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys ||  nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys ) continue;
 		
 		{
-			const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-input");
+            node_idstr.clear();
+            node_idstr += nodeAnim->mNodeName.data;
+            node_idstr += std::string( "_matrix-input" );
 
 			std::vector<ai_real> frames;
 			for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
@@ -1288,12 +1292,14 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
 		}
 		
 		{
-			const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-output");
+            node_idstr.clear();
+
+            node_idstr += nodeAnim->mNodeName.data;
+            node_idstr += std::string("_matrix-output");
 			
 			std::vector<ai_real> keyframes;
 			keyframes.reserve(nodeAnim->mNumPositionKeys * 16);
 			for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
-				
 				aiVector3D Scaling = nodeAnim->mScalingKeys[i].mValue;
 				aiMatrix4x4 ScalingM;  // identity
 				ScalingM[0][0] = Scaling.x; ScalingM[1][1] = Scaling.y; ScalingM[2][2] = Scaling.z;
@@ -1360,7 +1366,6 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
 			PopTag();
 			mOutput << startstr << "</source>" << endstr;
 		}
-		
 	}
 	
 	for (size_t a = 0; a < anim->mNumChannels; ++a) {
@@ -1495,24 +1500,18 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
     // otherwise it is a normal node (NODE)
     const char * node_type;
     bool is_joint, is_skeleton_root = false;
-    if (NULL == findBone(pScene, pNode->mName.C_Str())) {
+    if (nullptr == findBone(pScene, pNode->mName.C_Str())) {
         node_type = "NODE";
         is_joint = false;
     } else {
         node_type = "JOINT";
         is_joint = true;
-        if(!pNode->mParent || NULL == findBone(pScene, pNode->mParent->mName.C_Str()))
+        if (!pNode->mParent || nullptr == findBone(pScene, pNode->mParent->mName.C_Str())) {
             is_skeleton_root = true;
+        }
     }
 
     const std::string node_name_escaped = XMLEscape(pNode->mName.data);
-	/* // customized, Note! the id field is crucial for inter-xml look up, it cannot be replaced with sid ?!
-    mOutput << startstr
-            << "<node ";
-    if(is_skeleton_root)
-        mOutput << "id=\"" << "skeleton_root" << "\" "; // For now, only support one skeleton in a scene.
-    mOutput << (is_joint ? "s" : "") << "id=\"" << node_name_escaped;
-	 */
 	mOutput << startstr << "<node ";
 	if(is_skeleton_root) {
 		mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"" : "") ; // For now, only support one skeleton in a scene.
@@ -1528,7 +1527,23 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
 
     // write transformation - we can directly put the matrix there
     // TODO: (thom) decompose into scale - rot - quad to allow addressing it by animations afterwards
-    const aiMatrix4x4& mat = pNode->mTransformation;
+    aiMatrix4x4 mat = pNode->mTransformation;
+
+    // If this node is a Camera node, the camera coordinate system needs to be multiplied in.
+    // When importing from Collada, the mLookAt is set to 0, 0, -1, and the node transform is unchanged.
+    // When importing from a different format, mLookAt is set to 0, 0, 1. Therefore, the local camera
+    // coordinate system must be changed to matche the Collada specification.
+    for (size_t i = 0; i<mScene->mNumCameras; i++){
+        if (mScene->mCameras[i]->mName == pNode->mName){
+            aiMatrix4x4 sourceView;
+            mScene->mCameras[i]->GetCameraMatrix(sourceView);
+
+            aiMatrix4x4 colladaView;
+            colladaView.a1 = colladaView.c3 = -1; // move into -z space.
+            mat *= (sourceView * colladaView);
+            break;
+        }
+    }
 	
 	// customized, sid should be 'matrix' to match with loader code.
     //mOutput << startstr << "<matrix sid=\"transform\">";

+ 4 - 3
Engine/lib/assimp/code/ColladaExporter.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -54,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <vector>
 #include <map>
 
-#include "StringUtils.h"
+#include <assimp/StringUtils.h>
 
 struct aiScene;
 struct aiNode;
@@ -188,7 +189,7 @@ protected:
      {}
   };
 
-  // summarize a material in an convinient way.
+  // summarize a material in an convenient way.
   struct Material
   {
     std::string name;

+ 6 - 4
Engine/lib/assimp/code/ColladaHelper.h

@@ -4,7 +4,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -271,12 +272,13 @@ struct Node
     /** Node instances at this node */
     std::vector<NodeInstance> mNodeInstances;
 
-    /** Rootnodes: Name of primary camera, if any */
+    /** Root-nodes: Name of primary camera, if any */
     std::string mPrimaryCamera;
 
     //! Constructor. Begin with a zero parent
-    Node() {
-        mParent = NULL;
+    Node()
+    : mParent( nullptr ){
+        // empty
     }
 
     //! Destructor: delete all children subsequently

+ 133 - 103
Engine/lib/assimp/code/ColladaLoader.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -46,23 +47,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
 
 #include "ColladaLoader.h"
+#include "ColladaParser.h"
+
 #include <assimp/anim.h>
 #include <assimp/scene.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/Importer.hpp>
 #include <assimp/importerdesc.h>
+#include <assimp/Defines.h>
 
-#include "ColladaParser.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include "SkeletonMeshBuilder.h"
-#include "CreateAnimMesh.h"
+#include <assimp/fast_atof.h>
+#include <assimp/ParsingUtils.h>
+#include <assimp/SkeletonMeshBuilder.h>
+#include <assimp/CreateAnimMesh.h>
 
 #include "time.h"
 #include "math.h"
 #include <algorithm>
 #include <numeric>
-#include <assimp/Defines.h>
 
 using namespace Assimp;
 using namespace Assimp::Formatter;
@@ -83,34 +85,37 @@ static const aiImporterDesc desc = {
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 ColladaLoader::ColladaLoader()
-    : mFileName()
-	, mMeshIndexByID()
-	, mMaterialIndexByName()
-	, mMeshes()
-	, newMats()
-	, mCameras()
-	, mLights()
-	, mTextures()
-	, mAnims()
-	, noSkeletonMesh( false )
-    , ignoreUpDirection(false)
-    , mNodeNameCounter( 0 )
-{}
+: mFileName()
+, mMeshIndexByID()
+, mMaterialIndexByName()
+, mMeshes()
+, newMats()
+, mCameras()
+, mLights()
+, mTextures()
+, mAnims()
+, noSkeletonMesh( false )
+, ignoreUpDirection(false)
+, useColladaName( false )
+, mNodeNameCounter( 0 ) {
+    // empty
+}
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-ColladaLoader::~ColladaLoader()
-{}
+ColladaLoader::~ColladaLoader() {
+    // empty
+}
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
-bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
+bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
     // check file extension
     std::string extension = GetExtension(pFile);
 
-    if( extension == "dae")
+    if (extension == "dae") {
         return true;
+    }
 
     // XML - too generic, we need to open the file and search for typical keywords
     if( extension == "xml" || !extension.length() || checkSig)  {
@@ -118,10 +123,13 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
          *  support a specific file extension in general pIOHandler
          *  might be NULL and it's our duty to return true here.
          */
-        if (!pIOHandler)return true;
+        if (!pIOHandler) {
+            return true;
+        }
         const char* tokens[] = {"<collada"};
         return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
     }
+
     return false;
 }
 
@@ -130,6 +138,7 @@ void ColladaLoader::SetupProperties(const Importer* pImp)
 {
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,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;
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -141,8 +150,7 @@ const aiImporterDesc* ColladaLoader::GetInfo () const
 
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure.
-void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
+void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
     mFileName = pFile;
 
     // clean all member arrays - just for safety, it should work even if we did not
@@ -178,26 +186,27 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
     // ... then fill the materials with the now adjusted settings
     FillMaterials(parser, pScene);
 
-        // Apply unitsize scale calculation
-        pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0,  0,  0,
-                                                          0,  parser.mUnitSize,  0,  0,
-                                                          0,  0,  parser.mUnitSize,  0,
-                                                          0,  0,  0,  1);
-        if( !ignoreUpDirection ) {
-        // Convert to Y_UP, if different orientation
-        if( parser.mUpDirection == ColladaParser::UP_X)
-            pScene->mRootNode->mTransformation *= aiMatrix4x4(
-                 0, -1,  0,  0,
-                 1,  0,  0,  0,
-                 0,  0,  1,  0,
-                 0,  0,  0,  1);
-        else if( parser.mUpDirection == ColladaParser::UP_Z)
-            pScene->mRootNode->mTransformation *= aiMatrix4x4(
-                 1,  0,  0,  0,
-                 0,  0,  1,  0,
-                 0, -1,  0,  0,
-                 0,  0,  0,  1);
-        }
+    // Apply unit-size scale calculation
+    pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0,  0,  0,
+                                                        0,  parser.mUnitSize,  0,  0,
+                                                        0,  0,  parser.mUnitSize,  0,
+                                                        0,  0,  0,  1);
+    if( !ignoreUpDirection ) {
+    // Convert to Y_UP, if different orientation
+    if( parser.mUpDirection == ColladaParser::UP_X)
+        pScene->mRootNode->mTransformation *= aiMatrix4x4(
+                0, -1,  0,  0,
+                1,  0,  0,  0,
+                0,  0,  1,  0,
+                0,  0,  0,  1);
+    else if( parser.mUpDirection == ColladaParser::UP_Z)
+        pScene->mRootNode->mTransformation *= aiMatrix4x4(
+                1,  0,  0,  0,
+                0,  0,  1,  0,
+                0, -1,  0,  0,
+                0,  0,  0,  1);
+    }
+
     // store all meshes
     StoreSceneMeshes( pScene);
 
@@ -291,7 +300,7 @@ void ColladaLoader::ResolveNodeInstances( const ColladaParser& pParser, const Co
             nd = FindNode(pParser.mRootNode, nodeInst.mNode);
         }
         if (!nd)
-            DefaultLogger::get()->error("Collada: Unable to resolve reference to instanced node " + nodeInst.mNode);
+            ASSIMP_LOG_ERROR_F("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode);
 
         else {
             //  attach this node to the list of children
@@ -308,7 +317,7 @@ void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler
     std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
     if (it != table.mMap.end()) {
         if (it->second.mType != Collada::IT_Texcoord)
-            DefaultLogger::get()->error("Collada: Unexpected effect input mapping");
+            ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping");
 
         sampler.mUVId = it->second.mSet;
     }
@@ -324,7 +333,7 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll
         ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find( lid.mLight);
         if( srcLightIt == pParser.mLightLibrary.end())
         {
-            DefaultLogger::get()->warn("Collada: Unable to find light for ID \"" + lid.mLight + "\". Skipping.");
+            ASSIMP_LOG_WARN_F("Collada: Unable to find light for ID \"" , lid.mLight , "\". Skipping.");
             continue;
         }
         const Collada::Light* srcLight = &srcLightIt->second;
@@ -392,14 +401,14 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
         ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find( cid.mCamera);
         if( srcCameraIt == pParser.mCameraLibrary.end())
         {
-            DefaultLogger::get()->warn("Collada: Unable to find camera for ID \"" + cid.mCamera + "\". Skipping.");
+            ASSIMP_LOG_WARN_F("Collada: Unable to find camera for ID \"" , cid.mCamera , "\". Skipping.");
             continue;
         }
         const Collada::Camera* srcCamera = &srcCameraIt->second;
 
         // orthographic cameras not yet supported in Assimp
         if (srcCamera->mOrtho) {
-            DefaultLogger::get()->warn("Collada: Orthographic cameras are not supported.");
+            ASSIMP_LOG_WARN("Collada: Orthographic cameras are not supported.");
         }
 
         // now fill our ai data structure
@@ -469,7 +478,7 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
 
             if( !srcMesh)
             {
-                DefaultLogger::get()->warn( format() << "Collada: Unable to find geometry for ID \"" << mid.mMeshOrController << "\". Skipping." );
+                ASSIMP_LOG_WARN_F( "Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping." );
                 continue;
             }
         } else
@@ -498,7 +507,8 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
             }
             else
             {
-                DefaultLogger::get()->warn( format() << "Collada: No material specified for subgroup <" << submesh.mMaterial << "> in geometry <" << mid.mMeshOrController << ">." );
+                ASSIMP_LOG_WARN_F( "Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <",
+                    mid.mMeshOrController, ">." );
                 if( !mid.mMaterials.empty() )
                     meshMaterial = mid.mMaterials.begin()->second.mMatName;
             }
@@ -720,8 +730,11 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
         std::vector<aiAnimMesh*> animMeshes;
         for (unsigned int i = 0; i < targetMeshes.size(); i++)
         {
-            aiAnimMesh *animMesh = aiCreateAnimMesh(targetMeshes.at(i));
-            animMesh->mWeight = targetWeights[i];
+            aiMesh* targetMesh = targetMeshes.at(i);
+            aiAnimMesh *animMesh = aiCreateAnimMesh(targetMesh);
+            float weight = targetWeights[i];
+            animMesh->mWeight = weight == 0 ? 1.0f : weight;
+            animMesh->mName = targetMesh->mName;
             animMeshes.push_back(animMesh);
         }
         dstMesh->mMethod = (method == Collada::Relative)
@@ -736,10 +749,6 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
     // create bones if given
     if( pSrcController && pSrcController->mType == Collada::Skin)
     {
-        // refuse if the vertex count does not match
-//      if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
-//          throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
-
         // resolve references - joint names
         const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
         const Collada::Data& jointNames = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointNamesAcc.mSource);
@@ -871,7 +880,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
             if( bnode)
                 bone->mName.Set( FindNameForNode( bnode));
             else
-                DefaultLogger::get()->warn( format() << "ColladaLoader::CreateMesh(): could not find corresponding node for joint \"" << bone->mName.data << "\"." );
+                ASSIMP_LOG_WARN_F( "ColladaLoader::CreateMesh(): could not find corresponding node for joint \"", bone->mName.data, "\"." );
 
             // and insert bone
             dstMesh->mBones[boneCount++] = bone;
@@ -952,7 +961,7 @@ void ColladaLoader::StoreSceneMaterials( aiScene* pScene)
 // Stores all animations
 void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser)
 {
-    // recursivly collect all animations from the collada scene
+    // recursively collect all animations from the collada scene
     StoreAnimations( pScene, pParser, &pParser.mAnims, "");
 
     // catch special case: many animations with the same length, each affecting only a single node.
@@ -967,7 +976,8 @@ void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pPars
             for( size_t b = a+1; b < mAnims.size(); ++b)
             {
                 aiAnimation* other = mAnims[b];
-                if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration && other->mTicksPerSecond == templateAnim->mTicksPerSecond )
+                if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration && 
+                        other->mTicksPerSecond == templateAnim->mTicksPerSecond )
                     collectedAnimIndices.push_back( b);
             }
 
@@ -1119,6 +1129,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
             continue;
 
         // now check all channels if they affect the current node
+        std::string targetID, subElement;
         for( std::vector<Collada::AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
             cit != pSrcAnim->mChannels.end(); ++cit)
         {
@@ -1145,7 +1156,9 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
             }
             if( srcChannel.mTarget.find( '/', slashPos+1) != std::string::npos)
                 continue;
-            std::string targetID = srcChannel.mTarget.substr( 0, slashPos);
+
+            targetID.clear();
+            targetID = srcChannel.mTarget.substr( 0, slashPos);
             if( targetID != srcNode->mID)
                 continue;
 
@@ -1158,7 +1171,8 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
 
                 entry.mTransformId = srcChannel.mTarget.substr( slashPos+1, dotPos - slashPos - 1);
 
-                std::string subElement = srcChannel.mTarget.substr( dotPos+1);
+                subElement.clear();
+                subElement = srcChannel.mTarget.substr( dotPos+1);
                 if( subElement == "ANGLE")
                     entry.mSubElement = 3; // last number in an Axis-Angle-Transform is the angle
                 else if( subElement == "X")
@@ -1168,9 +1182,8 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
                 else if( subElement == "Z")
                     entry.mSubElement = 2;
                 else
-                    DefaultLogger::get()->warn( format() << "Unknown anim subelement <" << subElement << ">. Ignoring" );
-            } else
-            {
+                    ASSIMP_LOG_WARN_F( "Unknown anim subelement <", subElement, ">. Ignoring" );
+            } else {
                 // no subelement following, transformId is remaining string
                 entry.mTransformId = srcChannel.mTarget.substr( slashPos+1);
             }
@@ -1179,7 +1192,8 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
             if (bracketPos != std::string::npos)
             {
                 entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1, bracketPos - slashPos - 1);
-                std::string subElement = srcChannel.mTarget.substr(bracketPos);
+                subElement.clear();
+                subElement = srcChannel.mTarget.substr(bracketPos);
 
                 if (subElement == "(0)(0)")
                     entry.mSubElement = 0;
@@ -1213,7 +1227,6 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
                     entry.mSubElement = 14;
                 else if (subElement == "(3)(3)")
                     entry.mSubElement = 15;
-
             }
 
             // determine which transform step is affected by this channel
@@ -1399,7 +1412,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
               anims.push_back( dstAnim);
         } else
         {
-          DefaultLogger::get()->warn( "Collada loader: found empty animation channel, ignored. Please check your exporter.");
+            ASSIMP_LOG_WARN( "Collada loader: found empty animation channel, ignored. Please check your exporter.");
         }
 
         if( !entries.empty() && entries.front().mTimeAccessor->mCount > 0 )
@@ -1554,7 +1567,7 @@ void ColladaLoader::AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
             }
         }
         if (-1 == map) {
-            DefaultLogger::get()->warn("Collada: unable to determine UV channel for texture");
+            ASSIMP_LOG_WARN("Collada: unable to determine UV channel for texture");
             map = 0;
         }
     }
@@ -1591,7 +1604,7 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
                 break;
 
             default:
-                DefaultLogger::get()->warn("Collada: Unrecognized shading mode, using gouraud shading");
+                ASSIMP_LOG_WARN("Collada: Unrecognized shading mode, using gouraud shading");
                 shadeMode = aiShadingMode_Gouraud;
                 break;
             }
@@ -1650,9 +1663,10 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
         }
 
         // add textures, if given
-        if( !effect.mTexAmbient.mName.empty())
-             /* It is merely a lightmap */
-            AddTexture( mat, pParser, effect, effect.mTexAmbient, aiTextureType_LIGHTMAP);
+        if (!effect.mTexAmbient.mName.empty()) {
+            // It is merely a light-map
+            AddTexture(mat, pParser, effect, effect.mTexAmbient, aiTextureType_LIGHTMAP);
+        }
 
         if( !effect.mTexEmissive.mName.empty())
             AddTexture( mat, pParser, effect, effect.mTexEmissive, aiTextureType_EMISSIVE);
@@ -1680,8 +1694,8 @@ void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
 {
     newMats.reserve(pParser.mMaterialLibrary.size());
 
-    for( ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin(); matIt != pParser.mMaterialLibrary.end(); ++matIt)
-    {
+    for( ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin(); 
+        matIt != pParser.mMaterialLibrary.end(); ++matIt) {
         const Collada::Material& material = matIt->second;
         // a material is only a reference to an effect
         ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find( material.mEffect);
@@ -1745,11 +1759,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
     ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
     if( imIt == pParser.mImageLibrary.end())
     {
-        //missing texture should not stop the conversion
-        //throw DeadlyImportError( format() <<
-        //    "Collada: Unable to resolve effect texture entry \"" << pName << "\", ended up at ID \"" << name << "\"." );
-
-        DefaultLogger::get()->warn("Collada: Unable to resolve effect texture entry \"" + pName + "\", ended up at ID \"" + name + "\".");
+        ASSIMP_LOG_WARN_F("Collada: Unable to resolve effect texture entry \"", pName, "\", ended up at ID \"", name, "\".");
 
         //set default texture file name
         result.Set(name + ".jpg");
@@ -1768,7 +1778,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
 
         // setup format hint
         if (imIt->second.mEmbeddedFormat.length() > 3) {
-            DefaultLogger::get()->warn("Collada: texture format hint is too long, truncating to 3 characters");
+            ASSIMP_LOG_WARN("Collada: texture format hint is too long, truncating to 3 characters");
         }
         strncpy(tex->achFormatHint,imIt->second.mEmbeddedFormat.c_str(),3);
 
@@ -1778,6 +1788,11 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
         tex->pcData = (aiTexel*)new char[tex->mWidth];
         memcpy(tex->pcData,&imIt->second.mImageData[0],tex->mWidth);
 
+        // TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
+        // In FBX files textures are now stored internally by Assimp with their filename included
+        // Now Assimp can lookup through the loaded textures after all data is processed
+        // We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
+        // This may occur on this case too, it has to be studied
         // setup texture reference string
         result.data[0] = '*';
         result.length = 1 + ASSIMP_itoa10(result.data+1,static_cast<unsigned int>(MAXLEN-1),static_cast<int32_t>(mTextures.size()));
@@ -1799,7 +1814,7 @@ void ColladaLoader::ConvertPath (aiString& ss)
 {
     // TODO: collada spec, p 22. Handle URI correctly.
     // For the moment we're just stripping the file:// away to make it work.
-    // Windoes doesn't seem to be able to find stuff like
+    // Windows doesn't seem to be able to find stuff like
     // 'file://..\LWO\LWO2\MappingModes\earthSpherical.jpg'
     if (0 == strncmp(ss.data,"file://",7))
     {
@@ -1810,10 +1825,13 @@ void ColladaLoader::ConvertPath (aiString& ss)
 
   // Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
   // I need to filter it without destroying linux paths starting with "/somewhere"
-  if( ss.data[0] == '/' && isalpha( ss.data[1]) && ss.data[2] == ':' )
-  {
-    ss.length--;
-    memmove( ss.data, ss.data+1, ss.length);
+#if defined( _MSC_VER )
+    if( ss.data[0] == '/' && isalpha( (unsigned char) ss.data[1]) && ss.data[2] == ':' ) {
+#else
+    if (ss.data[ 0 ] == '/' && isalpha( ss.data[ 1 ] ) && ss.data[ 2 ] == ':') {
+#endif
+    --ss.length;
+    ::memmove( ss.data, ss.data+1, ss.length);
     ss.data[ss.length] = 0;
   }
 
@@ -1863,9 +1881,9 @@ const std::string& ColladaLoader::ReadString( const Collada::Accessor& pAccessor
 void ColladaLoader::CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const
 {
     poNodes.push_back( pNode);
-
-    for( size_t a = 0; a < pNode->mNumChildren; ++a)
-        CollectNodes( pNode->mChildren[a], poNodes);
+    for (size_t a = 0; a < pNode->mNumChildren; ++a) {
+        CollectNodes(pNode->mChildren[a], poNodes);
+    }
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -1907,17 +1925,29 @@ const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, c
 // The name must be unique for proper node-bone association.
 std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode)
 {
-    // Now setup the name of the assimp node. The collada name might not be
-    // unique, so we use the collada ID.
-    if (!pNode->mID.empty())
-        return pNode->mID;
-    else if (!pNode->mSID.empty())
-    return pNode->mSID;
-  else
+    // If explicitly requested, just use the collada name.
+    if (useColladaName)
+    {
+        if (!pNode->mName.empty()) {
+            return pNode->mName;
+        } else {
+            return format() << "$ColladaAutoName$_" << mNodeNameCounter++;
+        }
+    }
+    else
     {
-        // No need to worry. Unnamed nodes are no problem at all, except
-        // if cameras or lights need to be assigned to them.
-    return format() << "$ColladaAutoName$_" << mNodeNameCounter++;
+        // Now setup the name of the assimp node. The collada name might not be
+        // unique, so we use the collada ID.
+        if (!pNode->mID.empty())
+            return pNode->mID;
+        else if (!pNode->mSID.empty())
+            return pNode->mSID;
+        else
+        {
+            // No need to worry. Unnamed nodes are no problem at all, except
+            // if cameras or lights need to be assigned to them.
+            return format() << "$ColladaAutoName$_" << mNodeNameCounter++;
+        }
     }
 }
 

+ 4 - 2
Engine/lib/assimp/code/ColladaLoader.h

@@ -4,7 +4,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -44,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_COLLADALOADER_H_INC
 #define AI_COLLADALOADER_H_INC
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include "ColladaParser.h"
 
 struct aiNode;
@@ -247,6 +248,7 @@ protected:
 
     bool noSkeletonMesh;
     bool ignoreUpDirection;
+    bool useColladaName;
 
     /** Used by FindNameForNode() to generate unique node names */
     unsigned int mNodeNameCounter;

+ 50 - 34
Engine/lib/assimp/code/ColladaParser.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -49,13 +50,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <sstream>
 #include <stdarg.h>
 #include "ColladaParser.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include "StringUtils.h"
+#include <assimp/fast_atof.h>
+#include <assimp/ParsingUtils.h>
+#include <assimp/StringUtils.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/light.h>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 
 #include <memory>
 
@@ -67,7 +68,7 @@ using namespace Assimp::Formatter;
 // Constructor to be privately used by Importer
 ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
     : mFileName( pFile )
-    , mReader( NULL )
+    , mReader( nullptr )
     , mDataLibrary()
     , mAccessorLibrary()
     , mMeshLibrary()
@@ -78,20 +79,20 @@ ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
     , mLightLibrary()
     , mCameraLibrary()
     , mControllerLibrary()
-    , mRootNode( NULL )
+    , mRootNode( nullptr )
     , mAnims()
     , mUnitSize( 1.0f )
     , mUpDirection( UP_Y )
     , mFormat(FV_1_5_n )    // We assume the newest file format by default
 {
     // validate io-handler instance
-    if ( NULL == pIOHandler ) {
+    if (nullptr == pIOHandler ) {
         throw DeadlyImportError("IOSystem is NULL." );
     }
 
     // open the file
     std::unique_ptr<IOStream> file( pIOHandler->Open(pFile ) );
-    if (file.get() == NULL) {
+    if (file.get() == nullptr) {
         throw DeadlyImportError( "Failed to open file " + pFile + "." );
     }
 
@@ -151,22 +152,22 @@ void ColladaParser::ReadContents()
 
                     if (!::strncmp(version,"1.5",3)) {
                         mFormat =  FV_1_5_n;
-                        DefaultLogger::get()->debug("Collada schema version is 1.5.n");
+                        ASSIMP_LOG_DEBUG("Collada schema version is 1.5.n");
                     }
                     else if (!::strncmp(version,"1.4",3)) {
                         mFormat =  FV_1_4_n;
-                        DefaultLogger::get()->debug("Collada schema version is 1.4.n");
+                        ASSIMP_LOG_DEBUG("Collada schema version is 1.4.n");
                     }
                     else if (!::strncmp(version,"1.3",3)) {
                         mFormat =  FV_1_3_n;
-                        DefaultLogger::get()->debug("Collada schema version is 1.3.n");
+                        ASSIMP_LOG_DEBUG("Collada schema version is 1.3.n");
                     }
                 }
 
                 ReadStructure();
             } else
             {
-                DefaultLogger::get()->debug( format() << "Ignoring global element <" << mReader->getNodeName() << ">." );
+                ASSIMP_LOG_DEBUG_F( "Ignoring global element <", mReader->getNodeName(), ">." );
                 SkipElement();
             }
         } else
@@ -221,6 +222,7 @@ void ColladaParser::ReadStructure()
     }
 
 	PostProcessRootAnimations();
+    PostProcessControllers();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -359,6 +361,21 @@ void ColladaParser::ReadAnimationClipLibrary()
 	}
 }
 
+void ColladaParser::PostProcessControllers()
+{
+    std::string meshId;
+    for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it) {
+        meshId = it->second.mMeshId;
+        ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
+        while(findItr != mControllerLibrary.end()) {
+            meshId = findItr->second.mMeshId;
+            findItr = mControllerLibrary.find(meshId);
+        }
+    
+        it->second.mMeshId = meshId;
+    }
+}
+
 // ------------------------------------------------------------------------------------------------
 // Re-build animations from animation clip library, if present, otherwise combine single-channel animations
 void ColladaParser::PostProcessRootAnimations()
@@ -967,13 +984,13 @@ void ColladaParser::ReadImage( Collada::Image& pImage)
                     // they're not skipped.
                     int attrib = TestAttribute("array_index");
                     if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) {
-                        DefaultLogger::get()->warn("Collada: Ignoring texture array index");
+                        ASSIMP_LOG_WARN("Collada: Ignoring texture array index");
                         continue;
                     }
 
                     attrib = TestAttribute("mip_index");
                     if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) {
-                        DefaultLogger::get()->warn("Collada: Ignoring MIP map layer");
+                        ASSIMP_LOG_WARN("Collada: Ignoring MIP map layer");
                         continue;
                     }
 
@@ -994,7 +1011,7 @@ void ColladaParser::ReadImage( Collada::Image& pImage)
                     // embedded image. get format
                     const int attrib = TestAttribute("format");
                     if (-1 == attrib)
-                        DefaultLogger::get()->warn("Collada: Unknown image file format");
+                        ASSIMP_LOG_WARN("Collada: Unknown image file format");
                     else pImage.mEmbeddedFormat = mReader->getAttributeValue(attrib);
 
                     const char* data = GetTextContent();
@@ -1573,7 +1590,7 @@ void ColladaParser::ReadSamplerProperties( Sampler& out )
                     out.mOp = aiTextureOp_Multiply;
 
                 else  {
-                    DefaultLogger::get()->warn("Collada: Unsupported MAYA texture blend mode");
+                    ASSIMP_LOG_WARN("Collada: Unsupported MAYA texture blend mode");
                 }
                 TestClosing( "blend_mode");
             }
@@ -2345,7 +2362,7 @@ size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pP
     if( expectedPointCount > 0 && indices.size() != expectedPointCount * numOffsets) {
         if (pPrimType == Prim_Lines) {
             // HACK: We just fix this number since SketchUp 15.3.331 writes the wrong 'count' for 'lines'
-            ReportWarning( "Expected different index count in <p> element, %d instead of %d.", indices.size(), expectedPointCount * numOffsets);
+            ReportWarning( "Expected different index count in <p> element, %zu instead of %zu.", indices.size(), expectedPointCount * numOffsets);
             pNumPrimitives = (indices.size() / numOffsets) / 2;
         } else
             ThrowException( "Expected different index count in <p> element.");
@@ -2524,7 +2541,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
             if( pInput.mIndex == 0)
                 pMesh->mPositions.push_back( aiVector3D( obj[0], obj[1], obj[2]));
             else
-                DefaultLogger::get()->error("Collada: just one vertex position stream supported");
+                ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
             break;
         case IT_Normal:
             // pad to current vertex count if necessary
@@ -2535,7 +2552,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
             if( pInput.mIndex == 0)
                 pMesh->mNormals.push_back( aiVector3D( obj[0], obj[1], obj[2]));
             else
-                DefaultLogger::get()->error("Collada: just one vertex normal stream supported");
+                ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
             break;
         case IT_Tangent:
             // pad to current vertex count if necessary
@@ -2546,7 +2563,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
             if( pInput.mIndex == 0)
                 pMesh->mTangents.push_back( aiVector3D( obj[0], obj[1], obj[2]));
             else
-                DefaultLogger::get()->error("Collada: just one vertex tangent stream supported");
+                ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
             break;
         case IT_Bitangent:
             // pad to current vertex count if necessary
@@ -2557,7 +2574,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
             if( pInput.mIndex == 0)
                 pMesh->mBitangents.push_back( aiVector3D( obj[0], obj[1], obj[2]));
             else
-                DefaultLogger::get()->error("Collada: just one vertex bitangent stream supported");
+                ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
             break;
         case IT_Texcoord:
             // up to 4 texture coord sets are fine, ignore the others
@@ -2573,7 +2590,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
                     pMesh->mNumUVComponents[pInput.mIndex]=3;
             }   else
             {
-                DefaultLogger::get()->error("Collada: too many texture coordinate sets. Skipping.");
+                ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping.");
             }
             break;
         case IT_Color:
@@ -2593,7 +2610,7 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
                 pMesh->mColors[pInput.mIndex].push_back(result);
             } else
             {
-                DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping.");
+                ASSIMP_LOG_ERROR("Collada: too many vertex color sets. Skipping.");
             }
 
             break;
@@ -2722,7 +2739,7 @@ void ColladaParser::ReadSceneNode( Node* pNode)
                 {
                     const char* s = mReader->getAttributeValue(attrId);
                     if (s[0] != '#')
-                        DefaultLogger::get()->error("Collada: Unresolved reference format of camera");
+                        ASSIMP_LOG_ERROR("Collada: Unresolved reference format of camera");
                     else
                         pNode->mPrimaryCamera = s+1;
                 }
@@ -2735,7 +2752,7 @@ void ColladaParser::ReadSceneNode( Node* pNode)
                 {
                     const char* s = mReader->getAttributeValue(attrID);
                     if (s[0] != '#')
-                        DefaultLogger::get()->error("Collada: Unresolved reference format of node");
+                        ASSIMP_LOG_ERROR("Collada: Unresolved reference format of node");
                     else
                     {
                         pNode->mNodeInstances.push_back(NodeInstance());
@@ -2753,7 +2770,7 @@ void ColladaParser::ReadSceneNode( Node* pNode)
                 // Reference to a light, name given in 'url' attribute
                 int attrID = TestAttribute("url");
                 if (-1 == attrID)
-                    DefaultLogger::get()->warn("Collada: Expected url attribute in <instance_light> element");
+                    ASSIMP_LOG_WARN("Collada: Expected url attribute in <instance_light> element");
                 else
                 {
                     const char* url = mReader->getAttributeValue( attrID);
@@ -2769,7 +2786,7 @@ void ColladaParser::ReadSceneNode( Node* pNode)
                 // Reference to a camera, name given in 'url' attribute
                 int attrID = TestAttribute("url");
                 if (-1 == attrID)
-                    DefaultLogger::get()->warn("Collada: Expected url attribute in <instance_camera> element");
+                    ASSIMP_LOG_WARN("Collada: Expected url attribute in <instance_camera> element");
                 else
                 {
                     const char* url = mReader->getAttributeValue( attrID);
@@ -2856,7 +2873,7 @@ void ColladaParser::ReadMaterialVertexInputBinding( Collada::SemanticMappingTabl
                 tbl.mMap[s] = vn;
             }
             else if( IsElement( "bind")) {
-                DefaultLogger::get()->warn("Collada: Found unsupported <bind> element");
+                ASSIMP_LOG_WARN("Collada: Found unsupported <bind> element");
             }
         }
         else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)    {
@@ -2975,10 +2992,9 @@ void ColladaParser::ReportWarning(const char* msg,...)
     ai_assert(iLen > 0);
 
     va_end(args);
-    DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen));
+    ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer,iLen));
 }
 
-
 // ------------------------------------------------------------------------------------------------
 // Skips all data until the end node of the current element
 void ColladaParser::SkipElement()
@@ -3089,7 +3105,7 @@ const char* ColladaParser::TestTextContent()
     // read contents of the element
     if( !mReader->read() )
         return NULL;
-    if( mReader->getNodeType() != irr::io::EXN_TEXT)
+    if( mReader->getNodeType() != irr::io::EXN_TEXT && mReader->getNodeType() != irr::io::EXN_CDATA)
         return NULL;
 
     // skip leading whitespace
@@ -3173,7 +3189,7 @@ aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector<Transform
 Collada::InputType ColladaParser::GetTypeForSemantic( const std::string& semantic)
 {
     if ( semantic.empty() ) {
-        DefaultLogger::get()->warn( format() << "Vertex input type is empty." );
+        ASSIMP_LOG_WARN("Vertex input type is empty." );
         return IT_Invalid;
     }
 
@@ -3192,7 +3208,7 @@ Collada::InputType ColladaParser::GetTypeForSemantic( const std::string& semanti
     else if( semantic == "TANGENT" || semantic == "TEXTANGENT")
         return IT_Tangent;
 
-    DefaultLogger::get()->warn( format() << "Unknown vertex input type \"" << semantic << "\". Ignoring." );
+    ASSIMP_LOG_WARN_F( "Unknown vertex input type \"", semantic, "\". Ignoring." );
     return IT_Invalid;
 }
 

+ 7 - 3
Engine/lib/assimp/code/ColladaParser.h

@@ -2,7 +2,8 @@
  Open Asset Import Library (assimp)
  ----------------------------------------------------------------------
 
- Copyright (c) 2006-2017, assimp team
+ Copyright (c) 2006-2019, assimp team
+
 
  All rights reserved.
 
@@ -46,10 +47,10 @@
 #ifndef AI_COLLADAPARSER_H_INC
 #define AI_COLLADAPARSER_H_INC
 
-#include "irrXMLWrapper.h"
+#include <assimp/irrXMLWrapper.h>
 #include "ColladaHelper.h"
 #include <assimp/ai_assert.h>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 
 namespace Assimp
 {
@@ -86,6 +87,9 @@ namespace Assimp
 		/** Reads the animation clip library */
 		void ReadAnimationClipLibrary();
 
+        /** Unwrap controllers dependency hierarchy */
+        void PostProcessControllers();
+    
 		/** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
 		void PostProcessRootAnimations();
 

+ 9 - 8
Engine/lib/assimp/code/ComputeUVMappingProcess.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -44,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "ComputeUVMappingProcess.h"
 #include "ProcessHelper.h"
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 
 using namespace Assimp;
 
@@ -98,7 +99,7 @@ inline unsigned int FindEmptyUVChannel (aiMesh* mesh)
     for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m)
         if (!mesh->mTextureCoords[m])return m;
 
-    DefaultLogger::get()->error("Unable to compute UV coordinates, no free UV slot found");
+    ASSIMP_LOG_ERROR("Unable to compute UV coordinates, no free UV slot found");
     return UINT_MAX;
 }
 
@@ -383,13 +384,13 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
 // ------------------------------------------------------------------------------------------------
 void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* )
 {
-    DefaultLogger::get()->error("Mapping type currently not implemented");
+    ASSIMP_LOG_ERROR("Mapping type currently not implemented");
 }
 
 // ------------------------------------------------------------------------------------------------
 void ComputeUVMappingProcess::Execute( aiScene* pScene)
 {
-    DefaultLogger::get()->debug("GenUVCoordsProcess begin");
+    ASSIMP_LOG_DEBUG("GenUVCoordsProcess begin");
     char buffer[1024];
 
     if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
@@ -417,7 +418,7 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
                             TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
                             MappingTypeToString(mapping));
 
-                        DefaultLogger::get()->info(buffer);
+                        ASSIMP_LOG_INFO(buffer);
                     }
 
                     if (aiTextureMapping_OTHER == mapping)
@@ -484,7 +485,7 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
                             }
                             if (m && idx != outIdx)
                             {
-                                DefaultLogger::get()->warn("UV index mismatch. Not all meshes assigned to "
+                                ASSIMP_LOG_WARN("UV index mismatch. Not all meshes assigned to "
                                     "this material have equal numbers of UV channels. The UV index stored in  "
                                     "the material structure does therefore not apply for all meshes. ");
                             }
@@ -501,5 +502,5 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
             }
         }
     }
-    DefaultLogger::get()->debug("GenUVCoordsProcess finished");
+    ASSIMP_LOG_DEBUG("GenUVCoordsProcess finished");
 }

+ 2 - 1
Engine/lib/assimp/code/ComputeUVMappingProcess.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 

+ 111 - 29
Engine/lib/assimp/code/ConvertToLHProcess.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -58,6 +59,25 @@ using namespace Assimp;
 
 #ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
 
+namespace {
+
+template <typename aiMeshType>
+void flipUVs(aiMeshType* pMesh) {
+    if (pMesh == nullptr) { return; }
+    // mirror texture y coordinate
+    for (unsigned int tcIdx = 0; tcIdx < AI_MAX_NUMBER_OF_TEXTURECOORDS; tcIdx++) {
+        if (!pMesh->HasTextureCoords(tcIdx)) {
+            break;
+        }
+
+        for (unsigned int vIdx = 0; vIdx < pMesh->mNumVertices; vIdx++) {
+            pMesh->mTextureCoords[tcIdx][vIdx].y = 1.0f - pMesh->mTextureCoords[tcIdx][vIdx].y;
+        }
+    }
+}
+
+} // namespace
+
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 MakeLeftHandedProcess::MakeLeftHandedProcess()
@@ -84,18 +104,20 @@ void MakeLeftHandedProcess::Execute( aiScene* pScene)
 {
     // Check for an existent root node to proceed
     ai_assert(pScene->mRootNode != NULL);
-    DefaultLogger::get()->debug("MakeLeftHandedProcess begin");
+    ASSIMP_LOG_DEBUG("MakeLeftHandedProcess begin");
 
     // recursively convert all the nodes
     ProcessNode( pScene->mRootNode, aiMatrix4x4());
 
     // process the meshes accordingly
-    for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
-        ProcessMesh( pScene->mMeshes[a]);
+    for ( unsigned int a = 0; a < pScene->mNumMeshes; ++a ) {
+        ProcessMesh( pScene->mMeshes[ a ] );
+    }
 
     // process the materials accordingly
-    for( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
-        ProcessMaterial( pScene->mMaterials[a]);
+    for ( unsigned int a = 0; a < pScene->mNumMaterials; ++a ) {
+        ProcessMaterial( pScene->mMaterials[ a ] );
+    }
 
     // transform all animation channels as well
     for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
@@ -107,7 +129,7 @@ void MakeLeftHandedProcess::Execute( aiScene* pScene)
             ProcessAnimation( nodeAnim);
         }
     }
-    DefaultLogger::get()->debug("MakeLeftHandedProcess finished");
+    ASSIMP_LOG_DEBUG("MakeLeftHandedProcess finished");
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -135,14 +157,18 @@ void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pPare
 
 // ------------------------------------------------------------------------------------------------
 // Converts a single mesh to left handed coordinates.
-void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
-{
+void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) {
+    if ( nullptr == pMesh ) {
+        ASSIMP_LOG_ERROR( "Nullptr to mesh found." );
+        return;
+    }
     // mirror positions, normals and stuff along the Z axis
     for( size_t a = 0; a < pMesh->mNumVertices; ++a)
     {
         pMesh->mVertices[a].z *= -1.0f;
-        if( pMesh->HasNormals())
+        if (pMesh->HasNormals()) {
             pMesh->mNormals[a].z *= -1.0f;
+        }
         if( pMesh->HasTangentsAndBitangents())
         {
             pMesh->mTangents[a].z *= -1.0f;
@@ -150,6 +176,23 @@ void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
         }
     }
 
+    // mirror anim meshes positions, normals and stuff along the Z axis
+    for (size_t m = 0; m < pMesh->mNumAnimMeshes; ++m)
+    {
+        for (size_t a = 0; a < pMesh->mAnimMeshes[m]->mNumVertices; ++a)
+        {
+            pMesh->mAnimMeshes[m]->mVertices[a].z *= -1.0f;
+            if (pMesh->mAnimMeshes[m]->HasNormals()) {
+                pMesh->mAnimMeshes[m]->mNormals[a].z *= -1.0f;
+            }
+            if (pMesh->mAnimMeshes[m]->HasTangentsAndBitangents())
+            {
+                pMesh->mAnimMeshes[m]->mTangents[a].z *= -1.0f;
+                pMesh->mAnimMeshes[m]->mBitangents[a].z *= -1.0f;
+            }
+        }
+    }
+
     // mirror offset matrices of all bones
     for( size_t a = 0; a < pMesh->mNumBones; ++a)
     {
@@ -172,8 +215,12 @@ void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
 
 // ------------------------------------------------------------------------------------------------
 // Converts a single material to left handed coordinates.
-void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
-{
+void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat) {
+    if ( nullptr == _mat ) {
+        ASSIMP_LOG_ERROR( "Nullptr to aiMaterial found." );
+        return;
+    }
+
     aiMaterial* mat = (aiMaterial*)_mat;
     for (unsigned int a = 0; a < mat->mNumProperties;++a)   {
         aiMaterialProperty* prop = mat->mProperties[a];
@@ -182,7 +229,6 @@ void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
         if (!::strcmp( prop->mKey.data, "$tex.mapaxis"))    {
             ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
             aiVector3D* pff = (aiVector3D*)prop->mData;
-
             pff->z *= -1.f;
         }
     }
@@ -236,13 +282,13 @@ bool FlipUVsProcess::IsActive( unsigned int pFlags) const
 // Executes the post processing step on the given imported data.
 void FlipUVsProcess::Execute( aiScene* pScene)
 {
-    DefaultLogger::get()->debug("FlipUVsProcess begin");
+    ASSIMP_LOG_DEBUG("FlipUVsProcess begin");
     for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
         ProcessMesh(pScene->mMeshes[i]);
 
     for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
         ProcessMaterial(pScene->mMaterials[i]);
-    DefaultLogger::get()->debug("FlipUVsProcess finished");
+    ASSIMP_LOG_DEBUG("FlipUVsProcess finished");
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -253,7 +299,7 @@ void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
     for (unsigned int a = 0; a < mat->mNumProperties;++a)   {
         aiMaterialProperty* prop = mat->mProperties[a];
         if( !prop ) {
-            DefaultLogger::get()->debug( "Property is null" );
+            ASSIMP_LOG_DEBUG( "Property is null" );
             continue;
         }
 
@@ -273,15 +319,9 @@ void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
 // Converts a single mesh
 void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
 {
-    // mirror texture y coordinate
-    for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)   {
-        if( !pMesh->HasTextureCoords( a ) ) {
-            break;
-        }
-
-        for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
-            pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
-        }
+    flipUVs(pMesh);
+    for (unsigned int idx = 0; idx < pMesh->mNumAnimMeshes; idx++) {
+        flipUVs(pMesh->mAnimMeshes[idx]);
     }
 }
 
@@ -310,10 +350,10 @@ bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
 // Executes the post processing step on the given imported data.
 void FlipWindingOrderProcess::Execute( aiScene* pScene)
 {
-    DefaultLogger::get()->debug("FlipWindingOrderProcess begin");
+    ASSIMP_LOG_DEBUG("FlipWindingOrderProcess begin");
     for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
         ProcessMesh(pScene->mMeshes[i]);
-    DefaultLogger::get()->debug("FlipWindingOrderProcess finished");
+    ASSIMP_LOG_DEBUG("FlipWindingOrderProcess finished");
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -324,8 +364,50 @@ void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
     for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
     {
         aiFace& face = pMesh->mFaces[a];
-        for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
-            std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
+        for (unsigned int b = 0; b < face.mNumIndices / 2; b++) {
+            std::swap(face.mIndices[b], face.mIndices[face.mNumIndices - 1 - b]);
+        }
+    }
+
+    // invert the order of all components in this mesh anim meshes
+    for (unsigned int m = 0; m < pMesh->mNumAnimMeshes; m++) {
+        aiAnimMesh* animMesh = pMesh->mAnimMeshes[m];
+        unsigned int numVertices = animMesh->mNumVertices;
+        if (animMesh->HasPositions()) {
+            for (unsigned int a = 0; a < numVertices; a++)
+            {
+                std::swap(animMesh->mVertices[a], animMesh->mVertices[numVertices - 1 - a]);
+            }
+        }
+        if (animMesh->HasNormals()) {
+            for (unsigned int a = 0; a < numVertices; a++)
+            {
+                std::swap(animMesh->mNormals[a], animMesh->mNormals[numVertices - 1 - a]);
+            }
+        }
+        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) {
+            if (animMesh->HasTextureCoords(i)) {
+                for (unsigned int a = 0; a < numVertices; a++)
+                {
+                    std::swap(animMesh->mTextureCoords[i][a], animMesh->mTextureCoords[i][numVertices - 1 - a]);
+                }
+            }
+        }
+        if (animMesh->HasTangentsAndBitangents()) {
+            for (unsigned int a = 0; a < numVertices; a++)
+            {
+                std::swap(animMesh->mTangents[a], animMesh->mTangents[numVertices - 1 - a]);
+                std::swap(animMesh->mBitangents[a], animMesh->mBitangents[numVertices - 1 - a]);
+            }
+        }
+        for (unsigned int v = 0; v < AI_MAX_NUMBER_OF_COLOR_SETS; v++) {
+            if (animMesh->HasVertexColors(v)) {
+                for (unsigned int a = 0; a < numVertices; a++)
+                {
+                    std::swap(animMesh->mColors[v][a], animMesh->mColors[v][numVertices - 1 - a]);
+                }
+            }
+        }
     }
 }
 

+ 2 - 1
Engine/lib/assimp/code/ConvertToLHProcess.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 

+ 1 - 1
Engine/lib/assimp/code/CreateAnimMesh.cpp

@@ -40,7 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-#include "CreateAnimMesh.h"
+#include <assimp/CreateAnimMesh.h>
 
 namespace Assimp    {
 

+ 78 - 8
Engine/lib/assimp/code/D3MFExporter.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -48,8 +49,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/IOStream.hpp>
 #include <assimp/Exporter.hpp>
 #include <assimp/DefaultLogger.hpp>
+#include <assimp/StringUtils.h>
+#include <assimp/Exceptional.h>
 
-#include "Exceptional.h"
 #include "3MFXmlTags.h"
 #include "D3MFOpcPackage.h"
 
@@ -115,6 +117,7 @@ bool D3MFExporter::exportArchive( const char *file ) {
     if ( nullptr == m_zipArchive ) {
         return false;
     }
+
     ok |= exportContentTypes();
     ok |= export3DModel();
     ok |= exportRelations();
@@ -125,7 +128,6 @@ bool D3MFExporter::exportArchive( const char *file ) {
     return ok;
 }
 
-
 bool D3MFExporter::exportContentTypes() {
     mContentOutput.clear();
 
@@ -152,7 +154,11 @@ bool D3MFExporter::exportRelations() {
     mRelOutput << "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
 
     for ( size_t i = 0; i < mRelations.size(); ++i ) {
-        mRelOutput << "<Relationship Target=\"/" << mRelations[ i ]->target << "\" ";
+        if ( mRelations[ i ]->target[ 0 ] == '/' ) {
+            mRelOutput << "<Relationship Target=\"" << mRelations[ i ]->target << "\" ";
+        } else {
+            mRelOutput << "<Relationship Target=\"/" << mRelations[ i ]->target << "\" ";
+        }
         mRelOutput << "Id=\"" << mRelations[i]->id << "\" ";
         mRelOutput << "Type=\"" << mRelations[ i ]->type << "\" />";
         mRelOutput << std::endl;
@@ -176,6 +182,10 @@ bool D3MFExporter::export3DModel() {
     mModelOutput << "<" << XmlTag::resources << ">";
     mModelOutput << std::endl;
 
+    writeMetaData();
+
+    writeBaseMaterials();
+
     writeObjects();
 
 
@@ -202,6 +212,63 @@ void D3MFExporter::writeHeader() {
     mModelOutput << std::endl;
 }
 
+void D3MFExporter::writeMetaData() {
+    if ( nullptr == mScene->mMetaData ) {
+        return;
+    }
+
+    const unsigned int numMetaEntries( mScene->mMetaData->mNumProperties );
+    if ( 0 == numMetaEntries ) {
+        return;
+    }
+
+	const aiString *key = nullptr;
+    const aiMetadataEntry *entry(nullptr);
+    for ( size_t i = 0; i < numMetaEntries; ++i ) {
+        mScene->mMetaData->Get( i, key, entry );
+        std::string k( key->C_Str() );
+        aiString value;
+        mScene->mMetaData->Get(  k, value );
+        mModelOutput << "<" << XmlTag::meta << " " << XmlTag::meta_name << "=\"" << key->C_Str() << "\">";
+        mModelOutput << value.C_Str();
+        mModelOutput << "</" << XmlTag::meta << ">" << std::endl;
+    }
+}
+
+void D3MFExporter::writeBaseMaterials() {
+    mModelOutput << "<basematerials id=\"1\">\n";
+    std::string strName, hexDiffuseColor , tmp;
+    for ( size_t i = 0; i < mScene->mNumMaterials; ++i ) {
+        aiMaterial *mat = mScene->mMaterials[ i ];
+        aiString name;
+        if ( mat->Get( AI_MATKEY_NAME, name ) != aiReturn_SUCCESS ) {
+            strName = "basemat_" + to_string( i );
+        } else {
+            strName = name.C_Str();
+        }
+        aiColor4D color;
+        if ( mat->Get( AI_MATKEY_COLOR_DIFFUSE, color ) == aiReturn_SUCCESS ) {
+            hexDiffuseColor.clear();
+            tmp.clear();
+            hexDiffuseColor = "#";
+            
+            tmp = DecimalToHexa( color.r );
+            hexDiffuseColor += tmp;
+            tmp = DecimalToHexa( color.g );
+            hexDiffuseColor += tmp;
+            tmp = DecimalToHexa( color.b );
+            hexDiffuseColor += tmp;
+            tmp = DecimalToHexa( color.a );
+            hexDiffuseColor += tmp;
+        } else {
+            hexDiffuseColor = "#FFFFFFFF";
+        }
+
+        mModelOutput << "<base name=\""+strName+"\" "+" displaycolor=\""+hexDiffuseColor+"\" />\n";
+    }
+    mModelOutput << "</basematerials>\n";
+}
+
 void D3MFExporter::writeObjects() {
     if ( nullptr == mScene->mRootNode ) {
         return;
@@ -241,7 +308,9 @@ void D3MFExporter::writeMesh( aiMesh *mesh ) {
     }
     mModelOutput << "</" << XmlTag::vertices << ">" << std::endl;
 
-    writeFaces( mesh );
+    const unsigned int matIdx( mesh->mMaterialIndex );
+
+    writeFaces( mesh, matIdx );
 
     mModelOutput << "</" << XmlTag::mesh << ">" << std::endl;
 }
@@ -251,7 +320,7 @@ void D3MFExporter::writeVertex( const aiVector3D &pos ) {
     mModelOutput << std::endl;
 }
 
-void D3MFExporter::writeFaces( aiMesh *mesh ) {
+void D3MFExporter::writeFaces( aiMesh *mesh, unsigned int matIdx ) {
     if ( nullptr == mesh ) {
         return;
     }
@@ -263,7 +332,8 @@ void D3MFExporter::writeFaces( aiMesh *mesh ) {
     for ( unsigned int i = 0; i < mesh->mNumFaces; ++i ) {
         aiFace &currentFace = mesh->mFaces[ i ];
         mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[ 0 ] << "\" v2=\""
-                << currentFace.mIndices[ 1 ] << "\" v3=\"" << currentFace.mIndices[ 2 ] << "\"/>";
+                << currentFace.mIndices[ 1 ] << "\" v3=\"" << currentFace.mIndices[ 2 ]
+                << "\" pid=\"1\" p1=\""+to_string(matIdx)+"\" />";
         mModelOutput << std::endl;
     }
     mModelOutput << "</" << XmlTag::triangles << ">";
@@ -324,5 +394,5 @@ void D3MFExporter::writeRelInfoToFile( const std::string &folder, const std::str
 } // Namespace D3MF
 } // Namespace Assimp
 
-#endif // ASSIMP_BUILD_NO3MF_EXPORTER
+#endif // ASSIMP_BUILD_NO_3MF_EXPORTER
 #endif // ASSIMP_BUILD_NO_EXPORT

+ 7 - 4
Engine/lib/assimp/code/D3MFExporter.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -59,7 +60,7 @@ class IOStream;
 namespace D3MF {
 
 #ifndef ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO3MF_EXPORTER
+#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
 
 struct OpcPackageRelationship;
 
@@ -75,10 +76,12 @@ public:
 
 protected:
     void writeHeader();
+    void writeMetaData();
+    void writeBaseMaterials();
     void writeObjects();
     void writeMesh( aiMesh *mesh );
     void writeVertex( const aiVector3D &pos );
-    void writeFaces( aiMesh *mesh );
+    void writeFaces( aiMesh *mesh, unsigned int matIdx );
     void writeBuild();
     void exportContentTyp( const std::string &filename );
     void writeModelToArchive( const std::string &folder, const std::string &modelName );
@@ -95,7 +98,7 @@ private:
     std::vector<OpcPackageRelationship*> mRelations;
 };
 
-#endif // ASSIMP_BUILD_NO3MF_EXPORTER
+#endif // ASSIMP_BUILD_NO_3MF_EXPORTER
 #endif // ASSIMP_BUILD_NO_EXPORT
 
 } // Namespace D3MF

+ 234 - 85
Engine/lib/assimp/code/D3MFImporter.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -47,8 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/IOSystem.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/importerdesc.h>
-#include "StringComparison.h"
-#include "StringUtils.h"
+#include <assimp/StringComparison.h>
+#include <assimp/StringUtils.h>
 
 #include <string>
 #include <vector>
@@ -57,17 +58,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <memory>
 
 #include "D3MFOpcPackage.h"
-#include <contrib/unzip/unzip.h>
-#include "irrXMLWrapper.h"
+#include <unzip.h>
+#include <assimp/irrXMLWrapper.h>
 #include "3MFXmlTags.h"
+#include <assimp/fast_atof.h>
+
+#include <iomanip>
 
 namespace Assimp {
 namespace D3MF {
 
 class XmlSerializer {
 public:
+    using MatArray = std::vector<aiMaterial*>;
+    using MatId2MatArray = std::map<unsigned int, std::vector<unsigned int>>;
+
     XmlSerializer(XmlReader* xmlReader)
-    : xmlReader(xmlReader) {
+    : mMeshes()
+    , mMatArray()
+    , mActiveMatGroup( 99999999 )
+    , mMatId2MatArray()
+    , xmlReader(xmlReader){
 		// empty
     }
 
@@ -76,14 +87,24 @@ public:
     }
 
     void ImportXml(aiScene* scene) {
+        if ( nullptr == scene ) {
+            return;
+        }
+
         scene->mRootNode = new aiNode();
         std::vector<aiNode*> children;
 
+        std::string nodeName;
         while(ReadToEndElement(D3MF::XmlTag::model)) {
-            if(xmlReader->getNodeName() == D3MF::XmlTag::object) {
+            nodeName = xmlReader->getNodeName();
+            if( nodeName == D3MF::XmlTag::object) {
                 children.push_back(ReadObject(scene));
-            } else if(xmlReader->getNodeName() == D3MF::XmlTag::build) {
-
+            } else if( nodeName == D3MF::XmlTag::build) {
+                // 
+            } else if ( nodeName == D3MF::XmlTag::basematerials ) {
+                ReadBaseMaterials();
+            } else if ( nodeName == D3MF::XmlTag::meta ) {
+                ReadMetadata();
             }
         }
 
@@ -91,31 +112,47 @@ public:
             scene->mRootNode->mName.Set( "3MF" );
         }
 
-        scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
+        // import the metadata
+        if ( !mMetaData.empty() ) {
+            const size_t numMeta( mMetaData.size() );
+            scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>( numMeta ) );
+            for ( size_t i = 0; i < numMeta; ++i ) {
+                aiString val( mMetaData[ i ].value );
+                scene->mMetaData->Set(static_cast<unsigned int>( i ), mMetaData[ i ].name, val );
+            }
+        }
+
+        // import the meshes
+        scene->mNumMeshes = static_cast<unsigned int>( mMeshes.size());
         scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
+        std::copy( mMeshes.begin(), mMeshes.end(), scene->mMeshes);
 
-        std::copy(meshes.begin(), meshes.end(), scene->mMeshes);
+        // import the materials
+        scene->mNumMaterials = static_cast<unsigned int>( mMatArray.size() );
+        if ( 0 != scene->mNumMaterials ) {
+            scene->mMaterials = new aiMaterial*[ scene->mNumMaterials ];
+            std::copy( mMatArray.begin(), mMatArray.end(), scene->mMaterials );
+        }
 
+        // create the scenegraph
         scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size());
         scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
-
         std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
     }
 
 private:
-    aiNode* ReadObject(aiScene* scene)
-    {
+    aiNode* ReadObject(aiScene* scene) {
         std::unique_ptr<aiNode> node(new aiNode());
 
         std::vector<unsigned long> meshIds;
 
         const char *attrib( nullptr );
         std::string name, type;
-        attrib = xmlReader->getAttributeValue( D3MF::XmlTag::name.c_str() );
+        attrib = xmlReader->getAttributeValue( D3MF::XmlTag::id.c_str() );
         if ( nullptr != attrib ) {
             name = attrib;
         }
-        attrib = xmlReader->getAttributeValue( D3MF::XmlTag::name.c_str() );
+        attrib = xmlReader->getAttributeValue( D3MF::XmlTag::type.c_str() );
         if ( nullptr != attrib ) {
             type = attrib;
         }
@@ -123,19 +160,16 @@ private:
         node->mParent = scene->mRootNode;
         node->mName.Set(name);
 
-        size_t meshIdx = meshes.size();
+        size_t meshIdx = mMeshes.size();
 
-        while(ReadToEndElement(D3MF::XmlTag::object))
-        {
-            if(xmlReader->getNodeName() == D3MF::XmlTag::mesh)
-            {
+        while(ReadToEndElement(D3MF::XmlTag::object)) {
+            if(xmlReader->getNodeName() == D3MF::XmlTag::mesh) {
                 auto mesh = ReadMesh();
 
                 mesh->mName.Set(name);
-                meshes.push_back(mesh);
+                mMeshes.push_back(mesh);
                 meshIds.push_back(static_cast<unsigned long>(meshIdx));
-                meshIdx++;
-
+                ++meshIdx;
             }
         }
 
@@ -146,19 +180,14 @@ private:
         std::copy(meshIds.begin(), meshIds.end(), node->mMeshes);
 
         return node.release();
-
     }
 
-    aiMesh* ReadMesh() {
+    aiMesh *ReadMesh() {
         aiMesh* mesh = new aiMesh();
-        while(ReadToEndElement(D3MF::XmlTag::mesh))
-        {
-            if(xmlReader->getNodeName() == D3MF::XmlTag::vertices)
-            {
+        while(ReadToEndElement(D3MF::XmlTag::mesh)) {
+            if(xmlReader->getNodeName() == D3MF::XmlTag::vertices) {
                 ImportVertices(mesh);
-            }
-            else if(xmlReader->getNodeName() == D3MF::XmlTag::triangles)
-            {
+            } else if(xmlReader->getNodeName() == D3MF::XmlTag::triangles) {
                 ImportTriangles(mesh);
             }
         }
@@ -166,14 +195,25 @@ private:
         return mesh;
     }
 
-    void ImportVertices(aiMesh* mesh)
-    {
-        std::vector<aiVector3D> vertices;
+    void ReadMetadata() {
+        const std::string name = xmlReader->getAttributeValue( D3MF::XmlTag::meta_name.c_str() );
+        xmlReader->read();
+        const std::string value = xmlReader->getNodeData();
 
-        while(ReadToEndElement(D3MF::XmlTag::vertices))
-        {
-            if(xmlReader->getNodeName() == D3MF::XmlTag::vertex)
-            {
+        if ( name.empty() ) {
+            return;
+        }
+
+        MetaEntry entry;
+        entry.name = name;
+        entry.value = value;
+        mMetaData.push_back( entry );
+    }
+
+    void ImportVertices(aiMesh* mesh) {
+        std::vector<aiVector3D> vertices;
+        while(ReadToEndElement(D3MF::XmlTag::vertices)) {
+            if(xmlReader->getNodeName() == D3MF::XmlTag::vertex) {
                 vertices.push_back(ReadVertex());
             }
         }
@@ -181,11 +221,9 @@ private:
         mesh->mVertices = new aiVector3D[mesh->mNumVertices];
 
         std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
-
     }
 
-    aiVector3D ReadVertex()
-    {
+    aiVector3D ReadVertex() {
         aiVector3D vertex;
 
         vertex.x = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::x.c_str()), nullptr);
@@ -195,16 +233,18 @@ private:
         return vertex;
     }
 
-    void ImportTriangles(aiMesh* mesh)
-    {
+    void ImportTriangles(aiMesh* mesh) {
          std::vector<aiFace> faces;
 
-
-         while(ReadToEndElement(D3MF::XmlTag::triangles))
-         {
-             if(xmlReader->getNodeName() == D3MF::XmlTag::triangle)
-             {
+         while(ReadToEndElement(D3MF::XmlTag::triangles)) {
+             const std::string nodeName( xmlReader->getNodeName() );
+             if(xmlReader->getNodeName() == D3MF::XmlTag::triangle) {
                  faces.push_back(ReadTriangle());
+                 const char *pidToken( xmlReader->getAttributeValue( D3MF::XmlTag::p1.c_str() ) );
+                 if ( nullptr != pidToken ) {
+                     int matIdx( std::atoi( pidToken ) );
+                     mesh->mMaterialIndex = matIdx;
+                 }
              }
          }
 
@@ -215,8 +255,7 @@ private:
         std::copy(faces.begin(), faces.end(), mesh->mFaces);
     }
 
-    aiFace ReadTriangle()
-    {
+    aiFace ReadTriangle() {
         aiFace face;
 
         face.mNumIndices = 3;
@@ -228,52 +267,158 @@ private:
         return face;
     }
 
+    void ReadBaseMaterials() {
+        std::vector<unsigned int> MatIdArray;
+        const char *baseMaterialId( xmlReader->getAttributeValue( D3MF::XmlTag::basematerials_id.c_str() ) );
+        if ( nullptr != baseMaterialId ) {
+            unsigned int id = std::atoi( baseMaterialId );
+            const size_t newMatIdx( mMatArray.size() );
+            if ( id != mActiveMatGroup ) {
+                mActiveMatGroup = id;
+                MatId2MatArray::const_iterator it( mMatId2MatArray.find( id ) );
+                if ( mMatId2MatArray.end() == it ) {
+                    MatIdArray.clear();
+                    mMatId2MatArray[ id ] = MatIdArray;
+                } else {
+                    MatIdArray = it->second;
+                }
+            }
+            MatIdArray.push_back( static_cast<unsigned int>( newMatIdx ) );
+            mMatId2MatArray[ mActiveMatGroup ] = MatIdArray;
+        }
+
+        while ( ReadToEndElement( D3MF::XmlTag::basematerials ) ) {
+            mMatArray.push_back( readMaterialDef() );
+        }
+    }
+
+    bool parseColor( const char *color, aiColor4D &diffuse ) {
+        if ( nullptr == color ) {
+            return false;
+        }
+
+        //format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
+        const size_t len( strlen( color ) );
+        if ( 9 != len && 7 != len) {
+            return false;
+        }
+
+        const char *buf( color );
+        if ( '#' != *buf ) {
+            return false;
+        }
+        ++buf;
+        char comp[ 3 ] = { 0,0,'\0' };
+
+        comp[ 0 ] = *buf;
+        ++buf;
+        comp[ 1 ] = *buf;
+        ++buf;
+        diffuse.r = static_cast<ai_real>( strtol( comp, NULL, 16 ) ) / ai_real(255.0);
+
+
+        comp[ 0 ] = *buf;
+        ++buf;
+        comp[ 1 ] = *buf;
+        ++buf;
+        diffuse.g = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / ai_real(255.0);
+
+        comp[ 0 ] = *buf;
+        ++buf;
+        comp[ 1 ] = *buf;
+        ++buf;
+        diffuse.b = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / ai_real(255.0);
+
+        if(7 == len)
+            return true;
+        comp[ 0 ] = *buf;
+        ++buf;
+        comp[ 1 ] = *buf;
+        ++buf;
+        diffuse.a = static_cast< ai_real >( strtol( comp, NULL, 16 ) ) / ai_real(255.0);
+
+        return true;
+    }
+
+    void assignDiffuseColor( aiMaterial *mat ) {
+        const char *color = xmlReader->getAttributeValue( D3MF::XmlTag::basematerials_displaycolor.c_str() );
+        aiColor4D diffuse;
+        if ( parseColor( color, diffuse ) ) {
+            mat->AddProperty<aiColor4D>( &diffuse, 1, AI_MATKEY_COLOR_DIFFUSE );
+        }
+
+    }
+    aiMaterial *readMaterialDef() {
+        aiMaterial *mat( nullptr );
+        const char *name( nullptr );
+        const std::string nodeName( xmlReader->getNodeName() );
+        if ( nodeName == D3MF::XmlTag::basematerials_base ) {
+            name = xmlReader->getAttributeValue( D3MF::XmlTag::basematerials_name.c_str() );
+            std::string stdMatName;
+            aiString matName;
+            std::string strId( to_string( mActiveMatGroup ) );
+            stdMatName += "id";
+            stdMatName += strId;
+            stdMatName += "_";
+            if ( nullptr != name ) {
+                stdMatName += std::string( name );
+            } else {
+                stdMatName += "basemat";
+            }
+            matName.Set( stdMatName );
+
+            mat = new aiMaterial;
+            mat->AddProperty( &matName, AI_MATKEY_NAME );
+
+            assignDiffuseColor( mat );
+        }
+
+        return mat;
+    }
+
 private:
-    bool ReadToStartElement(const std::string& startTag)
-    {
-        while(xmlReader->read())
-        {
-            if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT && xmlReader->getNodeName() == startTag)
-            {
+    bool ReadToStartElement(const std::string& startTag) {
+        while(xmlReader->read()) {
+            const std::string &nodeName( xmlReader->getNodeName() );
+            if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT && nodeName == startTag) {
                 return true;
-            }
-            else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END &&
-                     xmlReader->getNodeName() == startTag)
-            {
+            } else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END && nodeName == startTag) {
                 return false;
             }
         }
-        //DefaultLogger::get()->error("unexpected EOF, expected closing <" + closeTag + "> tag");
+
         return false;
     }
 
-    bool ReadToEndElement(const std::string& closeTag)
-    {
-        while(xmlReader->read())
-        {
+    bool ReadToEndElement(const std::string& closeTag) {
+        while(xmlReader->read()) {
+            const std::string &nodeName( xmlReader->getNodeName() );
             if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT) {
                 return true;
-            }
-            else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END
-                     && xmlReader->getNodeName() == closeTag)
-            {
+            } else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END && nodeName == closeTag) {
                 return false;
             }
         }
-        DefaultLogger::get()->error("unexpected EOF, expected closing <" + closeTag + "> tag");
+        ASSIMP_LOG_ERROR("unexpected EOF, expected closing <" + closeTag + "> tag");
+
         return false;
     }
 
-
 private:
-    std::vector<aiMesh*> meshes;
+    struct MetaEntry {
+        std::string name;
+        std::string value;
+    };
+    std::vector<MetaEntry> mMetaData;
+    std::vector<aiMesh*> mMeshes;
+    MatArray mMatArray;
+    unsigned int mActiveMatGroup;
+    MatId2MatArray mMatId2MatArray;
     XmlReader* xmlReader;
 };
 
 } //namespace D3MF
 
-static const std::string Extension = "3mf";
-
 static const aiImporterDesc desc = {
     "3mf Importer",
     "",
@@ -284,10 +429,9 @@ static const aiImporterDesc desc = {
     0,
     0,
     0,
-    Extension.c_str()
+    "3mf"
 };
 
-
 D3MFImporter::D3MFImporter()
 : BaseImporter() {
     // empty
@@ -297,14 +441,19 @@ D3MFImporter::~D3MFImporter() {
     // empty
 }
 
-bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
-    const std::string extension = GetExtension(pFile);
-    if(extension == Extension ) {
+bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const {
+    const std::string extension( GetExtension( filename ) );
+    if(extension == desc.mFileExtensions ) {
         return true;
     } else if ( !extension.length() || checkSig ) {
-        if (nullptr == pIOHandler ) {
-            return true;
+        if ( nullptr == pIOHandler ) {
+            return false;
+        }
+        if ( !D3MF::D3MFOpcPackage::isZipArchive( pIOHandler, filename ) ) {
+            return false;
         }
+        D3MF::D3MFOpcPackage opcPackage( pIOHandler, filename );
+        return opcPackage.validate();
     }
 
     return false;
@@ -318,8 +467,8 @@ const aiImporterDesc *D3MFImporter::GetInfo() const {
     return &desc;
 }
 
-void D3MFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
-    D3MF::D3MFOpcPackage opcPackage(pIOHandler, pFile);
+void D3MFImporter::InternReadFile( const std::string &filename, aiScene *pScene, IOSystem *pIOHandler ) {
+    D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
 
     std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(opcPackage.RootStream()));
     std::unique_ptr<D3MF::XmlReader> xmlReader(irr::io::createIrrXMLReader(xmlStream.get()));

+ 3 - 2
Engine/lib/assimp/code/D3MFImporter.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -42,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_D3MFLOADER_H_INCLUDED
 #define AI_D3MFLOADER_H_INCLUDED
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 
 namespace Assimp {
 

+ 44 - 33
Engine/lib/assimp/code/D3MFOpcPackage.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -42,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
 
 #include "D3MFOpcPackage.h"
-#include "Exceptional.h"
+#include <assimp/Exceptional.h>
 
 #include <assimp/IOStream.hpp>
 #include <assimp/IOSystem.hpp>
@@ -55,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <map>
 #include <algorithm>
 #include <cassert>
-#include <contrib/unzip/unzip.h>
+#include <unzip.h>
 #include "3MFXmlTags.h"
 
 namespace Assimp {
@@ -246,13 +247,13 @@ private:
 // ------------------------------------------------------------------------------------------------
 //  Constructor.
 D3MFZipArchive::D3MFZipArchive(IOSystem* pIOHandler, const std::string& rFile)
-: m_ZipFileHandle(NULL)
+: m_ZipFileHandle( nullptr )
 , m_ArchiveMap() {
     if (! rFile.empty()) {                
         zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler);            
 
         m_ZipFileHandle = unzOpen2(rFile.c_str(), &mapping);
-        if(m_ZipFileHandle != NULL) {            
+        if(m_ZipFileHandle != nullptr ) {
             mapArchive();
         }
     }
@@ -266,32 +267,32 @@ D3MFZipArchive::~D3MFZipArchive() {
     }
     m_ArchiveMap.clear();
 
-    if(m_ZipFileHandle != NULL) {
+    if(m_ZipFileHandle != nullptr) {
         unzClose(m_ZipFileHandle);
-        m_ZipFileHandle = NULL;
+        m_ZipFileHandle = nullptr;
     }
 }
 
 // ------------------------------------------------------------------------------------------------
 //  Returns true, if the archive is already open.
 bool D3MFZipArchive::isOpen() const {
-    return (m_ZipFileHandle != NULL);
+    return (m_ZipFileHandle != nullptr );
 }
 
 // ------------------------------------------------------------------------------------------------
 //  Returns true, if the filename is part of the archive.
 bool D3MFZipArchive::Exists(const char* pFile) const {
-    ai_assert(pFile != NULL);
+    ai_assert(pFile != nullptr );
 
-    bool exist = false;
-
-    if (pFile != NULL) {
-        std::string rFile(pFile);
-        std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile);
+    if ( pFile == nullptr ) {
+        return false;
+    }
 
-        if(it != m_ArchiveMap.end()) {
-            exist = true;
-        }
+    std::string filename(pFile);
+    std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(filename);
+    bool exist( false );
+    if(it != m_ArchiveMap.end()) {
+        exist = true;
     }
 
     return exist;
@@ -433,8 +434,8 @@ public:
 
     std::vector<OpcPackageRelationshipPtr> m_relationShips;
 };
-// ------------------------------------------------------------------------------------------------
 
+// ------------------------------------------------------------------------------------------------
 D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
 : mRootStream(nullptr)
 , mZipArchive() {    
@@ -459,28 +460,19 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
             if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) {
                 rootFile = rootFile.substr( 1 );
                 if ( rootFile[ 0 ] == '/' ) {
-                    // deal with zipbug
+                    // deal with zip-bug
                     rootFile = rootFile.substr( 1 );
                 }
             }
 
-            DefaultLogger::get()->debug(rootFile);
+            ASSIMP_LOG_DEBUG(rootFile);
 
             mRootStream = mZipArchive->Open(rootFile.c_str());
             ai_assert( mRootStream != nullptr );
             if ( nullptr == mRootStream ) {
-                throw DeadlyExportError( "Cannot open rootfile in archive : " + rootFile );
+                throw DeadlyExportError( "Cannot open root-file in archive : " + rootFile );
             }
 
-        //    const size_t size = zipArchive->FileSize();
-        //    m_Data.resize( size );
-
-        //    const size_t readSize = pMapFile->Read( &m_Data[0], sizeof( char ), size );
-        //    if ( readSize != size )
-        //    {
-        //        m_Data.clear();
-        //        return false;
-        //    }
             mZipArchive->Close( fileStream );
 
         } else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
@@ -497,6 +489,25 @@ IOStream* D3MFOpcPackage::RootStream() const {
     return mRootStream;
 }
 
+static const std::string ModelRef = "3D/3dmodel.model";
+
+bool D3MFOpcPackage::validate() {
+    if ( nullptr == mRootStream || nullptr == mZipArchive ) {
+        return false;
+    }
+
+    return mZipArchive->Exists( ModelRef.c_str() );
+}
+
+bool D3MFOpcPackage::isZipArchive( IOSystem* pIOHandler, const std::string& rFile ) {
+    D3MF::D3MFZipArchive ar( pIOHandler, rFile );
+    if ( !ar.isOpen() ) {
+        return false;
+    }
+
+    return true;
+}
+
 std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) {
     std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(stream));
     std::unique_ptr<XmlReader> xml(irr::io::createIrrXMLReader(xmlStream.get()));
@@ -507,14 +518,14 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) {
         return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
     });
 
-    if(itr == reader.m_relationShips.end())
-        throw DeadlyImportError("Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
+    if ( itr == reader.m_relationShips.end() ) {
+        throw DeadlyImportError( "Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE );
+    }
 
     return (*itr)->target;
 }
 
 } // Namespace D3MF
-
 } // Namespace Assimp
 
 #endif //ASSIMP_BUILD_NO_3MF_IMPORTER

+ 10 - 7
Engine/lib/assimp/code/D3MFOpcPackage.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -45,13 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <memory>
 
 #include <assimp/IOSystem.hpp>
-#include "irrXMLWrapper.h"
+#include <assimp/irrXMLWrapper.h>
 
 namespace Assimp {
 namespace D3MF {
 
-typedef irr::io::IrrXMLReader XmlReader;
-typedef std::shared_ptr<XmlReader> XmlReaderPtr;
+using XmlReader = irr::io::IrrXMLReader ;
+using XmlReaderPtr = std::shared_ptr<XmlReader> ;
 
 struct OpcPackageRelationship {
     std::string id;
@@ -63,9 +64,11 @@ class D3MFZipArchive;
 
 class D3MFOpcPackage {
 public:
-    D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile);
+    D3MFOpcPackage( IOSystem* pIOHandler, const std::string& rFile );
     ~D3MFOpcPackage();
     IOStream* RootStream() const;
+    bool validate();
+    static bool isZipArchive( IOSystem* pIOHandler, const std::string& rFile );
 
 protected:
     std::string ReadPackageRootRelationship(IOStream* stream);
@@ -75,7 +78,7 @@ private:
     std::unique_ptr<D3MFZipArchive> mZipArchive;
 };
 
-}
-}
+} // Namespace D3MF
+} // Namespace Assimp
 
 #endif // D3MFOPCPACKAGE_H

+ 28 - 42
Engine/lib/assimp/code/DXFHelper.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -46,36 +47,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_DXFHELPER_H
 #define INCLUDED_DXFHELPER_H
 
-#include "LineSplitter.h"
-#include "TinyFormatter.h"
-#include "StreamReader.h"
-#include "fast_atof.h"
+#include <assimp/LineSplitter.h>
+#include <assimp/TinyFormatter.h>
+#include <assimp/StreamReader.h>
+#include <assimp/fast_atof.h>
 #include <vector>
 #include <assimp/DefaultLogger.hpp>
 
 namespace Assimp {
-    namespace DXF {
-
+namespace DXF {
 
 // read pairs of lines, parse group code and value and provide utilities
 // to convert the data to the target data type.
-class LineReader
-{
-
+// do NOT skip empty lines. In DXF files, they count as valid data.
+class LineReader {
 public:
-
     LineReader(StreamReaderLE& reader)
-         // do NOT skip empty lines. In DXF files, they count as valid data.
-        : splitter(reader,false,true)
-        , groupcode( 0 )
-        , value()
-        , end()
-    {
+    : splitter(reader,false,true)
+    , groupcode( 0 )
+    , value()
+    , end() {
+        // empty
     }
 
-public:
-
-
     // -----------------------------------------
     bool Is(int gc, const char* what) const {
         return groupcode == gc && !strcmp(what,value.c_str());
@@ -101,8 +95,6 @@ public:
         return !((bool)*this);
     }
 
-public:
-
     // -----------------------------------------
     unsigned int ValueAsUnsignedInt() const {
         return strtoul10(value.c_str());
@@ -118,8 +110,6 @@ public:
         return fast_atof(value.c_str());
     }
 
-public:
-
     // -----------------------------------------
     /** pseudo-iterator increment to advance to the next (groupcode/value) pair */
     LineReader& operator++() {
@@ -145,7 +135,7 @@ public:
                 for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++);
 
                 splitter++;
-                DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
+                ASSIMP_LOG_DEBUG((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
             }
         } catch(std::logic_error&) {
             ai_assert(!splitter);
@@ -168,21 +158,18 @@ public:
     }
 
 private:
-
     LineSplitter splitter;
     int groupcode;
     std::string value;
     int end;
 };
 
-
-
 // represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed.
-struct PolyLine
-{
+struct PolyLine {
     PolyLine()
-        : flags()
-    {}
+    : flags() {
+        // empty
+    }
 
     std::vector<aiVector3D> positions;
     std::vector<aiColor4D>  colors;
@@ -194,14 +181,15 @@ struct PolyLine
     std::string desc;
 };
 
-
 // reference to a BLOCK. Specifies its own coordinate system.
-struct InsertBlock
-{
+struct InsertBlock {
     InsertBlock()
-        : scale(1.f,1.f,1.f)
-        , angle()
-    {}
+    : pos()
+    , scale(1.f,1.f,1.f)
+    , angle()
+    , name() {
+        // empty
+    }
 
     aiVector3D pos;
     aiVector3D scale;
@@ -228,9 +216,7 @@ struct FileData
     std::vector<Block> blocks;
 };
 
+}
+} // Namespace Assimp
 
-
-
-
-}}
 #endif

+ 126 - 127
Engine/lib/assimp/code/DXFLoader.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -48,9 +49,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
 
 #include "DXFLoader.h"
-#include "ParsingUtils.h"
+#include <assimp/ParsingUtils.h>
 #include "ConvertToLHProcess.h"
-#include "fast_atof.h"
+#include <assimp/fast_atof.h>
 
 #include "DXFHelper.h"
 #include <assimp/IOSystem.hpp>
@@ -62,16 +63,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 using namespace Assimp;
 
 // AutoCAD Binary DXF<CR><LF><SUB><NULL>
-#define AI_DXF_BINARY_IDENT ("AutoCAD Binary DXF\r\n\x1a\0")
-#define AI_DXF_BINARY_IDENT_LEN (24)
+const std::string AI_DXF_BINARY_IDENT = std::string("AutoCAD Binary DXF\r\n\x1a\0");
+const size_t AI_DXF_BINARY_IDENT_LEN = 24u;
 
 // default vertex color that all uncolored vertices will receive
-#define AI_DXF_DEFAULT_COLOR aiColor4D(0.6f,0.6f,0.6f,0.6f)
+const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
 
 // color indices for DXF - 16 are supported, the table is
 // taken directly from the DXF spec.
-static aiColor4D g_aclrDxfIndexColors[] =
-{
+static aiColor4D g_aclrDxfIndexColors[] = {
     aiColor4D (0.6f, 0.6f, 0.6f, 1.0f),
     aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
     aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
@@ -92,6 +92,10 @@ static aiColor4D g_aclrDxfIndexColors[] =
 #define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
 #define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC"
 
+static const int GroupCode_Name  = 2;
+static const int GroupCode_XComp = 10;
+static const int GroupCode_YComp = 20;
+static const int GroupCode_ZComp = 30;
 
 static const aiImporterDesc desc = {
     "Drawing Interchange Format (DXF) Importer",
@@ -109,45 +113,53 @@ static const aiImporterDesc desc = {
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 DXFImporter::DXFImporter()
-{}
+: BaseImporter() {
+    // empty
+}
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-DXFImporter::~DXFImporter()
-{}
+DXFImporter::~DXFImporter() {
+    // empty
+}
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
-bool DXFImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
-    return SimpleExtensionCheck(pFile,"dxf");
+bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool checkSig ) const {
+    const std::string& extension = GetExtension( filename );
+    if ( extension == desc.mFileExtensions ) {
+        return true;
+    }
+
+    if ( extension.empty() || checkSig ) {
+        const char *pTokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
+        return BaseImporter::SearchFileHeaderForToken(pIOHandler, filename, pTokens, 4, 32 );
+    }
+
+    return false;
 }
 
 // ------------------------------------------------------------------------------------------------
 // Get a list of all supported file extensions
-const aiImporterDesc* DXFImporter::GetInfo () const
-{
+const aiImporterDesc* DXFImporter::GetInfo () const {
     return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure.
-void DXFImporter::InternReadFile( const std::string& pFile,
-    aiScene* pScene,
-    IOSystem* pIOHandler)
-{
-    std::shared_ptr<IOStream> file = std::shared_ptr<IOStream>( pIOHandler->Open( pFile) );
+void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene, IOSystem* pIOHandler) {
+    std::shared_ptr<IOStream> file = std::shared_ptr<IOStream>( pIOHandler->Open( filename) );
 
     // Check whether we can read the file
-    if( file.get() == NULL) {
-        throw DeadlyImportError( "Failed to open DXF file " + pFile + "");
+    if( file.get() == nullptr ) {
+        throw DeadlyImportError( "Failed to open DXF file " + filename + "");
     }
 
-    // check whether this is a binaray DXF file - we can't read binary DXF files :-(
+    // Check whether this is a binary DXF file - we can't read binary DXF files :-(
     char buff[AI_DXF_BINARY_IDENT_LEN+1] = {0};
     file->Read(buff,AI_DXF_BINARY_IDENT_LEN,1);
 
-    if (!strncmp(AI_DXF_BINARY_IDENT,buff,AI_DXF_BINARY_IDENT_LEN)) {
+    if (0 == strncmp(AI_DXF_BINARY_IDENT.c_str(),buff,AI_DXF_BINARY_IDENT_LEN)) {
         throw DeadlyImportError("DXF: Binary files are not supported at the moment");
     }
 
@@ -190,7 +202,7 @@ void DXFImporter::InternReadFile( const std::string& pFile,
 
         // comments
         else if (reader.Is(999)) {
-            DefaultLogger::get()->info("DXF Comment: " + reader.Value());
+            ASSIMP_LOG_INFO_F("DXF Comment: ", reader.Value());
         }
 
         // don't read past the official EOF sign
@@ -202,7 +214,7 @@ void DXFImporter::InternReadFile( const std::string& pFile,
         ++reader;
     }
     if (!eof) {
-        DefaultLogger::get()->warn("DXF: EOF reached, but did not encounter DXF EOF marker");
+        ASSIMP_LOG_WARN("DXF: EOF reached, but did not encounter DXF EOF marker");
     }
 
     ConvertMeshes(pScene,output);
@@ -216,13 +228,11 @@ void DXFImporter::InternReadFile( const std::string& pFile,
 }
 
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output)
-{
+void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) {
     // the process of resolving all the INSERT statements can grow the
-    // polycount excessively, so log the original number.
+    // poly-count excessively, so log the original number.
     // XXX Option to import blocks as separate nodes?
     if (!DefaultLogger::isNullLogger()) {
-
         unsigned int vcount = 0, icount = 0;
         for (const DXF::Block& bl : output.blocks) {
             for (std::shared_ptr<const DXF::PolyLine> pl : bl.lines) {
@@ -231,16 +241,14 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output)
             }
         }
 
-        DefaultLogger::get()->debug((Formatter::format("DXF: Unexpanded polycount is "),
-            icount,", vertex count is ",vcount
-        ));
+        ASSIMP_LOG_DEBUG_F("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount);
     }
 
     if (! output.blocks.size()  ) {
         throw DeadlyImportError("DXF: no data blocks loaded");
     }
 
-    DXF::Block* entities = 0;
+    DXF::Block* entities( nullptr );
 
     // index blocks by name
     DXF::BlockMap blocks_by_name;
@@ -285,7 +293,7 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output)
         }
     }
 
-    if (!pScene->mNumMeshes) {
+    if ( 0 == pScene->mNumMeshes) {
         throw DeadlyImportError("DXF: this file contains no 3d data");
     }
 
@@ -358,16 +366,13 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output)
 
 
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& blocks_by_name)
-{
+void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& blocks_by_name) {
     for (const DXF::InsertBlock& insert : bl.insertions) {
 
         // first check if the referenced blocks exists ...
         const DXF::BlockMap::const_iterator it = blocks_by_name.find(insert.name);
         if (it == blocks_by_name.end()) {
-            DefaultLogger::get()->error((Formatter::format("DXF: Failed to resolve block reference: "),
-                insert.name,"; skipping"
-            ));
+            ASSIMP_LOG_ERROR_F("DXF: Failed to resolve block reference: ", insert.name,"; skipping" );
             continue;
         }
 
@@ -387,7 +392,7 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
 
                 // XXX rotation currently ignored - I didn't find an appropriate sample model.
                 if (insert.angle != 0.f) {
-                    DefaultLogger::get()->warn("DXF: BLOCK rotation not currently implemented");
+                    ASSIMP_LOG_WARN("DXF: BLOCK rotation not currently implemented");
                 }
 
                 for (aiVector3D& v : pl_out->positions) {
@@ -400,10 +405,8 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
     }
 }
 
-
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/)
-{
+void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/) {
     // generate an almost-white default material. Reason:
     // the default vertex color is GREY, so we are
     // already at Assimp's usual default color.
@@ -427,10 +430,8 @@ void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/)
     pScene->mMaterials[0] = pcMat;
 }
 
-
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/)
-{
+void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/) {
     // generate the output scene graph, which is just the root node with a single child for each layer.
     pScene->mRootNode = new aiNode();
     pScene->mRootNode->mName.Set("<DXF_ROOT>");
@@ -438,9 +439,7 @@ void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/)
     if (1 == pScene->mNumMeshes)    {
         pScene->mRootNode->mMeshes = new unsigned int[ pScene->mRootNode->mNumMeshes = 1 ];
         pScene->mRootNode->mMeshes[0] = 0;
-    }
-    else
-    {
+    } else {
         pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren = pScene->mNumMeshes ];
         for (unsigned int m = 0; m < pScene->mRootNode->mNumChildren;++m)   {
             aiNode* p = pScene->mRootNode->mChildren[m] = new aiNode();
@@ -455,22 +454,17 @@ void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/)
 
 
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::SkipSection(DXF::LineReader& reader)
-{
+void DXFImporter::SkipSection(DXF::LineReader& reader) {
     for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++);
 }
 
-
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::ParseHeader(DXF::LineReader& reader, DXF::FileData& /*output*/)
-{
+void DXFImporter::ParseHeader(DXF::LineReader& reader, DXF::FileData& ) {
     for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++);
 }
 
-
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output)
-{
+void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) {
     while( !reader.End() && !reader.Is(0,"ENDSEC")) {
         if (reader.Is(0,"BLOCK")) {
             ParseBlock(++reader,output);
@@ -479,15 +473,11 @@ void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output)
         ++reader;
     }
 
-    DefaultLogger::get()->debug((Formatter::format("DXF: got "),
-        output.blocks.size()," entries in BLOCKS"
-    ));
+    ASSIMP_LOG_DEBUG_F("DXF: got ", output.blocks.size()," entries in BLOCKS" );
 }
 
-
 // ------------------------------------------------------------------------------------------------
-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.
     output.blocks.push_back( DXF::Block() );
     DXF::Block& block = output.blocks.back();
@@ -495,17 +485,17 @@ void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output)
     while( !reader.End() && !reader.Is(0,"ENDBLK")) {
 
         switch(reader.GroupCode()) {
-            case 2:
+            case GroupCode_Name:
                 block.name = reader.Value();
                 break;
 
-            case 10:
+            case GroupCode_XComp:
                 block.base.x = reader.ValueAsFloat();
                 break;
-            case 20:
+            case GroupCode_YComp:
                 block.base.y = reader.ValueAsFloat();
                 break;
-            case 30:
+            case GroupCode_ZComp:
                 block.base.z = reader.ValueAsFloat();
                 break;
         }
@@ -517,7 +507,7 @@ void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output)
 
         // XXX is this a valid case?
         if (reader.Is(0,"INSERT")) {
-            DefaultLogger::get()->warn("DXF: INSERT within a BLOCK not currently supported; skipping");
+            ASSIMP_LOG_WARN("DXF: INSERT within a BLOCK not currently supported; skipping");
             for( ;!reader.End() && !reader.Is(0,"ENDBLK"); ++reader);
             break;
         }
@@ -531,11 +521,9 @@ void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output)
     }
 }
 
-
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
-{
-    // push a new block onto the stack.
+void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output) {
+    // Push a new block onto the stack.
     output.blocks.push_back( DXF::Block() );
     DXF::Block& block = output.blocks.back();
 
@@ -561,34 +549,29 @@ void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
         ++reader;
     }
 
-    DefaultLogger::get()->debug((Formatter::format("DXF: got "),
-        block.lines.size()," polylines and ", block.insertions.size() ," inserted blocks in ENTITIES"
-    ));
+    ASSIMP_LOG_DEBUG_F( "DXF: got ", block.lines.size()," polylines and ", block.insertions.size(), 
+        " inserted blocks in ENTITIES" );
 }
 
-
-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() );
     DXF::InsertBlock& bl = output.blocks.back().insertions.back();
 
     while( !reader.End() && !reader.Is(0)) {
-
-        switch(reader.GroupCode())
-        {
+        switch(reader.GroupCode()) {
             // name of referenced block
-        case 2:
+        case GroupCode_Name:
             bl.name = reader.Value();
             break;
 
             // translation
-        case 10:
+        case GroupCode_XComp:
             bl.pos.x = reader.ValueAsFloat();
             break;
-        case 20:
+        case GroupCode_YComp:
             bl.pos.y = reader.ValueAsFloat();
             break;
-        case 30:
+        case GroupCode_ZComp:
             bl.pos.z = reader.ValueAsFloat();
             break;
 
@@ -618,8 +601,7 @@ void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output)
 #define DXF_POLYLINE_FLAG_POLYFACEMESH  0x40
 
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
-{
+void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) {
     output.blocks.back().lines.push_back( std::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() ) );
     DXF::PolyLine& line = *output.blocks.back().lines.back();
 
@@ -672,16 +654,15 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
     //}
 
     if (vguess && line.positions.size() != vguess) {
-        DefaultLogger::get()->warn((Formatter::format("DXF: unexpected vertex count in polymesh: "),
-            line.positions.size(),", expected ", vguess
-        ));
+        ASSIMP_LOG_WARN_F("DXF: unexpected vertex count in polymesh: ",
+            line.positions.size(),", expected ", vguess );
     }
 
     if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH ) {
         if (line.positions.size() < 3 || line.indices.size() < 3)   {
-                DefaultLogger::get()->warn("DXF: not enough vertices for polymesh; ignoring");
-                output.blocks.back().lines.pop_back();
-                return;
+            ASSIMP_LOG_WARN("DXF: not enough vertices for polymesh; ignoring");
+            output.blocks.back().lines.pop_back();
+            return;
         }
 
         // if these numbers are wrong, parsing might have gone wild.
@@ -689,13 +670,11 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
         // to set the 71 and 72 fields, respectively, to valid values.
         // So just fire a warning.
         if (iguess && line.counts.size() != iguess) {
-            DefaultLogger::get()->warn((Formatter::format("DXF: unexpected face count in polymesh: "),
-                line.counts.size(),", expected ", iguess
-            ));
+            ASSIMP_LOG_WARN_F( "DXF: unexpected face count in polymesh: ", line.counts.size(),", expected ", iguess );
         }
     }
     else if (!line.indices.size() && !line.counts.size()) {
-        // a polyline - so there are no indices yet.
+        // a poly-line - so there are no indices yet.
         size_t guess = line.positions.size() + (line.flags & DXF_POLYLINE_FLAG_CLOSED ? 1 : 0);
         line.indices.reserve(guess);
 
@@ -719,8 +698,7 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
 #define DXF_VERTEX_FLAG_HAS_POSITIONS 0x40
 
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& line)
-{
+void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& line) {
     unsigned int cnti = 0, flags = 0;
     unsigned int indices[4];
 
@@ -733,14 +711,13 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
             break;
         }
 
-        switch (reader.GroupCode())
-        {
+        switch (reader.GroupCode()) {
         case 8:
                 // layer to which the vertex belongs to - assume that
-                // this is always the layer the top-level polyline
+                // this is always the layer the top-level poly-line
                 // entity resides on as well.
                 if(reader.Value() != line.layer) {
-                    DefaultLogger::get()->warn("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set");
+                    ASSIMP_LOG_WARN("DXF: expected vertex to be part of a poly-face but the 0x128 flag isn't set");
                 }
                 break;
 
@@ -749,9 +726,17 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
                 break;
 
         // VERTEX COORDINATES
-        case 10: out.x = reader.ValueAsFloat();break;
-        case 20: out.y = reader.ValueAsFloat();break;
-        case 30: out.z = reader.ValueAsFloat();break;
+        case GroupCode_XComp:
+            out.x = reader.ValueAsFloat();
+            break;
+
+        case GroupCode_YComp:
+            out.y = reader.ValueAsFloat();
+            break;
+
+        case GroupCode_ZComp:
+            out.z = reader.ValueAsFloat();
+            break;
 
         // POLYFACE vertex indices
         case 71:
@@ -759,7 +744,7 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
         case 73:
         case 74:
             if (cnti == 4) {
-                DefaultLogger::get()->warn("DXF: more than 4 indices per face not supported; ignoring");
+                ASSIMP_LOG_WARN("DXF: more than 4 indices per face not supported; ignoring");
                 break;
             }
             indices[cnti++] = reader.ValueAsUnsignedInt();
@@ -775,7 +760,7 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
     }
 
     if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH && !(flags & DXF_VERTEX_FLAG_PART_OF_POLYFACE)) {
-        DefaultLogger::get()->warn("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set");
+        ASSIMP_LOG_WARN("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set");
     }
 
     if (cnti) {
@@ -783,14 +768,17 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
         for (unsigned int i = 0; i < cnti; ++i) {
             // IMPORTANT NOTE: POLYMESH indices are ONE-BASED
             if (indices[i] == 0) {
-                DefaultLogger::get()->warn("DXF: invalid vertex index, indices are one-based.");
+                ASSIMP_LOG_WARN("DXF: invalid vertex index, indices are one-based.");
                 --line.counts.back();
+                // Workaround to fix issue 2229
+                if (line.counts.back() == 0) {
+                    line.counts.pop_back();
+                }
                 continue;
             }
             line.indices.push_back(indices[i]-1);
         }
-    }
-    else {
+    } else {
         line.positions.push_back(out);
         line.colors.push_back(clr);
     }
@@ -824,62 +812,74 @@ void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
             break;
 
         // x position of the first corner
-        case 10: vip[0].x = reader.ValueAsFloat();
+        case 10:
+            vip[0].x = reader.ValueAsFloat();
             b[2] = true;
             break;
 
         // y position of the first corner
-        case 20: vip[0].y = reader.ValueAsFloat();
+        case 20:
+            vip[0].y = reader.ValueAsFloat();
             b[2] = true;
             break;
 
         // z position of the first corner
-        case 30: vip[0].z = reader.ValueAsFloat();
+        case 30:
+            vip[0].z = reader.ValueAsFloat();
             b[2] = true;
             break;
 
         // x position of the second corner
-        case 11: vip[1].x = reader.ValueAsFloat();
+        case 11:
+            vip[1].x = reader.ValueAsFloat();
             b[3] = true;
             break;
 
         // y position of the second corner
-        case 21: vip[1].y = reader.ValueAsFloat();
+        case 21:
+            vip[1].y = reader.ValueAsFloat();
             b[3] = true;
             break;
 
         // z position of the second corner
-        case 31: vip[1].z = reader.ValueAsFloat();
+        case 31:
+            vip[1].z = reader.ValueAsFloat();
             b[3] = true;
             break;
 
         // x position of the third corner
-        case 12: vip[2].x = reader.ValueAsFloat();
+        case 12:
+            vip[2].x = reader.ValueAsFloat();
             b[0] = true;
             break;
 
         // y position of the third corner
-        case 22: vip[2].y = reader.ValueAsFloat();
+        case 22:
+            vip[2].y = reader.ValueAsFloat();
             b[0] = true;
             break;
 
         // z position of the third corner
-        case 32: vip[2].z = reader.ValueAsFloat();
+        case 32:
+            vip[2].z = reader.ValueAsFloat();
             b[0] = true;
             break;
 
         // x position of the fourth corner
-        case 13: vip[3].x = reader.ValueAsFloat();
+        case 13:
+            vip[3].x = reader.ValueAsFloat();
             b[1] = true;
             break;
 
         // y position of the fourth corner
-        case 23: vip[3].y = reader.ValueAsFloat();
+        case 23:
+            vip[3].y = reader.ValueAsFloat();
             b[1] = true;
             break;
 
         // z position of the fourth corner
-        case 33: vip[3].z = reader.ValueAsFloat();
+        case 33:
+            vip[3].z = reader.ValueAsFloat();
             b[1] = true;
             break;
 
@@ -900,7 +900,7 @@ void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
 
     // sanity checks to see if we got something meaningful
     if ((b[1] && !b[0]) || !b[2] || !b[3]) {
-        DefaultLogger::get()->warn("DXF: unexpected vertex setup in 3DFACE/LINE/FACE entity; ignoring");
+        ASSIMP_LOG_WARN("DXF: unexpected vertex setup in 3DFACE/LINE/FACE entity; ignoring");
         output.blocks.back().lines.pop_back();
         return;
     }
@@ -916,4 +916,3 @@ void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
 }
 
 #endif // !! ASSIMP_BUILD_NO_DXF_IMPORTER
-

+ 16 - 21
Engine/lib/assimp/code/DXFLoader.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -45,36 +46,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_DXFLOADER_H_INCLUDED
 #define AI_DXFLOADER_H_INCLUDED
 
-#include "BaseImporter.h"
+#include <assimp/BaseImporter.h>
 #include <map>
 
 namespace Assimp    {
-    namespace DXF {
-
-        class LineReader;
-        struct FileData;
-        struct PolyLine;
-        struct Block;
-        struct InsertBlock;
 
-        typedef std::map<std::string, const DXF::Block*> BlockMap;
-    }
+// Forward declarations
+namespace DXF {
+    class LineReader;
+    struct FileData;
+    struct PolyLine;
+    struct Block;
+    struct InsertBlock;
 
+    typedef std::map<std::string, const DXF::Block*> BlockMap;
+}
 
 // ---------------------------------------------------------------------------
-/** DXF importer implementation.
- *
-*/
-class DXFImporter : public BaseImporter
-{
+/** 
+ *  @brief  DXF importer implementation.
+ */
+class DXFImporter : public BaseImporter {
 public:
     DXFImporter();
     ~DXFImporter();
 
-
-
-public:
-
     // -------------------------------------------------------------------
     /** Returns whether the class can handle the format of the given file.
     * See BaseImporter::CanRead() for details.  */
@@ -82,7 +78,6 @@ public:
         bool checkSig) const;
 
 protected:
-
     // -------------------------------------------------------------------
     /** Return importer meta information.
      * See #BaseImporter::GetInfo for the details*/

+ 7 - 8
Engine/lib/assimp/code/DeboneProcess.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -90,7 +91,7 @@ void DeboneProcess::SetupProperties(const Importer* pImp)
 // Executes the post processing step on the given imported data.
 void DeboneProcess::Execute( aiScene* pScene)
 {
-    DefaultLogger::get()->debug("DeboneProcess begin");
+    ASSIMP_LOG_DEBUG("DeboneProcess begin");
 
     if(!pScene->mNumMeshes) {
         return;
@@ -147,9 +148,7 @@ void DeboneProcess::Execute( aiScene* pScene)
                 }
 
                 if(!DefaultLogger::isNullLogger()) {
-                    char buffer[1024];
-                    ::ai_snprintf(buffer,1024,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
-                    DefaultLogger::get()->info(buffer);
+                    ASSIMP_LOG_INFO_F("Removed %u bones. Input bones:", in - out, ". Output bones: ", out);
                 }
 
                 // and destroy the source mesh. It should be completely contained inside the new submeshes
@@ -172,7 +171,7 @@ void DeboneProcess::Execute( aiScene* pScene)
         UpdateNode( pScene->mRootNode);
     }
 
-    DefaultLogger::get()->debug("DeboneProcess end");
+    ASSIMP_LOG_DEBUG("DeboneProcess end");
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -208,7 +207,7 @@ bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
                 if(vertexBones[vid]!=cUnowned)  {
                     if(vertexBones[vid]==i) //double entry
                     {
-                        DefaultLogger::get()->warn("Encountered double entry in bone weights");
+                        ASSIMP_LOG_WARN("Encountered double entry in bone weights");
                     }
                     else //TODO: track attraction in order to break tie
                     {
@@ -280,7 +279,7 @@ void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMe
                 if(vertexBones[vid]!=cUnowned)  {
                     if(vertexBones[vid]==i) //double entry
                     {
-                        //DefaultLogger::get()->warn("Encountered double entry in bone weights");
+                        ASSIMP_LOG_WARN("Encountered double entry in bone weights");
                     }
                     else //TODO: track attraction in order to break tie
                     {

+ 2 - 1
Engine/lib/assimp/code/DeboneProcess.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 

+ 4 - 2
Engine/lib/assimp/code/DefaultIOStream.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -123,7 +124,8 @@ size_t DefaultIOStream::FileSize() const
         // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
 #if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
         struct __stat64 fileStat;
-        int err = _stat64(  mFilename.c_str(), &fileStat );
+        //using fileno + fstat avoids having to handle the filename
+        int err = _fstat64(  _fileno(mFile), &fileStat );
         if (0 != err)
             return 0;
         mCachedSize = (size_t) (fileStat.st_size);

+ 91 - 33
Engine/lib/assimp/code/DefaultIOSystem.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -41,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 /** @file Default implementation of IOSystem using the standard C file functions */
 
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
 
 #include <assimp/DefaultIOSystem.h>
 #include <assimp/DefaultIOStream.h>
@@ -54,31 +55,53 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <stdlib.h>
 #endif
 
-using namespace Assimp;
+#ifdef _WIN32
+#include <windows.h>
+#endif
 
-// ------------------------------------------------------------------------------------------------
-// Constructor.
-DefaultIOSystem::DefaultIOSystem()
-{
-    // nothing to do here
-}
+using namespace Assimp;
 
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-DefaultIOSystem::~DefaultIOSystem()
-{
-    // nothing to do here
-}
+// maximum path length
+// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
+#ifdef PATH_MAX
+#   define PATHLIMIT PATH_MAX
+#else
+#   define PATHLIMIT 4096
+#endif
 
 // ------------------------------------------------------------------------------------------------
 // Tests for the existence of a file at the given path.
 bool DefaultIOSystem::Exists( const char* pFile) const
 {
+#ifdef _WIN32
+    wchar_t fileName16[PATHLIMIT];
+
+#ifndef WindowsStore
+    bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
+    if (isUnicode) {
+
+        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
+        struct __stat64 filestat;
+        if (0 != _wstat64(fileName16, &filestat)) {
+            return false;
+        }
+    } else {
+#endif
+        FILE* file = ::fopen(pFile, "rb");
+        if (!file)
+            return false;
+
+        ::fclose(file);
+#ifndef WindowsStore
+    }
+#endif
+#else
     FILE* file = ::fopen( pFile, "rb");
     if( !file)
         return false;
 
     ::fclose( file);
+#endif
     return true;
 }
 
@@ -88,10 +111,26 @@ IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
 {
     ai_assert(NULL != strFile);
     ai_assert(NULL != strMode);
-
-    FILE* file = ::fopen( strFile, strMode);
-    if( NULL == file)
-        return NULL;
+    FILE* file;
+#ifdef _WIN32
+    wchar_t fileName16[PATHLIMIT];
+#ifndef WindowsStore
+    bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
+    if (isUnicode) {
+        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
+        std::string mode8(strMode);
+        file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str());
+    } else {
+#endif
+        file = ::fopen(strFile, strMode);
+#ifndef WindowsStore
+    }
+#endif
+#else
+    file = ::fopen(strFile, strMode);
+#endif
+    if (nullptr == file)
+        return nullptr;
 
     return new DefaultIOStream(file, (std::string) strFile);
 }
@@ -121,32 +160,51 @@ bool IOSystem::ComparePaths (const char* one, const char* second) const
     return !ASSIMP_stricmp(one,second);
 }
 
-// maximum path length
-// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
-#ifdef PATH_MAX
-#   define PATHLIMIT PATH_MAX
-#else
-#   define PATHLIMIT 4096
-#endif
-
 // ------------------------------------------------------------------------------------------------
 // Convert a relative path into an absolute path
-inline void MakeAbsolutePath (const char* in, char* _out)
+inline static void MakeAbsolutePath (const char* in, char* _out)
 {
     ai_assert(in && _out);
-    char* ret;
 #if defined( _MSC_VER ) || defined( __MINGW32__ )
-    ret = ::_fullpath( _out, in, PATHLIMIT );
+#ifndef WindowsStore
+    bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0;
+    if (isUnicode) {
+        wchar_t out16[PATHLIMIT];
+        wchar_t in16[PATHLIMIT];
+        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT);
+        wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT);
+        if (ret) {
+            WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr);
+        }
+        if (!ret) {
+            // preserve the input path, maybe someone else is able to fix
+            // the path before it is accessed (e.g. our file system filter)
+            ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
+            strcpy(_out, in);
+        }
+
+    } else {
+#endif
+        char* ret = :: _fullpath(_out, in, PATHLIMIT);
+        if (!ret) {
+            // preserve the input path, maybe someone else is able to fix
+            // the path before it is accessed (e.g. our file system filter)
+            ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
+            strcpy(_out, in);
+        }
+#ifndef WindowsStore
+    }
+#endif
 #else
     // use realpath
-    ret = realpath(in, _out);
-#endif
+    char* ret = realpath(in, _out);
     if(!ret) {
         // preserve the input path, maybe someone else is able to fix
         // the path before it is accessed (e.g. our file system filter)
-        DefaultLogger::get()->warn("Invalid path: "+std::string(in));
+        ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
         strcpy(_out,in);
     }
+#endif
 }
 
 // ------------------------------------------------------------------------------------------------

+ 59 - 70
Engine/lib/assimp/code/DefaultLogger.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -44,12 +45,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *  @brief Implementation of DefaultLogger (and Logger)
  */
 
-
 // Default log streams
 #include "Win32DebugLogStream.h"
 #include "StdOStreamLogStream.h"
 #include "FileLogStream.h"
-#include "StringUtils.h"
+#include <assimp/StringUtils.h>
 
 #include <assimp/DefaultIOSystem.h>
 #include <assimp/NullLogger.hpp>
@@ -61,8 +61,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_SINGLETHREADED
 #   include <thread>
 #   include <mutex>
-
-std::mutex loggerMutex;
+    std::mutex loggerMutex;
 #endif
 
 namespace Assimp    {
@@ -75,22 +74,19 @@ static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::War
 
 // ----------------------------------------------------------------------------------
 // Represents a log-stream + its error severity
-struct LogStreamInfo
-{
-    unsigned int m_uiErrorSeverity;
-    LogStream *m_pStream;
+struct LogStreamInfo {
+    unsigned int  m_uiErrorSeverity;
+    LogStream    *m_pStream;
 
     // Constructor
     LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) :
         m_uiErrorSeverity( uiErrorSev ),
-        m_pStream( pStream )
-    {
+        m_pStream( pStream ) {
         // empty
     }
 
     // Destructor
-    ~LogStreamInfo()
-    {
+    ~LogStreamInfo() {
         delete m_pStream;
     }
 };
@@ -108,7 +104,7 @@ LogStream* LogStream::createDefaultStream(aiDefaultLogStream    streams,
 #ifdef WIN32
         return new Win32DebugLogStream();
 #else
-        return NULL;
+        return nullptr;
 #endif
 
         // Platform-independent default streams
@@ -117,7 +113,7 @@ LogStream* LogStream::createDefaultStream(aiDefaultLogStream    streams,
     case aiDefaultLogStream_STDOUT:
         return new StdOStreamLogStream(std::cout);
     case aiDefaultLogStream_FILE:
-        return (name && *name ? new FileLogStream(name,io) : NULL);
+        return (name && *name ? new FileLogStream(name,io) : nullptr );
     default:
         // We don't know this default log stream, so raise an assertion
         ai_assert(false);
@@ -133,34 +129,38 @@ LogStream* LogStream::createDefaultStream(aiDefaultLogStream    streams,
 Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
     LogSeverity severity                       /*= NORMAL*/,
     unsigned int defStreams                    /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
-    IOSystem* io                               /*= NULL*/)
-{
+    IOSystem* io                               /*= NULL*/) {
     // enter the mutex here to avoid concurrency problems
 #ifndef ASSIMP_BUILD_SINGLETHREADED
     std::lock_guard<std::mutex> lock(loggerMutex);
 #endif
 
-    if (m_pLogger && !isNullLogger() )
+    if ( m_pLogger && !isNullLogger() ) {
         delete m_pLogger;
+    }
 
     m_pLogger = new DefaultLogger( severity );
 
     // Attach default log streams
     // Stream the log to the MSVC debugger?
-    if (defStreams & aiDefaultLogStream_DEBUGGER)
-        m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));
+    if ( defStreams & aiDefaultLogStream_DEBUGGER ) {
+        m_pLogger->attachStream( LogStream::createDefaultStream( aiDefaultLogStream_DEBUGGER ) );
+    }
 
     // Stream the log to COUT?
-    if (defStreams & aiDefaultLogStream_STDOUT)
-        m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));
+    if ( defStreams & aiDefaultLogStream_STDOUT ) {
+        m_pLogger->attachStream( LogStream::createDefaultStream( aiDefaultLogStream_STDOUT ) );
+    }
 
     // Stream the log to CERR?
-    if (defStreams & aiDefaultLogStream_STDERR)
-         m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));
+    if ( defStreams & aiDefaultLogStream_STDERR ) {
+        m_pLogger->attachStream( LogStream::createDefaultStream( aiDefaultLogStream_STDERR ) );
+    }
 
     // Stream the log to a file
-    if (defStreams & aiDefaultLogStream_FILE && name && *name)
-        m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));
+    if ( defStreams & aiDefaultLogStream_FILE && name && *name ) {
+        m_pLogger->attachStream( LogStream::createDefaultStream( aiDefaultLogStream_FILE, name, io ) );
+    }
 
     return m_pLogger;
 }
@@ -199,7 +199,6 @@ void Logger::warn(const char* message)  {
 
 // ----------------------------------------------------------------------------------
 void Logger::error(const char* message) {
-
     // SECURITY FIX: see above
     if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
         return;
@@ -208,23 +207,24 @@ void Logger::error(const char* message) {
 }
 
 // ----------------------------------------------------------------------------------
-void DefaultLogger::set( Logger *logger )
-{
+void DefaultLogger::set( Logger *logger ) {
     // enter the mutex here to avoid concurrency problems
 #ifndef ASSIMP_BUILD_SINGLETHREADED
     std::lock_guard<std::mutex> lock(loggerMutex);
 #endif
 
-    if (!logger)logger = &s_pNullLogger;
-    if (m_pLogger && !isNullLogger() )
+    if ( nullptr == logger ) {
+        logger = &s_pNullLogger;
+    }
+    if ( nullptr != m_pLogger && !isNullLogger() ) {
         delete m_pLogger;
+    }
 
     DefaultLogger::m_pLogger = logger;
 }
 
 // ----------------------------------------------------------------------------------
-bool DefaultLogger::isNullLogger()
-{
+bool DefaultLogger::isNullLogger() {
     return m_pLogger == &s_pNullLogger;
 }
 
@@ -235,8 +235,7 @@ Logger *DefaultLogger::get() {
 
 // ----------------------------------------------------------------------------------
 //  Kills the only instance
-void DefaultLogger::kill()
-{
+void DefaultLogger::kill() {
     // enter the mutex here to avoid concurrency problems
 #ifndef ASSIMP_BUILD_SINGLETHREADED
     std::lock_guard<std::mutex> lock(loggerMutex);
@@ -251,10 +250,10 @@ void DefaultLogger::kill()
 
 // ----------------------------------------------------------------------------------
 //  Debug message
-void DefaultLogger::OnDebug( const char* message )
-{
-	if ( m_Severity == Logger::NORMAL )
-		return;
+void DefaultLogger::OnDebug( const char* message ) {
+    if ( m_Severity == Logger::NORMAL ) {
+        return;
+    }
 
 	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
 	char msg[Size];
@@ -265,8 +264,7 @@ void DefaultLogger::OnDebug( const char* message )
 
 // ----------------------------------------------------------------------------------
 //  Logs an info
-void DefaultLogger::OnInfo( const char* message )
-{
+void DefaultLogger::OnInfo( const char* message ){
 	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
 	char msg[Size];
     ai_snprintf(msg, Size, "Info,  T%u: %s", GetThreadID(), message );
@@ -276,8 +274,7 @@ void DefaultLogger::OnInfo( const char* message )
 
 // ----------------------------------------------------------------------------------
 //  Logs a warning
-void DefaultLogger::OnWarn( const char* message )
-{
+void DefaultLogger::OnWarn( const char* message ) {
 	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
 	char msg[Size];
 	ai_snprintf(msg, Size, "Warn,  T%u: %s", GetThreadID(), message );
@@ -287,8 +284,7 @@ void DefaultLogger::OnWarn( const char* message )
 
 // ----------------------------------------------------------------------------------
 //  Logs an error
-void DefaultLogger::OnError( const char* message )
-{
+void DefaultLogger::OnError( const char* message ) {
 	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
 	char msg[ Size ];
     ai_snprintf(msg, Size, "Error, T%u: %s", GetThreadID(), message );
@@ -298,10 +294,10 @@ void DefaultLogger::OnError( const char* message )
 
 // ----------------------------------------------------------------------------------
 //  Will attach a new stream
-bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
-{
-    if (!pStream)
+bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity ) {
+    if ( nullptr == pStream ) {
         return false;
+    }
 
     if (0 == severity)  {
         severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
@@ -311,8 +307,7 @@ bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
         it != m_StreamArray.end();
         ++it )
     {
-        if ( (*it)->m_pStream == pStream )
-        {
+        if ( (*it)->m_pStream == pStream ) {
             (*it)->m_uiErrorSeverity |= severity;
             return true;
         }
@@ -325,34 +320,31 @@ bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
 
 // ----------------------------------------------------------------------------------
 //  Detach a stream
-bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
-{
-    if (!pStream)
+bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity ) {
+    if ( nullptr == pStream ) {
         return false;
+    }
 
     if (0 == severity)  {
         severity = SeverityAll;
     }
 
-    for ( StreamIt it = m_StreamArray.begin();
-        it != m_StreamArray.end();
-        ++it )
-    {
-        if ( (*it)->m_pStream == pStream )
-        {
+    bool res( false );
+    for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
+        if ( (*it)->m_pStream == pStream ) {
             (*it)->m_uiErrorSeverity &= ~severity;
-            if ( (*it)->m_uiErrorSeverity == 0 )
-            {
+            if ( (*it)->m_uiErrorSeverity == 0 ) {
                 // don't delete the underlying stream 'cause the caller gains ownership again
-                (**it).m_pStream = NULL;
+                (**it).m_pStream = nullptr;
                 delete *it;
                 m_StreamArray.erase( it );
+                res = true;
                 break;
             }
             return true;
         }
     }
-    return false;
+    return res;
 }
 
 // ----------------------------------------------------------------------------------
@@ -360,15 +352,13 @@ bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
 DefaultLogger::DefaultLogger(LogSeverity severity)
     :   Logger  ( severity )
     ,   noRepeatMsg (false)
-    ,   lastLen( 0 )
-{
+    ,   lastLen( 0 ) {
     lastMsg[0] = '\0';
 }
 
 // ----------------------------------------------------------------------------------
 //  Destructor
-DefaultLogger::~DefaultLogger()
-{
+DefaultLogger::~DefaultLogger() {
     for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
         // also frees the underlying stream, we are its owner.
         delete *it;
@@ -377,9 +367,8 @@ DefaultLogger::~DefaultLogger()
 
 // ----------------------------------------------------------------------------------
 //  Writes message to stream
-void DefaultLogger::WriteToStreams(const char *message, ErrorSeverity ErrorSev )
-{
-    ai_assert(NULL != message);
+void DefaultLogger::WriteToStreams(const char *message, ErrorSeverity ErrorSev ) {
+    ai_assert(nullptr != message);
 
     // Check whether this is a repeated message
     if (! ::strncmp( message,lastMsg, lastLen-1))

+ 3 - 4
Engine/lib/assimp/code/DefaultProgressHandler.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -51,9 +52,7 @@ namespace Assimp    {
 
 // ------------------------------------------------------------------------------------
 /** @brief Internal default implementation of the #ProgressHandler interface. */
-class DefaultProgressHandler
-    : public ProgressHandler    {
-
+class DefaultProgressHandler : public ProgressHandler    {
 
     virtual bool Update(float /*percentage*/) {
         return false;

+ 109 - 0
Engine/lib/assimp/code/DropFaceNormalsProcess.cpp

@@ -0,0 +1,109 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file Implementation of the post processing step to drop face
+* normals for all imported faces.
+*/
+
+
+#include "DropFaceNormalsProcess.h"
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/Exceptional.h>
+
+using namespace Assimp;
+
+// ------------------------------------------------------------------------------------------------
+// Constructor to be privately used by Importer
+DropFaceNormalsProcess::DropFaceNormalsProcess()
+{
+    // nothing to do here
+}
+
+// ------------------------------------------------------------------------------------------------
+// Destructor, private as well
+DropFaceNormalsProcess::~DropFaceNormalsProcess()
+{
+    // nothing to do here
+}
+
+// ------------------------------------------------------------------------------------------------
+// Returns whether the processing step is present in the given flag field.
+bool DropFaceNormalsProcess::IsActive( unsigned int pFlags) const {
+    return  (pFlags & aiProcess_DropNormals) != 0;
+}
+
+// ------------------------------------------------------------------------------------------------
+// Executes the post processing step on the given imported data.
+void DropFaceNormalsProcess::Execute( aiScene* pScene) {
+    ASSIMP_LOG_DEBUG("DropFaceNormalsProcess begin");
+
+    if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
+        throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
+    }
+
+    bool bHas = false;
+    for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
+        bHas |= this->DropMeshFaceNormals( pScene->mMeshes[a]);
+    }
+    if (bHas)   {
+        ASSIMP_LOG_INFO("DropFaceNormalsProcess finished. "
+            "Face normals have been removed");
+    } else {
+        ASSIMP_LOG_DEBUG("DropFaceNormalsProcess finished. "
+            "No normals were present");
+    }
+}
+
+// ------------------------------------------------------------------------------------------------
+// Executes the post processing step on the given imported data.
+bool DropFaceNormalsProcess::DropMeshFaceNormals (aiMesh* pMesh) {
+    if (NULL == pMesh->mNormals) {
+        return false;
+    }
+    
+    delete[] pMesh->mNormals;
+    pMesh->mNormals = nullptr;
+    return true;
+}

+ 33 - 57
Engine/lib/assimp/code/StepExporter.h → Engine/lib/assimp/code/DropFaceNormalsProcess.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -36,75 +37,50 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-@author: Richard Steffen, 2014
-
 ----------------------------------------------------------------------
 */
 
-/** @file StepExporter.h
- * Declares the exporter class to write a scene to a Collada file
- */
-#ifndef AI_STEPEXPORTER_H_INC
-#define AI_STEPEXPORTER_H_INC
-
-#include <assimp/ai_assert.h>
-#include <assimp/matrix4x4.h>
-#include <assimp/Exporter.hpp>
-#include <sstream>
-
+/** @file Defines a post processing step to compute face normals for all loaded faces*/
+#ifndef AI_DROPFACENORMALPROCESS_H_INC
+#define AI_DROPFACENORMALPROCESS_H_INC
 
-struct aiScene;
-struct aiNode;
+#include "BaseProcess.h"
+#include <assimp/mesh.h>
 
 namespace Assimp
 {
 
-/// Helper class to export a given scene to a StepFile.
-/// Note: an StepFile uses a left hand system. Assimp used a right hand system (OpenGL), therefore we have to transform everything
-class StepExporter
+// ---------------------------------------------------------------------------
+/** The DropFaceNormalsProcess computes face normals for all faces of all meshes
+*/
+class ASSIMP_API_WINONLY DropFaceNormalsProcess : public BaseProcess
 {
 public:
-    /// Constructor for a specific scene to export
-    StepExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties);
 
-protected:
-    /// Starts writing the contents
-    void WriteFile();
+    DropFaceNormalsProcess();
+    ~DropFaceNormalsProcess();
 
 public:
-
-    /// Stringstream to write all output into
-    std::stringstream mOutput;
-
-protected:
-
-    /// hold the properties pointer
-    const ExportProperties* mProperties;
-
-    /// The IOSystem for output
-    IOSystem* mIOSystem;
-
-    /// Name of the file (without extension) where the scene will be exported
-    std::string mFile;
-
-    /// Path of the directory where the scene will be exported
-    std::string mPath;
-
-    /// The scene to be written
-    const aiScene* mScene;
-
-    /// current line end string for simple stream insertion
-    std::string endstr;
-
-    /// accumultated transformations for nodes
-    std::map<const aiNode*, aiMatrix4x4> trafos;
-
-    /// map to all meshed of nodes
-    typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
-    MeshesByNodeMap meshes;
-
+    // -------------------------------------------------------------------
+    /** Returns whether the processing step is present in the given flag field.
+    * @param pFlags The processing flags the importer was called with. A bitwise
+    *   combination of #aiPostProcessSteps.
+    * @return true if the process is present in this flag fields, false if not.
+    */
+    bool IsActive( unsigned int pFlags) const;
+
+    // -------------------------------------------------------------------
+    /** Executes the post processing step on the given imported data.
+    * At the moment a process is not supposed to fail.
+    * @param pScene The imported data to work at.
+    */
+    void Execute( aiScene* pScene);
+
+
+private:
+    bool DropMeshFaceNormals(aiMesh* pcMesh);
 };
 
-}
+} // end of namespace Assimp
 
-#endif // !! AI_STEPEXPORTER_H_INC
+#endif // !!AI_DROPFACENORMALPROCESS_H_INC

+ 152 - 0
Engine/lib/assimp/code/EmbedTexturesProcess.cpp

@@ -0,0 +1,152 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+#include "EmbedTexturesProcess.h"
+#include <assimp/ParsingUtils.h>
+#include "ProcessHelper.h"
+
+#include <fstream>
+
+using namespace Assimp;
+
+EmbedTexturesProcess::EmbedTexturesProcess()
+: BaseProcess() {
+}
+
+EmbedTexturesProcess::~EmbedTexturesProcess() {
+}
+
+bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const {
+    return (pFlags & aiProcess_EmbedTextures) != 0;
+}
+
+void EmbedTexturesProcess::SetupProperties(const Importer* pImp) {
+    mRootPath = pImp->GetPropertyString("sourceFilePath");
+    mRootPath = mRootPath.substr(0, mRootPath.find_last_of("\\/") + 1u);
+}
+
+void EmbedTexturesProcess::Execute(aiScene* pScene) {
+    if (pScene == nullptr || pScene->mRootNode == nullptr) return;
+
+    aiString path;
+
+    uint32_t embeddedTexturesCount = 0u;
+
+    for (auto matId = 0u; matId < pScene->mNumMaterials; ++matId) {
+        auto material = pScene->mMaterials[matId];
+
+        for (auto ttId = 1u; ttId < AI_TEXTURE_TYPE_MAX; ++ttId) {
+            auto tt = static_cast<aiTextureType>(ttId);
+            auto texturesCount = material->GetTextureCount(tt);
+
+            for (auto texId = 0u; texId < texturesCount; ++texId) {
+                material->GetTexture(tt, texId, &path);
+                if (path.data[0] == '*') continue; // Already embedded
+
+                // Indeed embed
+                if (addTexture(pScene, path.data)) {
+                    auto embeddedTextureId = pScene->mNumTextures - 1u;
+                    ::ai_snprintf(path.data, 1024, "*%u", embeddedTextureId);
+                    material->AddProperty(&path, AI_MATKEY_TEXTURE(tt, texId));
+                    embeddedTexturesCount++;
+                }
+            }
+        }
+    }
+
+    ASSIMP_LOG_INFO_F("EmbedTexturesProcess finished. Embedded ", embeddedTexturesCount, " textures." );
+}
+
+bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
+    std::streampos imageSize = 0;
+    std::string    imagePath = path;
+
+    // Test path directly
+    std::ifstream file(imagePath, std::ios::binary | std::ios::ate);
+    if ((imageSize = file.tellg()) == std::streampos(-1)) {
+        ASSIMP_LOG_WARN_F("EmbedTexturesProcess: Cannot find image: ", imagePath, ". Will try to find it in root folder.");
+
+        // Test path in root path
+        imagePath = mRootPath + path;
+        file.open(imagePath, std::ios::binary | std::ios::ate);
+        if ((imageSize = file.tellg()) == std::streampos(-1)) {
+            // Test path basename in root path
+            imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u);
+            file.open(imagePath, std::ios::binary | std::ios::ate);
+            if ((imageSize = file.tellg()) == std::streampos(-1)) {
+                ASSIMP_LOG_ERROR_F("EmbedTexturesProcess: Unable to embed texture: ", path, ".");
+                return false;
+            }
+        }
+    }
+
+    aiTexel* imageContent = new aiTexel[ 1ul + static_cast<unsigned long>( imageSize ) / sizeof(aiTexel)];
+    file.seekg(0, std::ios::beg);
+    file.read(reinterpret_cast<char*>(imageContent), imageSize);
+
+    // Enlarging the textures table
+    unsigned int textureId = pScene->mNumTextures++;
+    auto oldTextures = pScene->mTextures;
+    pScene->mTextures = new aiTexture*[pScene->mNumTextures];
+    ::memmove(pScene->mTextures, oldTextures, sizeof(aiTexture*) * (pScene->mNumTextures - 1u));
+
+    // Add the new texture
+    auto pTexture = new aiTexture;
+    pTexture->mHeight = 0; // Means that this is still compressed
+    pTexture->mWidth = static_cast<uint32_t>(imageSize);
+    pTexture->pcData = imageContent;
+
+    auto extension = path.substr(path.find_last_of('.') + 1u);
+    std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
+    if (extension == "jpeg") {
+        extension = "jpg";
+    }
+
+    size_t len = extension.size();
+    if (len > HINTMAXTEXTURELEN -1 ) {
+        len = HINTMAXTEXTURELEN - 1;
+    }
+    ::strncpy(pTexture->achFormatHint, extension.c_str(), len);
+    pScene->mTextures[textureId] = pTexture;
+
+    return true;
+}

+ 85 - 0
Engine/lib/assimp/code/EmbedTexturesProcess.h

@@ -0,0 +1,85 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+#pragma once
+
+#include "BaseProcess.h"
+
+#include <string>
+
+struct aiNode;
+
+namespace Assimp {
+
+/**
+ *  Force embedding of textures (using the path = "*1" convention).
+ *  If a texture's file does not exist at the specified path
+ *  (due, for instance, to an absolute path generated on another system),
+ *  it will check if a file with the same name exists at the root folder
+ *  of the imported model. And if so, it uses that.
+ */
+class ASSIMP_API EmbedTexturesProcess : public BaseProcess {
+public:
+    /// The default class constructor.
+    EmbedTexturesProcess();
+
+    /// The class destructor.
+    virtual ~EmbedTexturesProcess();
+
+    /// Overwritten, @see BaseProcess
+    virtual bool IsActive(unsigned int pFlags) const;
+
+    /// Overwritten, @see BaseProcess
+    virtual void SetupProperties(const Importer* pImp);
+
+    /// Overwritten, @see BaseProcess
+    virtual void Execute(aiScene* pScene);
+
+private:
+    // Resolve the path and add the file content to the scene as a texture.
+    bool addTexture(aiScene* pScene, std::string path) const;
+
+private:
+    std::string mRootPath;
+};
+
+} // namespace Assimp

+ 107 - 61
Engine/lib/assimp/code/Exporter.cpp

@@ -3,7 +3,8 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 
 All rights reserved.
@@ -53,23 +54,24 @@ Here we implement only the C++ interface (Assimp::Exporter).
 
 #ifndef ASSIMP_BUILD_NO_EXPORT
 
-#include "BlobIOSystem.h"
+#include <assimp/BlobIOSystem.h>
 #include <assimp/SceneCombiner.h>
-#include "BaseProcess.h"
-#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
+#include <assimp/DefaultIOSystem.h>
+#include <assimp/Exporter.hpp>
+#include <assimp/mesh.h>
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
 
+#include "DefaultProgressHandler.h"
+#include "BaseProcess.h"
 #include "JoinVerticesProcess.h"
 #include "MakeVerboseFormat.h"
 #include "ConvertToLHProcess.h"
-#include "Exceptional.h"
+#include "PretransformVertices.h"
+#include <assimp/Exceptional.h>
 #include "ScenePrivate.h"
-#include <memory>
 
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/Exporter.hpp>
-#include <assimp/mesh.h>
-#include <assimp/postprocess.h>
-#include <assimp/scene.h>
+#include <memory>
 
 namespace Assimp {
 
@@ -92,9 +94,12 @@ void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperti
 void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneGLTF2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneGLB2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
 
 // ------------------------------------------------------------------------------------------------
@@ -145,12 +150,14 @@ Exporter::ExportFormatEntry gExporters[] =
 #endif
 
 #ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
+    Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2,
+        aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
+    Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb", &ExportSceneGLB2,
+        aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
     Exporter::ExportFormatEntry( "gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF,
         aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
     Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
         aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
-    Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf2", &ExportSceneGLTF2,
-        aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
 #endif
 
 #ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
@@ -165,7 +172,12 @@ Exporter::ExportFormatEntry gExporters[] =
     Exporter::ExportFormatEntry( "x3d", "Extensible 3D", "x3d" , &ExportSceneX3D, 0 ),
 #endif
 
-#ifndef ASSIMP_BUILD_NO3MF_EXPORTER
+#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
+    Exporter::ExportFormatEntry( "fbx", "Autodesk FBX (binary)", "fbx", &ExportSceneFBX, 0 ),
+    Exporter::ExportFormatEntry( "fbxa", "Autodesk FBX (ascii)", "fbx", &ExportSceneFBXA, 0 ),
+#endif
+
+#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
     Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 )
 #endif
 };
@@ -176,10 +188,14 @@ Exporter::ExportFormatEntry gExporters[] =
 class ExporterPimpl {
 public:
     ExporterPimpl()
-        : blob()
-        , mIOSystem(new Assimp::DefaultIOSystem())
-        , mIsDefaultIOHandler(true)
-    {
+    : blob()
+    , mIOSystem(new Assimp::DefaultIOSystem())
+    , mIsDefaultIOHandler(true)
+    , mProgressHandler( nullptr )
+    , mIsDefaultProgressHandler( true )
+    , mPostProcessingSteps()
+    , mError()
+    , mExporters() {
         GetPostProcessingStepInstanceList(mPostProcessingSteps);
 
         // grab all built-in exporters
@@ -189,14 +205,14 @@ public:
         }
     }
 
-    ~ExporterPimpl()
-    {
+    ~ExporterPimpl() {
         delete blob;
 
         // Delete all post-processing plug-ins
         for( unsigned int a = 0; a < mPostProcessingSteps.size(); a++) {
             delete mPostProcessingSteps[a];
         }
+        delete mProgressHandler;
     }
 
 public:
@@ -204,6 +220,10 @@ public:
     std::shared_ptr< Assimp::IOSystem > mIOSystem;
     bool mIsDefaultIOHandler;
 
+    /** The progress handler */
+    ProgressHandler *mProgressHandler;
+    bool mIsDefaultProgressHandler;
+
     /** Post processing steps we can apply at the imported data. */
     std::vector< BaseProcess* > mPostProcessingSteps;
 
@@ -221,13 +241,12 @@ using namespace Assimp;
 // ------------------------------------------------------------------------------------------------
 Exporter :: Exporter()
 : pimpl(new ExporterPimpl()) {
-    // empty
+    pimpl->mProgressHandler = new DefaultProgressHandler();
 }
 
 // ------------------------------------------------------------------------------------------------
 Exporter::~Exporter() {
     FreeBlob();
-
     delete pimpl;
 }
 
@@ -247,12 +266,32 @@ bool Exporter::IsDefaultIOHandler() const {
     return pimpl->mIsDefaultIOHandler;
 }
 
+// ------------------------------------------------------------------------------------------------
+void Exporter::SetProgressHandler(ProgressHandler* pHandler) {
+    ai_assert(nullptr != pimpl);
+
+    if ( nullptr == pHandler) {
+        // Release pointer in the possession of the caller
+        pimpl->mProgressHandler = new DefaultProgressHandler();
+        pimpl->mIsDefaultProgressHandler = true;
+        return;
+    }
+
+    if (pimpl->mProgressHandler == pHandler) {
+        return;
+    }
+
+    delete pimpl->mProgressHandler;
+    pimpl->mProgressHandler = pHandler;
+    pimpl->mIsDefaultProgressHandler = false;
+}
+
 // ------------------------------------------------------------------------------------------------
 const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
                                                 unsigned int, const ExportProperties* /*pProperties*/ ) {
     if (pimpl->blob) {
         delete pimpl->blob;
-        pimpl->blob = NULL;
+        pimpl->blob = nullptr;
     }
 
     std::shared_ptr<IOSystem> old = pimpl->mIOSystem;
@@ -261,7 +300,7 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
 
     if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
         pimpl->mIOSystem = old;
-        return NULL;
+        return nullptr;
     }
 
     pimpl->blob = blobio->GetBlobChain();
@@ -283,6 +322,7 @@ bool IsVerboseFormat(const aiMesh* mesh) {
             }
         }
     }
+
     return true;
 }
 
@@ -293,11 +333,13 @@ bool IsVerboseFormat(const aiScene* pScene) {
             return false;
         }
     }
+
     return true;
 }
 
 // ------------------------------------------------------------------------------------------------
-aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties) {
+aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
+        unsigned int pPreprocessing, const ExportProperties* pProperties) {
     ASSIMP_BEGIN_EXCEPTION_REGION();
 
     // when they create scenes from scratch, users will likely create them not in verbose
@@ -306,6 +348,8 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
     // meshes upfront.
     const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
 
+    pimpl->mProgressHandler->UpdateFileWrite(0, 4);
+
     pimpl->mError = "";
     for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
         const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i];
@@ -313,9 +357,11 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
             try {
                 // Always create a full copy of the scene. We might optimize this one day,
                 // but for now it is the most pragmatic way.
-                aiScene* scenecopy_tmp = NULL;
+                aiScene* scenecopy_tmp = nullptr;
                 SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
 
+                pimpl->mProgressHandler->UpdateFileWrite(1, 4);
+
                 std::unique_ptr<aiScene> scenecopy(scenecopy_tmp);
                 const ScenePrivateData* const priv = ScenePriv(pScene);
 
@@ -351,7 +397,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
                     }
 
                     if (verbosify || (exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
-                        DefaultLogger::get()->debug("export: Scene data not in verbose format, applying MakeVerboseFormat step first");
+                        ASSIMP_LOG_DEBUG("export: Scene data not in verbose format, applying MakeVerboseFormat step first");
 
                         MakeVerboseFormatProcess proc;
                         proc.Execute(scenecopy.get());
@@ -362,6 +408,8 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
                     }
                 }
 
+                pimpl->mProgressHandler->UpdateFileWrite(2, 4);
+
                 if (pp) {
                     // the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout
                     {
@@ -385,6 +433,11 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
                         }
                     }
 
+                    bool exportPointCloud(false);
+                    if (nullptr != pProperties) {
+                        exportPointCloud = pProperties->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS);
+                    }
+
                     // dispatch other processes
                     for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
                         BaseProcess* const p = pimpl->mPostProcessingSteps[a];
@@ -393,16 +446,20 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
                             && !dynamic_cast<FlipUVsProcess*>(p)
                             && !dynamic_cast<FlipWindingOrderProcess*>(p)
                             && !dynamic_cast<MakeLeftHandedProcess*>(p)) {
-
+                            if (dynamic_cast<PretransformVertices*>(p) && exportPointCloud) {
+                                continue;
+                            }
                             p->Execute(scenecopy.get());
                         }
                     }
                     ScenePrivateData* const privOut = ScenePriv(scenecopy.get());
-                    ai_assert(privOut);
+                    ai_assert(nullptr != privOut);
 
                     privOut->mPPStepsApplied |= pp;
                 }
 
+                pimpl->mProgressHandler->UpdateFileWrite(3, 4);
+
                 if(must_join_again) {
                     JoinVerticesProcess proc;
                     proc.Execute(scenecopy.get());
@@ -410,6 +467,8 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
 
                 ExportProperties emptyProperties;  // Never pass NULL ExportProperties so Exporters don't have to worry.
                 exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
+
+                pimpl->mProgressHandler->UpdateFileWrite(4, 4);
             } catch (DeadlyExportError& err) {
                 pimpl->mError = err.what();
                 return AI_FAILURE;
@@ -420,7 +479,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
 
     pimpl->mError = std::string("Found no exporter to handle this file format: ") + pFormatId;
     ASSIMP_END_EXCEPTION_REGION(aiReturn);
-    
+
     return AI_FAILURE;
 }
 
@@ -429,11 +488,10 @@ const char* Exporter::GetErrorString() const {
     return pimpl->mError.c_str();
 }
 
-
 // ------------------------------------------------------------------------------------------------
 void Exporter::FreeBlob() {
     delete pimpl->blob;
-    pimpl->blob = NULL;
+    pimpl->blob = nullptr;
 
     pimpl->mError = "";
 }
@@ -446,7 +504,7 @@ const aiExportDataBlob* Exporter::GetBlob() const {
 // ------------------------------------------------------------------------------------------------
 const aiExportDataBlob* Exporter::GetOrphanedBlob() const {
     const aiExportDataBlob* tmp = pimpl->blob;
-    pimpl->blob = NULL;
+    pimpl->blob = nullptr;
     return tmp;
 }
 
@@ -458,7 +516,7 @@ size_t Exporter::GetExportFormatCount() const {
 // ------------------------------------------------------------------------------------------------
 const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const {
     if (index >= GetExportFormatCount()) {
-        return NULL;
+        return nullptr;
     }
 
     // Return from static storage if the requested index is built-in.
@@ -483,7 +541,8 @@ aiReturn Exporter::RegisterExporter(const ExportFormatEntry& desc) {
 
 // ------------------------------------------------------------------------------------------------
 void Exporter::UnregisterExporter(const char* id) {
-    for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin(); it != pimpl->mExporters.end(); ++it) {
+    for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin();
+            it != pimpl->mExporters.end(); ++it) {
         if (!strcmp((*it).mDescription.id,id)) {
             pimpl->mExporters.erase(it);
             break;
@@ -519,82 +578,69 @@ bool ExportProperties::SetPropertyFloat(const char* szName, ai_real iValue) {
 
 // ------------------------------------------------------------------------------------------------
 // Set a configuration property
-bool ExportProperties :: SetPropertyString(const char* szName, const std::string& value)
-{
+bool ExportProperties::SetPropertyString(const char* szName, const std::string& value) {
     return SetGenericProperty<std::string>(mStringProperties, szName,value);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Set a configuration property
-bool ExportProperties :: SetPropertyMatrix(const char* szName, const aiMatrix4x4& value)
-{
+bool ExportProperties::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) {
     return SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Get a configuration property
-int ExportProperties :: GetPropertyInteger(const char* szName,
-    int iErrorReturn /*= 0xffffffff*/) const
-{
+int ExportProperties::GetPropertyInteger(const char* szName, int iErrorReturn /*= 0xffffffff*/) const {
     return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Get a configuration property
-ai_real ExportProperties :: GetPropertyFloat(const char* szName,
-    ai_real iErrorReturn /*= 10e10*/) const
-{
+ai_real ExportProperties::GetPropertyFloat(const char* szName, ai_real iErrorReturn /*= 10e10*/) const {
     return GetGenericProperty<ai_real>(mFloatProperties,szName,iErrorReturn);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Get a configuration property
-const std::string ExportProperties :: GetPropertyString(const char* szName,
-    const std::string& iErrorReturn /*= ""*/) const
-{
+const std::string ExportProperties::GetPropertyString(const char* szName,
+        const std::string& iErrorReturn /*= ""*/) const {
     return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Has a configuration property
-const aiMatrix4x4 ExportProperties :: GetPropertyMatrix(const char* szName,
-    const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const
-{
+const aiMatrix4x4 ExportProperties::GetPropertyMatrix(const char* szName,
+        const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const {
     return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Has a configuration property
-bool ExportProperties :: HasPropertyInteger(const char* szName) const
-{
+bool ExportProperties::HasPropertyInteger(const char* szName) const {
     return HasGenericProperty<int>(mIntProperties, szName);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Has a configuration property
-bool ExportProperties :: HasPropertyBool(const char* szName) const
-{
+bool ExportProperties::HasPropertyBool(const char* szName) const {
     return HasGenericProperty<int>(mIntProperties, szName);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Has a configuration property
-bool ExportProperties :: HasPropertyFloat(const char* szName) const
-{
+bool ExportProperties::HasPropertyFloat(const char* szName) const {
     return HasGenericProperty<ai_real>(mFloatProperties, szName);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Has a configuration property
-bool ExportProperties :: HasPropertyString(const char* szName) const
-{
+bool ExportProperties::HasPropertyString(const char* szName) const {
     return HasGenericProperty<std::string>(mStringProperties, szName);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Has a configuration property
-bool ExportProperties :: HasPropertyMatrix(const char* szName) const
-{
+bool ExportProperties::HasPropertyMatrix(const char* szName) const {
     return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName);
 }
 

+ 4 - 3
Engine/lib/assimp/code/FBXAnimation.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -104,8 +105,8 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
     const Scope& sc = GetRequiredScope(element);
 
     // find target node
-    const char* whitelist[] = {"Model","NodeAttribute"};
-    const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
+    const char* whitelist[] = {"Model","NodeAttribute","Deformer"};
+    const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,3);
 
     for(const Connection* con : conns) {
 

+ 35 - 29
Engine/lib/assimp/code/FBXBinaryTokenizer.cpp

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 
@@ -50,8 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXUtil.h"
 #include <assimp/defs.h>
 #include <stdint.h>
-#include "Exceptional.h"
-#include "ByteSwapper.h"
+#include <assimp/Exceptional.h>
+#include <assimp/ByteSwapper.h>
 
 namespace Assimp {
 namespace FBX {
@@ -82,7 +83,7 @@ namespace FBX {
 //   e_unknown_21 = 1 << 21,
 //   e_unknown_22 = 1 << 22,
 //   e_unknown_23 = 1 << 23,
-//   e_flag_field_size_64_bit = 1 << 24, // Not sure what is 
+//   e_flag_field_size_64_bit = 1 << 24, // Not sure what is
 //   e_unknown_25 = 1 << 25,
 //   e_unknown_26 = 1 << 26,
 //   e_unknown_27 = 1 << 27,
@@ -129,30 +130,26 @@ AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offse
 
 
 // ------------------------------------------------------------------------------------------------
-uint32_t Offset(const char* begin, const char* cursor)
-{
+uint32_t Offset(const char* begin, const char* cursor) {
     ai_assert(begin <= cursor);
+
     return static_cast<unsigned int>(cursor - begin);
 }
 
-
 // ------------------------------------------------------------------------------------------------
-void TokenizeError(const std::string& message, const char* begin, const char* cursor)
-{
+void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
     TokenizeError(message, Offset(begin, cursor));
 }
 
-
 // ------------------------------------------------------------------------------------------------
-uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
-{
+uint32_t ReadWord(const char* input, const char*& cursor, const char* end) {
     const size_t k_to_read = sizeof( uint32_t );
     if(Offset(cursor, end) < k_to_read ) {
         TokenizeError("cannot ReadWord, out of bounds",input, cursor);
     }
 
     uint32_t word;
-    memcpy(&word, cursor, 4);
+    ::memcpy(&word, cursor, 4);
     AI_SWAP4(word);
 
     cursor += k_to_read;
@@ -167,7 +164,8 @@ uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
         TokenizeError("cannot ReadDoubleWord, out of bounds",input, cursor);
     }
 
-    uint64_t dword = *reinterpret_cast<const uint64_t*>(cursor);
+    uint64_t dword /*= *reinterpret_cast<const uint64_t*>(cursor)*/;
+    ::memcpy( &dword, cursor, sizeof( uint64_t ) );
     AI_SWAP8(dword);
 
     cursor += k_to_read;
@@ -176,24 +174,21 @@ uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
 }
 
 // ------------------------------------------------------------------------------------------------
-uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
-{
+uint8_t ReadByte(const char* input, const char*& cursor, const char* end) {
     if(Offset(cursor, end) < sizeof( uint8_t ) ) {
         TokenizeError("cannot ReadByte, out of bounds",input, cursor);
     }
 
-    uint8_t word = *reinterpret_cast<const uint8_t*>(cursor);
+    uint8_t word;/* = *reinterpret_cast< const uint8_t* >( cursor )*/
+    ::memcpy( &word, cursor, sizeof( uint8_t ) );
     ++cursor;
 
     return word;
 }
 
-
 // ------------------------------------------------------------------------------------------------
-unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end,
-    bool long_length = false,
-    bool allow_null = false)
-{
+unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input,
+        const char*& cursor, const char* end, bool long_length = false, bool allow_null = false) {
     const uint32_t len_len = long_length ? 4 : 1;
     if(Offset(cursor, end) < len_len) {
         TokenizeError("cannot ReadString, out of bounds reading length",input, cursor);
@@ -222,8 +217,7 @@ unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const ch
 }
 
 // ------------------------------------------------------------------------------------------------
-void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end)
-{
+void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end) {
     if(Offset(cursor, end) < 1) {
         TokenizeError("cannot ReadData, out of bounds reading length",input, cursor);
     }
@@ -282,8 +276,8 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
     case 'f':
     case 'd':
     case 'l':
-    case 'i':   {
-
+    case 'i':
+    case 'c':   {
         const uint32_t length = ReadWord(input, cursor, end);
         const uint32_t encoding = ReadWord(input, cursor, end);
 
@@ -304,6 +298,10 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
                 stride = 8;
                 break;
 
+            case 'c':
+                stride = 1;
+                break;
+
             default:
                 ai_assert(false);
             };
@@ -422,7 +420,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
     return true;
 }
 
-}
+} // anonymous namespace
 
 // ------------------------------------------------------------------------------------------------
 // TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
@@ -434,6 +432,14 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
         TokenizeError("file is too short",0);
     }
 
+    //uint32_t offset = 0x15;
+/*    const char* cursor = input + 0x15;
+
+    const uint32_t flags = ReadWord(input, cursor, input + length);
+
+    const uint8_t padding_0 = ReadByte(input, cursor, input + length); // unused
+    const uint8_t padding_1 = ReadByte(input, cursor, input + length); // unused*/
+
     if (strncmp(input,"Kaydara FBX Binary",18)) {
         TokenizeError("magic bytes not found",0);
     }
@@ -446,8 +452,8 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
 	/*Result ignored*/ ReadByte(input, cursor, input + length);
 	const uint32_t version = ReadWord(input, cursor, input + length);
 	const bool is64bits = version >= 7500;
-    while (cursor < input + length)
-    {
+    const char *end = input + length;
+    while (cursor < end ) {
 		if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
             break;
         }

+ 86 - 0
Engine/lib/assimp/code/FBXCommon.h

@@ -0,0 +1,86 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file FBXCommon.h
+* Some useful constants and enums for dealing with FBX files.
+*/
+#ifndef AI_FBXCOMMON_H_INC
+#define AI_FBXCOMMON_H_INC
+
+#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
+
+
+namespace FBX
+{
+    const std::string NULL_RECORD = { // 13 null bytes
+        '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'
+    }; // who knows why
+    const std::string SEPARATOR = {'\x00', '\x01'}; // for use inside strings
+    const std::string MAGIC_NODE_TAG = "_$AssimpFbx$"; // from import
+    const int64_t SECOND = 46186158000; // FBX's kTime unit
+
+    // rotation order. We'll probably use EulerXYZ for everything
+    enum RotOrder {
+        RotOrder_EulerXYZ = 0,
+        RotOrder_EulerXZY,
+        RotOrder_EulerYZX,
+        RotOrder_EulerYXZ,
+        RotOrder_EulerZXY,
+        RotOrder_EulerZYX,
+
+        RotOrder_SphericXYZ,
+
+        RotOrder_MAX // end-of-enum sentinel
+    };
+
+    // transformation inheritance method. Most of the time RSrs
+    enum TransformInheritance {
+        TransformInheritance_RrSs = 0,
+        TransformInheritance_RSrs,
+        TransformInheritance_Rrs,
+
+        TransformInheritance_MAX // end-of-enum sentinel
+    };
+}
+
+#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
+
+#endif // AI_FBXCOMMON_H_INC

+ 2 - 1
Engine/lib/assimp/code/FBXCompileConfig.h

@@ -2,7 +2,8 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2019, assimp team
+
 
 All rights reserved.
 

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません