Adjust node scale for avatar models generated by glTF Tools for M-Renderer 19/273419/6
authorRichard Huang <r.huang@samsung.com>
Tue, 5 Apr 2022 09:31:38 +0000 (10:31 +0100)
committerRichard Huang <r.huang@samsung.com>
Thu, 7 Apr 2022 16:01:55 +0000 (17:01 +0100)
Change-Id: I4bbfd455aafd4772e8b0433e469f07e981bcf9d4

automated-tests/resources/MRendererTest.gltf [new file with mode: 0644]
automated-tests/src/dali-scene-loader/utc-Dali-Gltf2Loader.cpp
dali-scene-loader/internal/gltf2-asset.h
dali-scene-loader/public-api/gltf2-loader.cpp

diff --git a/automated-tests/resources/MRendererTest.gltf b/automated-tests/resources/MRendererTest.gltf
new file mode 100644 (file)
index 0000000..ae3d113
--- /dev/null
@@ -0,0 +1,179 @@
+{\r
+  "scene" : 0,\r
+  "scenes" : [\r
+    {\r
+      "nodes" : [ 0 ]\r
+    }\r
+  ],\r
+\r
+  "nodes" : [\r
+    {\r
+      "mesh" : 0,\r
+      "rotation" : [ 0.0, 0.0, 0.0, 1.0 ],\r
+      "scale": [\r
+          100.0,\r
+          100.0,\r
+          100.0\r
+      ],\r
+      "name": "RootNode"\r
+    }\r
+  ],\r
+\r
+  "meshes" : [\r
+    {\r
+      "primitives" : [ {\r
+        "attributes" : {\r
+          "POSITION" : 1\r
+        },\r
+        "indices" : 0,\r
+        "material": 0\r
+      } ]\r
+    }\r
+  ],\r
+\r
+  "animations": [\r
+    {\r
+      "samplers" : [\r
+        {\r
+          "input" : 2,\r
+          "interpolation" : "LINEAR",\r
+          "output" : 3\r
+        }\r
+      ],\r
+      "channels" : [ {\r
+        "sampler" : 0,\r
+        "target" : {\r
+          "node" : 0,\r
+          "path" : "rotation"\r
+        }\r
+      } ]\r
+    }\r
+  ],\r
+\r
+  "buffers" : [\r
+    {\r
+      "uri" : "simpleTriangle.bin",\r
+      "byteLength" : 44\r
+    },\r
+    {\r
+      "uri" : "animation.bin",\r
+      "byteLength" : 100\r
+    }\r
+  ],\r
+\r
+  "bufferViews" : [\r
+    {\r
+      "buffer" : 0,\r
+      "byteOffset" : 0,\r
+      "byteLength" : 6,\r
+      "target" : 34963\r
+    },\r
+    {\r
+      "buffer" : 0,\r
+      "byteOffset" : 8,\r
+      "byteLength" : 36,\r
+      "target" : 34962\r
+    },\r
+    {\r
+      "buffer" : 1,\r
+      "byteOffset" : 0,\r
+      "byteLength" : 100\r
+    }\r
+  ],\r
+\r
+  "accessors" : [\r
+    {\r
+      "bufferView" : 0,\r
+      "byteOffset" : 0,\r
+      "componentType" : 5123,\r
+      "count" : 3,\r
+      "type" : "SCALAR",\r
+      "max" : [ 2 ],\r
+      "min" : [ 0 ]\r
+    },\r
+    {\r
+      "bufferView" : 1,\r
+      "byteOffset" : 0,\r
+      "componentType" : 5126,\r
+      "count" : 3,\r
+      "type" : "VEC3",\r
+      "max" : [ 1.0, 1.0, 0.0 ],\r
+      "min" : [ 0.0, 0.0, 0.0 ]\r
+    },\r
+    {\r
+      "bufferView" : 2,\r
+      "byteOffset" : 0,\r
+      "componentType" : 5126,\r
+      "count" : 5,\r
+      "type" : "SCALAR",\r
+      "max" : [ 1.0 ],\r
+      "min" : [ 0.0 ]\r
+    },\r
+    {\r
+      "bufferView" : 2,\r
+      "byteOffset" : 20,\r
+      "componentType" : 5126,\r
+      "count" : 5,\r
+      "type" : "VEC4",\r
+      "max" : [ 0.0, 0.0, 1.0, 1.0 ],\r
+      "min" : [ 0.0, 0.0, 0.0, -0.707 ]\r
+    }\r
+  ],\r
+\r
+  "asset" : {\r
+    "generator": "glTF Tools for M-Renderer",\r
+    "version" : "2.0"\r
+  },\r
+\r
+  "materials": [\r
+    {\r
+      "pbrMetallicRoughness":\r
+      {\r
+        "baseColorTexture":\r
+        {\r
+          "index": 0,\r
+          "texCoord": 0\r
+        },\r
+        "metallicFactor": 0,\r
+        "baseColorFactor":\r
+        [\r
+          1,\r
+          1,\r
+          1,\r
+          1\r
+        ],\r
+        "roughnessFactor": 1\r
+      },\r
+      "emissiveFactor":\r
+      [\r
+        0,\r
+        0,\r
+        0\r
+      ],\r
+      "alphaMode": "OPAQUE",\r
+      "doubleSided": false\r
+    }\r
+  ],\r
+\r
+  "textures": [\r
+    {\r
+      "sampler": 0,\r
+      "source": 0\r
+    }\r
+  ],\r
+\r
+  "images": [\r
+    {\r
+      "uri": "AnimatedCube_BaseColor.png"\r
+    }\r
+  ],\r
+\r
+  "samplers": [\r
+    {\r
+      "magFilter": 9729,\r
+      "minFilter": 9986,\r
+      "wrapS": 10497,\r
+      "wrapT": 10497\r
+    }\r
+  ]\r
+}\r
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;
+}
index 1ec67e2..f5bd6b9 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE_LOADER_GLTF2_ASSET_H_
 #define DALI_SCENE_LOADER_GLTF2_ASSET_H_
 /*
- * Copyright (c) 2021 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.
@@ -93,6 +93,7 @@ private:
 
 struct Asset
 {
+  std::string_view mGenerator;
   std::string_view mVersion;
 };
 
index 18923cf..923d0e4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 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.
@@ -43,6 +43,11 @@ const std::string ORIENTATION_PROPERTY("orientation");
 const std::string SCALE_PROPERTY("scale");
 const std::string BLEND_SHAPE_WEIGHTS_UNIFORM("uBlendShapeWeight");
 
+const std::string MRENDERER_MODEL_IDENTIFICATION("M-Renderer");
+
+const std::string ROOT_NODE_NAME("RootNode");
+const Vector3     SCALE_TO_ADJUST(100.0f, 100.0f, 100.0f);
+
 const Geometry::Type GLTF2_TO_DALI_PRIMITIVES[]{
   Geometry::POINTS,
   Geometry::LINES,
@@ -692,7 +697,7 @@ void ConvertCamera(const gt::Camera& camera, CameraParameters& camParams)
   }
 }
 
-void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& cctx)
+void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& cctx, bool isMRendererModel)
 {
   auto& output    = cctx.mOutput;
   auto& scene     = output.mScene;
@@ -715,6 +720,11 @@ void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, Con
       nodeDef->mPosition    = node.mTranslation;
       nodeDef->mOrientation = node.mRotation;
       nodeDef->mScale       = node.mScale;
+
+      if(isMRendererModel && node.mName == ROOT_NODE_NAME && node.mScale == SCALE_TO_ADJUST)
+      {
+        nodeDef->mScale *= 0.01f;
+      }
     }
 
     return nodeDef;
@@ -774,11 +784,11 @@ void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, Con
 
   for(auto& n : node.mChildren)
   {
-    ConvertNode(*n, n.GetIndex(), idx, cctx);
+    ConvertNode(*n, n.GetIndex(), idx, cctx, isMRendererModel);
   }
 }
 
-void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx)
+void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx, bool isMRendererModel)
 {
   auto& outScene = cctx.mOutput.mScene;
   Index rootIdx  = outScene.GetNodeCount();
@@ -788,7 +798,7 @@ void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx)
       break;
 
     case 1:
-      ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, cctx);
+      ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, cctx, isMRendererModel);
       outScene.AddRootNode(rootIdx);
       break;
 
@@ -802,25 +812,25 @@ void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx)
 
       for(auto& n : scene.mNodes)
       {
-        ConvertNode(*n, n.GetIndex(), rootIdx, cctx);
+        ConvertNode(*n, n.GetIndex(), rootIdx, cctx, isMRendererModel);
       }
       break;
     }
   }
 }
 
-void ConvertNodes(const gt::Document& doc, ConversionContext& cctx)
+void ConvertNodes(const gt::Document& doc, ConversionContext& cctx, bool isMRendererModel)
 {
-  ConvertSceneNodes(*doc.mScene, cctx);
+  ConvertSceneNodes(*doc.mScene, cctx, isMRendererModel);
 
   for(uint32_t i = 0, i1 = doc.mScene.GetIndex(); i < i1; ++i)
   {
-    ConvertSceneNodes(doc.mScenes[i], cctx);
+    ConvertSceneNodes(doc.mScenes[i], cctx, isMRendererModel);
   }
 
   for(uint32_t i = doc.mScene.GetIndex() + 1; i < doc.mScenes.size(); ++i)
   {
-    ConvertSceneNodes(doc.mScenes[i], cctx);
+    ConvertSceneNodes(doc.mScenes[i], cctx, isMRendererModel);
   }
 }
 
@@ -1155,10 +1165,23 @@ void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactor
 
   gt::Document doc;
 
-  auto& rootObj        = js::Cast<json_object_s>(*root);
-  auto  jsAsset        = js::FindObjectChild("asset", rootObj);
-  auto  jsAssetVersion = js::FindObjectChild("version", js::Cast<json_object_s>(*jsAsset));
-  doc.mAsset.mVersion  = js::Read::StringView(*jsAssetVersion);
+  auto& rootObj = js::Cast<json_object_s>(*root);
+  auto  jsAsset = js::FindObjectChild("asset", rootObj);
+
+  auto jsAssetVersion = js::FindObjectChild("version", js::Cast<json_object_s>(*jsAsset));
+  if(jsAssetVersion)
+  {
+    doc.mAsset.mVersion = js::Read::StringView(*jsAssetVersion);
+  }
+
+  bool isMRendererModel(false);
+  auto jsAssetGenerator = js::FindObjectChild("generator", js::Cast<json_object_s>(*jsAsset));
+  if(jsAssetGenerator)
+  {
+    doc.mAsset.mGenerator = js::Read::StringView(*jsAssetGenerator);
+    isMRendererModel      = (doc.mAsset.mGenerator.find(MRENDERER_MODEL_IDENTIFICATION) != std::string_view::npos);
+  }
+
 
   gt::SetRefReaderObject(doc);
   DOCUMENT_READER.Read(rootObj, doc);
@@ -1168,7 +1191,7 @@ void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactor
 
   ConvertMaterials(doc, cctx);
   ConvertMeshes(doc, cctx);
-  ConvertNodes(doc, cctx);
+  ConvertNodes(doc, cctx, isMRendererModel);
   ConvertAnimations(doc, cctx);
 
   ProcessSkins(doc, cctx);