Explorar o código

Merge branch 'master' into master

Kim Kulling %!s(int64=5) %!d(string=hai) anos
pai
achega
3f5136b7b2

+ 2 - 2
.clang-format

@@ -71,7 +71,7 @@ IncludeCategories:
     Priority:        3
 # IncludeIsMainRegex: '(Test)?$'
 IndentCaseLabels: true
-# IndentPPDirectives: None
+IndentPPDirectives: AfterHash
 IndentWidth:     4
 # IndentWrappedFunctionNames: false
 # JavaScriptQuotes: Leave
@@ -108,7 +108,7 @@ IndentWidth:     4
 # SpacesInParentheses: false
 # SpacesInSquareBrackets: false
 TabWidth:        4
-UseTab:          Always
+UseTab:          Never
 ---
 ### C++ specific config ###
 Language:        Cpp

+ 0 - 4
CMakeLists.txt

@@ -437,10 +437,6 @@ ELSE(HUNTER_ENABLED)
     DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
 ENDIF(HUNTER_ENABLED)
 
-if (ASSIMP_BUILD_SAMPLES OR ASSIMP_BUILD_SAMPLES)
-  FIND_PACKAGE(DirectX)
-endif(ASSIMP_BUILD_SAMPLES OR ASSIMP_BUILD_SAMPLES)
-
 IF( BUILD_DOCS )
   ADD_SUBDIRECTORY(doc)
 ENDIF( BUILD_DOCS )

+ 3 - 4
code/Common/BaseImporter.cpp

@@ -191,7 +191,7 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
     }
 
     std::unique_ptr<IOStream> pStream (pIOHandler->Open(pFile));
-    if (pStream.get() ) {
+    if (pStream) {
         // read 200 characters from the file
         std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]);
         char *buffer( _buffer.get() );
@@ -283,7 +283,6 @@ std::string BaseImporter::GetExtension( const std::string& file ) {
         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>);
@@ -309,7 +308,7 @@ std::string BaseImporter::GetExtension( const std::string& file ) {
     };
     magic = reinterpret_cast<const char*>(_magic);
     std::unique_ptr<IOStream> pStream (pIOHandler->Open(pFile));
-    if (pStream.get() ) {
+    if (pStream) {
 
         // skip to offset
         pStream->Seek(offset,aiOrigin_SET);
@@ -603,7 +602,7 @@ unsigned int BatchLoader::AddLoadRequest(const std::string& file,
     }
 
     // no, we don't have it. So add it to the queue ...
-    m_data->requests.push_back(LoadRequest(file,steps,map, m_data->next_id));
+    m_data->requests.emplace_back(file, steps, map, m_data->next_id);
     return m_data->next_id++;
 }
 

+ 4 - 4
code/Common/Importer.cpp

@@ -1071,7 +1071,7 @@ ai_real Importer::GetPropertyFloat(const char* szName, ai_real iErrorReturn /*=
 
 // ------------------------------------------------------------------------------------------------
 // Get a configuration property
-const std::string Importer::GetPropertyString(const char* szName, const std::string& iErrorReturn /*= ""*/) const {
+std::string Importer::GetPropertyString(const char* szName, const std::string& iErrorReturn /*= ""*/) const {
     ai_assert(nullptr != pimpl);
     
     return GetGenericProperty<std::string>(pimpl->mStringProperties,szName,iErrorReturn);
@@ -1079,7 +1079,7 @@ const std::string Importer::GetPropertyString(const char* szName, const std::str
 
 // ------------------------------------------------------------------------------------------------
 // Get a configuration property
-const aiMatrix4x4 Importer::GetPropertyMatrix(const char* szName, const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const {
+aiMatrix4x4 Importer::GetPropertyMatrix(const char* szName, const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const {
     ai_assert(nullptr != pimpl);
     
     return GetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties,szName,iErrorReturn);
@@ -1110,10 +1110,9 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const {
     aiScene* mScene = pimpl->mScene;
 
     // return if we have no scene loaded
-    if (!pimpl->mScene)
+    if (!mScene)
         return;
 
-
     in.total = sizeof(aiScene);
 
     // add all meshes
@@ -1202,5 +1201,6 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const {
             in.materials += pc->mProperties[a]->mDataLength;
         }
     }
+
     in.total += in.materials;
 }

+ 0 - 2
code/Common/ZipArchiveIOSystem.cpp

@@ -343,8 +343,6 @@ namespace Assimp {
     }
 
     ZipArchiveIOSystem::Implement::~Implement() {
-        m_ArchiveMap.clear();
-
         if (m_ZipFileHandle != nullptr) {
             unzClose(m_ZipFileHandle);
             m_ZipFileHandle = nullptr;

+ 4 - 11
code/Obj/ObjFileData.h

@@ -110,10 +110,7 @@ struct Object {
     std::vector<unsigned int> m_Meshes;
 
     //! \brief  Default constructor
-    Object() 
-    : m_strObjName("") {
-        // empty
-    }
+    Object() = default;
 
     //! \brief  Destructor
     ~Object() {
@@ -191,16 +188,12 @@ struct Material {
     ,   illumination_model (1)
     ,   ior     ( ai_real( 1.0 ) )
     ,   transparent( ai_real( 1.0), ai_real (1.0), ai_real(1.0)) {
-        // empty
-        for (size_t i = 0; i < TextureTypeCount; ++i) {
-            clamp[ i ] = false;
-        }
+
+	    std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false);
     }
 
     // Destructor
-    ~Material() {
-        // empty
-    }
+    ~Material() = default;
 };
 
 // ------------------------------------------------------------------------------------------------

+ 22 - 27
code/Obj/ObjFileImporter.cpp

@@ -175,15 +175,15 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
         ai_assert(false);
     }
 
-    if (pModel->m_Objects.size() > 0) {
+    if (!pModel->m_Objects.empty()) {
 
         unsigned int meshCount = 0;
         unsigned int childCount = 0;
 
-        for(size_t index = 0; index < pModel->m_Objects.size(); ++index) {
-            if(pModel->m_Objects[index]) {
+        for (auto object : pModel->m_Objects) {
+            if(object) {
                 ++childCount;
-                meshCount += (unsigned int)pModel->m_Objects[index]->m_Meshes.size();
+                meshCount += (unsigned int)object->m_Meshes.size();
             }
         }
 
@@ -365,8 +365,8 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
         unsigned int outIndex( 0 );
 
         // Copy all data from all stored meshes
-        for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
-            ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
+        for (auto& face : pObjMesh->m_Faces) {
+            ObjFile::Face* const inp = face;
             if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
                 for(size_t i = 0; i < inp->m_vertices.size() - 1; ++i) {
                     aiFace& f = pMesh->mFaces[ outIndex++ ];
@@ -385,7 +385,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
             }
 
             aiFace *pFace = &pMesh->mFaces[ outIndex++ ];
-            const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_vertices.size();
+            const unsigned int uiNumIndices = (unsigned int) face->m_vertices.size();
             uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices;
             if (pFace->mNumIndices > 0) {
                 pFace->mIndices = new unsigned int[ uiNumIndices ];
@@ -446,13 +446,10 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
     // Copy vertices, normals and textures into aiMesh instance
     bool normalsok = true, uvok = true;
     unsigned int newIndex = 0, outIndex = 0;
-    for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ ) {
-        // Get source face
-        ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ];
-
+    for (auto sourceFace : pObjMesh->m_Faces) {
         // Copy all index arrays
-        for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_vertices.size(); vertexIndex++ ) {
-            const unsigned int vertex = pSourceFace->m_vertices.at( vertexIndex );
+        for (size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < sourceFace->m_vertices.size(); vertexIndex++ ) {
+            const unsigned int vertex = sourceFace->m_vertices.at(vertexIndex );
             if ( vertex >= pModel->m_Vertices.size() ) {
                 throw DeadlyImportError( "OBJ: vertex index out of range" );
             }
@@ -464,8 +461,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
             pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
 
             // Copy all normals
-            if ( normalsok && !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_normals.size()) {
-                const unsigned int normal = pSourceFace->m_normals.at( vertexIndex );
+            if ( normalsok && !pModel->m_Normals.empty() && vertexIndex < sourceFace->m_normals.size()) {
+                const unsigned int normal = sourceFace->m_normals.at(vertexIndex );
                 if ( normal >= pModel->m_Normals.size() )
                 {
                     normalsok = false;
@@ -484,9 +481,9 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
             }
 
             // Copy all texture coordinates
-            if ( uvok && !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_texturCoords.size())
+            if ( uvok && !pModel->m_TextureCoord.empty() && vertexIndex < sourceFace->m_texturCoords.size())
             {
-                const unsigned int tex = pSourceFace->m_texturCoords.at( vertexIndex );
+                const unsigned int tex = sourceFace->m_texturCoords.at(vertexIndex );
 
                 if ( tex >= pModel->m_TextureCoord.size() )
                 {
@@ -502,16 +499,16 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
             // Get destination face
             aiFace *pDestFace = &pMesh->mFaces[ outIndex ];
 
-            const bool last = ( vertexIndex == pSourceFace->m_vertices.size() - 1 );
-            if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) {
+            const bool last = (vertexIndex == sourceFace->m_vertices.size() - 1 );
+            if (sourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) {
                 pDestFace->mIndices[ outVertexIndex ] = newIndex;
                 outVertexIndex++;
             }
 
-            if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) {
+            if (sourceFace->m_PrimitiveType == aiPrimitiveType_POINT) {
                 outIndex++;
                 outVertexIndex = 0;
-            } else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) {
+            } else if (sourceFace->m_PrimitiveType == aiPrimitiveType_LINE) {
                 outVertexIndex = 0;
 
                 if(!last)
@@ -520,7 +517,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
                 if (vertexIndex) {
                     if(!last) {
                         pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ];
-                        if ( !pSourceFace->m_normals.empty() && !pModel->m_Normals.empty()) {
+                        if (!sourceFace->m_normals.empty() && !pModel->m_Normals.empty()) {
                             pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ];
                         }
                         if ( !pModel->m_TextureCoord.empty() ) {
@@ -563,13 +560,11 @@ void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects
         return;
 
     iNumMeshes += static_cast<unsigned int>( rObjects.size() );
-    for (std::vector<ObjFile::Object*>::const_iterator it = rObjects.begin();
-        it != rObjects.end();
-        ++it)
+    for (auto object: rObjects)
     {
-        if (!(*it)->m_SubObjects.empty())
+        if (!object->m_SubObjects.empty())
         {
-            countObjects((*it)->m_SubObjects, iNumMeshes);
+            countObjects(object->m_SubObjects, iNumMeshes);
         }
     }
 }

+ 2 - 2
code/Obj/ObjFileMtlImporter.cpp

@@ -274,7 +274,7 @@ void ObjFileMtlImporter::getFloatValue( ai_real &value )
 //  Creates a material from loaded data.
 void ObjFileMtlImporter::createMaterial()
 {
-    std::string line( "" );
+    std::string line;
     while( !IsLineEnd( *m_DataIt ) ) {
         line += *m_DataIt;
         ++m_DataIt;
@@ -282,7 +282,7 @@ void ObjFileMtlImporter::createMaterial()
 
     std::vector<std::string> token;
     const unsigned int numToken = tokenize<std::string>( line, token, " \t" );
-    std::string name( "" );
+    std::string name;
     if ( numToken == 1 ) {
         name = AI_DEFAULT_MATERIAL_NAME;
     } else {

+ 23 - 25
code/Obj/ObjFileParser.cpp

@@ -53,6 +53,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/material.h>
 #include <assimp/Importer.hpp>
 #include <cstdlib>
+#include <memory>
+#include <utility>
 
 namespace Assimp {
 
@@ -71,16 +73,16 @@ ObjFileParser::ObjFileParser()
 
 ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName,
                               IOSystem *io, ProgressHandler* progress,
-                              const std::string &originalObjFileName) :
+                              std::string originalObjFileName) :
     m_DataIt(),
     m_DataItEnd(),
     m_pModel(nullptr),
     m_uiLine(0),
-    m_pIO( io ),
+    m_pIO(io),
     m_progress(progress),
-    m_originalObjFileName(originalObjFileName)
+    m_originalObjFileName(std::move(originalObjFileName))
 {
-    std::fill_n(m_buffer,Buffersize,0);
+    std::fill_n(m_buffer, Buffersize,0);
 
     // Create the model instance to store all the data
     m_pModel.reset(new ObjFile::Model());
@@ -96,7 +98,8 @@ ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::str
     parseFile( streamBuffer );
 }
 
-ObjFileParser::~ObjFileParser() {
+ObjFileParser::~ObjFileParser()
+{
 }
 
 void ObjFileParser::setBuffer( std::vector<char> &buffer ) {
@@ -128,7 +131,7 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
             processed = static_cast<unsigned int>(filePos);
             lastFilePos = filePos;
             progressCounter++;
-            m_progress->UpdateFileRead( processed, progressTotal );
+            m_progress->UpdateFileRead(processed, progressTotal);
         }
 
         // parse line
@@ -182,7 +185,7 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
 
                 getNameNoSpace(m_DataIt, m_DataItEnd, name);
 
-                size_t nextSpace = name.find(" ");
+                size_t nextSpace = name.find(' ');
                 if (nextSpace != std::string::npos)
                     name = name.substr(0, nextSpace);
 
@@ -199,7 +202,7 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
 
                 getNameNoSpace(m_DataIt, m_DataItEnd, name);
 
-                size_t nextSpace = name.find(" ");
+                size_t nextSpace = name.find(' ');
                 if (nextSpace != std::string::npos)
                     name = name.substr(0, nextSpace);
 
@@ -274,13 +277,8 @@ static bool isDataDefinitionEnd( const char *tmp ) {
 
 static bool isNanOrInf(const char * in) {
     // Look for "nan" or "inf", case insensitive
-    if ((in[0] == 'N' || in[0] == 'n') && ASSIMP_strincmp(in, "nan", 3) == 0) {
-        return true;
-    }
-    else if ((in[0] == 'I' || in[0] == 'i') && ASSIMP_strincmp(in, "inf", 3) == 0) {
-        return true;
-    }
-    return false;
+	return ((in[0] == 'N' || in[0] == 'n') && ASSIMP_strincmp(in, "nan", 3) == 0) ||
+	       ((in[0] == 'I' || in[0] == 'i') && ASSIMP_strincmp(in, "inf", 3) == 0);
 }
 
 size_t ObjFileParser::getNumComponentsInDataDefinition() {
@@ -341,7 +339,7 @@ size_t ObjFileParser::getTexCoordVector( std::vector<aiVector3D> &point3d_array
     if (!std::isfinite(z))
         z = 0;
 
-    point3d_array.push_back( aiVector3D( x, y, z ) );
+    point3d_array.emplace_back( x, y, z );
     m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
     return numComponents;
 }
@@ -357,7 +355,7 @@ void ObjFileParser::getVector3( std::vector<aiVector3D> &point3d_array ) {
     copyNextWord( m_buffer, Buffersize );
     z = ( ai_real ) fast_atof( m_buffer );
 
-    point3d_array.push_back( aiVector3D( x, y, z ) );
+    point3d_array.emplace_back( x, y, z );
     m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 
@@ -378,7 +376,7 @@ void ObjFileParser::getHomogeneousVector3( std::vector<aiVector3D> &point3d_arra
     if (w == 0)
       throw DeadlyImportError("OBJ: Invalid component in homogeneous vector (Division by zero)");
 
-    point3d_array.push_back( aiVector3D( x/w, y/w, z/w ) );
+    point3d_array.emplace_back( x/w, y/w, z/w );
     m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 
@@ -393,7 +391,7 @@ void ObjFileParser::getTwoVectors3( std::vector<aiVector3D> &point3d_array_a, st
     copyNextWord( m_buffer, Buffersize );
     z = ( ai_real ) fast_atof( m_buffer );
 
-    point3d_array_a.push_back( aiVector3D( x, y, z ) );
+    point3d_array_a.emplace_back( x, y, z );
 
     copyNextWord(m_buffer, Buffersize);
     x = (ai_real) fast_atof(m_buffer);
@@ -404,7 +402,7 @@ void ObjFileParser::getTwoVectors3( std::vector<aiVector3D> &point3d_array_a, st
     copyNextWord( m_buffer, Buffersize );
     z = ( ai_real ) fast_atof( m_buffer );
 
-    point3d_array_b.push_back( aiVector3D( x, y, z ) );
+    point3d_array_b.emplace_back( x, y, z );
 
     m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
@@ -417,7 +415,7 @@ void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
     copyNextWord(m_buffer, Buffersize);
     y = (ai_real) fast_atof(m_buffer);
 
-    point2d_array.push_back(aiVector2D(x, y));
+    point2d_array.emplace_back(x, y);
 
     m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
@@ -439,9 +437,9 @@ void ObjFileParser::getFace( aiPrimitiveType type ) {
 
     const bool vt = (!m_pModel->m_TextureCoord.empty());
     const bool vn = (!m_pModel->m_Normals.empty());
-    int iStep = 0, iPos = 0;
+    int iPos = 0;
     while ( m_DataIt != m_DataItEnd ) {
-        iStep = 1;
+        int iStep = 1;
 
         if ( IsLineEnd( *m_DataIt ) ) {
             break;
@@ -845,7 +843,7 @@ void ObjFileParser::createMesh( const std::string &meshName )
 bool ObjFileParser::needsNewMesh( const std::string &materialName )
 {
     // If no mesh data yet
-    if(m_pModel->m_pCurrentMesh == 0)
+    if (m_pModel->m_pCurrentMesh == nullptr)
     {
         return true;
     }
@@ -856,7 +854,7 @@ bool ObjFileParser::needsNewMesh( const std::string &materialName )
         && curMatIdx != matIdx
         // no need create a new mesh if no faces in current
         // lets say 'usemtl' goes straight after 'g'
-        && m_pModel->m_pCurrentMesh->m_Faces.size() > 0 )
+        && !m_pModel->m_pCurrentMesh->m_Faces.empty() )
     {
         // New material -> only one material per mesh, so we need to create a new
         // material

+ 1 - 1
code/Obj/ObjFileParser.h

@@ -78,7 +78,7 @@ public:
     /// @brief  The default constructor.
     ObjFileParser();
     /// @brief  Constructor with data array.
-    ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem* io, ProgressHandler* progress, const std::string &originalObjFileName);
+    ObjFileParser(IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem* io, ProgressHandler* progress, std::string originalObjFileName);
     /// @brief  Destructor
     ~ObjFileParser();
     /// @brief  If you want to load in-core data.

+ 3 - 5
code/PostProcessing/TextureTransform.cpp

@@ -92,9 +92,8 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
      *  are applied is - as always - scaling, rotation, translation.
      */
 
-    char szTemp[512];
-    int rounded = 0;
-
+	int rounded;
+	char szTemp[512];
 
     /* Optimize the rotation angle. That's slightly difficult as
      * we have an inprecise floating-point number (when comparing
@@ -185,7 +184,6 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
             info.mTranslation.y = out;
         }
     }
-    return;
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -428,7 +426,7 @@ void TextureTransformStep::Execute( aiScene* pScene)
         // at the end of the list
         bool ref[AI_MAX_NUMBER_OF_TEXTURECOORDS];
         for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
-            ref[n] = (!mesh->mTextureCoords[n] ? true : false);
+            ref[n] = !mesh->mTextureCoords[n];
 
         for (it = trafo.begin();it != trafo.end(); ++it)
             ref[(*it).uvIndex] = true;

+ 6 - 0
code/PostProcessing/ValidateDataStructure.cpp

@@ -777,6 +777,12 @@ void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
     SearchForInvalidTextures(pMaterial,aiTextureType_DISPLACEMENT);
     SearchForInvalidTextures(pMaterial,aiTextureType_LIGHTMAP);
     SearchForInvalidTextures(pMaterial,aiTextureType_REFLECTION);
+    SearchForInvalidTextures(pMaterial,aiTextureType_BASE_COLOR);
+    SearchForInvalidTextures(pMaterial,aiTextureType_NORMAL_CAMERA);
+    SearchForInvalidTextures(pMaterial,aiTextureType_EMISSION_COLOR);
+    SearchForInvalidTextures(pMaterial,aiTextureType_METALNESS);
+    SearchForInvalidTextures(pMaterial,aiTextureType_DIFFUSE_ROUGHNESS);
+    SearchForInvalidTextures(pMaterial,aiTextureType_AMBIENT_OCCLUSION);
 }
 
 // ------------------------------------------------------------------------------------------------

+ 5 - 0
code/glTF2/glTF2Importer.cpp

@@ -926,6 +926,11 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
 
 	if (node.camera) {
 		pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
+		if (node.translation.isPresent) {
+			aiVector3D trans;
+			CopyValue(node.translation.value, trans);
+			pScene->mCameras[node.camera.GetIndex()]->mPosition = trans;
+		}
 	}
 
 	if (node.light) {

+ 2 - 2
include/assimp/Importer.hpp

@@ -285,7 +285,7 @@ public:
      *  The return value remains valid until the property is modified.
      * @see GetPropertyInteger()
      */
-    const std::string GetPropertyString(const char* szName,
+    std::string GetPropertyString(const char* szName,
         const std::string& sErrorReturn = "") const;
 
     // -------------------------------------------------------------------
@@ -294,7 +294,7 @@ public:
      *  The return value remains valid until the property is modified.
      * @see GetPropertyInteger()
      */
-    const aiMatrix4x4 GetPropertyMatrix(const char* szName,
+    aiMatrix4x4 GetPropertyMatrix(const char* szName,
         const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;
 
     // -------------------------------------------------------------------

+ 1 - 1
samples/SimpleTexturedOpenGL/CMakeLists.txt

@@ -35,7 +35,7 @@ ADD_EXECUTABLE( assimp_simpletexturedogl WIN32
 
 SET_PROPERTY(TARGET assimp_simpletexturedogl PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
 
-TARGET_LINK_LIBRARIES( assimp_simpletexturedogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} DevIL.lib )
+TARGET_LINK_LIBRARIES( assimp_simpletexturedogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} )
 
 SET_TARGET_PROPERTIES( assimp_simpletexturedogl PROPERTIES
   OUTPUT_NAME assimp_simpletexturedogl

+ 91 - 39
samples/SimpleTexturedOpenGL/SimpleTexturedOpenGL/src/model_loading.cpp

@@ -21,6 +21,8 @@
 #define STB_IMAGE_IMPLEMENTATION
 #include "contrib/stb_image/stb_image.h"
 
+#include <locale>
+#include <codecvt>
 #include <fstream>
 
 //to map image filenames to textureIds
@@ -75,6 +77,36 @@ GLuint*		textureIds;							// pointer to texture Array
 // Create an instance of the Importer class
 Assimp::Importer importer;
 
+// Used to convert between multibyte and unicode strings.
+class UTFConverter {
+	using UTFConverterImpl = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>;
+public:
+	UTFConverter(const char* s) :
+		s_(s),
+		ws_(impl_.from_bytes(s)) {
+	}
+	UTFConverter(const std::string& s) :
+		s_(s),
+		ws_(impl_.from_bytes(s)) {
+	}
+	UTFConverter(const std::wstring& s) :
+		s_(impl_.to_bytes(s)),
+		ws_(s) {
+	}
+	inline const std::string& str() const {
+		return s_;
+	}
+	inline const wchar_t* c_wstr() const {
+		return ws_.c_str();
+	}
+private:
+	static UTFConverterImpl impl_;
+	std::string s_;
+	std::wstring ws_;
+};
+
+typename UTFConverter::UTFConverterImpl UTFConverter::impl_;
+
 void createAILogger()
 {
     // Change this line to normal if you not want to analyse the import process
@@ -120,7 +152,7 @@ bool Import3DFromFile( const std::string& pFile)
 	}
 	else
 	{
-		MessageBox(NULL, ("Couldn't open file: " + pFile).c_str() , "ERROR", MB_OK | MB_ICONEXCLAMATION);
+		MessageBox(NULL, UTFConverter("Couldn't open file: " + pFile).c_wstr() , TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
 		logInfo( importer.GetErrorString());
 		return false;
 	}
@@ -170,8 +202,21 @@ std::string getBasePath(const std::string& path)
 	return (std::string::npos == pos) ? "" : path.substr(0, pos + 1);
 }
 
+void freeTextureIds()
+{
+	textureIdMap.clear(); //no need to delete pointers in it manually here. (Pointers point to textureIds deleted in next step)
+
+	if (textureIds)
+	{
+		delete[] textureIds;
+		textureIds = NULL;
+	}
+}
+
 int LoadGLTextures(const aiScene* scene)
 {
+	freeTextureIds();
+
 	//ILboolean success;
 
 	/* Before calling ilInit() version should be checked. */
@@ -205,7 +250,7 @@ int LoadGLTextures(const aiScene* scene)
 		}
 	}
 
-	int numTextures = textureIdMap.size();
+	const size_t numTextures = textureIdMap.size();
 
 
 	/* array with DevIL image IDs */
@@ -217,13 +262,13 @@ int LoadGLTextures(const aiScene* scene)
 
 	/* create and fill array with GL texture ids */
 	textureIds = new GLuint[numTextures];
-	glGenTextures(numTextures, textureIds); /* Texture name generation */
+	glGenTextures(static_cast<GLsizei>(numTextures), textureIds); /* Texture name generation */
 
 	/* get iterator */
 	std::map<std::string, GLuint*>::iterator itr = textureIdMap.begin();
 
 	std::string basepath = getBasePath(modelpath);
-	for (int i=0; i<numTextures; i++)
+	for (size_t i=0; i<numTextures; i++)
 	{
 
 		//save IL image ID
@@ -268,7 +313,7 @@ int LoadGLTextures(const aiScene* scene)
 		else
 		{
 			/* Error occurred */
-			MessageBox(NULL, ("Couldn't load Image: " + fileloc).c_str() , "ERROR", MB_OK | MB_ICONEXCLAMATION);
+			MessageBox(NULL, UTFConverter("Couldn't load Image: " + fileloc).c_wstr(), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
 		}
 	}
     // Because we have already copied image data into texture data  we can release memory used by image.
@@ -534,31 +579,34 @@ void KillGLWindow()			// Properly Kill The Window
 	{
 		if (!wglMakeCurrent(NULL, NULL))	// Are We Able To Release The DC And RC Contexts?
 		{
-			MessageBox(NULL, "Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
+			MessageBox(NULL, TEXT("Release Of DC And RC Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
 		}
 
 		if (!wglDeleteContext(hRC))			// Are We Able To Delete The RC?
 		{
-			MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
+			MessageBox(NULL, TEXT("Release Rendering Context Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
 		}
 		hRC = NULL;
 	}
 
-	if (hDC && !ReleaseDC(hWnd, hDC))	// Are We able to Release The DC?
+	if (hDC)
 	{
-		MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
-		hDC=NULL;
+		if (!ReleaseDC(hWnd, hDC)) // Are We able to Release The DC?
+			MessageBox(NULL, TEXT("Release Device Context Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
+		hDC = NULL;
 	}
 
-	if (hWnd && !DestroyWindow(hWnd))	// Are We Able To Destroy The Window
+	if (hWnd)
 	{
-		MessageBox(NULL, "Could Not Release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
+		if (!DestroyWindow(hWnd)) // Are We Able To Destroy The Window
+			MessageBox(NULL, TEXT("Could Not Release hWnd."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
 		hWnd = NULL;
-	}
+	} 
 
-	if (!UnregisterClass("OpenGL", hInstance))	// Are We Able To Unregister Class
+	if (hInstance)
 	{
-		MessageBox(NULL, "Could Not Unregister Class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
+		if (!UnregisterClass(TEXT("OpenGL"), hInstance)) // Are We Able To Unregister Class
+			MessageBox(NULL, TEXT("Could Not Unregister Class."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
 		hInstance = NULL;
 	}
 }
@@ -566,7 +614,7 @@ void KillGLWindow()			// Properly Kill The Window
 GLboolean abortGLInit(const char* abortMessage)
 {
 	KillGLWindow();									// Reset Display
-	MessageBox(NULL, abortMessage, "ERROR", MB_OK|MB_ICONEXCLAMATION);
+	MessageBox(NULL, UTFConverter(abortMessage).c_wstr(), TEXT("ERROR"), MB_OK|MB_ICONEXCLAMATION);
 	return FALSE;									// quit and return False
 }
 
@@ -594,11 +642,11 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
 	wc.hCursor		= LoadCursor(NULL, IDC_ARROW);	// Load the default arrow
 	wc.hbrBackground= NULL;							// No Background required for OpenGL
 	wc.lpszMenuName	= NULL;							// No Menu
-	wc.lpszClassName= "OpenGL";						// Class Name
+	wc.lpszClassName= TEXT("OpenGL");		        // Class Name
 
 	if (!RegisterClass(&wc))
 	{
-		MessageBox(NULL, "Failed to register the window class", "ERROR", MB_OK | MB_ICONEXCLAMATION);
+		MessageBox(NULL, TEXT("Failed to register the window class"), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
 		return FALSE;		//exit and return false
 	}
 
@@ -616,14 +664,14 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
 		if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
 		{
 			// If The Mode Fails, Offer Two Options.  Quit Or Run In A Window.
-			if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
+			if (MessageBox(NULL,TEXT("The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?"),TEXT("NeHe GL"),MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
 			{
 				fullscreen = FALSE;		// Select Windowed Mode (Fullscreen = FALSE)
 			}
 			else
 			{
 				//Popup Messagebox: Closing
-				MessageBox(NULL, "Program will close now.", "ERROR", MB_OK|MB_ICONSTOP);
+				MessageBox(NULL, TEXT("Program will close now."), TEXT("ERROR"), MB_OK|MB_ICONSTOP);
 				return FALSE; //exit, return false
 			}
 		}
@@ -644,8 +692,8 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
 	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);		// Adjust Window To True Requestes Size
 
 	if (!(hWnd=CreateWindowEx(	dwExStyle,						// Extended Style For The Window
-								"OpenGL",						// Class Name
-								title,							// Window Title
+								TEXT("OpenGL"),						// Class Name
+								UTFConverter(title).c_wstr(),							// Window Title
 								WS_CLIPSIBLINGS |				// Required Window Style
 								WS_CLIPCHILDREN |				// Required Window Style
 								dwStyle,						// Selected WIndow Style
@@ -729,6 +777,16 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
 	return TRUE;
 }
 
+void cleanup()
+{
+	freeTextureIds();
+
+	destroyAILogger();
+
+	if (hWnd)
+		KillGLWindow();
+};
+
 LRESULT CALLBACK WndProc(HWND hWnd,				// Handles for this Window
 						 UINT uMsg,				// Message for this Window
 						 WPARAM wParam,			// additional message Info
@@ -807,20 +865,25 @@ int WINAPI WinMain( HINSTANCE hInstance,         // The instance
 	if (argv != NULL && argc > 1)
 	{
 		std::wstring modelpathW(argv[1]);
-		modelpath = std::string(modelpathW.begin(), modelpathW.end());
+		modelpath = UTFConverter(modelpathW).str();
 	}
 
-	if (!Import3DFromFile(modelpath)) return 0;
+	if (!Import3DFromFile(modelpath))
+	{
+		cleanup();
+		return 0;
+	}
 
 	logInfo("=============== Post Import ====================");
 
-	if (MessageBox(NULL, "Would You Like To Run In Fullscreen Mode?", "Start Fullscreen?", MB_YESNO|MB_ICONEXCLAMATION)==IDNO)
+	if (MessageBox(NULL, TEXT("Would You Like To Run In Fullscreen Mode?"), TEXT("Start Fullscreen?"), MB_YESNO|MB_ICONEXCLAMATION)==IDNO)
 	{
 		fullscreen=FALSE;
 	}
 
 	if (!CreateGLWindow(windowTitle, 640, 480, 16, fullscreen))
 	{
+		cleanup();
 		return 0;
 	}
 
@@ -861,6 +924,7 @@ int WINAPI WinMain( HINSTANCE hInstance,         // The instance
 				fullscreen=!fullscreen;
 				if (!CreateGLWindow(windowTitle, 640, 480, 16, fullscreen))
 				{
+					cleanup();
 					return 0;
 				}
 			}
@@ -868,18 +932,6 @@ int WINAPI WinMain( HINSTANCE hInstance,         // The instance
 	}
 
 	// *** cleanup ***
-
-	textureIdMap.clear(); //no need to delete pointers in it manually here. (Pointers point to textureIds deleted in next step)
-
-	if (textureIds)
-	{
-		delete[] textureIds;
-		textureIds = NULL;
-	}
-
-	// *** cleanup end ***
-
-	destroyAILogger();
-	KillGLWindow();
-	return (msg.wParam);
+	cleanup();
+	return static_cast<int>(msg.wParam);
 }