Explorar el Código

Merge branch 'master' into kimkulling_dev

Kim Kulling hace 6 años
padre
commit
c4d98ced49

+ 3 - 0
.travis.yml

@@ -30,6 +30,9 @@ env:
     - secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
     - secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
     - PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
     - PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
 
 
+git:
+  depth: 1
+
 matrix:
 matrix:
   include:
   include:
     - os: linux
     - os: linux

+ 5 - 3
appveyor.yml

@@ -4,6 +4,8 @@
 # clone directory
 # clone directory
 clone_folder: c:\projects\assimp
 clone_folder: c:\projects\assimp
 
 
+clone_depth: 1
+
 # branches to build
 # branches to build
 branches:
 branches:
   # whitelist
   # whitelist
@@ -52,11 +54,11 @@ cache:
   - bin\.mtime_cache
   - bin\.mtime_cache
   
   
 before_build:
 before_build:
+  - echo NUMBER_OF_PROCESSORS=%NUMBER_OF_PROCESSORS%
   - ruby scripts\AppVeyor\mtime_cache -g scripts\AppVeyor\cacheglobs.txt -c bin\.mtime_cache\cache.json
   - ruby scripts\AppVeyor\mtime_cache -g scripts\AppVeyor\cacheglobs.txt -c bin\.mtime_cache\cache.json
   
   
-build:
-  parallel: true
-  project: Assimp.sln
+build_script:
+  cmake --build . --config Release -- /maxcpucount:2
   
   
 after_build:
 after_build:
   - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" (
   - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" (

+ 5 - 5
code/Assjson/cencode.c

@@ -45,7 +45,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
 			{
 			{
 				state_in->result = result;
 				state_in->result = result;
 				state_in->step = step_A;
 				state_in->step = step_A;
-				return codechar - code_out;
+				return (int)(codechar - code_out);
 			}
 			}
 			fragment = *plainchar++;
 			fragment = *plainchar++;
 			result = (fragment & 0x0fc) >> 2;
 			result = (fragment & 0x0fc) >> 2;
@@ -56,7 +56,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
 			{
 			{
 				state_in->result = result;
 				state_in->result = result;
 				state_in->step = step_B;
 				state_in->step = step_B;
-				return codechar - code_out;
+				return (int)(codechar - code_out);
 			}
 			}
 			fragment = *plainchar++;
 			fragment = *plainchar++;
 			result |= (fragment & 0x0f0) >> 4;
 			result |= (fragment & 0x0f0) >> 4;
@@ -67,7 +67,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
 			{
 			{
 				state_in->result = result;
 				state_in->result = result;
 				state_in->step = step_C;
 				state_in->step = step_C;
-				return codechar - code_out;
+				return (int)(codechar - code_out);
 			}
 			}
 			fragment = *plainchar++;
 			fragment = *plainchar++;
 			result |= (fragment & 0x0c0) >> 6;
 			result |= (fragment & 0x0c0) >> 6;
@@ -84,7 +84,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
 		}
 		}
 	}
 	}
 	/* control should not reach here */
 	/* control should not reach here */
-	return codechar - code_out;
+	return (int)(codechar - code_out);
 }
 }
 
 
 int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
 int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
@@ -107,7 +107,7 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
 	}
 	}
 	*codechar++ = '\n';
 	*codechar++ = '\n';
 	
 	
-	return codechar - code_out;
+	return (int)(codechar - code_out);
 }
 }
 
 
 #pragma warning(pop)
 #pragma warning(pop)

+ 2 - 2
code/MDL/HalfLife/HL1MDLLoader.cpp

@@ -175,9 +175,9 @@ void HL1MDLLoader::load_file() {
 
 
         release_resources();
         release_resources();
 
 
-    } catch (const std::exception &e) {
+    } catch (...) {
         release_resources();
         release_resources();
-        throw e;
+        throw;
     }
     }
 }
 }
 
 

+ 3 - 3
code/MDL/MDLLoader.cpp

@@ -179,9 +179,9 @@ void MDLImporter::InternReadFile( const std::string& pFile,
     }
     }
 
 
     // This should work for all other types of MDL files, too ...
     // This should work for all other types of MDL files, too ...
-    // the quake header is one of the smallest, afaik
+    // the HL1 sequence group header is one of the smallest, afaik
     iFileSize = (unsigned int)file->FileSize();
     iFileSize = (unsigned int)file->FileSize();
-    if( iFileSize < sizeof(MDL::Header)) {
+    if( iFileSize < sizeof(MDL::HalfLife::SequenceHeader_HL1)) {
         throw DeadlyImportError( "MDL File is too small.");
         throw DeadlyImportError( "MDL File is too small.");
     }
     }
 
 
@@ -1575,7 +1575,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
 				const size_t maxSize(buffersize - (i*AI_MDL7_MAX_GROUPNAMESIZE));
 				const size_t maxSize(buffersize - (i*AI_MDL7_MAX_GROUPNAMESIZE));
 				pcNode->mName.length = ai_snprintf(szBuffer, maxSize, "Group_%u", p);
 				pcNode->mName.length = ai_snprintf(szBuffer, maxSize, "Group_%u", p);
 			} else {
 			} else {
-				pcNode->mName.length = ::strlen(szBuffer);
+				pcNode->mName.length = (ai_uint32)::strlen(szBuffer);
 			}
 			}
             ::strncpy(pcNode->mName.data,szBuffer,MAXLEN-1);
             ::strncpy(pcNode->mName.data,szBuffer,MAXLEN-1);
             ++p;
             ++p;

+ 3 - 3
code/MDL/MDLMaterialLoader.cpp

@@ -541,7 +541,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
         size_t iLen2 = iLen+1;
         size_t iLen2 = iLen+1;
         iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
         iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
         memcpy(szFile.data,(const char*)szCurrent,iLen2);
         memcpy(szFile.data,(const char*)szCurrent,iLen2);
-        szFile.length = iLen;
+        szFile.length = (ai_uint32)iLen;
 
 
         szCurrent += iLen2;
         szCurrent += iLen2;
 
 
@@ -710,7 +710,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
         aiString szFile;
         aiString szFile;
         const size_t iLen = strlen((const char*)szCurrent);
         const size_t iLen = strlen((const char*)szCurrent);
         ::memcpy(szFile.data,(const char*)szCurrent,iLen+1);
         ::memcpy(szFile.data,(const char*)szCurrent,iLen+1);
-        szFile.length = iLen;
+        szFile.length = (ai_uint32)iLen;
 
 
         pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
         pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
 
 
@@ -831,7 +831,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
         aiString szFile;
         aiString szFile;
         ::memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name));
         ::memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name));
         szFile.data[sizeof(pcSkin->texture_name)] = '\0';
         szFile.data[sizeof(pcSkin->texture_name)] = '\0';
-        szFile.length = ::strlen(szFile.data);
+        szFile.length = (ai_uint32)::strlen(szFile.data);
 
 
         pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME);
         pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME);
     }
     }

+ 1 - 1
code/X/XFileImporter.cpp

@@ -211,7 +211,7 @@ aiNode* XFileImporter::CreateNodes( aiScene* pScene, aiNode* pParent, const XFil
 
 
     // create node
     // create node
     aiNode* node = new aiNode;
     aiNode* node = new aiNode;
-    node->mName.length = pNode->mName.length();
+    node->mName.length = (ai_uint32)pNode->mName.length();
     node->mParent = pParent;
     node->mParent = pParent;
     memcpy( node->mName.data, pNode->mName.c_str(), pNode->mName.length());
     memcpy( node->mName.data, pNode->mName.c_str(), pNode->mName.length());
     node->mName.data[node->mName.length] = 0;
     node->mName.data[node->mName.length] = 0;

+ 3 - 1
code/glTF/glTFAsset.inl

@@ -688,7 +688,9 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
         bufferView->byteOffset = b->AppendData(data, length);
         bufferView->byteOffset = b->AppendData(data, length);
     }
     }
     else { // text file: will be stored as a data uri
     else { // text file: will be stored as a data uri
-        this->mData.reset(data);
+        uint8_t *temp = new uint8_t[length];
+        memcpy(temp, data, length);
+        this->mData.reset(temp);
         this->mDataLength = length;
         this->mDataLength = length;
     }
     }
 }
 }

+ 4 - 5
code/glTF/glTFExporter.cpp

@@ -100,17 +100,16 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
 {
 {
     aiScene* sceneCopy_tmp;
     aiScene* sceneCopy_tmp;
     SceneCombiner::CopyScene(&sceneCopy_tmp, pScene);
     SceneCombiner::CopyScene(&sceneCopy_tmp, pScene);
-    aiScene *sceneCopy(sceneCopy_tmp);
 
 
     SplitLargeMeshesProcess_Triangle tri_splitter;
     SplitLargeMeshesProcess_Triangle tri_splitter;
     tri_splitter.SetLimit(0xffff);
     tri_splitter.SetLimit(0xffff);
-    tri_splitter.Execute(sceneCopy);
+    tri_splitter.Execute(sceneCopy_tmp);
 
 
     SplitLargeMeshesProcess_Vertex vert_splitter;
     SplitLargeMeshesProcess_Vertex vert_splitter;
     vert_splitter.SetLimit(0xffff);
     vert_splitter.SetLimit(0xffff);
-    vert_splitter.Execute(sceneCopy);
+    vert_splitter.Execute(sceneCopy_tmp);
 
 
-    mScene = sceneCopy;
+    mScene.reset(sceneCopy_tmp);
 
 
     mAsset.reset( new glTF::Asset( pIOSystem ) );
     mAsset.reset( new glTF::Asset( pIOSystem ) );
 
 
@@ -877,7 +876,7 @@ void glTFExporter::ExportMetadata()
 
 
 	// Copyright
 	// Copyright
 	aiString copyright_str;
 	aiString copyright_str;
-	if (mScene->mMetaData->Get(AI_METADATA_SOURCE_COPYRIGHT, copyright_str)) {
+	if (mScene->mMetaData != nullptr && mScene->mMetaData->Get(AI_METADATA_SOURCE_COPYRIGHT, copyright_str)) {
 		asset.copyright = copyright_str.C_Str();
 		asset.copyright = copyright_str.C_Str();
 	}
 	}
 }
 }

+ 1 - 1
code/glTF/glTFExporter.h

@@ -90,7 +90,7 @@ namespace Assimp
 
 
         const char* mFilename;
         const char* mFilename;
         IOSystem* mIOSystem;
         IOSystem* mIOSystem;
-        const aiScene* mScene;
+        std::shared_ptr<const aiScene> mScene;
         const ExportProperties* mProperties;
         const ExportProperties* mProperties;
 
 
         std::map<std::string, unsigned int> mTexturesByPath;
         std::map<std::string, unsigned int> mTexturesByPath;

+ 5 - 2
code/glTF2/glTF2Asset.inl

@@ -752,6 +752,7 @@ inline uint8_t* Image::StealData()
 	return mData.release();
 	return mData.release();
 }
 }
 
 
+// Never take over the ownership of data whenever binary or not
 inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
 inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
 {
 {
     Ref<Buffer> b = r.GetBodyBuffer();
     Ref<Buffer> b = r.GetBodyBuffer();
@@ -764,8 +765,10 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
         bufferView->byteOffset = b->AppendData(data, length);
         bufferView->byteOffset = b->AppendData(data, length);
     }
     }
     else { // text file: will be stored as a data uri
     else { // text file: will be stored as a data uri
-		this->mData.reset(data);
-		this->mDataLength = length;
+        uint8_t *temp = new uint8_t[length];
+        memcpy(temp, data, length);
+        this->mData.reset(temp);
+        this->mDataLength = length;
     }
     }
 }
 }
 
 

+ 2 - 4
code/glTF2/glTF2Exporter.cpp

@@ -352,10 +352,8 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
                     if (path[0] == '*') { // embedded
                     if (path[0] == '*') { // embedded
                         aiTexture* tex = mScene->mTextures[atoi(&path[1])];
                         aiTexture* tex = mScene->mTextures[atoi(&path[1])];
 
 
-                        // copy data since lifetime control is handed over to the asset
-                        uint8_t* data = new uint8_t[tex->mWidth];
-                        memcpy(data, tex->pcData, tex->mWidth);
-                        texture->source->SetData(data, tex->mWidth, *mAsset);
+                        // The asset has its own buffer, see Image::SetData
+                        texture->source->SetData(reinterpret_cast<uint8_t*> (tex->pcData), tex->mWidth, *mAsset);
 
 
                         if (tex->achFormatHint[0]) {
                         if (tex->achFormatHint[0]) {
                             std::string mimeType = "image/";
                             std::string mimeType = "image/";

+ 2 - 0
test/CMakeLists.txt

@@ -130,6 +130,8 @@ SET( IMPORTERS
   unit/ImportExport/utOFFImportExport.cpp
   unit/ImportExport/utOFFImportExport.cpp
   unit/ImportExport/utNFFImportExport.cpp
   unit/ImportExport/utNFFImportExport.cpp
   unit/ImportExport/utXGLImportExport.cpp
   unit/ImportExport/utXGLImportExport.cpp
+  unit/ImportExport/utMD2Importer.cpp
+  unit/ImportExport/utMD5Importer.cpp
   unit/ImportExport/utMDLImporter.cpp
   unit/ImportExport/utMDLImporter.cpp
   unit/ImportExport/MDL/MDLHL1TestFiles.h
   unit/ImportExport/MDL/MDLHL1TestFiles.h
   unit/ImportExport/MDL/utMDLImporter_HL1_ImportSettings.cpp
   unit/ImportExport/MDL/utMDLImporter_HL1_ImportSettings.cpp

BIN
test/models/COB/dwarf.cob


BIN
test/models/MS3D/Wuson.ms3d


BIN
test/models/glTF2/BoxTextured-glTF-Binary/BoxTextured.glb


+ 58 - 12
test/unit/ImportExport/utCOBImportExport.cpp

@@ -43,22 +43,68 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include "UnitTestPCH.h"
 #include "UnitTestPCH.h"
 #include "SceneDiffer.h"
 #include "SceneDiffer.h"
-#include "AbstractImportExportBase.h"
 
 
 #include <assimp/Importer.hpp>
 #include <assimp/Importer.hpp>
 #include <assimp/postprocess.h>
 #include <assimp/postprocess.h>
 
 
 using namespace Assimp;
 using namespace Assimp;
 
 
-class utCOBImportExport : public AbstractImportExportBase {
-public:
-    virtual bool importerTest() {
-        Assimp::Importer importer;
-        const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/molecule.cob", aiProcess_ValidateDataStructure);
-        return nullptr != scene;
-    }
-};
-
-TEST_F(utCOBImportExport, importAMFFromFileTest) {
-    EXPECT_TRUE(importerTest());
+
+TEST(utCOBImporter, importDwarfASCII) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/dwarf_ascii.cob", aiProcess_ValidateDataStructure);
+    // FIXME: this is wrong, it should succeed
+    // change to ASSERT_NE after it's been fixed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importDwarf) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/dwarf.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importMoleculeASCII) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/molecule_ascii.cob", aiProcess_ValidateDataStructure);
+    // FIXME: this is wrong, it should succeed
+    // change to ASSERT_NE after it's been fixed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importMolecule) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/molecule.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importSpider43ASCII) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/spider_4_3_ascii.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importSpider43) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/spider_4_3.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importSpider66ASCII) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/spider_6_6_ascii.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importSpider66) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/spider_6_6.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
 }
 }

+ 87 - 0
test/unit/ImportExport/utMD2Importer.cpp

@@ -0,0 +1,87 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2020, 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 "UnitTestPCH.h"
+
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <assimp/Importer.hpp>
+
+
+using namespace Assimp;
+
+
+
+TEST(utMD2Importer, importFaerie) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/MD2/faerie.md2", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD2Importer, importSydney) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/MD2/sydney.md2", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD2Importer, importDolphin) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD2/dolphin.md2", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD2Importer, importFlag) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD2/flag.md2", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD2Importer, importHorse) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD2/horse.md2", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}

+ 80 - 0
test/unit/ImportExport/utMD5Importer.cpp

@@ -0,0 +1,80 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2020, 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 "UnitTestPCH.h"
+
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <assimp/Importer.hpp>
+
+
+using namespace Assimp;
+
+
+
+TEST(utMD5Importer, importEmpty) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/MD5/invalid/empty.md5mesh", aiProcess_ValidateDataStructure);
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST(utMD5Importer, importSimpleCube) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/MD5/SimpleCube.md5mesh", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD5Importer, importBoarMan) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD5/BoarMan.md5mesh", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD5Importer, importBob) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD5/Bob.md5mesh", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}