1 /*
2 ---------------------------------------------------------------------------
3 Open Asset Import Library (assimp)
4 ---------------------------------------------------------------------------
5 
6 Copyright (c) 2006-2021, assimp team
7 
8 All rights reserved.
9 
10 Redistribution and use of this software in source and binary forms,
11 with or without modification, are permitted provided that the following
12 conditions are met:
13 
14 * Redistributions of source code must retain the above
15 copyright notice, this list of conditions and the
16 following disclaimer.
17 
18 * Redistributions in binary form must reproduce the above
19 copyright notice, this list of conditions and the
20 following disclaimer in the documentation and/or other
21 materials provided with the distribution.
22 
23 * Neither the name of the assimp team, nor the names of its
24 contributors may be used to endorse or promote products
25 derived from this software without specific prior
26 written permission of the assimp team.
27 
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 ---------------------------------------------------------------------------
40 */
41 
42 /** @file utMDLImporter_HL1_ImportSettings.cpp
43  *  @brief Half-Life 1 MDL loader import settings tests.
44  */
45 
46 #include "AbstractImportExportBase.h"
47 #include "AssetLib/MDL/HalfLife/HL1ImportDefinitions.h"
48 #include "MDLHL1TestFiles.h"
49 #include "UnitTestPCH.h"
50 #include <assimp/postprocess.h>
51 #include <assimp/scene.h>
52 #include <assimp/Importer.hpp>
53 #include <functional>
54 #include <initializer_list>
55 
56 using namespace Assimp;
57 
58 class utMDLImporter_HL1_ImportSettings : public ::testing::Test {
59 
60 public:
61     // Test various import settings scenarios.
62 
importSettings()63     void importSettings() {
64 
65         /* Verify that animations are *NOT* imported when
66            'Read animations' is disabled. */
67         load_with_import_setting_bool(
68                 MDL_HL1_FILE_MAN,
69                 AI_CONFIG_IMPORT_MDL_HL1_READ_ANIMATIONS,
70                 false, // Set config value to false.
71                 [&](const aiScene *scene) {
72                     EXPECT_EQ(0u, scene->mNumAnimations);
73                     EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS));
74                     EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_GROUPS));
75                     EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_TRANSITION_GRAPH));
76 
77                     expect_global_info_eq<int>(scene, { { 0, "NumSequences" },
78                                                               { 0, "NumTransitionNodes" } });
79                 });
80 
81         /* Verify that blend controllers info is *NOT* imported when
82            'Read blend controllers' is disabled. */
83         load_with_import_setting_bool(
84                 MDL_HL1_FILE_MAN,
85                 AI_CONFIG_IMPORT_MDL_HL1_READ_BLEND_CONTROLLERS,
86                 false, // Set config value to false.
87                 [&](const aiScene *scene) {
88                     EXPECT_NE(0u, scene->mNumAnimations);
89 
90                     const aiNode *sequence_infos = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS);
91                     EXPECT_NE(nullptr, sequence_infos);
92 
93                     for (unsigned int i = 0; i < sequence_infos->mNumChildren; ++i)
94                         EXPECT_EQ(nullptr, sequence_infos->mChildren[i]->FindNode(AI_MDL_HL1_NODE_BLEND_CONTROLLERS));
95 
96                     expect_global_info_eq(scene, 0, "NumBlendControllers");
97                 });
98 
99         /* Verify that animation events are *NOT* imported when
100            'Read animation events' is disabled. */
101         load_with_import_setting_bool(
102                 MDL_HL1_FILE_MAN,
103                 AI_CONFIG_IMPORT_MDL_HL1_READ_ANIMATION_EVENTS,
104                 false, // Set config value to false.
105                 [&](const aiScene *scene) {
106                     EXPECT_NE(0u, scene->mNumAnimations);
107 
108                     const aiNode *sequence_infos = scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_INFOS);
109                     EXPECT_NE(nullptr, sequence_infos);
110 
111                     for (unsigned int i = 0; i < sequence_infos->mNumChildren; ++i)
112                         EXPECT_EQ(nullptr, sequence_infos->mChildren[i]->FindNode(AI_MDL_HL1_NODE_ANIMATION_EVENTS));
113                 });
114 
115         /* Verify that sequence transitions info is read when
116            'Read sequence transitions' is enabled. */
117         load_with_import_setting_bool(
118                 ASSIMP_TEST_MDL_HL1_MODELS_DIR "sequence_transitions.mdl",
119                 AI_CONFIG_IMPORT_MDL_HL1_READ_SEQUENCE_TRANSITIONS,
120                 true, // Set config value to true.
121                 [&](const aiScene *scene) {
122                     EXPECT_NE(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_TRANSITION_GRAPH));
123                     expect_global_info_eq(scene, 4, "NumTransitionNodes");
124                 });
125 
126         /* Verify that sequence transitions info is *NOT* read when
127            'Read sequence transitions' is disabled. */
128         load_with_import_setting_bool(
129                 ASSIMP_TEST_MDL_HL1_MODELS_DIR "sequence_transitions.mdl",
130                 AI_CONFIG_IMPORT_MDL_HL1_READ_SEQUENCE_TRANSITIONS,
131                 false, // Set config value to false.
132                 [&](const aiScene *scene) {
133                     EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_SEQUENCE_TRANSITION_GRAPH));
134                     expect_global_info_eq(scene, 0, "NumTransitionNodes");
135                 });
136 
137         /* Verify that bone controllers info is *NOT* read when
138            'Read bone controllers' is disabled. */
139         load_with_import_setting_bool(
140                 MDL_HL1_FILE_MAN,
141                 AI_CONFIG_IMPORT_MDL_HL1_READ_BONE_CONTROLLERS,
142                 false, // Set config value to false.
143                 [&](const aiScene *scene) {
144                     EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_BONE_CONTROLLERS));
145                     expect_global_info_eq(scene, 0, "NumBoneControllers");
146                 });
147 
148         /* Verify that attachments info is *NOT* read when
149            'Read attachments' is disabled. */
150         load_with_import_setting_bool(
151                 MDL_HL1_FILE_MAN,
152                 AI_CONFIG_IMPORT_MDL_HL1_READ_ATTACHMENTS,
153                 false, // Set config value to false.
154                 [&](const aiScene *scene) {
155                     EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_ATTACHMENTS));
156                     expect_global_info_eq(scene, 0, "NumAttachments");
157                 });
158 
159         /* Verify that hitboxes info is *NOT* read when
160            'Read hitboxes' is disabled. */
161         load_with_import_setting_bool(
162                 MDL_HL1_FILE_MAN,
163                 AI_CONFIG_IMPORT_MDL_HL1_READ_HITBOXES,
164                 false, // Set config value to false.
165                 [&](const aiScene *scene) {
166                     EXPECT_EQ(nullptr, scene->mRootNode->FindNode(AI_MDL_HL1_NODE_HITBOXES));
167                     expect_global_info_eq(scene, 0, "NumHitboxes");
168                 });
169 
170         /* Verify that misc global info is *NOT* read when
171            'Read misc global info' is disabled. */
172         load_with_import_setting_bool(
173                 MDL_HL1_FILE_MAN,
174                 AI_CONFIG_IMPORT_MDL_HL1_READ_MISC_GLOBAL_INFO,
175                 false, // Set config value to false.
176                 [&](const aiScene *scene) {
177                     aiNode *global_info = get_global_info(scene);
178                     EXPECT_NE(nullptr, global_info);
179                     aiVector3D temp;
180                     EXPECT_FALSE(global_info->mMetaData->Get("EyePosition", temp));
181                 });
182     }
183 
184 private:
load_with_import_setting_bool(const char * file_path,const char * setting_key,bool setting_value,std::function<void (const aiScene *)> && func)185     void load_with_import_setting_bool(
186             const char *file_path,
187             const char *setting_key,
188             bool setting_value,
189             std::function<void(const aiScene *)> &&func) {
190         Assimp::Importer importer;
191         importer.SetPropertyBool(setting_key, setting_value);
192         const aiScene *scene = importer.ReadFile(file_path, aiProcess_ValidateDataStructure);
193         EXPECT_NE(nullptr, scene);
194         func(scene);
195     }
196 
get_global_info(const aiScene * scene)197     inline static aiNode *get_global_info(const aiScene *scene) {
198         return scene->mRootNode->FindNode(AI_MDL_HL1_NODE_GLOBAL_INFO);
199     }
200 
201     template <typename T>
expect_global_info_eq(const aiScene * scene,T expected_value,const char * key_name)202     static void expect_global_info_eq(
203             const aiScene *scene,
204             T expected_value,
205             const char *key_name) {
206         aiNode *global_info = get_global_info(scene);
207         EXPECT_NE(nullptr, global_info);
208         T temp;
209         EXPECT_TRUE(global_info->mMetaData->Get(key_name, temp));
210         EXPECT_EQ(expected_value, temp);
211     }
212 
213     template <typename T>
expect_global_info_eq(const aiScene * scene,std::initializer_list<std::pair<T,const char * >> p_kv)214     static void expect_global_info_eq(const aiScene *scene,
215             std::initializer_list<std::pair<T, const char *>> p_kv) {
216         aiNode *global_info = get_global_info(scene);
217         EXPECT_NE(nullptr, global_info);
218         for (auto it = p_kv.begin(); it != p_kv.end(); ++it) {
219             T temp;
220             EXPECT_TRUE(global_info->mMetaData->Get(it->second, temp));
221             EXPECT_EQ(it->first, temp);
222         }
223     }
224 };
225 
TEST_F(utMDLImporter_HL1_ImportSettings,importSettings)226 TEST_F(utMDLImporter_HL1_ImportSettings, importSettings) {
227     importSettings();
228 }
229