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 const MeshDefinition meshGroundTruth[]{
428 Accessor{Blob{0, 0}, {}},
429 Accessor{Blob{0, 0}, {}},
430 Accessor{Blob{0, 0}, {}},
431 Accessor{Blob{0, 0}, {}},
432 Accessor{Blob{0, 0}, {}},
433 Accessor{Blob{0, 0}, {}},
440 Accessor{Blob{0, 0}, {}},
441 Accessor{Blob{0, 0}, {}},
442 Accessor{Blob{0, 0}, {}},
443 Accessor{Blob{0, 0}, {}},
444 Accessor{Blob{0, 0}, {}},
445 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 &MeshDefinition::mIndices,
459 &MeshDefinition::mPositions,
460 &MeshDefinition::mNormals,
461 &MeshDefinition::mTexCoords,
462 &MeshDefinition::mColors,
463 &MeshDefinition::mTangents,
464 &MeshDefinition::mJoints0,
465 &MeshDefinition::mWeights0})
467 DALI_TEST_EQUAL((md.*mp).IsDefined(), (m.*mp).IsDefined());
468 DALI_TEST_EQUAL((md.*mp).mBlob.IsDefined(), (m.*mp).mBlob.IsDefined());
471 DALI_TEST_EQUAL(md.mBlendShapeHeader.IsDefined(), m.mBlendShapeHeader.IsDefined());
476 DALI_TEST_EQUAL(0u, ctx.resources.mSkeletons.size());
478 DALI_TEST_EQUAL(6u, ctx.cameras.size());
479 DALI_TEST_EQUAL(0u, ctx.lights.size());
480 DALI_TEST_EQUAL(1u, ctx.animations.size());
481 DALI_TEST_EQUAL(0u, ctx.animationGroups.size());
486 int UtcDaliGltfLoaderSuccess2(void)
490 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AnimatedCubeStride.gltf", ctx.loadResult);
492 DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
493 DALI_TEST_EQUAL(1u, ctx.scene.GetNodeCount());
497 Customization::Choices choices;
498 for(auto iRoot : ctx.scene.GetRoots())
500 auto resourceRefs = ctx.resources.CreateRefCounter();
501 ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs);
502 ctx.resources.mReferenceCounts = std::move(resourceRefs);
503 ctx.resources.LoadResources(ctx.pathProvider);
506 DALI_TEST_EQUAL(true, ctx.resources.mMeshes[0u].first.mPositions.IsDefined());
507 DALI_TEST_EQUAL(432, ctx.resources.mMeshes[0u].first.mPositions.mBlob.mLength);
512 int UtcDaliGltfLoaderSuccessShort(void)
516 const std::string resourcePath = TEST_RESOURCE_DIR "/";
517 auto pathProvider = [resourcePath](ResourceType::Value) {
521 Customization::Choices choices;
522 for(auto modelName : {
525 "AnimatedMorphCubeAnimateNonZeroFrame",
526 "AnimatedMorphSphere",
533 "MorphPrimitivesTest",
535 "SimpleSparseAccessor",
538 * For the Avocado glTF file and its Assets
539 * Donated by Microsoft for glTF testing
540 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/Avocado/glTF-Quantized
544 * For the AnimatedMorphCube 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/AnimatedMorphCube/glTF-Quantized
548 "AnimatedMorphCubeQuantized",
550 * For the MorphPrimitivesTest glTF file and its Assets
552 * Licensed under the terms of the CC BY 4.0 license: https://creativecommons.org/licenses/by/4.0/
553 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/MorphPrimitivesTest/glTF
554 * Modified using gltfpack 0.18.
556 "MorphPrimitivesTestQuantized",
558 * For the CesiumMilkTruck glTF file and its Assets
559 * Donated by Cesium for glTF testing
560 * Licensed under the terms of the CC BY 4.0 license: http://creativecommons.org/licenses/by/4.0/
561 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/CesiumMilkTruck/glTF
562 * Modified using gltfpack 0.18.
564 "CesiumMilkTruckQuantized",
569 auto& resources = ctx.resources;
570 resources.mEnvironmentMaps.push_back({});
572 printf("%s\n", modelName);
573 ctx.loader.LoadModel(resourcePath + modelName + ".gltf", ctx.loadResult);
574 DALI_TEST_CHECK(ctx.scene.GetNodeCount() > 0);
576 auto& scene = ctx.scene;
577 for(auto iRoot : scene.GetRoots())
579 struct Visitor : NodeDefinition::IVisitor
581 struct ResourceReceiver : IResourceReceiver
583 std::vector<bool> mCounts;
585 void Register(ResourceType::Value type, Index id) override
587 if(type == ResourceType::Mesh)
594 void Start(NodeDefinition& n) override
596 for(auto& renderable : n.mRenderables)
598 renderable->RegisterResources(receiver);
602 void Finish(NodeDefinition& n) override
606 visitor.receiver.mCounts.resize(resources.mMeshes.size(), false);
608 scene.Visit(iRoot, choices, visitor);
609 for(uint32_t i0 = 0, i1 = resources.mMeshes.size(); i0 < i1; ++i0)
611 if(visitor.receiver.mCounts[i0])
613 auto raw = resources.mMeshes[i0].first.LoadRaw(resourcePath, resources.mBuffers);
614 DALI_TEST_CHECK(!raw.mAttribs.empty());
616 resources.mMeshes[i0].second = resources.mMeshes[i0].first.Load(std::move(raw));
617 DALI_TEST_CHECK(resources.mMeshes[i0].second.geometry);
626 int UtcDaliGltfLoaderMRendererTest(void)
629 auto& resources = ctx.resources;
631 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/MRendererTest.gltf", ctx.loadResult);
633 auto& scene = ctx.scene;
634 auto& roots = scene.GetRoots();
635 DALI_TEST_EQUAL(roots.size(), 1u);
636 DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "RootNode");
637 DALI_TEST_EQUAL(scene.GetNode(roots[0])->mScale, Vector3(1.0f, 1.0f, 1.0f));
639 DALI_TEST_EQUAL(scene.GetNodeCount(), 1u);
641 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
642 ViewProjection viewProjection;
646 NodeDefinition::CreateParams nodeParams{
652 Customization::Choices choices;
656 Actor root = Actor::New();
657 SetActorCentered(root);
658 for(auto iRoot : roots)
660 auto resourceRefs = resources.CreateRefCounter();
661 scene.CountResourceRefs(iRoot, choices, resourceRefs);
662 ctx.resources.mReferenceCounts = std::move(resourceRefs);
663 ctx.resources.CountEnvironmentReferences();
664 ctx.resources.LoadResources(ctx.pathProvider);
665 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
667 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
668 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
673 DALI_TEST_EQUAL(root.GetChildCount(), 1u);
674 Actor child = root.GetChildAt(0);
676 DALI_TEST_EQUAL(child.GetProperty(Actor::Property::NAME).Get<std::string>(), "RootNode");
677 DALI_TEST_EQUAL(child.GetProperty(Actor::Property::SCALE).Get<Vector3>(), Vector3(1.0f, 1.0f, 1.0f));
678 DALI_TEST_EQUAL(child.GetRendererCount(), 1u);
679 DALI_TEST_EQUAL(child.GetRendererAt(0).GetTextures().GetTextureCount(), 5u);
681 DALI_TEST_EQUAL(child.GetRendererCount(), 1u);
682 DALI_TEST_EQUAL(child.GetRendererAt(0u).GetProperty<decltype(BlendMode::ON)>(Renderer::Property::BLEND_MODE), BlendMode::ON);
687 int UtcDaliGltfLoaderAnimationLoadingTest(void)
692 auto& resources = ctx.resources;
694 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/CesiumMan_e.gltf", ctx.loadResult);
696 auto& scene = ctx.scene;
697 auto& roots = scene.GetRoots();
698 DALI_TEST_EQUAL(roots.size(), 1u);
700 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
701 ViewProjection viewProjection;
705 NodeDefinition::CreateParams nodeParams{
711 Customization::Choices choices;
713 Actor root = Actor::New();
714 SetActorCentered(root);
715 for(auto iRoot : roots)
717 auto resourceRefs = resources.CreateRefCounter();
718 scene.CountResourceRefs(iRoot, choices, resourceRefs);
719 resources.mReferenceCounts = std::move(resourceRefs);
720 resources.CountEnvironmentReferences();
721 resources.LoadResources(ctx.pathProvider);
722 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
724 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
725 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
730 DALI_TEST_EQUAL(ctx.loadResult.mAnimationDefinitions.size(), 1u);
731 DALI_TEST_EQUAL(ctx.loadResult.mAnimationDefinitions[0].GetPropertyCount(), 57u);
733 uint32_t id = ctx.loadResult.mScene.GetNode(ctx.loadResult.mAnimationDefinitions[0].GetPropertyAt(0).mNodeIndex)->mNodeId;
734 DALI_TEST_EQUAL(id, root.FindChildByName("Skeleton_torso_joint_1").GetProperty<int32_t>(Dali::Actor::Property::ID));
739 int UtcDaliGltfLoaderImageFromBufferView(void)
743 auto& resources = ctx.resources;
745 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/EnvironmentTest_b.gltf", ctx.loadResult);
747 auto& scene = ctx.scene;
748 auto& roots = scene.GetRoots();
749 DALI_TEST_EQUAL(roots.size(), 1u);
751 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
752 ViewProjection viewProjection;
756 NodeDefinition::CreateParams nodeParams{
762 Customization::Choices choices;
766 Actor root = Actor::New();
767 SetActorCentered(root);
768 for(auto iRoot : roots)
770 auto resourceRefs = resources.CreateRefCounter();
771 scene.CountResourceRefs(iRoot, choices, resourceRefs);
772 resources.mReferenceCounts = std::move(resourceRefs);
773 resources.CountEnvironmentReferences();
774 resources.LoadResources(ctx.pathProvider);
775 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
777 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
778 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
783 DALI_TEST_CHECK(resources.mMaterials[0].second.GetTextureCount() > 1);
784 DALI_TEST_EQUAL(resources.mMaterials[0].second.GetTexture(0).GetWidth(), 256);
785 DALI_TEST_EQUAL(resources.mMaterials[0].second.GetTexture(0).GetHeight(), 256);
790 int UtcDaliGltfLoaderUint8Indices(void)
794 auto& resources = ctx.resources;
796 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AlphaBlendModeTest.gltf", ctx.loadResult);
798 auto& scene = ctx.scene;
799 auto& roots = scene.GetRoots();
800 DALI_TEST_EQUAL(roots.size(), 1u);
802 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
803 ViewProjection viewProjection;
807 NodeDefinition::CreateParams nodeParams{
813 Customization::Choices choices;
817 Actor root = Actor::New();
818 SetActorCentered(root);
819 for(auto iRoot : roots)
821 auto resourceRefs = resources.CreateRefCounter();
822 scene.CountResourceRefs(iRoot, choices, resourceRefs);
823 resources.mReferenceCounts = std::move(resourceRefs);
824 resources.CountEnvironmentReferences();
825 resources.LoadResources(ctx.pathProvider);
826 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
828 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
829 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
834 DALI_TEST_CHECK(root.FindChildByName("Bed"));
835 DALI_TEST_CHECK(root.FindChildByName("DecalBlend"));
836 DALI_TEST_CHECK(root.FindChildByName("DecalOpaque"));
841 int UtcDaliGltfLoaderQuantizedMesh(void)
845 auto& resources = ctx.resources;
848 * For the Avocado glTF file and its Assets
849 * Donated by Microsoft for glTF testing
850 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/Avocado/glTF-Quantized
852 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AvocadoQuantized.gltf", ctx.loadResult);
854 auto& scene = ctx.scene;
855 DALI_TEST_EQUAL(1u, scene.GetRoots().size());
856 DALI_TEST_EQUAL(1u, scene.GetNodeCount());
858 auto& roots = scene.GetRoots();
859 DALI_TEST_EQUAL(roots.size(), 1u);
861 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
862 ViewProjection viewProjection;
866 NodeDefinition::CreateParams nodeParams{
872 Customization::Choices choices;
876 Actor root = Actor::New();
877 SetActorCentered(root);
878 for(auto iRoot : roots)
880 auto resourceRefs = resources.CreateRefCounter();
881 scene.CountResourceRefs(iRoot, choices, resourceRefs);
882 resources.mReferenceCounts = std::move(resourceRefs);
883 resources.CountEnvironmentReferences();
884 resources.LoadResources(ctx.pathProvider);
885 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
887 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
888 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
893 auto& meshes = ctx.resources.mMeshes;
894 DALI_TEST_EQUAL(1u, meshes.size());
896 auto& md = meshes[0u].first;
898 DALI_TEST_EQUAL(MeshDefinition::Flags::U16_POSITION | MeshDefinition::Flags::S8_NORMAL | MeshDefinition::Flags::S8_TANGENT | MeshDefinition::Flags::U16_TEXCOORD, md.mFlags);
900 DALI_TEST_EQUAL(true, md.mPositions.IsDefined());
901 DALI_TEST_EQUAL(false, md.mPositions.mNormalized);
902 DALI_TEST_EQUAL(sizeof(uint16_t) * 3, md.mPositions.mBlob.mElementSizeHint);
903 DALI_TEST_EQUAL(true, md.mPositions.mBlob.IsDefined());
904 DALI_TEST_EQUAL(2436, md.mPositions.mBlob.mLength);
905 DALI_TEST_EQUAL(3u, md.mPositions.mBlob.mMin.size());
906 DALI_TEST_EQUAL(0.0f, md.mPositions.mBlob.mMin[0]);
907 DALI_TEST_EQUAL(0.0f, md.mPositions.mBlob.mMin[1]);
908 DALI_TEST_EQUAL(0.0f, md.mPositions.mBlob.mMin[2]);
909 DALI_TEST_EQUAL(3u, md.mPositions.mBlob.mMax.size());
910 DALI_TEST_EQUAL(11086.0f, md.mPositions.mBlob.mMax[0]);
911 DALI_TEST_EQUAL(16383.0f, md.mPositions.mBlob.mMax[1]);
912 DALI_TEST_EQUAL(7194.0f, md.mPositions.mBlob.mMax[2]);
914 DALI_TEST_EQUAL(true, md.mNormals.IsDefined());
915 DALI_TEST_EQUAL(true, md.mNormals.mNormalized);
916 DALI_TEST_EQUAL(sizeof(int8_t) * 3, md.mNormals.mBlob.mElementSizeHint);
917 DALI_TEST_EQUAL(true, md.mNormals.mBlob.IsDefined());
918 DALI_TEST_EQUAL(1218, md.mNormals.mBlob.mLength);
919 DALI_TEST_EQUAL(0u, md.mNormals.mBlob.mMin.size());
920 DALI_TEST_EQUAL(0u, md.mNormals.mBlob.mMax.size());
922 DALI_TEST_EQUAL(true, md.mTangents.IsDefined());
923 DALI_TEST_EQUAL(true, md.mTangents.mNormalized);
924 DALI_TEST_EQUAL(Property::VECTOR4, md.mTangentType);
925 DALI_TEST_EQUAL(sizeof(int8_t) * 4, md.mTangents.mBlob.mElementSizeHint);
926 DALI_TEST_EQUAL(true, md.mTangents.mBlob.IsDefined());
927 DALI_TEST_EQUAL(1624, md.mTangents.mBlob.mLength);
928 DALI_TEST_EQUAL(0u, md.mTangents.mBlob.mMin.size());
929 DALI_TEST_EQUAL(0u, md.mTangents.mBlob.mMax.size());
931 DALI_TEST_EQUAL(true, md.mTexCoords.IsDefined());
932 DALI_TEST_EQUAL(false, md.mTexCoords.mNormalized);
933 DALI_TEST_EQUAL(sizeof(uint16_t) * 2, md.mTexCoords.mBlob.mElementSizeHint);
934 DALI_TEST_EQUAL(true, md.mTexCoords.mBlob.IsDefined());
935 DALI_TEST_EQUAL(1624, md.mTexCoords.mBlob.mLength);
936 DALI_TEST_EQUAL(0u, md.mTexCoords.mBlob.mMin.size());
937 DALI_TEST_EQUAL(0u, md.mTexCoords.mBlob.mMax.size());