2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 // Enable debug log for test coverage
19 #define DEBUG_ENABLED 1
21 #include <dali-scene3d/internal/loader/gltf2-loader-impl.h>
22 #include <dali-scene3d/public-api/loader/load-result.h>
23 #include <dali-scene3d/public-api/loader/resource-bundle.h>
24 #include <dali-scene3d/public-api/loader/scene-definition.h>
25 #include <dali-scene3d/public-api/loader/shader-manager.h>
26 #include <dali-test-suite-utils.h>
27 #include <string_view>
30 using namespace Dali::Scene3D::Loader;
32 #define DALI_TEST_THROW(expression, exception, predicate) \
34 bool daliTestThrowSuccess__ = false; \
41 printf("No exception was thrown.\n"); \
43 catch(std::decay<exception>::type & ex) \
45 daliTestThrowSuccess__ = predicate(ex); \
49 printf("Wrong type of exception thrown.\n"); \
51 DALI_TEST_CHECK(daliTestThrowSuccess__); \
58 ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) {
59 return TEST_RESOURCE_DIR "/";
62 ResourceBundle resources;
63 SceneDefinition scene;
64 SceneMetadata metaData;
66 std::vector<AnimationDefinition> animations;
67 std::vector<AnimationGroupDefinition> animationGroups;
68 std::vector<CameraParameters> cameras;
69 std::vector<LightParameters> lights;
71 LoadResult loadResult{
80 Dali::Scene3D::Loader::Internal::Gltf2LoaderImpl loader;
83 struct ExceptionMessageStartsWith
85 const std::string_view expected;
87 bool operator()(const std::runtime_error& e)
89 const bool success = (0 == strncmp(e.what(), expected.data(), expected.size()));
92 printf("Expected: %s, got: %s.\n", expected.data(), e.what());
100 int UtcDaliGltfLoaderFailedToLoad1(void)
104 DALI_TEST_EQUAL(ctx.loader.LoadModel("non-existent.gltf", ctx.loadResult), false);
106 DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
107 DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
109 DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size());
110 DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size());
111 DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size());
112 DALI_TEST_EQUAL(0, ctx.resources.mShaders.size());
113 DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size());
115 DALI_TEST_EQUAL(0, ctx.cameras.size());
116 DALI_TEST_EQUAL(0, ctx.lights.size());
117 DALI_TEST_EQUAL(0, ctx.animations.size());
118 DALI_TEST_EQUAL(0, ctx.animationGroups.size());
123 int UtcDaliGltfLoaderFailedToLoad2(void)
129 DALI_TEST_EQUAL(ctx.loader.LoadModel(TEST_RESOURCE_DIR "/UnsupportedExtension.gltf", ctx.loadResult), false);
133 printf("Unsupported glTF extension required.\n");
136 DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
137 DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
139 DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size());
140 DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size());
141 DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size());
142 DALI_TEST_EQUAL(0, ctx.resources.mShaders.size());
143 DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size());
145 DALI_TEST_EQUAL(0, ctx.cameras.size());
146 DALI_TEST_EQUAL(0, ctx.lights.size());
147 DALI_TEST_EQUAL(0, ctx.animations.size());
148 DALI_TEST_EQUAL(0, ctx.animationGroups.size());
153 int UtcDaliGltfLoaderFailedToParse(void)
157 DALI_TEST_EQUAL(ctx.loader.LoadModel(TEST_RESOURCE_DIR "/invalid.gltf", ctx.loadResult), false);
159 DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
160 DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
162 DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size());
163 DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size());
164 DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size());
165 DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size());
167 DALI_TEST_EQUAL(0, ctx.cameras.size());
168 DALI_TEST_EQUAL(0, ctx.lights.size());
169 DALI_TEST_EQUAL(0, ctx.animations.size());
170 DALI_TEST_EQUAL(0, ctx.animationGroups.size());
175 int UtcDaliGltfLoaderSuccess1(void)
179 LoadSceneMetadata(TEST_RESOURCE_DIR "/AnimatedCube.metadata", ctx.metaData);
181 std::unordered_map<std::string, ImageMetadata> imageMetadataGroundTruth;
182 imageMetadataGroundTruth["AnimatedCube_BaseColor.png"] = ImageMetadata{ImageDimensions(256, 256), Dali::SamplingMode::BOX_THEN_NEAREST};
183 imageMetadataGroundTruth["AnimatedCube_MetallicRoughness.png"] = ImageMetadata{ImageDimensions(256, 256), Dali::SamplingMode::NEAREST};
185 auto metaData = ctx.metaData.mImageMetadata.begin();
186 for(auto& groundTruth : imageMetadataGroundTruth)
188 DALI_TEST_EQUAL(groundTruth.first, metaData->first);
189 DALI_TEST_EQUAL(groundTruth.second.mMinSize, metaData->second.mMinSize);
190 DALI_TEST_EQUAL(groundTruth.second.mSamplingMode, metaData->second.mSamplingMode);
194 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AnimatedCube.gltf", ctx.loadResult);
196 DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
197 DALI_TEST_EQUAL(9u, ctx.scene.GetNodeCount());
199 // Default envmap is used
200 DALI_TEST_EQUAL(1u, ctx.resources.mEnvironmentMaps.size());
204 Customization::Choices choices;
205 for(auto iRoot : ctx.scene.GetRoots())
207 auto resourceRefs = ctx.resources.CreateRefCounter();
208 ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs);
209 ctx.resources.mReferenceCounts = std::move(resourceRefs);
210 ctx.resources.CountEnvironmentReferences();
211 ctx.resources.LoadResources(ctx.pathProvider);
214 auto& materials = ctx.resources.mMaterials;
215 DALI_TEST_EQUAL(2u, materials.size());
216 const MaterialDefinition materialGroundTruth[]{
218 MaterialDefinition::ALBEDO | MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION |
219 MaterialDefinition::NORMAL | MaterialDefinition::SPECULAR | MaterialDefinition::SPECULAR_COLOR |
220 MaterialDefinition::GLTF_CHANNELS | (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT),
225 Vector4(1.000, 0.766, 0.336, 1.0),
228 Vector3(0.2, 0.1, 0.0),
237 Scene3D::Material::AlphaModeType::MASK,
243 MaterialDefinition::ALBEDO,
245 "AnimatedCube_BaseColor.png",
246 SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
247 ImageDimensions(256, 256),
248 SamplingMode::BOX_THEN_NEAREST,
252 MaterialDefinition::NORMAL,
254 "AnimatedCube_BaseColor.png",
255 SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
256 ImageDimensions(256, 256),
257 SamplingMode::BOX_THEN_NEAREST,
261 MaterialDefinition::OCCLUSION,
263 "AnimatedCube_BaseColor.png",
264 SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
265 ImageDimensions(256, 256),
266 SamplingMode::BOX_THEN_NEAREST,
270 MaterialDefinition::EMISSIVE,
272 "AnimatedCube_BaseColor.png",
273 SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
274 ImageDimensions(256, 256),
275 SamplingMode::BOX_THEN_NEAREST,
279 MaterialDefinition::SPECULAR,
281 "AnimatedCube_BaseColor.png",
282 SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
283 ImageDimensions(256, 256),
284 SamplingMode::BOX_THEN_NEAREST,
288 MaterialDefinition::SPECULAR_COLOR,
290 "AnimatedCube_BaseColor.png",
291 SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
292 ImageDimensions(256, 256),
293 SamplingMode::BOX_THEN_NEAREST,
300 MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
301 MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION | MaterialDefinition::NORMAL |
302 MaterialDefinition::GLTF_CHANNELS,
307 Vector4(1.000, 0.766, 0.336, 1.0),
310 Vector3(0.2, 0.1, 0.0),
319 Scene3D::Material::AlphaModeType::OPAQUE,
325 MaterialDefinition::ALBEDO,
327 "AnimatedCube_BaseColor.png",
328 SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
329 ImageDimensions(256, 256),
330 SamplingMode::BOX_THEN_NEAREST,
334 MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS,
336 "AnimatedCube_MetallicRoughness.png",
337 SamplerFlags::Encode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::MIRRORED_REPEAT),
338 ImageDimensions(256, 256),
339 SamplingMode::NEAREST,
343 MaterialDefinition::NORMAL,
345 "AnimatedCube_BaseColor.png",
346 SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
347 ImageDimensions(256, 256),
348 SamplingMode::BOX_THEN_NEAREST,
352 MaterialDefinition::OCCLUSION,
354 "AnimatedCube_BaseColor.png",
355 SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
356 ImageDimensions(256, 256),
357 SamplingMode::BOX_THEN_NEAREST,
361 MaterialDefinition::EMISSIVE,
363 "AnimatedCube_BaseColor.png",
364 SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
365 ImageDimensions(256, 256),
366 SamplingMode::BOX_THEN_NEAREST,
374 auto iMaterial = materials.begin();
375 auto iMetadata = ctx.metaData.mImageMetadata.begin();
376 for(auto& m : materialGroundTruth)
378 printf("material %ld\n", iMaterial - materials.begin());
379 auto& md = iMaterial->first;
380 DALI_TEST_EQUAL(md.mFlags, m.mFlags);
381 DALI_TEST_EQUAL(md.mEnvironmentIdx, m.mEnvironmentIdx);
382 DALI_TEST_EQUAL(md.mColor, m.mColor);
383 DALI_TEST_EQUAL(md.mMetallic, m.mMetallic);
384 DALI_TEST_EQUAL(md.mRoughness, m.mRoughness);
385 DALI_TEST_EQUAL(md.mBaseColorFactor, m.mBaseColorFactor);
386 DALI_TEST_EQUAL(md.mNormalScale, m.mNormalScale);
387 DALI_TEST_EQUAL(md.mOcclusionStrength, m.mOcclusionStrength);
388 DALI_TEST_EQUAL(md.mEmissiveFactor, m.mEmissiveFactor);
389 DALI_TEST_EQUAL(md.mIor, m.mIor);
390 DALI_TEST_EQUAL(md.mDielectricSpecular, m.mDielectricSpecular);
391 DALI_TEST_EQUAL(md.mSpecularFactor, m.mSpecularFactor);
392 DALI_TEST_EQUAL(md.mSpecularColorFactor, m.mSpecularColorFactor);
393 DALI_TEST_EQUAL(md.mNeedAlbedoTexture, m.mNeedAlbedoTexture);
394 DALI_TEST_EQUAL(md.mNeedMetallicRoughnessTexture, m.mNeedMetallicRoughnessTexture);
395 DALI_TEST_EQUAL(md.mNeedNormalTexture, m.mNeedNormalTexture);
396 DALI_TEST_EQUAL(md.mAlphaModeType, m.mAlphaModeType);
397 DALI_TEST_EQUAL(md.mIsOpaque, m.mIsOpaque);
398 DALI_TEST_EQUAL(md.mIsMask, m.mIsMask);
400 DALI_TEST_EQUAL(md.mTextureStages.size(), m.mTextureStages.size());
401 auto iTexture = md.mTextureStages.begin();
402 for(auto& ts : m.mTextureStages)
404 printf("texture %ld\n", iTexture - md.mTextureStages.begin());
405 DALI_TEST_EQUAL(iTexture->mSemantic, ts.mSemantic);
406 DALI_TEST_EQUAL(iTexture->mTexture.mImageUri, ts.mTexture.mImageUri);
407 DALI_TEST_EQUAL(uint32_t(iTexture->mTexture.mSamplerFlags), uint32_t(ts.mTexture.mSamplerFlags)); // don't interpret it as a character
408 DALI_TEST_EQUAL(iTexture->mTexture.mMinImageDimensions, ts.mTexture.mMinImageDimensions);
409 DALI_TEST_EQUAL(iTexture->mTexture.mSamplingMode, ts.mTexture.mSamplingMode);
417 auto& meshes = ctx.resources.mMeshes;
418 DALI_TEST_EQUAL(2u, meshes.size());
420 using Blob = MeshDefinition::Blob;
421 using Accessor = MeshDefinition::Accessor;
422 MeshDefinition meshGroundTruth[]{
428 Accessor{Blob{0, 0}, {}},
429 Accessor{Blob{0, 0}, {}},
430 Accessor{Blob{0, 0}, {}},
431 Accessor{Blob{0, 0}, {}},
438 Accessor{Blob{0, 0}, {}},
439 Accessor{Blob{0, 0}, {}},
440 Accessor{Blob{0, 0}, {}},
441 Accessor{Blob{0, 0}, {}},
444 meshGroundTruth[0].mColors.push_back(Accessor{Blob{0, 0}, {}});
445 meshGroundTruth[0].mTexCoords.push_back(Accessor{Blob{0, 0}, {}});
446 meshGroundTruth[1].mColors.push_back(Accessor{Blob{0, 0}, {}});
447 meshGroundTruth[1].mTexCoords.push_back(Accessor{Blob{0, 0}, {}});
449 auto iMesh = meshes.begin();
450 for(auto& m : meshGroundTruth)
452 printf("mesh %ld\n", iMesh - meshes.begin());
454 auto& md = iMesh->first;
455 DALI_TEST_EQUAL(md.mFlags, m.mFlags);
456 DALI_TEST_EQUAL(md.mPrimitiveType, m.mPrimitiveType);
458 DALI_TEST_EQUAL((md.mIndices).IsDefined(), (m.mIndices).IsDefined());
459 DALI_TEST_EQUAL((md.mIndices).mBlob.IsDefined(), (m.mIndices).mBlob.IsDefined());
461 DALI_TEST_EQUAL((md.mPositions).IsDefined(), (m.mPositions).IsDefined());
462 DALI_TEST_EQUAL((md.mPositions).mBlob.IsDefined(), (m.mPositions).mBlob.IsDefined());
464 DALI_TEST_EQUAL((md.mNormals).IsDefined(), (m.mNormals).IsDefined());
465 DALI_TEST_EQUAL((md.mNormals).mBlob.IsDefined(), (m.mNormals).mBlob.IsDefined());
467 DALI_TEST_EQUAL((md.mTangents).IsDefined(), (m.mTangents).IsDefined());
468 DALI_TEST_EQUAL((md.mTangents).mBlob.IsDefined(), (m.mTangents).mBlob.IsDefined());
470 DALI_TEST_EQUAL(md.mTexCoords.empty(), m.mTexCoords.empty());
471 DALI_TEST_EQUAL(md.mColors.empty(), m.mColors.empty());
473 DALI_TEST_EQUAL(md.mJoints.empty(), (m.mJoints.empty()));
474 DALI_TEST_EQUAL(md.mWeights.empty(), (m.mWeights.empty()));
476 DALI_TEST_EQUAL(md.mBlendShapeHeader.IsDefined(), m.mBlendShapeHeader.IsDefined());
481 DALI_TEST_EQUAL(0u, ctx.resources.mSkeletons.size());
483 DALI_TEST_EQUAL(6u, ctx.cameras.size());
484 DALI_TEST_EQUAL(0u, ctx.lights.size());
485 DALI_TEST_EQUAL(1u, ctx.animations.size());
486 DALI_TEST_EQUAL(0u, ctx.animationGroups.size());
491 int UtcDaliGltfLoaderSuccess2(void)
495 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AnimatedCubeStride.gltf", ctx.loadResult);
497 DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
498 DALI_TEST_EQUAL(1u, ctx.scene.GetNodeCount());
502 Customization::Choices choices;
503 for(auto iRoot : ctx.scene.GetRoots())
505 auto resourceRefs = ctx.resources.CreateRefCounter();
506 ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs);
507 ctx.resources.mReferenceCounts = std::move(resourceRefs);
508 ctx.resources.LoadResources(ctx.pathProvider);
511 DALI_TEST_EQUAL(true, ctx.resources.mMeshes[0u].first.mPositions.IsDefined());
512 DALI_TEST_EQUAL(432, ctx.resources.mMeshes[0u].first.mPositions.mBlob.mLength);
517 int UtcDaliGltfLoaderSuccessShort(void)
521 const std::string resourcePath = TEST_RESOURCE_DIR "/";
522 auto pathProvider = [resourcePath](ResourceType::Value) {
526 Customization::Choices choices;
527 for(auto modelName : {
530 "AnimatedMorphCubeAnimateNonZeroFrame",
531 "AnimatedMorphSphere",
538 "MorphPrimitivesTest",
540 "SimpleSparseAccessor",
541 "TextureTransformMultiTest",
544 * For the Avocado glTF file and its Assets
545 * Donated by Microsoft for glTF testing
546 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/Avocado/glTF-Quantized
550 * For the AnimatedMorphCube glTF file and its Assets
551 * Donated by Microsoft for glTF testing
552 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/AnimatedMorphCube/glTF-Quantized
554 "AnimatedMorphCubeQuantized",
556 * For the MorphPrimitivesTest glTF file and its Assets
558 * Licensed under the terms of the CC BY 4.0 license: https://creativecommons.org/licenses/by/4.0/
559 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/MorphPrimitivesTest/glTF
560 * Modified using gltfpack 0.18.
562 "MorphPrimitivesTestQuantized",
564 * For the CesiumMilkTruck glTF file and its Assets
565 * Donated by Cesium for glTF testing
566 * Licensed under the terms of the CC BY 4.0 license: http://creativecommons.org/licenses/by/4.0/
567 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/CesiumMilkTruck/glTF
568 * Modified using gltfpack 0.18.
570 "CesiumMilkTruckQuantized",
575 auto& resources = ctx.resources;
576 resources.mEnvironmentMaps.push_back({});
578 printf("%s\n", modelName);
579 ctx.loader.LoadModel(resourcePath + modelName + ".gltf", ctx.loadResult);
580 DALI_TEST_CHECK(ctx.scene.GetNodeCount() > 0);
582 auto& scene = ctx.scene;
583 for(auto iRoot : scene.GetRoots())
585 struct Visitor : NodeDefinition::IVisitor
587 struct ResourceReceiver : IResourceReceiver
589 std::vector<bool> mCounts;
591 void Register(ResourceType::Value type, Index id) override
593 if(type == ResourceType::Mesh)
600 void Start(NodeDefinition& n) override
602 for(auto& renderable : n.mRenderables)
604 renderable->RegisterResources(receiver);
608 void Finish(NodeDefinition& n) override
612 visitor.receiver.mCounts.resize(resources.mMeshes.size(), false);
614 scene.Visit(iRoot, choices, visitor);
615 for(uint32_t i0 = 0, i1 = resources.mMeshes.size(); i0 < i1; ++i0)
617 if(visitor.receiver.mCounts[i0])
619 auto raw = resources.mMeshes[i0].first.LoadRaw(resourcePath, resources.mBuffers);
620 DALI_TEST_CHECK(!raw.mAttribs.empty());
622 resources.mMeshes[i0].second = resources.mMeshes[i0].first.Load(std::move(raw));
623 DALI_TEST_CHECK(resources.mMeshes[i0].second.geometry);
632 int UtcDaliGltfLoaderMRendererTest(void)
635 auto& resources = ctx.resources;
637 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/MRendererTest.gltf", ctx.loadResult);
639 auto& scene = ctx.scene;
640 auto& roots = scene.GetRoots();
641 DALI_TEST_EQUAL(roots.size(), 1u);
642 DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "RootNode");
643 DALI_TEST_EQUAL(scene.GetNode(roots[0])->mScale, Vector3(1.0f, 1.0f, 1.0f));
645 DALI_TEST_EQUAL(scene.GetNodeCount(), 1u);
647 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
648 ViewProjection viewProjection;
652 NodeDefinition::CreateParams nodeParams{
658 Customization::Choices choices;
662 Actor root = Actor::New();
663 SetActorCentered(root);
664 for(auto iRoot : roots)
666 auto resourceRefs = resources.CreateRefCounter();
667 scene.CountResourceRefs(iRoot, choices, resourceRefs);
668 ctx.resources.mReferenceCounts = std::move(resourceRefs);
669 ctx.resources.CountEnvironmentReferences();
670 ctx.resources.LoadResources(ctx.pathProvider);
671 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
673 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
674 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
679 DALI_TEST_EQUAL(root.GetChildCount(), 1u);
680 Actor child = root.GetChildAt(0);
682 DALI_TEST_EQUAL(child.GetProperty(Actor::Property::NAME).Get<std::string>(), "RootNode");
683 DALI_TEST_EQUAL(child.GetProperty(Actor::Property::SCALE).Get<Vector3>(), Vector3(1.0f, 1.0f, 1.0f));
684 DALI_TEST_EQUAL(child.GetRendererCount(), 1u);
685 DALI_TEST_EQUAL(child.GetRendererAt(0).GetTextures().GetTextureCount(), 5u);
687 DALI_TEST_EQUAL(child.GetRendererCount(), 1u);
688 DALI_TEST_EQUAL(child.GetRendererAt(0u).GetProperty<decltype(BlendMode::ON)>(Renderer::Property::BLEND_MODE), BlendMode::ON);
693 int UtcDaliGltfLoaderAnimationLoadingTest(void)
698 auto& resources = ctx.resources;
700 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/CesiumMan_e.gltf", ctx.loadResult);
702 auto& scene = ctx.scene;
703 auto& roots = scene.GetRoots();
704 DALI_TEST_EQUAL(roots.size(), 1u);
706 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
707 ViewProjection viewProjection;
711 NodeDefinition::CreateParams nodeParams{
717 Customization::Choices choices;
719 Actor root = Actor::New();
720 SetActorCentered(root);
721 for(auto iRoot : roots)
723 auto resourceRefs = resources.CreateRefCounter();
724 scene.CountResourceRefs(iRoot, choices, resourceRefs);
725 resources.mReferenceCounts = std::move(resourceRefs);
726 resources.CountEnvironmentReferences();
727 resources.LoadResources(ctx.pathProvider);
728 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
730 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
731 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
736 DALI_TEST_EQUAL(ctx.loadResult.mAnimationDefinitions.size(), 1u);
737 DALI_TEST_EQUAL(ctx.loadResult.mAnimationDefinitions[0].GetPropertyCount(), 57u);
739 uint32_t id = ctx.loadResult.mScene.GetNode(ctx.loadResult.mAnimationDefinitions[0].GetPropertyAt(0).mNodeIndex)->mNodeId;
740 DALI_TEST_EQUAL(id, root.FindChildByName("Skeleton_torso_joint_1").GetProperty<int32_t>(Dali::Actor::Property::ID));
745 int UtcDaliGltfLoaderImageFromBufferView(void)
749 auto& resources = ctx.resources;
751 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/EnvironmentTest_b.gltf", ctx.loadResult);
753 auto& scene = ctx.scene;
754 auto& roots = scene.GetRoots();
755 DALI_TEST_EQUAL(roots.size(), 1u);
757 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
758 ViewProjection viewProjection;
762 NodeDefinition::CreateParams nodeParams{
768 Customization::Choices choices;
772 Actor root = Actor::New();
773 SetActorCentered(root);
774 for(auto iRoot : roots)
776 auto resourceRefs = resources.CreateRefCounter();
777 scene.CountResourceRefs(iRoot, choices, resourceRefs);
778 resources.mReferenceCounts = std::move(resourceRefs);
779 resources.CountEnvironmentReferences();
780 resources.LoadResources(ctx.pathProvider);
781 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
783 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
784 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
789 DALI_TEST_CHECK(resources.mMaterials[0].second.GetTextureCount() > 1);
790 DALI_TEST_EQUAL(resources.mMaterials[0].second.GetTexture(0).GetWidth(), 256);
791 DALI_TEST_EQUAL(resources.mMaterials[0].second.GetTexture(0).GetHeight(), 256);
796 int UtcDaliGltfLoaderUint8Indices(void)
800 auto& resources = ctx.resources;
802 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AlphaBlendModeTest.gltf", ctx.loadResult);
804 auto& scene = ctx.scene;
805 auto& roots = scene.GetRoots();
806 DALI_TEST_EQUAL(roots.size(), 1u);
808 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
809 ViewProjection viewProjection;
813 NodeDefinition::CreateParams nodeParams{
819 Customization::Choices choices;
823 Actor root = Actor::New();
824 SetActorCentered(root);
825 for(auto iRoot : roots)
827 auto resourceRefs = resources.CreateRefCounter();
828 scene.CountResourceRefs(iRoot, choices, resourceRefs);
829 resources.mReferenceCounts = std::move(resourceRefs);
830 resources.CountEnvironmentReferences();
831 resources.LoadResources(ctx.pathProvider);
832 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
834 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
835 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
840 DALI_TEST_CHECK(root.FindChildByName("Bed"));
841 DALI_TEST_CHECK(root.FindChildByName("DecalBlend"));
842 DALI_TEST_CHECK(root.FindChildByName("DecalOpaque"));
847 int UtcDaliGltfLoaderQuantizedMesh(void)
851 auto& resources = ctx.resources;
854 * For the Avocado glTF file and its Assets
855 * Donated by Microsoft for glTF testing
856 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/Avocado/glTF-Quantized
858 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AvocadoQuantized.gltf", ctx.loadResult);
860 auto& scene = ctx.scene;
861 DALI_TEST_EQUAL(1u, scene.GetRoots().size());
862 DALI_TEST_EQUAL(1u, scene.GetNodeCount());
864 auto& roots = scene.GetRoots();
865 DALI_TEST_EQUAL(roots.size(), 1u);
867 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
868 ViewProjection viewProjection;
872 NodeDefinition::CreateParams nodeParams{
878 Customization::Choices choices;
882 Actor root = Actor::New();
883 SetActorCentered(root);
884 for(auto iRoot : roots)
886 auto resourceRefs = resources.CreateRefCounter();
887 scene.CountResourceRefs(iRoot, choices, resourceRefs);
888 resources.mReferenceCounts = std::move(resourceRefs);
889 resources.CountEnvironmentReferences();
890 resources.LoadResources(ctx.pathProvider);
891 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
893 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
894 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
899 auto& meshes = ctx.resources.mMeshes;
900 DALI_TEST_EQUAL(1u, meshes.size());
902 auto& md = meshes[0u].first;
904 DALI_TEST_EQUAL(MeshDefinition::Flags::U16_POSITION | MeshDefinition::Flags::S8_NORMAL | MeshDefinition::Flags::S8_TANGENT | MeshDefinition::Flags::U16_TEXCOORD, md.mFlags);
906 DALI_TEST_EQUAL(true, md.mPositions.IsDefined());
907 DALI_TEST_EQUAL(false, md.mPositions.mNormalized);
908 DALI_TEST_EQUAL(sizeof(uint16_t) * 3, md.mPositions.mBlob.mElementSizeHint);
909 DALI_TEST_EQUAL(true, md.mPositions.mBlob.IsDefined());
910 DALI_TEST_EQUAL(2436, md.mPositions.mBlob.mLength);
911 DALI_TEST_EQUAL(3u, md.mPositions.mBlob.mMin.size());
912 DALI_TEST_EQUAL(0.0f, md.mPositions.mBlob.mMin[0]);
913 DALI_TEST_EQUAL(0.0f, md.mPositions.mBlob.mMin[1]);
914 DALI_TEST_EQUAL(0.0f, md.mPositions.mBlob.mMin[2]);
915 DALI_TEST_EQUAL(3u, md.mPositions.mBlob.mMax.size());
916 DALI_TEST_EQUAL(11086.0f, md.mPositions.mBlob.mMax[0]);
917 DALI_TEST_EQUAL(16383.0f, md.mPositions.mBlob.mMax[1]);
918 DALI_TEST_EQUAL(7194.0f, md.mPositions.mBlob.mMax[2]);
920 DALI_TEST_EQUAL(true, md.mNormals.IsDefined());
921 DALI_TEST_EQUAL(true, md.mNormals.mNormalized);
922 DALI_TEST_EQUAL(sizeof(int8_t) * 3, md.mNormals.mBlob.mElementSizeHint);
923 DALI_TEST_EQUAL(true, md.mNormals.mBlob.IsDefined());
924 DALI_TEST_EQUAL(1218, md.mNormals.mBlob.mLength);
925 DALI_TEST_EQUAL(0u, md.mNormals.mBlob.mMin.size());
926 DALI_TEST_EQUAL(0u, md.mNormals.mBlob.mMax.size());
928 DALI_TEST_EQUAL(true, md.mTangents.IsDefined());
929 DALI_TEST_EQUAL(true, md.mTangents.mNormalized);
930 DALI_TEST_EQUAL(Property::VECTOR4, md.mTangentType);
931 DALI_TEST_EQUAL(sizeof(int8_t) * 4, md.mTangents.mBlob.mElementSizeHint);
932 DALI_TEST_EQUAL(true, md.mTangents.mBlob.IsDefined());
933 DALI_TEST_EQUAL(1624, md.mTangents.mBlob.mLength);
934 DALI_TEST_EQUAL(0u, md.mTangents.mBlob.mMin.size());
935 DALI_TEST_EQUAL(0u, md.mTangents.mBlob.mMax.size());
937 DALI_TEST_EQUAL(false, md.mTexCoords.empty());
938 DALI_TEST_EQUAL(true, md.mTexCoords[0].IsDefined());
939 DALI_TEST_EQUAL(false, md.mTexCoords[0].mNormalized);
940 DALI_TEST_EQUAL(sizeof(uint16_t) * 2, md.mTexCoords[0].mBlob.mElementSizeHint);
941 DALI_TEST_EQUAL(true, md.mTexCoords[0].mBlob.IsDefined());
942 DALI_TEST_EQUAL(1624, md.mTexCoords[0].mBlob.mLength);
943 DALI_TEST_EQUAL(0u, md.mTexCoords[0].mBlob.mMin.size());
944 DALI_TEST_EQUAL(0u, md.mTexCoords[0].mBlob.mMax.size());
949 int UtcDaliGltfLoaderTextureTransform(void)
953 auto& resources = ctx.resources;
956 * For the Avocado glTF file and its Assets
957 * Donated by Microsoft for glTF testing
958 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/Avocado/glTF-Quantized
960 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AvocadoQuantized.gltf", ctx.loadResult);
962 auto& scene = ctx.scene;
963 DALI_TEST_EQUAL(1u, scene.GetRoots().size());
964 DALI_TEST_EQUAL(1u, scene.GetNodeCount());
968 Customization::Choices choices;
969 for(auto iRoot : scene.GetRoots())
971 auto resourceRefs = resources.CreateRefCounter();
972 scene.CountResourceRefs(iRoot, choices, resourceRefs);
973 resources.mReferenceCounts = std::move(resourceRefs);
974 resources.CountEnvironmentReferences();
975 resources.LoadResources(ctx.pathProvider);
978 auto& materials = resources.mMaterials;
979 DALI_TEST_EQUAL(1u, materials.size());
981 auto iMaterial = materials.begin();
982 auto& md = iMaterial->first;
984 DALI_TEST_EQUAL(3u, md.mTextureStages.size());
986 Matrix3 textureTransformGroundTruth(0.000238f, 0.0f, 0.0f, 0.0f, 0.000242f, 0.0f, 0.00678f, 0.002982f, 1.0f);
987 DALI_TEST_EQUALS(md.mTextureStages[0].mTexture.mTransform, textureTransformGroundTruth, 0.01f, TEST_LOCATION);
988 DALI_TEST_EQUALS(md.mTextureStages[1].mTexture.mTransform, textureTransformGroundTruth, 0.01f, TEST_LOCATION);
989 DALI_TEST_EQUALS(md.mTextureStages[2].mTexture.mTransform, textureTransformGroundTruth, 0.01f, TEST_LOCATION);