// Enable debug log for test coverage
#define DEBUG_ENABLED 1
+#include <dali-scene3d/public-api/loader/gltf2-loader.h>
+#include <dali-scene3d/public-api/loader/load-result.h>
+#include <dali-scene3d/public-api/loader/resource-bundle.h>
+#include <dali-scene3d/public-api/loader/scene-definition.h>
+#include <dali-scene3d/public-api/loader/shader-definition-factory.h>
#include <dali-test-suite-utils.h>
#include <string_view>
-#include "dali-scene3d/public-api/loader/gltf2-loader.h"
-#include "dali-scene3d/public-api/loader/load-result.h"
-#include "dali-scene3d/public-api/loader/resource-bundle.h"
-#include "dali-scene3d/public-api/loader/scene-definition.h"
-#include "dali-scene3d/public-api/loader/shader-definition-factory.h"
using namespace Dali;
using namespace Dali::Scene3D::Loader;
{
struct Context
{
- ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) {
+ ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type)
+ {
return TEST_RESOURCE_DIR "/";
};
ResourceBundle resources;
SceneDefinition scene;
+ SceneMetadata metaData;
std::vector<AnimationDefinition> animations;
std::vector<AnimationGroupDefinition> animationGroups;
LoadResult loadResult{
resources,
scene,
+ metaData,
animations,
animationGroups,
cameras,
ShaderDefinitionFactory sdf;
sdf.SetResources(ctx.resources);
+ InitializeGltfLoader();
DALI_TEST_THROW(LoadGltfScene("non-existent.gltf", sdf, ctx.loadResult),
std::runtime_error,
ExceptionMessageStartsWith{"Failed to load"});
ShaderDefinitionFactory sdf;
sdf.SetResources(ctx.resources);
+ InitializeGltfLoader();
DALI_TEST_THROW(LoadGltfScene(TEST_RESOURCE_DIR "/invalid.gltf", sdf, ctx.loadResult),
std::runtime_error,
ExceptionMessageStartsWith{"Failed to parse"});
{
Context ctx;
+ LoadSceneMetadata(TEST_RESOURCE_DIR "/AnimatedCube.metadata", ctx.metaData);
+
+ std::unordered_map<std::string, ImageMetadata> imageMetadataGroundTruth;
+ imageMetadataGroundTruth["AnimatedCube_BaseColor.png"] = ImageMetadata{ImageDimensions(256, 256), Dali::SamplingMode::BOX_THEN_NEAREST};
+ imageMetadataGroundTruth["AnimatedCube_MetallicRoughness.png"] = ImageMetadata{ImageDimensions(256, 256), Dali::SamplingMode::NEAREST};
+
+ auto metaData = ctx.metaData.mImageMetadata.begin();
+ for(auto& groundTruth : imageMetadataGroundTruth)
+ {
+ DALI_TEST_EQUAL(groundTruth.first, metaData->first);
+ DALI_TEST_EQUAL(groundTruth.second.mMinSize, metaData->second.mMinSize);
+ DALI_TEST_EQUAL(groundTruth.second.mSamplingMode, metaData->second.mSamplingMode);
+ ++metaData;
+ }
+
ShaderDefinitionFactory sdf;
sdf.SetResources(ctx.resources);
+ InitializeGltfLoader();
LoadGltfScene(TEST_RESOURCE_DIR "/AnimatedCube.gltf", sdf, ctx.loadResult);
DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
// Default envmap is used
DALI_TEST_EQUAL(1u, ctx.resources.mEnvironmentMaps.size());
+ TestApplication app;
+
+ Customization::Choices choices;
+ for(auto iRoot : ctx.scene.GetRoots())
+ {
+ auto resourceRefs = ctx.resources.CreateRefCounter();
+ ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs);
+ ctx.resources.CountEnvironmentReferences(resourceRefs);
+ ctx.resources.LoadResources(resourceRefs, ctx.pathProvider);
+ }
+
auto& materials = ctx.resources.mMaterials;
DALI_TEST_EQUAL(2u, materials.size());
const MaterialDefinition materialGroundTruth[]{
- {MaterialDefinition::ALBEDO | MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION |
- MaterialDefinition::NORMAL |
- (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT),
- 0,
- Color::WHITE,
- 1.f,
- 0.f,
- Vector4(1.000, 0.766, 0.336, 1.0),
- 1.f,
- 1.f,
- Vector3(0.2, 0.1, 0.0),
- true,
- false,
- true,
- false,
- {
- {MaterialDefinition::ALBEDO,
- {"AnimatedCube_BaseColor.png",
- SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
- {MaterialDefinition::NORMAL,
- {"AnimatedCube_BaseColor.png",
- SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
- {MaterialDefinition::OCCLUSION,
- {"AnimatedCube_BaseColor.png",
- SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
- {MaterialDefinition::EMISSIVE,
- {"AnimatedCube_BaseColor.png",
- SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
- }},
- {MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
- MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION |
- MaterialDefinition::NORMAL | MaterialDefinition::GLTF_CHANNELS,
- 0,
- Color::WHITE,
- 1.f,
- 0.f,
- Vector4(1.000, 0.766, 0.336, 1.0),
- 1.f,
- 1.f,
- Vector3(0.2, 0.1, 0.0),
- true,
- true,
- true,
- false,
- {
- {MaterialDefinition::ALBEDO,
- {"AnimatedCube_BaseColor.png",
- SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
- {MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | MaterialDefinition::GLTF_CHANNELS,
- {"AnimatedCube_MetallicRoughness.png",
- SamplerFlags::Encode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::MIRRORED_REPEAT)}},
- {MaterialDefinition::NORMAL,
- {"AnimatedCube_BaseColor.png",
- SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
- {MaterialDefinition::OCCLUSION,
- {"AnimatedCube_BaseColor.png",
- SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
- {MaterialDefinition::EMISSIVE,
- {"AnimatedCube_BaseColor.png",
- SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}},
- }},
+ {
+ nullptr,
+ MaterialDefinition::ALBEDO | MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION |
+ MaterialDefinition::NORMAL | MaterialDefinition::SPECULAR | MaterialDefinition::SPECULAR_COLOR |
+ (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT),
+ 0,
+ Color::WHITE,
+ 1.f,
+ 0.f,
+ Vector4(1.000, 0.766, 0.336, 1.0),
+ 1.f,
+ 1.f,
+ Vector3(0.2, 0.1, 0.0),
+ 0.0f,
+ 0.5f,
+ Vector3(0, 0, 1),
+ true,
+ false,
+ true,
+ false,
+ true,
+ true,
+ {
+ {
+ MaterialDefinition::ALBEDO,
+ {
+ "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::BOX_THEN_NEAREST,
+ },
+ },
+ {
+ MaterialDefinition::NORMAL,
+ {
+ "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::BOX_THEN_NEAREST,
+ },
+ },
+ {
+ MaterialDefinition::OCCLUSION,
+ {
+ "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::BOX_THEN_NEAREST,
+ },
+ },
+ {
+ MaterialDefinition::EMISSIVE,
+ {
+ "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::BOX_THEN_NEAREST,
+ },
+ },
+ {
+ MaterialDefinition::SPECULAR,
+ {
+ "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::BOX_THEN_NEAREST,
+ },
+ },
+ {
+ MaterialDefinition::SPECULAR_COLOR,
+ {
+ "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::BOX_THEN_NEAREST,
+ },
+ },
+ },
+ },
+ {
+ nullptr,
+ MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+ MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION | MaterialDefinition::NORMAL |
+ MaterialDefinition::GLTF_CHANNELS,
+ 0,
+ Color::WHITE,
+ 1.f,
+ 0.f,
+ Vector4(1.000, 0.766, 0.336, 1.0),
+ 1.f,
+ 1.f,
+ Vector3(0.2, 0.1, 0.0),
+ 0.04f,
+ 1.0f,
+ Vector3::ONE,
+ true,
+ true,
+ true,
+ false,
+ true,
+ false,
+ {
+ {
+ MaterialDefinition::ALBEDO,
+ {
+ "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::BOX_THEN_NEAREST,
+ },
+ },
+ {
+ MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | MaterialDefinition::GLTF_CHANNELS,
+ {
+ "AnimatedCube_MetallicRoughness.png",
+ SamplerFlags::Encode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::MIRRORED_REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::NEAREST,
+ },
+ },
+ {
+ MaterialDefinition::NORMAL,
+ {
+ "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::BOX_THEN_NEAREST,
+ },
+ },
+ {
+ MaterialDefinition::OCCLUSION,
+ {
+ "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::BOX_THEN_NEAREST,
+ },
+ },
+ {
+ MaterialDefinition::EMISSIVE,
+ {
+ "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT),
+ ImageDimensions(256, 256),
+ SamplingMode::BOX_THEN_NEAREST,
+ },
+ },
+ },
+ },
};
auto iMaterial = materials.begin();
+ auto iMetadata = ctx.metaData.mImageMetadata.begin();
for(auto& m : materialGroundTruth)
{
printf("material %ld\n", iMaterial - materials.begin());
DALI_TEST_EQUAL(md.mNormalScale, m.mNormalScale);
DALI_TEST_EQUAL(md.mOcclusionStrength, m.mOcclusionStrength);
DALI_TEST_EQUAL(md.mEmissiveFactor, m.mEmissiveFactor);
+ DALI_TEST_EQUAL(md.mDielectricSpecular, m.mDielectricSpecular);
+ DALI_TEST_EQUAL(md.mSpecularFactor, m.mSpecularFactor);
+ DALI_TEST_EQUAL(md.mSpecularColorFactor, m.mSpecularColorFactor);
DALI_TEST_EQUAL(md.mNeedAlbedoTexture, m.mNeedAlbedoTexture);
DALI_TEST_EQUAL(md.mNeedMetallicRoughnessTexture, m.mNeedMetallicRoughnessTexture);
DALI_TEST_EQUAL(md.mNeedNormalTexture, m.mNeedNormalTexture);
+ DALI_TEST_EQUAL(md.mIsOpaque, m.mIsOpaque);
+ DALI_TEST_EQUAL(md.mIsMask, m.mIsMask);
DALI_TEST_EQUAL(md.mTextureStages.size(), m.mTextureStages.size());
auto iTexture = md.mTextureStages.begin();
DALI_TEST_EQUAL(iTexture->mSemantic, ts.mSemantic);
DALI_TEST_EQUAL(iTexture->mTexture.mImageUri, ts.mTexture.mImageUri);
DALI_TEST_EQUAL(uint32_t(iTexture->mTexture.mSamplerFlags), uint32_t(ts.mTexture.mSamplerFlags)); // don't interpret it as a character
+ DALI_TEST_EQUAL(iTexture->mTexture.mMinImageDimensions, ts.mTexture.mMinImageDimensions);
+ DALI_TEST_EQUAL(iTexture->mTexture.mSamplingMode, ts.mTexture.mSamplingMode);
+
++iTexture;
}
++iMaterial;
+ ++iMetadata;
}
auto& meshes = ctx.resources.mMeshes;
using Accessor = MeshDefinition::Accessor;
const MeshDefinition meshGroundTruth[]{
{
+ nullptr,
0,
Geometry::TRIANGLES,
"AnimatedCube.bin",
Accessor{Blob{0, 0}, {}},
},
{
+ nullptr,
0,
Geometry::TRIANGLES,
"AnimatedCube.bin",
END_TEST;
}
+int UtcDaliGltfLoaderSuccess2(void)
+{
+ Context ctx;
+ ShaderDefinitionFactory sdf;
+ sdf.SetResources(ctx.resources);
+
+ InitializeGltfLoader();
+ LoadGltfScene(TEST_RESOURCE_DIR "/AnimatedCubeStride.gltf", sdf, ctx.loadResult);
+
+ DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
+ DALI_TEST_EQUAL(1u, ctx.scene.GetNodeCount());
+
+ TestApplication app;
+
+ Customization::Choices choices;
+ for(auto iRoot : ctx.scene.GetRoots())
+ {
+ auto resourceRefs = ctx.resources.CreateRefCounter();
+ ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs);
+ ctx.resources.LoadResources(resourceRefs, ctx.pathProvider);
+ }
+
+ DALI_TEST_EQUAL(true, ctx.resources.mMeshes[0u].first.mPositions.IsDefined());
+ DALI_TEST_EQUAL(432, ctx.resources.mMeshes[0u].first.mPositions.mBlob.mLength);
+
+ END_TEST;
+}
+
int UtcDaliGltfLoaderSuccessShort(void)
{
TestApplication app;
const std::string resourcePath = TEST_RESOURCE_DIR "/";
- auto pathProvider = [resourcePath](ResourceType::Value) {
+ auto pathProvider = [resourcePath](ResourceType::Value)
+ {
return resourcePath;
};
sdf.SetResources(resources);
printf("%s\n", modelName);
+ InitializeGltfLoader();
LoadGltfScene(resourcePath + modelName + ".gltf", sdf, ctx.loadResult);
DALI_TEST_CHECK(ctx.scene.GetNodeCount() > 0);
sdf.SetResources(ctx.resources);
auto& resources = ctx.resources;
+ InitializeGltfLoader();
LoadGltfScene(TEST_RESOURCE_DIR "/MRendererTest.gltf", sdf, ctx.loadResult);
auto& scene = ctx.scene;
DALI_TEST_EQUAL(child.GetRendererCount(), 1u);
DALI_TEST_EQUAL(child.GetRendererAt(0).GetTextures().GetTextureCount(), 4u);
+ DALI_TEST_EQUAL(child.GetRendererCount(), 1u);
+ DALI_TEST_EQUAL(child.GetRendererAt(0u).GetProperty<decltype(BlendMode::ON)>(Renderer::Property::BLEND_MODE), BlendMode::ON);
+
+ END_TEST;
+}
+
+int UtcDaliGltfLoaderAnimationLoadingTest(void)
+{
+ Context ctx;
+
+ ShaderDefinitionFactory sdf;
+ sdf.SetResources(ctx.resources);
+ auto& resources = ctx.resources;
+
+ InitializeGltfLoader();
+ LoadGltfScene(TEST_RESOURCE_DIR "/BoxAnimated.gltf", sdf, ctx.loadResult);
+
+ auto& scene = ctx.scene;
+ auto& roots = scene.GetRoots();
+ DALI_TEST_EQUAL(roots.size(), 1u);
+
+ ViewProjection viewProjection;
+ Transforms xforms{
+ MatrixStack{},
+ viewProjection};
+ NodeDefinition::CreateParams nodeParams{
+ resources,
+ xforms,
+ };
+
+ Customization::Choices choices;
+
+ TestApplication app;
+
+ Actor root = Actor::New();
+ SetActorCentered(root);
+ for(auto iRoot : roots)
+ {
+ auto resourceRefs = resources.CreateRefCounter();
+ scene.CountResourceRefs(iRoot, choices, resourceRefs);
+ resources.CountEnvironmentReferences(resourceRefs);
+ resources.LoadResources(resourceRefs, ctx.pathProvider);
+ if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
+ {
+ scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
+ scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
+ scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
+ root.Add(actor);
+ }
+ }
+
+ DALI_TEST_EQUAL(ctx.loadResult.mAnimationDefinitions.size(), 1u);
+ DALI_TEST_EQUAL(ctx.loadResult.mAnimationDefinitions[0].mProperties.size(), 2u);
+
+ uint32_t id = ctx.loadResult.mScene.GetNode(ctx.loadResult.mAnimationDefinitions[0].mProperties[0].mNodeIndex)->mNodeId;
+ DALI_TEST_EQUAL(id, root.FindChildByName("node2").GetProperty<int32_t>(Dali::Actor::Property::ID));
+ uint32_t id2 = ctx.loadResult.mScene.GetNode(ctx.loadResult.mAnimationDefinitions[0].mProperties[1].mNodeIndex)->mNodeId;
+ DALI_TEST_EQUAL(id2, root.FindChildByName("node0").GetProperty<int32_t>(Dali::Actor::Property::ID));
+
END_TEST;
}