diff --git a/code/MDL/HalfLife/HL1MDLLoader.cpp b/code/MDL/HalfLife/HL1MDLLoader.cpp index 06ffd7801..a53004eb5 100644 --- a/code/MDL/HalfLife/HL1MDLLoader.cpp +++ b/code/MDL/HalfLife/HL1MDLLoader.cpp @@ -182,6 +182,13 @@ void HL1MDLLoader::load_file() { read_global_info(); + if (!header_->numbodyparts) { + // This could be an MDL external texture file. In this case, + // add this flag to allow the scene to be loaded even if it + // has no meshes. + scene_->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; + } + // Append children to root node. if (rootnode_children_.size()) { scene_->mRootNode->addChildren( @@ -218,21 +225,6 @@ void HL1MDLLoader::validate_header(const Header_HL1 *header, bool is_texture_hea } } else { - // Every single Half-Life model is assumed to have at least one bodypart. - if (!header->numbodyparts) { - throw DeadlyImportError(MDL_HALFLIFE_LOG_HEADER "Model has no bodyparts"); - } - - // Every single Half-Life model is assumed to have at least one bone. - if (!header->numbones) { - throw DeadlyImportError(MDL_HALFLIFE_LOG_HEADER "Model has no bones"); - } - - // Every single Half-Life model is assumed to have at least one sequence group, - // which is the "default" sequence group. - if (!header->numseqgroups) { - throw DeadlyImportError(MDL_HALFLIFE_LOG_HEADER "Model has no sequence groups"); - } if (header->numbodyparts > AI_MDL_HL1_MAX_BODYPARTS) { log_warning_limit_exceeded(header->numbodyparts, "bodyparts"); @@ -498,6 +490,10 @@ void HL1MDLLoader::read_skins() { // ------------------------------------------------------------------------------------------------ void HL1MDLLoader::read_bones() { + if (!header_->numbones) { + return; + } + const Bone_HL1 *pbone = (const Bone_HL1 *)((uint8_t *)header_ + header_->boneindex); std::vector unique_bones_names(header_->numbones); @@ -588,6 +584,9 @@ void HL1MDLLoader::read_bones() { triangles, respectively (3 indices per face). */ void HL1MDLLoader::read_meshes() { + if (!header_->numbodyparts) { + return; + } int total_verts = 0; int total_triangles = 0; @@ -964,8 +963,9 @@ void HL1MDLLoader::read_meshes() { // ------------------------------------------------------------------------------------------------ void HL1MDLLoader::read_animations() { - if (!header_->numseq) + if (!header_->numseq) { return; + } const SequenceDesc_HL1 *pseqdesc = (const SequenceDesc_HL1 *)((uint8_t *)header_ + header_->seqindex); const SequenceGroup_HL1 *pseqgroup = nullptr; @@ -1067,6 +1067,9 @@ void HL1MDLLoader::read_animations() { // ------------------------------------------------------------------------------------------------ void HL1MDLLoader::read_sequence_groups_info() { + if (!header_->numseqgroups) { + return; + } aiNode *sequence_groups_node = new aiNode(AI_MDL_HL1_NODE_SEQUENCE_GROUPS); rootnode_children_.push_back(sequence_groups_node); diff --git a/test/unit/ImportExport/utMDLImporter.cpp b/test/unit/ImportExport/utMDLImporter.cpp index 561b3009f..b9a850175 100644 --- a/test/unit/ImportExport/utMDLImporter.cpp +++ b/test/unit/ImportExport/utMDLImporter.cpp @@ -57,13 +57,24 @@ public: virtual bool importerTest() { Assimp::Importer importer; - const aiScene *scene = importer.ReadFile(MDL_HL1_FILE_MAN, 0); - EXPECT_NE(nullptr, scene); + importerTest_HL1(&importer); // Add further MDL tests... return true; } + +private: + void importerTest_HL1(Assimp::Importer* const importer) { + const aiScene *scene = importer->ReadFile(MDL_HL1_FILE_MAN, 0); + EXPECT_NE(nullptr, scene); + + // Test that the importer can directly load an HL1 MDL external texture file. + scene = importer->ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "manT.mdl", aiProcess_ValidateDataStructure); + EXPECT_NE(nullptr, scene); + EXPECT_NE(0u, scene->mNumTextures); + EXPECT_NE(0u, scene->mNumMaterials); + } }; TEST_F(utMDLImporter, importMDLFromFileTest) {