Adjust node scale for avatar models generated by glTF Tools for M-Renderer
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-scene-loader / utc-Dali-Gltf2Loader.cpp
index 3f829dc..47515b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 // Enable debug log for test coverage
 #define DEBUG_ENABLED 1
 
+#include <dali-test-suite-utils.h>
+#include <string_view>
+#include "dali-scene-loader/public-api/gltf2-loader.h"
+#include "dali-scene-loader/public-api/load-result.h"
 #include "dali-scene-loader/public-api/resource-bundle.h"
 #include "dali-scene-loader/public-api/scene-definition.h"
-#include "dali-scene-loader/public-api/load-result.h"
-#include "dali-scene-loader/public-api/gltf2-loader.h"
 #include "dali-scene-loader/public-api/shader-definition-factory.h"
-#include <dali-test-suite-utils.h>
-#include <string_view>
 
 using namespace Dali;
 using namespace Dali::SceneLoader;
 
 #define DALI_TEST_THROW(expression, exception, predicate) \
-  {\
-    bool daliTestThrowSuccess__ = false;\
-    try\
-    {\
-      do { expression; } while(0);\
-      printf("No exception was thrown.\n");\
-    }\
-    catch (std::decay<exception>::type& ex)\
-    {\
-      daliTestThrowSuccess__ = predicate(ex);\
-    }\
-    catch (...)\
-    {\
-      printf("Wrong type of exception thrown.\n");\
-    }\
-    DALI_TEST_CHECK(daliTestThrowSuccess__);\
+  {                                                       \
+    bool daliTestThrowSuccess__ = false;                  \
+    try                                                   \
+    {                                                     \
+      do                                                  \
+      {                                                   \
+        expression;                                       \
+      } while(0);                                         \
+      printf("No exception was thrown.\n");               \
+    }                                                     \
+    catch(std::decay<exception>::type & ex)               \
+    {                                                     \
+      daliTestThrowSuccess__ = predicate(ex);             \
+    }                                                     \
+    catch(...)                                            \
+    {                                                     \
+      printf("Wrong type of exception thrown.\n");        \
+    }                                                     \
+    DALI_TEST_CHECK(daliTestThrowSuccess__);              \
   }
 
 namespace
 {
 struct Context
 {
-  ResourceBundle resources;
+  ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) {
+    return TEST_RESOURCE_DIR "/";
+  };
+
+  ResourceBundle  resources;
   SceneDefinition scene;
 
-  std::vector<AnimationDefinition> animations;
+  std::vector<AnimationDefinition>      animations;
   std::vector<AnimationGroupDefinition> animationGroups;
-  std::vector<CameraParameters> cameras;
-  std::vector<LightParameters> lights;
+  std::vector<CameraParameters>         cameras;
+  std::vector<LightParameters>          lights;
 
-  LoadResult loadResult {
+  LoadResult loadResult{
     resources,
     scene,
     animations,
     animationGroups,
     cameras,
-    lights
-  };
+    lights};
 };
 
 struct ExceptionMessageStartsWith
@@ -77,7 +83,7 @@ struct ExceptionMessageStartsWith
   bool operator()(const std::runtime_error& e)
   {
     const bool success = (0 == strncmp(e.what(), expected.data(), expected.size()));
-    if (!success)
+    if(!success)
     {
       printf("Expected: %s, got: %s.\n", expected.data(), e.what());
     }
@@ -85,7 +91,7 @@ struct ExceptionMessageStartsWith
   }
 };
 
-}
+} // namespace
 
 int UtcDaliGltfLoaderFailedToLoad(void)
 {
@@ -95,8 +101,8 @@ int UtcDaliGltfLoaderFailedToLoad(void)
   sdf.SetResources(ctx.resources);
 
   DALI_TEST_THROW(LoadGltfScene("non-existent.gltf", sdf, ctx.loadResult),
-    std::runtime_error,
-    ExceptionMessageStartsWith{"Failed to load"});
+                  std::runtime_error,
+                  ExceptionMessageStartsWith{"Failed to load"});
 
   DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
   DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
@@ -123,8 +129,8 @@ int UtcDaliGltfLoaderFailedToParse(void)
   sdf.SetResources(ctx.resources);
 
   DALI_TEST_THROW(LoadGltfScene(TEST_RESOURCE_DIR "/invalid.gltf", sdf, ctx.loadResult),
-    std::runtime_error,
-    ExceptionMessageStartsWith{"Failed to parse"});
+                  std::runtime_error,
+                  ExceptionMessageStartsWith{"Failed to parse"});
 
   DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
   DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
@@ -159,50 +165,46 @@ int UtcDaliGltfLoaderSuccess1(void)
 
   auto& materials = ctx.resources.mMaterials;
   DALI_TEST_EQUAL(2u, materials.size());
-  const MaterialDefinition materialGroundTruth[] {
-    {
-      MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
-        MaterialDefinition::NORMAL | MaterialDefinition::TRANSPARENCY | MaterialDefinition::GLTF_CHANNELS |
-        (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT),
-      0,
-      Vector4(1.f, .766f, .336f, 1.f),
-      1.f,
-      0.f,
-      {
-        { 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::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
-        MaterialDefinition::NORMAL | MaterialDefinition::GLTF_CHANNELS,
-      0,
-      Vector4(1.f, .766f, .336f, 1.f),
-      1.f,
-      0.f,
-      {
-        { 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) } },
-      }
-    },
+  const MaterialDefinition materialGroundTruth[]{
+    {MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+       MaterialDefinition::NORMAL | MaterialDefinition::TRANSPARENCY | MaterialDefinition::GLTF_CHANNELS |
+       (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT),
+     0,
+     Vector4(1.f, .766f, .336f, 1.f),
+     1.f,
+     0.f,
+     {
+       {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::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+       MaterialDefinition::NORMAL | MaterialDefinition::GLTF_CHANNELS,
+     0,
+     Vector4(1.f, .766f, .336f, 1.f),
+     1.f,
+     0.f,
+     {
+       {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)}},
+     }},
   };
 
   auto iMaterial = materials.begin();
-  for (auto& m : materialGroundTruth)
+  for(auto& m : materialGroundTruth)
   {
     printf("material %ld\n", iMaterial - materials.begin());
     auto& md = iMaterial->first;
@@ -214,7 +216,7 @@ int UtcDaliGltfLoaderSuccess1(void)
 
     DALI_TEST_EQUAL(md.mTextureStages.size(), m.mTextureStages.size());
     auto iTexture = md.mTextureStages.begin();
-    for (auto& ts: m.mTextureStages)
+    for(auto& ts : m.mTextureStages)
     {
       printf("texture %ld\n", iTexture - md.mTextureStages.begin());
       DALI_TEST_EQUAL(iTexture->mSemantic, ts.mSemantic);
@@ -228,48 +230,47 @@ int UtcDaliGltfLoaderSuccess1(void)
   auto& meshes = ctx.resources.mMeshes;
   DALI_TEST_EQUAL(2u, meshes.size());
 
-  using Blob = MeshDefinition::Blob;
+  using Blob     = MeshDefinition::Blob;
   using Accessor = MeshDefinition::Accessor;
-  const MeshDefinition meshGroundTruth[] {
+  const MeshDefinition meshGroundTruth[]{
     {
       0,
       Geometry::TRIANGLES,
       "AnimatedCube.bin",
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
     },
     {
       0,
       Geometry::TRIANGLES,
       "AnimatedCube.bin",
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
-      Accessor{ Blob{ 0, 0 }, {} },
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
+      Accessor{Blob{0, 0}, {}},
     },
   };
 
   auto iMesh = meshes.begin();
-  for (auto& m : meshGroundTruth)
+  for(auto& m : meshGroundTruth)
   {
     printf("mesh %ld\n", iMesh - meshes.begin());
 
     auto& md = iMesh->first;
     DALI_TEST_EQUAL(md.mFlags, m.mFlags);
     DALI_TEST_EQUAL(md.mPrimitiveType, m.mPrimitiveType);
-    for (auto mp: {
-      &MeshDefinition::mIndices,
-      &MeshDefinition::mPositions,
-      &MeshDefinition::mNormals,
-      &MeshDefinition::mTexCoords,
-      &MeshDefinition::mTangents,
-      &MeshDefinition::mJoints0,
-      &MeshDefinition::mWeights0
-    })
+    for(auto mp : {
+          &MeshDefinition::mIndices,
+          &MeshDefinition::mPositions,
+          &MeshDefinition::mNormals,
+          &MeshDefinition::mTexCoords,
+          &MeshDefinition::mTangents,
+          &MeshDefinition::mJoints0,
+          &MeshDefinition::mWeights0})
     {
       DALI_TEST_EQUAL((md.*mp).IsDefined(), (m.*mp).IsDefined());
       DALI_TEST_EQUAL((md.*mp).mBlob.IsDefined(), (m.*mp).mBlob.IsDefined());
@@ -296,24 +297,25 @@ int UtcDaliGltfLoaderSuccessShort(void)
   TestApplication app;
 
   const std::string resourcePath = TEST_RESOURCE_DIR "/";
-  auto pathProvider = [resourcePath](ResourceType::Value) {
+  auto              pathProvider = [resourcePath](ResourceType::Value) {
     return resourcePath;
   };
 
   Customization::Choices choices;
-  for (auto modelName : {
-    "2CylinderEngine",
-    "AnimatedMorphCube",
-    "AnimatedMorphSphere",
-    "AnimatedTriangle",
-    "BoxAnimated",
-    "CesiumMan",
-    "CesiumMilkTruck",
-    "EnvironmentTest",
-    "MetalRoughSpheres",
-    "MorphPrimitivesTest",
-    "SimpleSparseAccessor",
-  })
+  for(auto modelName : {
+        "2CylinderEngine",
+        "AnimatedMorphCube",
+        "AnimatedMorphSphere",
+        "AnimatedTriangle",
+        "BoxAnimated",
+        "CesiumMan",
+        "CesiumMilkTruck",
+        "EnvironmentTest",
+        "MetalRoughSpheres",
+        "MorphPrimitivesTest",
+        "MRendererTest",
+        "SimpleSparseAccessor",
+      })
   {
     Context ctx;
 
@@ -329,17 +331,17 @@ int UtcDaliGltfLoaderSuccessShort(void)
     DALI_TEST_CHECK(ctx.scene.GetNodeCount() > 0);
 
     auto& scene = ctx.scene;
-    for (auto iRoot : scene.GetRoots())
+    for(auto iRoot : scene.GetRoots())
     {
-      struct Visitor: NodeDefinition::IVisitor
+      struct Visitor : NodeDefinition::IVisitor
       {
-        struct ResourceReceiver: IResourceReceiver
+        struct ResourceReceiver : IResourceReceiver
         {
           std::vector<bool> mCounts;
 
           void Register(ResourceType::Value type, Index id) override
           {
-            if (type == ResourceType::Mesh)
+            if(type == ResourceType::Mesh)
             {
               mCounts[id] = true;
             }
@@ -348,21 +350,22 @@ int UtcDaliGltfLoaderSuccessShort(void)
 
         void Start(NodeDefinition& n) override
         {
-          if (n.mRenderable)
+          if(n.mRenderable)
           {
             n.mRenderable->RegisterResources(receiver);
           }
         }
 
         void Finish(NodeDefinition& n) override
-        {}
+        {
+        }
       } visitor;
       visitor.receiver.mCounts.resize(resources.mMeshes.size(), false);
 
       scene.Visit(iRoot, choices, visitor);
-      for (uint32_t i0 = 0, i1 = resources.mMeshes.size(); i0 < i1; ++i0)
+      for(uint32_t i0 = 0, i1 = resources.mMeshes.size(); i0 < i1; ++i0)
       {
-        if (visitor.receiver.mCounts[i0])
+        if(visitor.receiver.mCounts[i0])
         {
           auto raw = resources.mMeshes[i0].first.LoadRaw(resourcePath);
           DALI_TEST_CHECK(!raw.mAttribs.empty());
@@ -376,3 +379,59 @@ int UtcDaliGltfLoaderSuccessShort(void)
 
   END_TEST;
 }
+
+int UtcDaliGltfLoaderMRendererTest(void)
+{
+  Context ctx;
+
+  ShaderDefinitionFactory sdf;
+  sdf.SetResources(ctx.resources);
+  auto& resources = ctx.resources;
+  resources.mEnvironmentMaps.push_back({});
+
+  LoadGltfScene(TEST_RESOURCE_DIR "/MRendererTest.gltf", sdf, ctx.loadResult);
+
+  auto& scene = ctx.scene;
+  auto& roots = scene.GetRoots();
+  DALI_TEST_EQUAL(roots.size(), 1u);
+  DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "RootNode");
+  DALI_TEST_EQUAL(scene.GetNode(roots[0])->mScale, Vector3(1.0f, 1.0f, 1.0f));
+
+  DALI_TEST_EQUAL(scene.GetNodeCount(), 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(root.GetChildCount(), 1u);
+  DALI_TEST_EQUAL(root.GetChildAt(0).GetProperty(Actor::Property::NAME).Get<std::string>(), "RootNode");
+  DALI_TEST_EQUAL(root.GetChildAt(0).GetProperty(Actor::Property::SCALE).Get<Vector3>(), Vector3(1.0f, 1.0f, 1.0f));
+
+  END_TEST;
+}