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 #include "AbstractImportExportBase.h"
43 #include "UnitTestPCH.h"
44
45 #include <assimp/commonMetaData.h>
46 #include <assimp/material.h>
47 #include <assimp/postprocess.h>
48 #include <assimp/scene.h>
49 #include <assimp/types.h>
50 #include <assimp/Importer.hpp>
51
52 using namespace Assimp;
53
54 class utFBXImporterExporter : public AbstractImportExportBase {
55 public:
importerTest()56 virtual bool importerTest() {
57 Assimp::Importer importer;
58 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/spider.fbx", aiProcess_ValidateDataStructure);
59 return nullptr != scene;
60 }
61 };
62
TEST_F(utFBXImporterExporter,importXFromFileTest)63 TEST_F(utFBXImporterExporter, importXFromFileTest) {
64 EXPECT_TRUE(importerTest());
65 }
66
TEST_F(utFBXImporterExporter,importBareBoxWithoutColorsAndTextureCoords)67 TEST_F(utFBXImporterExporter, importBareBoxWithoutColorsAndTextureCoords) {
68 Assimp::Importer importer;
69 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/box.fbx", aiProcess_ValidateDataStructure);
70 EXPECT_NE(nullptr, scene);
71 EXPECT_EQ(scene->mNumMeshes, 1u);
72 aiMesh *mesh = scene->mMeshes[0];
73 EXPECT_EQ(mesh->mNumFaces, 12u);
74 EXPECT_EQ(mesh->mNumVertices, 36u);
75 }
76
TEST_F(utFBXImporterExporter,importCubesWithNoNames)77 TEST_F(utFBXImporterExporter, importCubesWithNoNames) {
78 Assimp::Importer importer;
79 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/cubes_nonames.fbx", aiProcess_ValidateDataStructure);
80 ASSERT_TRUE(scene);
81
82 ASSERT_TRUE(scene->mRootNode);
83 const auto root = scene->mRootNode;
84 ASSERT_STREQ(root->mName.C_Str(), "RootNode");
85 ASSERT_TRUE(root->mChildren);
86 ASSERT_EQ(root->mNumChildren, 2u);
87 }
88
TEST_F(utFBXImporterExporter,importCubesWithUnicodeDuplicatedNames)89 TEST_F(utFBXImporterExporter, importCubesWithUnicodeDuplicatedNames) {
90 Assimp::Importer importer;
91 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/cubes_with_names.fbx", aiProcess_ValidateDataStructure);
92 ASSERT_TRUE(scene);
93
94 ASSERT_TRUE(scene->mRootNode);
95 const auto root = scene->mRootNode;
96 ASSERT_STREQ(root->mName.C_Str(), "RootNode");
97 ASSERT_TRUE(root->mChildren);
98 ASSERT_EQ(root->mNumChildren, 2u);
99
100 const auto child0 = root->mChildren[0];
101 ASSERT_TRUE(child0);
102 ASSERT_STREQ(child0->mName.C_Str(), "Cube2");
103 ASSERT_TRUE(child0->mChildren);
104 ASSERT_EQ(child0->mNumChildren, 1u);
105
106 const auto child00 = child0->mChildren[0];
107 ASSERT_TRUE(child00);
108 ASSERT_STREQ(child00->mName.C_Str(), "\xd0\x9a\xd1\x83\xd0\xb1\x31");
109
110 const auto child1 = root->mChildren[1];
111 ASSERT_TRUE(child1);
112 ASSERT_STREQ(child1->mName.C_Str(), "Cube3");
113 ASSERT_TRUE(child1->mChildren);
114 ASSERT_EQ(child1->mNumChildren, 1u);
115
116 const auto child10 = child1->mChildren[0];
117 ASSERT_TRUE(child10);
118 ASSERT_STREQ(child10->mName.C_Str(), "\xd0\x9a\xd1\x83\xd0\xb1\x31");
119 }
120
TEST_F(utFBXImporterExporter,importCubesComplexTransform)121 TEST_F(utFBXImporterExporter, importCubesComplexTransform) {
122 Assimp::Importer importer;
123 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/cubes_with_mirroring_and_pivot.fbx", aiProcess_ValidateDataStructure);
124 ASSERT_TRUE(scene);
125
126 ASSERT_TRUE(scene->mRootNode);
127 const auto root = scene->mRootNode;
128 ASSERT_STREQ(root->mName.C_Str(), "RootNode");
129 ASSERT_TRUE(root->mChildren);
130 ASSERT_EQ(root->mNumChildren, 2u);
131
132 const auto child0 = root->mChildren[0];
133 ASSERT_TRUE(child0);
134 ASSERT_STREQ(child0->mName.C_Str(), "Cube2");
135 ASSERT_TRUE(child0->mChildren);
136 ASSERT_EQ(child0->mNumChildren, 1u);
137
138 const auto child00 = child0->mChildren[0];
139 ASSERT_TRUE(child00);
140 ASSERT_STREQ(child00->mName.C_Str(), "Cube1");
141
142 const auto child1 = root->mChildren[1];
143 ASSERT_TRUE(child1);
144 ASSERT_STREQ(child1->mName.C_Str(), "Cube3");
145
146 auto parent = child1;
147 const size_t chain_length = 8u;
148 const char *chainStr[chain_length] = {
149 "Cube1_$AssimpFbx$_Translation",
150 "Cube1_$AssimpFbx$_RotationPivot",
151 "Cube1_$AssimpFbx$_RotationPivotInverse",
152 "Cube1_$AssimpFbx$_ScalingOffset",
153 "Cube1_$AssimpFbx$_ScalingPivot",
154 "Cube1_$AssimpFbx$_Scaling",
155 "Cube1_$AssimpFbx$_ScalingPivotInverse",
156 "Cube1"
157 };
158 for (size_t i = 0; i < chain_length; ++i) {
159 ASSERT_TRUE(parent->mChildren);
160 ASSERT_EQ(parent->mNumChildren, 1u);
161 auto node = parent->mChildren[0];
162 ASSERT_TRUE(node);
163 ASSERT_STREQ(node->mName.C_Str(), chainStr[i]);
164 parent = node;
165 }
166 ASSERT_EQ(0u, parent->mNumChildren) << "Leaf node";
167 }
168
TEST_F(utFBXImporterExporter,importCloseToIdentityTransforms)169 TEST_F(utFBXImporterExporter, importCloseToIdentityTransforms) {
170 Assimp::Importer importer;
171 // This was asserting in FBXConverter.cpp because the transforms appeared to be the identity by one test, but not by another.
172 // This asset should now load successfully.
173 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/close_to_identity_transforms.fbx", aiProcess_ValidateDataStructure);
174 ASSERT_TRUE(scene);
175 }
176
TEST_F(utFBXImporterExporter,importPhongMaterial)177 TEST_F(utFBXImporterExporter, importPhongMaterial) {
178 Assimp::Importer importer;
179 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/phong_cube.fbx", aiProcess_ValidateDataStructure);
180 EXPECT_NE(nullptr, scene);
181 EXPECT_EQ(1u, scene->mNumMaterials);
182 const aiMaterial *mat = scene->mMaterials[0];
183 EXPECT_NE(nullptr, mat);
184 float f;
185 aiColor3D c;
186
187 // phong_cube.fbx has all properties defined
188 EXPECT_EQ(mat->Get(AI_MATKEY_COLOR_DIFFUSE, c), aiReturn_SUCCESS);
189 EXPECT_EQ(c, aiColor3D(0.5, 0.25, 0.25));
190 EXPECT_EQ(mat->Get(AI_MATKEY_COLOR_SPECULAR, c), aiReturn_SUCCESS);
191 EXPECT_EQ(c, aiColor3D(0.25, 0.25, 0.5));
192 EXPECT_EQ(mat->Get(AI_MATKEY_SHININESS_STRENGTH, f), aiReturn_SUCCESS);
193 EXPECT_EQ(f, 0.5f);
194 EXPECT_EQ(mat->Get(AI_MATKEY_SHININESS, f), aiReturn_SUCCESS);
195 EXPECT_EQ(f, 10.0f);
196 EXPECT_EQ(mat->Get(AI_MATKEY_COLOR_AMBIENT, c), aiReturn_SUCCESS);
197 EXPECT_EQ(c, aiColor3D(0.125, 0.25, 0.25));
198 EXPECT_EQ(mat->Get(AI_MATKEY_COLOR_EMISSIVE, c), aiReturn_SUCCESS);
199 EXPECT_EQ(c, aiColor3D(0.25, 0.125, 0.25));
200 EXPECT_EQ(mat->Get(AI_MATKEY_COLOR_TRANSPARENT, c), aiReturn_SUCCESS);
201 EXPECT_EQ(c, aiColor3D(0.75, 0.5, 0.25));
202 EXPECT_EQ(mat->Get(AI_MATKEY_OPACITY, f), aiReturn_SUCCESS);
203 EXPECT_EQ(f, 0.5f);
204 }
205
TEST_F(utFBXImporterExporter,importUnitScaleFactor)206 TEST_F(utFBXImporterExporter, importUnitScaleFactor) {
207 Assimp::Importer importer;
208 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/global_settings.fbx", aiProcess_ValidateDataStructure);
209
210 EXPECT_NE(nullptr, scene);
211 EXPECT_NE(nullptr, scene->mMetaData);
212
213 float factor(0.0f);
214 scene->mMetaData->Get("UnitScaleFactor", factor);
215 EXPECT_EQ(500.0f, factor);
216
217 scene->mMetaData->Set("UnitScaleFactor", factor * 2.0f);
218 scene->mMetaData->Get("UnitScaleFactor", factor);
219 EXPECT_EQ(1000.0f, factor);
220 }
221
TEST_F(utFBXImporterExporter,importEmbeddedAsciiTest)222 TEST_F(utFBXImporterExporter, importEmbeddedAsciiTest) {
223 // see https://github.com/assimp/assimp/issues/1957
224 Assimp::Importer importer;
225 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/embedded_ascii/box.FBX", aiProcess_ValidateDataStructure);
226 EXPECT_NE(nullptr, scene);
227
228 EXPECT_EQ(1u, scene->mNumMaterials);
229 aiMaterial *mat = scene->mMaterials[0];
230 ASSERT_NE(nullptr, mat);
231
232 aiString path;
233 aiTextureMapMode modes[2];
234 EXPECT_EQ(aiReturn_SUCCESS, mat->GetTexture(aiTextureType_DIFFUSE, 0, &path, nullptr, nullptr, nullptr, nullptr, modes));
235 ASSERT_STREQ(path.C_Str(), "..\\..\\..\\Desktop\\uv_test.png");
236
237 ASSERT_EQ(1u, scene->mNumTextures);
238 ASSERT_TRUE(scene->mTextures[0]->pcData);
239 ASSERT_EQ(439176u, scene->mTextures[0]->mWidth) << "FBX ASCII base64 compression splits data by 512Kb, it should be two parts for this texture";
240 }
241
TEST_F(utFBXImporterExporter,importEmbeddedFragmentedAsciiTest)242 TEST_F(utFBXImporterExporter, importEmbeddedFragmentedAsciiTest) {
243 // see https://github.com/assimp/assimp/issues/1957
244 Assimp::Importer importer;
245 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/embedded_ascii/box_embedded_texture_fragmented.fbx", aiProcess_ValidateDataStructure);
246 EXPECT_NE(nullptr, scene);
247
248 EXPECT_EQ(1u, scene->mNumMaterials);
249 aiMaterial *mat = scene->mMaterials[0];
250 ASSERT_NE(nullptr, mat);
251
252 aiString path;
253 aiTextureMapMode modes[2];
254 ASSERT_EQ(aiReturn_SUCCESS, mat->GetTexture(aiTextureType_DIFFUSE, 0, &path, nullptr, nullptr, nullptr, nullptr, modes));
255 ASSERT_STREQ(path.C_Str(), "paper.png");
256
257 ASSERT_EQ(1u, scene->mNumTextures);
258 ASSERT_TRUE(scene->mTextures[0]->pcData);
259 ASSERT_EQ(968029u, scene->mTextures[0]->mWidth) << "FBX ASCII base64 compression splits data by 512Kb, it should be two parts for this texture";
260 }
261
TEST_F(utFBXImporterExporter,fbxTokenizeTestTest)262 TEST_F(utFBXImporterExporter, fbxTokenizeTestTest) {
263 //Assimp::Importer importer;
264 //const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/transparentTest2.fbx", aiProcess_ValidateDataStructure);
265 //EXPECT_NE(nullptr, scene);
266 }
267
TEST_F(utFBXImporterExporter,importOrphantEmbeddedTextureTest)268 TEST_F(utFBXImporterExporter, importOrphantEmbeddedTextureTest) {
269 // see https://github.com/assimp/assimp/issues/1957
270 Assimp::Importer importer;
271 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/box_orphant_embedded_texture.fbx", aiProcess_ValidateDataStructure);
272 EXPECT_NE(nullptr, scene);
273
274 EXPECT_EQ(1u, scene->mNumMaterials);
275 aiMaterial *mat = scene->mMaterials[0];
276 ASSERT_NE(nullptr, mat);
277
278 aiString path;
279 aiTextureMapMode modes[2];
280 ASSERT_EQ(aiReturn_SUCCESS, mat->GetTexture(aiTextureType_DIFFUSE, 0, &path, nullptr, nullptr, nullptr, nullptr, modes));
281 ASSERT_STREQ(path.C_Str(), "..\\Primitives\\GridGrey.tga");
282
283 ASSERT_EQ(1u, scene->mNumTextures);
284 ASSERT_TRUE(scene->mTextures[0]->pcData);
285 ASSERT_EQ(9026u, scene->mTextures[0]->mWidth) << "FBX ASCII base64 compression used for a texture.";
286 }
287
TEST_F(utFBXImporterExporter,sceneMetadata)288 TEST_F(utFBXImporterExporter, sceneMetadata) {
289 Assimp::Importer importer;
290 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/global_settings.fbx",
291 aiProcess_ValidateDataStructure);
292 ASSERT_NE(scene, nullptr);
293 ASSERT_NE(scene->mMetaData, nullptr);
294 {
295 ASSERT_TRUE(scene->mMetaData->HasKey(AI_METADATA_SOURCE_FORMAT));
296 aiString format;
297 ASSERT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_FORMAT, format));
298 ASSERT_EQ(strcmp(format.C_Str(), "Autodesk FBX Importer"), 0);
299 }
300 {
301 ASSERT_TRUE(scene->mMetaData->HasKey(AI_METADATA_SOURCE_FORMAT_VERSION));
302 aiString version;
303 ASSERT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_FORMAT_VERSION, version));
304 ASSERT_EQ(strcmp(version.C_Str(), "7400"), 0);
305 }
306 {
307 ASSERT_TRUE(scene->mMetaData->HasKey(AI_METADATA_SOURCE_GENERATOR));
308 aiString generator;
309 ASSERT_TRUE(scene->mMetaData->Get(AI_METADATA_SOURCE_GENERATOR, generator));
310 ASSERT_EQ(strncmp(generator.C_Str(), "Blender", 7), 0);
311 }
312 }
313
TEST_F(utFBXImporterExporter,importCubesWithOutOfRangeFloat)314 TEST_F(utFBXImporterExporter, importCubesWithOutOfRangeFloat) {
315 Assimp::Importer importer;
316 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/cubes_with_outofrange_float.fbx", aiProcess_ValidateDataStructure);
317 ASSERT_NE(nullptr, scene);
318 ASSERT_TRUE(scene->mRootNode);
319 }
320
TEST_F(utFBXImporterExporter,importMaxPbrMaterialsMetalRoughness)321 TEST_F(utFBXImporterExporter, importMaxPbrMaterialsMetalRoughness) {
322 Assimp::Importer importer;
323 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/maxPbrMaterial_metalRough.fbx", aiProcess_ValidateDataStructure);
324 ASSERT_NE(nullptr, scene);
325 ASSERT_TRUE(scene->mRootNode);
326
327 ASSERT_EQ(scene->mNumMaterials, 1u);
328 const aiMaterial* mat = scene->mMaterials[0];
329 aiString texture;
330 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_BASE_COLOR, 0), texture), AI_SUCCESS);
331 EXPECT_EQ(texture, aiString("Textures\\albedo.png"));
332 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_METALNESS, 0), texture), AI_SUCCESS);
333 EXPECT_EQ(texture, aiString("Textures\\metalness.png"));
334 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_EMISSION_COLOR, 0), texture), AI_SUCCESS);
335 EXPECT_EQ(texture, aiString("Textures\\emission.png"));
336 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_NORMAL_CAMERA, 0), texture), AI_SUCCESS);
337 EXPECT_EQ(texture, aiString("Textures\\normal.png"));
338 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE_ROUGHNESS, 0), texture), AI_SUCCESS);
339 EXPECT_EQ(texture, aiString("Textures\\roughness.png"));
340 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_AMBIENT_OCCLUSION, 0), texture), AI_SUCCESS);
341 EXPECT_EQ(texture, aiString("Textures\\occlusion.png"));
342 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_OPACITY, 0), texture), AI_SUCCESS);
343 EXPECT_EQ(texture, aiString("Textures\\opacity.png"));
344
345 // The material contains values for standard properties (e.g. SpecularColor), where 3ds Max has presumably
346 // used formulas to map the Pbr values into the standard material model. However, the pbr values themselves
347 // are available in the material as untyped "raw" properties. We check that these are correctly parsed:
348
349 aiColor4D baseColor;
350 ASSERT_EQ(mat->Get("$raw.3dsMax|main|basecolor", aiTextureType_NONE, 0, baseColor), aiReturn_SUCCESS);
351 EXPECT_EQ(baseColor, aiColor4D(0, 1, 1, 1));
352
353 float metalness;
354 ASSERT_EQ(mat->Get("$raw.3dsMax|main|metalness", aiTextureType_NONE, 0, metalness), aiReturn_SUCCESS);
355 EXPECT_EQ(metalness, 0.25f);
356
357 float roughness;
358 ASSERT_EQ(mat->Get("$raw.3dsMax|main|roughness", aiTextureType_NONE, 0, roughness), aiReturn_SUCCESS);
359 EXPECT_EQ(roughness, 0.5f);
360
361 int useGlossiness;
362 ASSERT_EQ(mat->Get("$raw.3dsMax|main|useGlossiness", aiTextureType_NONE, 0, useGlossiness), aiReturn_SUCCESS);
363 EXPECT_EQ(useGlossiness, 2); // 1 = Roughness map is glossiness, 2 = Roughness map is roughness.
364
365 float bumpMapAmt; // Presumably amount.
366 ASSERT_EQ(mat->Get("$raw.3dsMax|main|bump_map_amt", aiTextureType_NONE, 0, bumpMapAmt), aiReturn_SUCCESS);
367 EXPECT_EQ(bumpMapAmt, 0.75f);
368
369 aiColor4D emitColor;
370 ASSERT_EQ(mat->Get("$raw.3dsMax|main|emit_color", aiTextureType_NONE, 0, emitColor), aiReturn_SUCCESS);
371 EXPECT_EQ(emitColor, aiColor4D(1, 1, 0, 1));
372 }
373
TEST_F(utFBXImporterExporter,importMaxPbrMaterialsSpecularGloss)374 TEST_F(utFBXImporterExporter, importMaxPbrMaterialsSpecularGloss) {
375 Assimp::Importer importer;
376 const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/maxPbrMaterial_specGloss.fbx", aiProcess_ValidateDataStructure);
377 ASSERT_NE(nullptr, scene);
378 ASSERT_TRUE(scene->mRootNode);
379
380 ASSERT_EQ(scene->mNumMaterials, 1u);
381 const aiMaterial* mat = scene->mMaterials[0];
382 aiString texture;
383 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_BASE_COLOR, 0), texture), AI_SUCCESS);
384 EXPECT_EQ(texture, aiString("Textures\\albedo.png"));
385 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_SPECULAR, 0), texture), AI_SUCCESS);
386 EXPECT_EQ(texture, aiString("Textures\\specular.png"));
387 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_EMISSION_COLOR, 0), texture), AI_SUCCESS);
388 EXPECT_EQ(texture, aiString("Textures\\emission.png"));
389 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_NORMAL_CAMERA, 0), texture), AI_SUCCESS);
390 EXPECT_EQ(texture, aiString("Textures\\normal.png"));
391 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0), texture), AI_SUCCESS);
392 EXPECT_EQ(texture, aiString("Textures\\glossiness.png"));
393 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_AMBIENT_OCCLUSION, 0), texture), AI_SUCCESS);
394 EXPECT_EQ(texture, aiString("Textures\\occlusion.png"));
395 ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_OPACITY, 0), texture), AI_SUCCESS);
396 EXPECT_EQ(texture, aiString("Textures\\opacity.png"));
397
398 // The material contains values for standard properties (e.g. SpecularColor), where 3ds Max has presumably
399 // used formulas to map the Pbr values into the standard material model. However, the pbr values themselves
400 // are available in the material as untyped "raw" properties. We check that these are correctly parsed:
401
402 aiColor4D baseColor;
403 ASSERT_EQ(mat->Get("$raw.3dsMax|main|basecolor", aiTextureType_NONE, 0, baseColor), aiReturn_SUCCESS);
404 EXPECT_EQ(baseColor, aiColor4D(0, 1, 1, 1));
405
406 aiColor4D specular;
407 ASSERT_EQ(mat->Get("$raw.3dsMax|main|Specular", aiTextureType_NONE, 0, specular), aiReturn_SUCCESS);
408 EXPECT_EQ(specular, aiColor4D(1, 1, 0, 1));
409
410 float glossiness;
411 ASSERT_EQ(mat->Get("$raw.3dsMax|main|glossiness", aiTextureType_NONE, 0, glossiness), aiReturn_SUCCESS);
412 EXPECT_EQ(glossiness, 0.33f);
413
414 int useGlossiness;
415 ASSERT_EQ(mat->Get("$raw.3dsMax|main|useGlossiness", aiTextureType_NONE, 0, useGlossiness), aiReturn_SUCCESS);
416 EXPECT_EQ(useGlossiness, 1); // 1 = Glossiness map is glossiness, 2 = Glossiness map is roughness.
417
418 float bumpMapAmt; // Presumably amount.
419 ASSERT_EQ(mat->Get("$raw.3dsMax|main|bump_map_amt", aiTextureType_NONE, 0, bumpMapAmt), aiReturn_SUCCESS);
420 EXPECT_EQ(bumpMapAmt, 0.66f);
421
422 aiColor4D emitColor;
423 ASSERT_EQ(mat->Get("$raw.3dsMax|main|emit_color", aiTextureType_NONE, 0, emitColor), aiReturn_SUCCESS);
424 EXPECT_EQ(emitColor, aiColor4D(1, 0, 1, 1));
425 }
426