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",
543 * For the Avocado glTF file and its Assets
544 * Donated by Microsoft for glTF testing
545 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/Avocado/glTF-Quantized
549 * For the AnimatedMorphCube glTF file and its Assets
550 * Donated by Microsoft for glTF testing
551 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/AnimatedMorphCube/glTF-Quantized
553 "AnimatedMorphCubeQuantized",
555 * For the MorphPrimitivesTest glTF file and its Assets
557 * Licensed under the terms of the CC BY 4.0 license: https://creativecommons.org/licenses/by/4.0/
558 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/MorphPrimitivesTest/glTF
559 * Modified using gltfpack 0.18.
561 "MorphPrimitivesTestQuantized",
563 * For the CesiumMilkTruck glTF file and its Assets
564 * Donated by Cesium for glTF testing
565 * Licensed under the terms of the CC BY 4.0 license: http://creativecommons.org/licenses/by/4.0/
566 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/CesiumMilkTruck/glTF
567 * Modified using gltfpack 0.18.
569 "CesiumMilkTruckQuantized",
574 auto& resources = ctx.resources;
575 resources.mEnvironmentMaps.push_back({});
577 printf("%s\n", modelName);
578 ctx.loader.LoadModel(resourcePath + modelName + ".gltf", ctx.loadResult);
579 DALI_TEST_CHECK(ctx.scene.GetNodeCount() > 0);
581 auto& scene = ctx.scene;
582 for(auto iRoot : scene.GetRoots())
584 struct Visitor : NodeDefinition::IVisitor
586 struct ResourceReceiver : IResourceReceiver
588 std::vector<bool> mCounts;
590 void Register(ResourceType::Value type, Index id) override
592 if(type == ResourceType::Mesh)
599 void Start(NodeDefinition& n) override
601 for(auto& renderable : n.mRenderables)
603 renderable->RegisterResources(receiver);
607 void Finish(NodeDefinition& n) override
611 visitor.receiver.mCounts.resize(resources.mMeshes.size(), false);
613 scene.Visit(iRoot, choices, visitor);
614 for(uint32_t i0 = 0, i1 = resources.mMeshes.size(); i0 < i1; ++i0)
616 if(visitor.receiver.mCounts[i0])
618 auto raw = resources.mMeshes[i0].first.LoadRaw(resourcePath, resources.mBuffers);
619 DALI_TEST_CHECK(!raw.mAttribs.empty());
621 resources.mMeshes[i0].second = resources.mMeshes[i0].first.Load(std::move(raw));
622 DALI_TEST_CHECK(resources.mMeshes[i0].second.geometry);
631 int UtcDaliGltfLoaderMRendererTest(void)
634 auto& resources = ctx.resources;
636 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/MRendererTest.gltf", ctx.loadResult);
638 auto& scene = ctx.scene;
639 auto& roots = scene.GetRoots();
640 DALI_TEST_EQUAL(roots.size(), 1u);
641 DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "RootNode");
642 DALI_TEST_EQUAL(scene.GetNode(roots[0])->mScale, Vector3(1.0f, 1.0f, 1.0f));
644 DALI_TEST_EQUAL(scene.GetNodeCount(), 1u);
646 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
647 ViewProjection viewProjection;
651 NodeDefinition::CreateParams nodeParams{
657 Customization::Choices choices;
661 Actor root = Actor::New();
662 SetActorCentered(root);
663 for(auto iRoot : roots)
665 auto resourceRefs = resources.CreateRefCounter();
666 scene.CountResourceRefs(iRoot, choices, resourceRefs);
667 ctx.resources.mReferenceCounts = std::move(resourceRefs);
668 ctx.resources.CountEnvironmentReferences();
669 ctx.resources.LoadResources(ctx.pathProvider);
670 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
672 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
673 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
678 DALI_TEST_EQUAL(root.GetChildCount(), 1u);
679 Actor child = root.GetChildAt(0);
681 DALI_TEST_EQUAL(child.GetProperty(Actor::Property::NAME).Get<std::string>(), "RootNode");
682 DALI_TEST_EQUAL(child.GetProperty(Actor::Property::SCALE).Get<Vector3>(), Vector3(1.0f, 1.0f, 1.0f));
683 DALI_TEST_EQUAL(child.GetRendererCount(), 1u);
684 DALI_TEST_EQUAL(child.GetRendererAt(0).GetTextures().GetTextureCount(), 5u);
686 DALI_TEST_EQUAL(child.GetRendererCount(), 1u);
687 DALI_TEST_EQUAL(child.GetRendererAt(0u).GetProperty<decltype(BlendMode::ON)>(Renderer::Property::BLEND_MODE), BlendMode::ON);
692 int UtcDaliGltfLoaderAnimationLoadingTest(void)
697 auto& resources = ctx.resources;
699 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/CesiumMan_e.gltf", ctx.loadResult);
701 auto& scene = ctx.scene;
702 auto& roots = scene.GetRoots();
703 DALI_TEST_EQUAL(roots.size(), 1u);
705 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
706 ViewProjection viewProjection;
710 NodeDefinition::CreateParams nodeParams{
716 Customization::Choices choices;
718 Actor root = Actor::New();
719 SetActorCentered(root);
720 for(auto iRoot : roots)
722 auto resourceRefs = resources.CreateRefCounter();
723 scene.CountResourceRefs(iRoot, choices, resourceRefs);
724 resources.mReferenceCounts = std::move(resourceRefs);
725 resources.CountEnvironmentReferences();
726 resources.LoadResources(ctx.pathProvider);
727 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
729 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
730 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
735 DALI_TEST_EQUAL(ctx.loadResult.mAnimationDefinitions.size(), 1u);
736 DALI_TEST_EQUAL(ctx.loadResult.mAnimationDefinitions[0].GetPropertyCount(), 57u);
738 uint32_t id = ctx.loadResult.mScene.GetNode(ctx.loadResult.mAnimationDefinitions[0].GetPropertyAt(0).mNodeIndex)->mNodeId;
739 DALI_TEST_EQUAL(id, root.FindChildByName("Skeleton_torso_joint_1").GetProperty<int32_t>(Dali::Actor::Property::ID));
744 int UtcDaliGltfLoaderImageFromBufferView(void)
748 auto& resources = ctx.resources;
750 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/EnvironmentTest_b.gltf", ctx.loadResult);
752 auto& scene = ctx.scene;
753 auto& roots = scene.GetRoots();
754 DALI_TEST_EQUAL(roots.size(), 1u);
756 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
757 ViewProjection viewProjection;
761 NodeDefinition::CreateParams nodeParams{
767 Customization::Choices choices;
771 Actor root = Actor::New();
772 SetActorCentered(root);
773 for(auto iRoot : roots)
775 auto resourceRefs = resources.CreateRefCounter();
776 scene.CountResourceRefs(iRoot, choices, resourceRefs);
777 resources.mReferenceCounts = std::move(resourceRefs);
778 resources.CountEnvironmentReferences();
779 resources.LoadResources(ctx.pathProvider);
780 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
782 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
783 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
788 DALI_TEST_CHECK(resources.mMaterials[0].second.GetTextureCount() > 1);
789 DALI_TEST_EQUAL(resources.mMaterials[0].second.GetTexture(0).GetWidth(), 256);
790 DALI_TEST_EQUAL(resources.mMaterials[0].second.GetTexture(0).GetHeight(), 256);
795 int UtcDaliGltfLoaderUint8Indices(void)
799 auto& resources = ctx.resources;
801 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AlphaBlendModeTest.gltf", ctx.loadResult);
803 auto& scene = ctx.scene;
804 auto& roots = scene.GetRoots();
805 DALI_TEST_EQUAL(roots.size(), 1u);
807 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
808 ViewProjection viewProjection;
812 NodeDefinition::CreateParams nodeParams{
818 Customization::Choices choices;
822 Actor root = Actor::New();
823 SetActorCentered(root);
824 for(auto iRoot : roots)
826 auto resourceRefs = resources.CreateRefCounter();
827 scene.CountResourceRefs(iRoot, choices, resourceRefs);
828 resources.mReferenceCounts = std::move(resourceRefs);
829 resources.CountEnvironmentReferences();
830 resources.LoadResources(ctx.pathProvider);
831 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
833 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
834 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
839 DALI_TEST_CHECK(root.FindChildByName("Bed"));
840 DALI_TEST_CHECK(root.FindChildByName("DecalBlend"));
841 DALI_TEST_CHECK(root.FindChildByName("DecalOpaque"));
846 int UtcDaliGltfLoaderQuantizedMesh(void)
850 auto& resources = ctx.resources;
853 * For the Avocado glTF file and its Assets
854 * Donated by Microsoft for glTF testing
855 * Take from https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/Avocado/glTF-Quantized
857 ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AvocadoQuantized.gltf", ctx.loadResult);
859 auto& scene = ctx.scene;
860 DALI_TEST_EQUAL(1u, scene.GetRoots().size());
861 DALI_TEST_EQUAL(1u, scene.GetNodeCount());
863 auto& roots = scene.GetRoots();
864 DALI_TEST_EQUAL(roots.size(), 1u);
866 Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager();
867 ViewProjection viewProjection;
871 NodeDefinition::CreateParams nodeParams{
877 Customization::Choices choices;
881 Actor root = Actor::New();
882 SetActorCentered(root);
883 for(auto iRoot : roots)
885 auto resourceRefs = resources.CreateRefCounter();
886 scene.CountResourceRefs(iRoot, choices, resourceRefs);
887 resources.mReferenceCounts = std::move(resourceRefs);
888 resources.CountEnvironmentReferences();
889 resources.LoadResources(ctx.pathProvider);
890 if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
892 scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
893 scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
898 auto& meshes = ctx.resources.mMeshes;
899 DALI_TEST_EQUAL(1u, meshes.size());
901 auto& md = meshes[0u].first;
903 DALI_TEST_EQUAL(MeshDefinition::Flags::U16_POSITION | MeshDefinition::Flags::S8_NORMAL | MeshDefinition::Flags::S8_TANGENT | MeshDefinition::Flags::U16_TEXCOORD, md.mFlags);
905 DALI_TEST_EQUAL(true, md.mPositions.IsDefined());
906 DALI_TEST_EQUAL(false, md.mPositions.mNormalized);
907 DALI_TEST_EQUAL(sizeof(uint16_t) * 3, md.mPositions.mBlob.mElementSizeHint);
908 DALI_TEST_EQUAL(true, md.mPositions.mBlob.IsDefined());
909 DALI_TEST_EQUAL(2436, md.mPositions.mBlob.mLength);
910 DALI_TEST_EQUAL(3u, md.mPositions.mBlob.mMin.size());
911 DALI_TEST_EQUAL(0.0f, md.mPositions.mBlob.mMin[0]);
912 DALI_TEST_EQUAL(0.0f, md.mPositions.mBlob.mMin[1]);
913 DALI_TEST_EQUAL(0.0f, md.mPositions.mBlob.mMin[2]);
914 DALI_TEST_EQUAL(3u, md.mPositions.mBlob.mMax.size());
915 DALI_TEST_EQUAL(11086.0f, md.mPositions.mBlob.mMax[0]);
916 DALI_TEST_EQUAL(16383.0f, md.mPositions.mBlob.mMax[1]);
917 DALI_TEST_EQUAL(7194.0f, md.mPositions.mBlob.mMax[2]);
919 DALI_TEST_EQUAL(true, md.mNormals.IsDefined());
920 DALI_TEST_EQUAL(true, md.mNormals.mNormalized);
921 DALI_TEST_EQUAL(sizeof(int8_t) * 3, md.mNormals.mBlob.mElementSizeHint);
922 DALI_TEST_EQUAL(true, md.mNormals.mBlob.IsDefined());
923 DALI_TEST_EQUAL(1218, md.mNormals.mBlob.mLength);
924 DALI_TEST_EQUAL(0u, md.mNormals.mBlob.mMin.size());
925 DALI_TEST_EQUAL(0u, md.mNormals.mBlob.mMax.size());
927 DALI_TEST_EQUAL(true, md.mTangents.IsDefined());
928 DALI_TEST_EQUAL(true, md.mTangents.mNormalized);
929 DALI_TEST_EQUAL(Property::VECTOR4, md.mTangentType);
930 DALI_TEST_EQUAL(sizeof(int8_t) * 4, md.mTangents.mBlob.mElementSizeHint);
931 DALI_TEST_EQUAL(true, md.mTangents.mBlob.IsDefined());
932 DALI_TEST_EQUAL(1624, md.mTangents.mBlob.mLength);
933 DALI_TEST_EQUAL(0u, md.mTangents.mBlob.mMin.size());
934 DALI_TEST_EQUAL(0u, md.mTangents.mBlob.mMax.size());
936 DALI_TEST_EQUAL(false, md.mTexCoords.empty());
937 DALI_TEST_EQUAL(true, md.mTexCoords[0].IsDefined());
938 DALI_TEST_EQUAL(false, md.mTexCoords[0].mNormalized);
939 DALI_TEST_EQUAL(sizeof(uint16_t) * 2, md.mTexCoords[0].mBlob.mElementSizeHint);
940 DALI_TEST_EQUAL(true, md.mTexCoords[0].mBlob.IsDefined());
941 DALI_TEST_EQUAL(1624, md.mTexCoords[0].mBlob.mLength);
942 DALI_TEST_EQUAL(0u, md.mTexCoords[0].mBlob.mMin.size());
943 DALI_TEST_EQUAL(0u, md.mTexCoords[0].mBlob.mMax.size());