Ambient occlusion support in DLI model 20/274120/3
authorRichard Huang <r.huang@samsung.com>
Thu, 21 Apr 2022 12:52:56 +0000 (13:52 +0100)
committerRichard Huang <r.huang@samsung.com>
Fri, 22 Apr 2022 11:02:49 +0000 (12:02 +0100)
Change-Id: If4378a8ecffbc37755b711805cc0f241dbd6e592

automated-tests/resources/coverageTest.bin [new file with mode: 0644]
automated-tests/resources/coverageTest.dli [new file with mode: 0644]
automated-tests/resources/dli_pbr.fsh
automated-tests/src/dali-scene-loader/utc-Dali-DliLoader.cpp
automated-tests/src/dali-scene-loader/utc-Dali-ShaderDefinitionFactory.cpp
dali-scene-loader/public-api/dli-loader.cpp
dali-scene-loader/public-api/material-definition.cpp
dali-scene-loader/public-api/shader-definition-factory.cpp

diff --git a/automated-tests/resources/coverageTest.bin b/automated-tests/resources/coverageTest.bin
new file mode 100644 (file)
index 0000000..1d0e3d6
Binary files /dev/null and b/automated-tests/resources/coverageTest.bin differ
diff --git a/automated-tests/resources/coverageTest.dli b/automated-tests/resources/coverageTest.dli
new file mode 100644 (file)
index 0000000..a380378
--- /dev/null
@@ -0,0 +1,82 @@
+{
+  "asset": { "version": "1.0" },
+  "scene": 0,
+  "scenes": [ { "nodes": [ 0 ] } ],
+  "nodes": [
+    {
+      "name": "root",
+      "matrix": [ 0.2, 0, 0, 0, 0, -0, 0.2, 0, 0, -0.2, -0, 0, 0, 0, 0, 1 ],
+      "model": {
+        "mesh": 0,
+        "material": 0
+      }
+    }
+  ],
+  "meshes": [
+    {
+      "uri": "coverageTest.bin",
+      "attributes": 31,
+      "primitive": "TRIANGLES",
+      "indices": { "byteOffset": 0, "byteLength": 600 },
+      "positions": { "byteOffset": 600, "byteLength": 2364 },
+      "normals": { "byteOffset": 2964, "byteLength": 2364 },
+      "textures": { "byteOffset": 5328, "byteLength": 1576 },
+      "tangents": { "byteOffset": 6904, "byteLength": 2364 }
+    }
+  ],
+  "skeletons": [
+  ],
+  "cameras": [
+    {
+      "fov": 60,
+      "near": 0.1,
+      "far": 100,
+      "matrix": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3.5, 1 ]
+    }
+  ],
+  "materials": [
+    {
+      "name": "material1",
+      "color": [ 1, 1, 0, 1 ],
+      "roughness": 0.4,
+      "metallic": 0,
+      "occlusionMap": "exercise/Icons/Icon_Idle.png",
+      "mipmap": true,
+      "environment" : 1
+    },
+    {
+      "name": "",
+      "color": [ 1, 1, 1, 1 ],
+      "roughness": 1,
+      "metallic": 1,
+      "mipmap": true
+    }
+  ],
+  "lights" : [ {
+      "matrix" : [ 0.8950600624084473, 0.0914330929517746, 0.4364715814590454, 0.0, 0.3676385283470154, 0.4026888310909271, -0.8382623195648193, 0.0, -0.25240713357925415, 0.9107588529586792, 0.3268163800239563, 0.0, 0.0, 0.0, -1.0, 1.0 ],
+      "color" : [ 0.8, 0.8, 0.8 ],
+      "intensity" : 1.0,
+      "shadowMapSize" : 256,
+      "orthographicSize" : 4.2760005,
+      "shadowIntensity" : 1.0
+    } ],
+  "environment" : [ {
+      "cubeInitialOrientation" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+      "iblIntensity" : 1.0
+  }, {
+      "cubeSpecular" : "Studio/Radiance.ktx",
+      "cubeDiffuse" : "Studio/Irradiance.ktx",
+      "cubeInitialOrientation" : [ 0.6716271638870239, 0.07979151606559753, -0.7365801334381104, 0.0, 0.07979151606559753, 0.9806114435195923, 0.17898204922676086, 0.0, 0.7365801334381104, -0.17898204922676086, 0.6522386074066162, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+      "iblIntensity" : 0.75
+  } ],
+  "shaders": [
+    {
+      "vertex": "dli_pbr.vsh",
+      "fragment": "dli_pbr.fsh",
+      "defines" : [ "OCCLUSION", "DISPLACEMENT" ],
+      "rendererState": "DEPTH_TEST|DEPTH_WRITE|CULL_BACK|DEPTH_FUNC:LESS_EQUAL",
+      "uCubeMatrix": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ],
+      "uMaxLOD": 6
+    }
+  ]
+}
index 72a0d31..6a961d2 100644 (file)
   uniform sampler2D sNormalRoughness;\r
 #endif\r
 \r
   uniform sampler2D sNormalRoughness;\r
 #endif\r
 \r
+#ifdef OCCLUSION\r
+  uniform sampler2D sAmbientOcclusion;\r
+#endif //OCCLUSION\r
+\r
 uniform samplerCube sDiffuse;\r
 uniform samplerCube sSpecular;\r
 \r
 uniform samplerCube sDiffuse;\r
 uniform samplerCube sSpecular;\r
 \r
@@ -152,6 +156,11 @@ void main()
   vec3 finalColor = diffuseColor + specColor;\r
 \r
   finalColor = sqrt( finalColor ) * uIblIntensity;\r
   vec3 finalColor = diffuseColor + specColor;\r
 \r
   finalColor = sqrt( finalColor ) * uIblIntensity;\r
+\r
+#ifdef OCCLUSION\r
+  finalColor *= texture(sAmbientOcclusion, vUV.st).r;\r
+#endif //OCCLUSION\r
+\r
 #ifdef THREE_TEX\r
   FragColor = vec4( finalColor, alpha );\r
 #else //THREE_TEX\r
 #ifdef THREE_TEX\r
   FragColor = vec4( finalColor, alpha );\r
 #else //THREE_TEX\r
index d09d2da..b63df36 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.
  *
  * 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
 
 // Enable debug log for test coverage
 #define DEBUG_ENABLED 1
 
+#include <dali-test-suite-utils.h>
+#include <string_view>
+#include "dali-scene-loader/internal/json-util.h"
 #include "dali-scene-loader/public-api/dli-loader.h"
 #include "dali-scene-loader/public-api/dli-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/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/internal/json-util.h"
-#include <dali-test-suite-utils.h>
-#include <string_view>
 
 using namespace Dali;
 using namespace Dali::SceneLoader;
 
 namespace
 {
 
 using namespace Dali;
 using namespace Dali::SceneLoader;
 
 namespace
 {
-
-void ConfigureBlendShapeShaders(ResourceBundle& resources, const SceneDefinition& scene, Actor root,
-  std::vector<BlendshapeShaderConfigurationRequest>&& requests)
+void ConfigureBlendShapeShaders(ResourceBundle& resources, const SceneDefinition& scene, Actor root, std::vector<BlendshapeShaderConfigurationRequest>&& requests)
 {
   std::vector<std::string> errors;
 {
   std::vector<std::string> errors;
-  auto onError = [&errors](const std::string& msg) {
+  auto                     onError = [&errors](const std::string& msg) {
     errors.push_back(msg);
   };
 
     errors.push_back(msg);
   };
 
-  if (!scene.ConfigureBlendshapeShaders(resources, root, std::move(requests), onError))
+  if(!scene.ConfigureBlendshapeShaders(resources, root, std::move(requests), onError))
   {
     ExceptionFlinger flinger(ASSERT_LOCATION);
   {
     ExceptionFlinger flinger(ASSERT_LOCATION);
-    for (auto& msg : errors)
+    for(auto& msg : errors)
     {
       flinger << msg << '\n';
     }
     {
       flinger << msg << '\n';
     }
@@ -56,33 +54,32 @@ struct Context
     return TEST_RESOURCE_DIR "/";
   };
 
     return TEST_RESOURCE_DIR "/";
   };
 
-  ResourceBundle resources;
-  SceneDefinition scene;
-  std::vector<CameraParameters> cameraParameters;
-  std::vector<LightParameters> lights;
-  std::vector<AnimationDefinition> animations;
+  ResourceBundle                        resources;
+  SceneDefinition                       scene;
+  std::vector<CameraParameters>         cameraParameters;
+  std::vector<LightParameters>          lights;
+  std::vector<AnimationDefinition>      animations;
   std::vector<AnimationGroupDefinition> animGroups;
 
   std::vector<AnimationGroupDefinition> animGroups;
 
-  LoadResult output {
+  LoadResult output{
     resources,
     scene,
     animations,
     animGroups,
     cameraParameters,
     resources,
     scene,
     animations,
     animGroups,
     cameraParameters,
-    lights
-  };
+    lights};
 
 
-  DliLoader::InputParams input {
+  DliLoader::InputParams input{
     pathProvider(ResourceType::Mesh),
     nullptr,
     {},
     {},
     nullptr,
   };
     pathProvider(ResourceType::Mesh),
     nullptr,
     {},
     {},
     nullptr,
   };
-  DliLoader::LoadParams loadParams{ input, output };
+  DliLoader::LoadParams loadParams{input, output};
 
   std::vector<std::string> errors;
 
   std::vector<std::string> errors;
-  DliLoader loader;
+  DliLoader                loader;
 
   StringCallback onError = [this](const std::string& error) {
     errors.push_back(error);
 
   StringCallback onError = [this](const std::string& error) {
     errors.push_back(error);
@@ -97,7 +94,7 @@ struct Context
 
 bool StringHasTokens(const char* string, const std::vector<const char*>& tokens)
 {
 
 bool StringHasTokens(const char* string, const std::vector<const char*>& tokens)
 {
-  for (auto& token: tokens)
+  for(auto& token : tokens)
   {
     auto result = strstr(string, token);
     if(nullptr == result)
   {
     auto result = strstr(string, token);
     if(nullptr == result)
@@ -109,7 +106,7 @@ bool StringHasTokens(const char* string, const std::vector<const char*>& tokens)
   return true;
 }
 
   return true;
 }
 
-}
+} // namespace
 
 int UtcDaliDliLoaderLoadSceneNotFound(void)
 {
 
 int UtcDaliDliLoaderLoadSceneNotFound(void)
 {
@@ -118,7 +115,7 @@ int UtcDaliDliLoaderLoadSceneNotFound(void)
   DALI_TEST_EQUAL(ctx.loader.LoadScene("does_not_exist.dli", ctx.loadParams), false);
 
   auto error = ctx.loader.GetParseError();
   DALI_TEST_EQUAL(ctx.loader.LoadScene("does_not_exist.dli", ctx.loadParams), false);
 
   auto error = ctx.loader.GetParseError();
-  DALI_TEST_CHECK(StringHasTokens(error.c_str(), { "Empty source buffer to parse." }));
+  DALI_TEST_CHECK(StringHasTokens(error.c_str(), {"Empty source buffer to parse."}));
 
   END_TEST;
 }
 
   END_TEST;
 }
@@ -131,49 +128,48 @@ int UtcDaliDliLoaderLoadSceneFailParse(void)
   DALI_TEST_EQUAL(ctx.loader.LoadScene(path, ctx.loadParams), false);
 
   auto error = ctx.loader.GetParseError();
   DALI_TEST_EQUAL(ctx.loader.LoadScene(path, ctx.loadParams), false);
 
   auto error = ctx.loader.GetParseError();
-  DALI_TEST_CHECK(StringHasTokens(error.c_str(), { "Unexpected character." }));
+  DALI_TEST_CHECK(StringHasTokens(error.c_str(), {"Unexpected character."}));
 
   END_TEST;
 }
 
 int UtcDaliDliLoaderLoadSceneAssertions(void)
 {
 
   END_TEST;
 }
 
 int UtcDaliDliLoaderLoadSceneAssertions(void)
 {
-  const std::pair<std::string, std::string> pathExceptionPairs[] {
-     // from RequireChild()
-    { "scenes-nodes-missing", "Failed to find child node" },
-    { "scenes-missing", "Failed to find child node" },
-    { "nodes-missing", "Failed to find child node" },
+  const std::pair<std::string, std::string> pathExceptionPairs[]{
+    // from RequireChild()
+    {"scenes-nodes-missing", "Failed to find child node"},
+    {"scenes-missing", "Failed to find child node"},
+    {"nodes-missing", "Failed to find child node"},
     // from ParseSceneInternal()
     // from ParseSceneInternal()
-    { "scene-out-of-bounds", "out of bounds" },
-    { "nodes-invalid-type", "invalid type; array required" },
-    { "nodes-array-empty", "must define a node id" },
-    { "root-id-invalid", "invalid value for root node index" },
-    { "root-id-out-of-bounds", "out of bounds" },
-    { "root-node-invalid-type", "invalid JSON type; object required" },
+    {"scene-out-of-bounds", "out of bounds"},
+    {"nodes-invalid-type", "invalid type; array required"},
+    {"nodes-array-empty", "must define a node id"},
+    {"root-id-invalid", "invalid value for root node index"},
+    {"root-id-out-of-bounds", "out of bounds"},
+    {"root-node-invalid-type", "invalid JSON type; object required"},
     // from ParseSkeletons()
     // from ParseSkeletons()
-    { "skeleton-node-missing", "Missing required attribute" },
-    { "skeleton-root-not-found", "not defined" },
+    {"skeleton-node-missing", "Missing required attribute"},
+    {"skeleton-root-not-found", "not defined"},
     // from ParseShaders()
     // from ParseShaders()
-    { "shader-vertex-missing", "Missing vertex / fragment shader" },
-    { "shader-fragment-missing", "Missing vertex / fragment shader" },
+    {"shader-vertex-missing", "Missing vertex / fragment shader"},
+    {"shader-fragment-missing", "Missing vertex / fragment shader"},
     // from ParseMeshes()
     // from ParseMeshes()
-    { "mesh-uri-missing", "Missing required attribute" },
-    { "mesh-indices-read-fail", "Failed to read indices" },
-    { "mesh-positions-read-fail", "Failed to read positions" },
+    {"mesh-uri-missing", "Missing required attribute"},
+    {"mesh-indices-read-fail", "Failed to read indices"},
+    {"mesh-positions-read-fail", "Failed to read positions"},
     // from ParseMaterials()
     // from ParseMaterials()
-    { "material-environment-out-of-bounds", "out of bounds" },
+    {"material-environment-out-of-bounds", "out of bounds"},
     // from ParseNodes()
     // from ParseNodes()
-    { "node-model-mesh-missing", "Missing mesh" },
-    { "node-arc-mesh-missing", "Missing mesh" },
-    { "node-animated-image-mesh-missing", "Missing mesh" },
-    { "node-renderable-mesh-invalid-type", "Invalid Mesh index type" },
-    { "node-renderable-mesh-out-of-bounds", "out of bounds" },
-    { "node-child-invalid-type", "invalid index type" },
-    { "node-name-already-used", "name already used" },
+    {"node-model-mesh-missing", "Missing mesh"},
+    {"node-arc-mesh-missing", "Missing mesh"},
+    {"node-animated-image-mesh-missing", "Missing mesh"},
+    {"node-renderable-mesh-invalid-type", "Invalid Mesh index type"},
+    {"node-renderable-mesh-out-of-bounds", "out of bounds"},
+    {"node-child-invalid-type", "invalid index type"},
+    {"node-name-already-used", "name already used"},
     // from ParseAnimations()
     // from ParseAnimations()
-    { "animation-failed-to-open", "Failed to open animation data" }
-  };
-  for (auto& i: pathExceptionPairs)
+    {"animation-failed-to-open", "Failed to open animation data"}};
+  for(auto& i : pathExceptionPairs)
   {
     Context ctx;
 
   {
     Context ctx;
 
@@ -214,10 +210,9 @@ int UtcDaliDliLoaderLoadSceneExercise(void)
   DALI_TEST_EQUAL(ctx.animGroups.size(), 16u);
 
   ViewProjection viewProjection;
   DALI_TEST_EQUAL(ctx.animGroups.size(), 16u);
 
   ViewProjection viewProjection;
-  Transforms xforms {
+  Transforms     xforms{
     MatrixStack{},
     MatrixStack{},
-    viewProjection
-  };
+    viewProjection};
   NodeDefinition::CreateParams nodeParams{
     resources,
     xforms,
   NodeDefinition::CreateParams nodeParams{
     resources,
     xforms,
@@ -229,13 +224,13 @@ int UtcDaliDliLoaderLoadSceneExercise(void)
 
   Actor root = Actor::New();
   SetActorCentered(root);
 
   Actor root = Actor::New();
   SetActorCentered(root);
-  for (auto iRoot : scene.GetRoots())
+  for(auto iRoot : scene.GetRoots())
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
     resources.CountEnvironmentReferences(resourceRefs);
     resources.LoadResources(resourceRefs, ctx.pathProvider);
   {
     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))
+    if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
       scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
       scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
@@ -257,49 +252,47 @@ int UtcDaliDliLoaderLoadSceneMorph(void)
   Context ctx;
 
   std::vector<std::string> metadata;
   Context ctx;
 
   std::vector<std::string> metadata;
-  uint32_t metadataCount = 0;
-  ctx.input.mPreNodeCategoryProcessors.push_back({ "metadata",
-    [&](const Property::Array& array, StringCallback) {
-      std::string key, value;
-      for (uint32_t i0 = 0, i1 = array.Count(); i0 < i1; ++i0)
-      {
-        auto& data = array.GetElementAt(i0);
-        DALI_TEST_EQUAL(data.GetType(), Property::MAP);
-
-        auto map = data.GetMap();
-        auto key = map->Find("key");
-        auto value = map->Find("value");
-        DALI_TEST_EQUAL(key->GetType(), Property::STRING);
-        DALI_TEST_EQUAL(value->GetType(), Property::STRING);
-        metadata.push_back(key->Get<std::string>() + ":" + value->Get<std::string>());
-
-        ++metadataCount;
-      }
-    }
-  });
+  uint32_t                 metadataCount = 0;
+  ctx.input.mPreNodeCategoryProcessors.push_back({"metadata",
+                                                  [&](const Property::Array& array, StringCallback) {
+                                                    std::string key, value;
+                                                    for(uint32_t i0 = 0, i1 = array.Count(); i0 < i1; ++i0)
+                                                    {
+                                                      auto& data = array.GetElementAt(i0);
+                                                      DALI_TEST_EQUAL(data.GetType(), Property::MAP);
+
+                                                      auto map   = data.GetMap();
+                                                      auto key   = map->Find("key");
+                                                      auto value = map->Find("value");
+                                                      DALI_TEST_EQUAL(key->GetType(), Property::STRING);
+                                                      DALI_TEST_EQUAL(value->GetType(), Property::STRING);
+                                                      metadata.push_back(key->Get<std::string>() + ":" + value->Get<std::string>());
+
+                                                      ++metadataCount;
+                                                    }
+                                                  }});
 
   std::vector<std::string> behaviors;
 
   std::vector<std::string> behaviors;
-  uint32_t behaviorCount = 0;
-  ctx.input.mPostNodeCategoryProcessors.push_back({ "behaviors",
-    [&](const Property::Array& array, StringCallback) {
-      for (uint32_t i0 = 0, i1 = array.Count(); i0 < i1; ++i0)
-      {
-        auto& data = array.GetElementAt(i0);
-        DALI_TEST_EQUAL(data.GetType(), Property::MAP);
-
-        auto map = data.GetMap();
-        auto event = map->Find("event");
-        auto url = map->Find("url");
-        DALI_TEST_EQUAL(event->GetType(), Property::STRING);
-        DALI_TEST_EQUAL(url->GetType(), Property::STRING);
-        behaviors.push_back(event->Get<std::string>() + ":" + url->Get<std::string>());
-
-        ++behaviorCount;
-      }
-    }
-  });
-
-  size_t numNodes = 0;
+  uint32_t                 behaviorCount = 0;
+  ctx.input.mPostNodeCategoryProcessors.push_back({"behaviors",
+                                                   [&](const Property::Array& array, StringCallback) {
+                                                     for(uint32_t i0 = 0, i1 = array.Count(); i0 < i1; ++i0)
+                                                     {
+                                                       auto& data = array.GetElementAt(i0);
+                                                       DALI_TEST_EQUAL(data.GetType(), Property::MAP);
+
+                                                       auto map   = data.GetMap();
+                                                       auto event = map->Find("event");
+                                                       auto url   = map->Find("url");
+                                                       DALI_TEST_EQUAL(event->GetType(), Property::STRING);
+                                                       DALI_TEST_EQUAL(url->GetType(), Property::STRING);
+                                                       behaviors.push_back(event->Get<std::string>() + ":" + url->Get<std::string>());
+
+                                                       ++behaviorCount;
+                                                     }
+                                                   }});
+
+  size_t numNodes                  = 0;
   ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, const Property::Map&, StringCallback) {
     ++numNodes;
   };
   ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, const Property::Map&, StringCallback) {
     ++numNodes;
   };
@@ -332,10 +325,9 @@ int UtcDaliDliLoaderLoadSceneMorph(void)
   DALI_TEST_EQUAL(behaviors.size(), 1u);
 
   ViewProjection viewProjection;
   DALI_TEST_EQUAL(behaviors.size(), 1u);
 
   ViewProjection viewProjection;
-  Transforms xforms {
+  Transforms     xforms{
     MatrixStack{},
     MatrixStack{},
-    viewProjection
-  };
+    viewProjection};
   NodeDefinition::CreateParams nodeParams{
     resources,
     xforms,
   NodeDefinition::CreateParams nodeParams{
     resources,
     xforms,
@@ -347,13 +339,13 @@ int UtcDaliDliLoaderLoadSceneMorph(void)
 
   Actor root = Actor::New();
   SetActorCentered(root);
 
   Actor root = Actor::New();
   SetActorCentered(root);
-  for (auto iRoot : scene.GetRoots())
+  for(auto iRoot : scene.GetRoots())
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
     resources.CountEnvironmentReferences(resourceRefs);
     resources.LoadResources(resourceRefs, ctx.pathProvider);
   {
     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))
+    if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
       scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
       scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
@@ -397,10 +389,9 @@ int UtcDaliDliLoaderLoadSceneArc(void)
   DALI_TEST_EQUAL(ctx.animGroups.size(), 0u);
 
   ViewProjection viewProjection;
   DALI_TEST_EQUAL(ctx.animGroups.size(), 0u);
 
   ViewProjection viewProjection;
-  Transforms xforms {
+  Transforms     xforms{
     MatrixStack{},
     MatrixStack{},
-    viewProjection
-  };
+    viewProjection};
   NodeDefinition::CreateParams nodeParams{
     resources,
     xforms,
   NodeDefinition::CreateParams nodeParams{
     resources,
     xforms,
@@ -412,13 +403,13 @@ int UtcDaliDliLoaderLoadSceneArc(void)
 
   Actor root = Actor::New();
   SetActorCentered(root);
 
   Actor root = Actor::New();
   SetActorCentered(root);
-  for (auto iRoot : scene.GetRoots())
+  for(auto iRoot : scene.GetRoots())
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
     resources.CountEnvironmentReferences(resourceRefs);
     resources.LoadResources(resourceRefs, ctx.pathProvider);
   {
     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))
+    if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
       scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
       scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
@@ -496,11 +487,10 @@ int UtcDaliDliLoaderLoadSceneExtras(void)
   DALI_TEST_EQUAL(scene.GetNodeCount(), 1u);
 
   ViewProjection viewProjection;
   DALI_TEST_EQUAL(scene.GetNodeCount(), 1u);
 
   ViewProjection viewProjection;
-  Transforms xforms {
+  Transforms     xforms{
     MatrixStack{},
     MatrixStack{},
-    viewProjection
-  };
-  auto& resources = ctx.resources;
+    viewProjection};
+  auto&                        resources = ctx.resources;
   NodeDefinition::CreateParams nodeParams{
     resources,
     xforms,
   NodeDefinition::CreateParams nodeParams{
     resources,
     xforms,
@@ -509,7 +499,7 @@ int UtcDaliDliLoaderLoadSceneExtras(void)
   Customization::Choices choices;
 
   TestApplication app;
   Customization::Choices choices;
 
   TestApplication app;
-  Actor actor = scene.CreateNodes(0, choices, nodeParams);
+  Actor           actor = scene.CreateNodes(0, choices, nodeParams);
 
   DALI_TEST_EQUAL(actor.GetProperty(actor.GetPropertyIndex("fudgeFactor")).Get<float>(), 9000.1f);
   DALI_TEST_EQUAL(actor.GetProperty(actor.GetPropertyIndex("fudgeVector")).Get<Vector2>(), Vector2(-.25f, 17.f));
 
   DALI_TEST_EQUAL(actor.GetProperty(actor.GetPropertyIndex("fudgeFactor")).Get<float>(), 9000.1f);
   DALI_TEST_EQUAL(actor.GetProperty(actor.GetPropertyIndex("fudgeVector")).Get<Vector2>(), Vector2(-.25f, 17.f));
@@ -541,11 +531,10 @@ int UtcDaliDliLoaderLoadSceneConstraints(void)
   DALI_TEST_EQUAL(scene.GetNodeCount(), 4u);
 
   ViewProjection viewProjection;
   DALI_TEST_EQUAL(scene.GetNodeCount(), 4u);
 
   ViewProjection viewProjection;
-  Transforms xforms {
+  Transforms     xforms{
     MatrixStack{},
     MatrixStack{},
-    viewProjection
-  };
-  auto& resources = ctx.resources;
+    viewProjection};
+  auto&                        resources = ctx.resources;
   NodeDefinition::CreateParams nodeParams{
     resources,
     xforms,
   NodeDefinition::CreateParams nodeParams{
     resources,
     xforms,
@@ -555,9 +544,9 @@ int UtcDaliDliLoaderLoadSceneConstraints(void)
 
   TestApplication app;
 
 
   TestApplication app;
 
-  Actor root = scene.CreateNodes(0, choices, nodeParams);
-  Actor alice = root.FindChildByName("Alice");
-  Actor bob = root.FindChildByName("Bob");
+  Actor root    = scene.CreateNodes(0, choices, nodeParams);
+  Actor alice   = root.FindChildByName("Alice");
+  Actor bob     = root.FindChildByName("Bob");
   Actor charlie = root.FindChildByName("Charlie");
 
   DALI_TEST_EQUAL(nodeParams.mConstrainables.size(), 3u);
   Actor charlie = root.FindChildByName("Charlie");
 
   DALI_TEST_EQUAL(nodeParams.mConstrainables.size(), 3u);
@@ -639,3 +628,78 @@ int UtcDaliDliLoaderNodeProcessor(void)
 
   END_TEST;
 }
 
   END_TEST;
 }
+
+int UtcDaliDliLoaderLoadCoverageTest(void)
+{
+  Context ctx;
+
+  auto path = ctx.pathProvider(ResourceType::Mesh) + "coverageTest.dli";
+  DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+  DALI_TEST_CHECK(ctx.errors.empty());
+
+  auto& scene = ctx.scene;
+  auto& roots = scene.GetRoots();
+  DALI_TEST_EQUAL(roots.size(), 1u);
+  DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "root");
+
+  DALI_TEST_EQUAL(scene.GetNodeCount(), 1u);
+
+  auto& resources = ctx.resources;
+  DALI_TEST_EQUAL(resources.mMeshes.size(), 1u);
+  DALI_TEST_EQUAL(resources.mShaders.size(), 1u);
+  DALI_TEST_EQUAL(resources.mEnvironmentMaps.size(), 2u);
+  DALI_TEST_EQUAL(resources.mSkeletons.size(), 0u);
+
+  auto& materials = ctx.resources.mMaterials;
+  DALI_TEST_EQUAL(2u, materials.size());
+
+  auto  iMaterial = materials.begin();
+  auto& md        = iMaterial->first;
+  DALI_TEST_EQUAL(md.mTextureStages.size(), 1u);
+
+  auto iTexture = md.mTextureStages.begin();
+  DALI_TEST_CHECK(MaskMatch(iTexture->mSemantic, MaterialDefinition::OCCLUSION));
+  DALI_TEST_EQUAL(iTexture->mTexture.mImageUri, "exercise/Icons/Icon_Idle.png");
+  ++iTexture;
+
+  DALI_TEST_EQUAL(ctx.cameraParameters.size(), 1u);
+  DALI_TEST_EQUAL(ctx.lights.size(), 1u);
+  DALI_TEST_EQUAL(ctx.animations.size(), 0u);
+  DALI_TEST_EQUAL(ctx.animGroups.size(), 0u);
+
+  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 : scene.GetRoots())
+  {
+    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));
+      ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests));
+      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>(), "root");
+
+  END_TEST;
+}
index c1b5481..80ed66d 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.
  *
  * 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
 
 // Enable debug log for test coverage
 #define DEBUG_ENABLED 1
 
+#include <dali-test-suite-utils.h>
+#include <set>
+#include <string_view>
 #include "dali-scene-loader/public-api/gltf2-loader.h"
 #include "dali-scene-loader/public-api/gltf2-loader.h"
-#include "dali-scene-loader/public-api/shader-definition-factory.h"
 #include "dali-scene-loader/public-api/node-definition.h"
 #include "dali-scene-loader/public-api/resource-bundle.h"
 #include "dali-scene-loader/public-api/node-definition.h"
 #include "dali-scene-loader/public-api/resource-bundle.h"
-#include <dali-test-suite-utils.h>
-#include <string_view>
-#include <set>
+#include "dali-scene-loader/public-api/shader-definition-factory.h"
 
 using namespace Dali;
 using namespace Dali::SceneLoader;
 
 namespace
 {
 
 using namespace Dali;
 using namespace Dali::SceneLoader;
 
 namespace
 {
-
 bool EndsWith(const std::string& str, const std::string& suffix) // ends_width() is C++20
 {
   return str.size() >= suffix.size() && str.substr(str.size() - suffix.size()).compare(suffix) == 0;
 bool EndsWith(const std::string& str, const std::string& suffix) // ends_width() is C++20
 {
   return str.size() >= suffix.size() && str.substr(str.size() - suffix.size()).compare(suffix) == 0;
@@ -57,7 +56,7 @@ void ClearMeshesAndMaterials(ResourceBundle& resources)
 
 struct Context
 {
 
 struct Context
 {
-  ResourceBundle resources;
+  ResourceBundle          resources;
   ShaderDefinitionFactory factory;
 
   Context()
   ShaderDefinitionFactory factory;
 
   Context()
@@ -68,29 +67,29 @@ struct Context
 
 struct ShaderParameters
 {
 
 struct ShaderParameters
 {
-  MeshDefinition& meshDef;
+  MeshDefinition&     meshDef;
   MaterialDefinition& materialDef;
   MaterialDefinition& materialDef;
-  NodeDefinition& nodeDef;
+  NodeDefinition&     nodeDef;
 };
 
 struct Permutation
 {
 };
 
 struct Permutation
 {
-  using ConfigureFn = void(*)(ShaderParameters&);
+  using ConfigureFn = void (*)(ShaderParameters&);
 
   ConfigureFn configureFn;
 
   std::set<std::string> defines;
 
   ConfigureFn configureFn;
 
   std::set<std::string> defines;
-  RendererState::Type rendererStateSet = 0;
-  RendererState::Type rendererStateClear = 0;
+  RendererState::Type   rendererStateSet   = 0;
+  RendererState::Type   rendererStateClear = 0;
 };
 
 struct PermutationSet
 {
   std::vector<const Permutation*> permutations;
 };
 
 struct PermutationSet
 {
   std::vector<const Permutation*> permutations;
-  Index shaderIdx;
+  Index                           shaderIdx;
 };
 
 };
 
-}
+} // namespace
 
 int UtcDaliShaderDefinitionFactoryProduceShaderInvalid(void)
 {
 
 int UtcDaliShaderDefinitionFactoryProduceShaderInvalid(void)
 {
@@ -121,173 +120,157 @@ int UtcDaliShaderDefinitionFactoryProduceShader(void)
       [](ShaderParameters& p) {
         p.materialDef.mFlags |= MaterialDefinition::TRANSPARENCY;
       },
       [](ShaderParameters& p) {
         p.materialDef.mFlags |= MaterialDefinition::TRANSPARENCY;
       },
-      { "THREE_TEX" },
+      {"THREE_TEX"},
       RendererState::ALPHA_BLEND,
       RendererState::DEPTH_WRITE,
     },
       RendererState::ALPHA_BLEND,
       RendererState::DEPTH_WRITE,
     },
-    {
-      [](ShaderParameters& p) {
-        p.materialDef.mTextureStages.push_back({ MaterialDefinition::ALBEDO, {} });
-      },
-      { "THREE_TEX" }
-    },
-    {
-      [](ShaderParameters& p) {
-        p.materialDef.mTextureStages.push_back({ MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS, {} });
-      },
-      { "THREE_TEX" }
-    },
-    {
-      [](ShaderParameters& p) {
-        p.materialDef.mTextureStages.push_back({ MaterialDefinition::NORMAL, {} });
-      },
-      { "THREE_TEX" }
-    },
-    {
-      [](ShaderParameters& p) {
-        p.materialDef.mFlags |= MaterialDefinition::SUBSURFACE;
-      },
-      { "SSS" }
-    },
-    {
-      [](ShaderParameters& p) {
-        p.materialDef.SetAlphaCutoff(.5f);
-      },
-      { "ALPHA_TEST" }
-    },
-    {
-      [](ShaderParameters& p) {
-        p.materialDef.SetAlphaCutoff(1.f);
-      },
-      { "ALPHA_TEST" }
-    },
-    {
-      [](ShaderParameters& p) {
-        p.materialDef.mFlags |= MaterialDefinition::GLTF_CHANNELS;
-      },
-      { "GLTF_CHANNELS" }
-    },
-    {
-      [](ShaderParameters& p) {
-        p.meshDef.mJoints0.mBlob.mOffset = 0;
-        p.meshDef.mWeights0.mBlob.mOffset = 0;
-      },
-      { "SKINNING" }
-    },
-    {
-      [](ShaderParameters& p) {
-        p.meshDef.mFlags |= MeshDefinition::FLIP_UVS_VERTICAL;
-      },
-      { "FLIP_V" }
-    },
+    {[](ShaderParameters& p) {
+       p.materialDef.mTextureStages.push_back({MaterialDefinition::ALBEDO, {}});
+     },
+     {"THREE_TEX"}},
+    {[](ShaderParameters& p) {
+       p.materialDef.mTextureStages.push_back({MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS, {}});
+     },
+     {"THREE_TEX"}},
+    {[](ShaderParameters& p) {
+       p.materialDef.mTextureStages.push_back({MaterialDefinition::NORMAL, {}});
+     },
+     {"THREE_TEX"}},
+    {[](ShaderParameters& p) {
+       p.materialDef.mFlags |= MaterialDefinition::SUBSURFACE;
+     },
+     {"SSS"}},
+    {[](ShaderParameters& p) {
+       p.materialDef.SetAlphaCutoff(.5f);
+     },
+     {"ALPHA_TEST"}},
+    {[](ShaderParameters& p) {
+       p.materialDef.SetAlphaCutoff(1.f);
+     },
+     {"ALPHA_TEST"}},
+    {[](ShaderParameters& p) {
+       p.materialDef.mFlags |= MaterialDefinition::GLTF_CHANNELS;
+     },
+     {"GLTF_CHANNELS"}},
+    {[](ShaderParameters& p) {
+       p.meshDef.mJoints0.mBlob.mOffset  = 0;
+       p.meshDef.mWeights0.mBlob.mOffset = 0;
+     },
+     {"SKINNING"}},
+    {[](ShaderParameters& p) {
+       p.meshDef.mFlags |= MeshDefinition::FLIP_UVS_VERTICAL;
+     },
+     {"FLIP_V"}},
     {
       [](ShaderParameters& p) {
         p.meshDef.mBlendShapes.push_back({});
       },
     },
     {
       [](ShaderParameters& p) {
         p.meshDef.mBlendShapes.push_back({});
       },
     },
-    {
-      [](ShaderParameters& p) {
-        p.meshDef.mBlendShapes.back().deltas.mBlob.mOffset = 0;
-      },
-      { "MORPH_POSITION", "MORPH" }
-    },
-    {
-      [](ShaderParameters& p) {
-        p.meshDef.mBlendShapes.back().normals.mBlob.mOffset = 0;
-      },
-      { "MORPH_NORMAL", "MORPH" }
-    },
-    {
-      [](ShaderParameters& p) {
-        p.meshDef.mBlendShapes.back().tangents.mBlob.mOffset = 0;
-      },
-      { "MORPH_TANGENT", "MORPH" }
-    },
-    {
-      [](ShaderParameters& p) {
-        auto& blendShapes = p.meshDef.mBlendShapes;
-        DALI_ASSERT_ALWAYS(!blendShapes.empty() &&
-          (blendShapes.back().deltas.mBlob.mOffset != MeshDefinition::INVALID ||
-          blendShapes.back().normals.mBlob.mOffset != MeshDefinition::INVALID ||
-          blendShapes.back().tangents.mBlob.mOffset != MeshDefinition::INVALID));
-        p.meshDef.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0;
-      },
-      { "MORPH_VERSION_2_0" }
-    },
+    {[](ShaderParameters& p) {
+       p.meshDef.mBlendShapes.back().deltas.mBlob.mOffset = 0;
+     },
+     {"MORPH_POSITION", "MORPH"}},
+    {[](ShaderParameters& p) {
+       p.meshDef.mBlendShapes.back().normals.mBlob.mOffset = 0;
+     },
+     {"MORPH_NORMAL", "MORPH"}},
+    {[](ShaderParameters& p) {
+       p.meshDef.mBlendShapes.back().tangents.mBlob.mOffset = 0;
+     },
+     {"MORPH_TANGENT", "MORPH"}},
+    {[](ShaderParameters& p) {
+       auto& blendShapes = p.meshDef.mBlendShapes;
+       DALI_ASSERT_ALWAYS(!blendShapes.empty() &&
+                          (blendShapes.back().deltas.mBlob.mOffset != MeshDefinition::INVALID ||
+                           blendShapes.back().normals.mBlob.mOffset != MeshDefinition::INVALID ||
+                           blendShapes.back().tangents.mBlob.mOffset != MeshDefinition::INVALID));
+       p.meshDef.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0;
+     },
+     {"MORPH_VERSION_2_0"}},
+
+    {[](ShaderParameters& p) {
+       p.materialDef.mFlags |= MaterialDefinition::OCCLUSION;
+     },
+
+     {"OCCLUSION"}},
   };
 
   };
 
-  PermutationSet permSets[] {
+  PermutationSet permSets[]{
     // default
     // default
-    { { &permutations[0] }, 0 },
+    {{&permutations[0]}, 0},
 
     // alpha
 
     // alpha
-    { { &permutations[0], &permutations[1] }, 1 },
+    {{&permutations[0], &permutations[1]}, 1},
 
     // three-texture setups
 
     // three-texture setups
-    { { &permutations[0], &permutations[2] }, 2 },
-    { { &permutations[0], &permutations[3] }, 2 },
-    { { &permutations[0], &permutations[4] }, 2 },
-    { { &permutations[0], &permutations[2], &permutations[3] }, 2 },
-    { { &permutations[0], &permutations[3], &permutations[4] }, 2 },
-    { { &permutations[0], &permutations[4], &permutations[2] }, 2 },
-    { { &permutations[0], &permutations[2], &permutations[3], &permutations[4] }, 2 },
+    {{&permutations[0], &permutations[2]}, 2},
+    {{&permutations[0], &permutations[3]}, 2},
+    {{&permutations[0], &permutations[4]}, 2},
+    {{&permutations[0], &permutations[2], &permutations[3]}, 2},
+    {{&permutations[0], &permutations[3], &permutations[4]}, 2},
+    {{&permutations[0], &permutations[4], &permutations[2]}, 2},
+    {{&permutations[0], &permutations[2], &permutations[3], &permutations[4]}, 2},
 
     // subsurface scattering
 
     // subsurface scattering
-    { { &permutations[0], &permutations[5] }, 3 },
+    {{&permutations[0], &permutations[5]}, 3},
 
     // alpha test
 
     // alpha test
-    { { &permutations[0], &permutations[6] }, 4 },
-    { { &permutations[0], &permutations[7] }, 4 },
+    {{&permutations[0], &permutations[6]}, 4},
+    {{&permutations[0], &permutations[7]}, 4},
 
     // glTF channels
 
     // glTF channels
-    { { &permutations[0], &permutations[8] }, 5 },
+    {{&permutations[0], &permutations[8]}, 5},
 
     // skinning
 
     // skinning
-    { { &permutations[0], &permutations[9] }, 6 },
+    {{&permutations[0], &permutations[9]}, 6},
 
     // flip uvs
 
     // flip uvs
-    { { &permutations[0], &permutations[10] }, 7 },
+    {{&permutations[0], &permutations[10]}, 7},
 
     // morphing
 
     // morphing
-    { { &permutations[0], &permutations[11], &permutations[12] }, 8 },
-    { { &permutations[0], &permutations[11], &permutations[13] }, 9 },
-    { { &permutations[0], &permutations[11], &permutations[14] }, 10 },
-    { { &permutations[0], &permutations[11], &permutations[12], &permutations[13] }, 11 },
-    { { &permutations[0], &permutations[11], &permutations[13], &permutations[14] }, 12 },
-    { { &permutations[0], &permutations[11], &permutations[14], &permutations[12] }, 13 },
-    { { &permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14] }, 14 },
-
-    { { &permutations[0], &permutations[11], &permutations[12], &permutations[15] }, 15 },
-    { { &permutations[0], &permutations[11], &permutations[13], &permutations[15] }, 16 },
-    { { &permutations[0], &permutations[11], &permutations[14], &permutations[15] }, 17 },
-    { { &permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[15] }, 18 },
-    { { &permutations[0], &permutations[11], &permutations[13], &permutations[14], &permutations[15] }, 19 },
-    { { &permutations[0], &permutations[11], &permutations[14], &permutations[12], &permutations[15] }, 20 },
-    { { &permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14], &permutations[15] }, 21 },
+    {{&permutations[0], &permutations[11], &permutations[12]}, 8},
+    {{&permutations[0], &permutations[11], &permutations[13]}, 9},
+    {{&permutations[0], &permutations[11], &permutations[14]}, 10},
+    {{&permutations[0], &permutations[11], &permutations[12], &permutations[13]}, 11},
+    {{&permutations[0], &permutations[11], &permutations[13], &permutations[14]}, 12},
+    {{&permutations[0], &permutations[11], &permutations[14], &permutations[12]}, 13},
+    {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14]}, 14},
+
+    {{&permutations[0], &permutations[11], &permutations[12], &permutations[15]}, 15},
+    {{&permutations[0], &permutations[11], &permutations[13], &permutations[15]}, 16},
+    {{&permutations[0], &permutations[11], &permutations[14], &permutations[15]}, 17},
+    {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[15]}, 18},
+    {{&permutations[0], &permutations[11], &permutations[13], &permutations[14], &permutations[15]}, 19},
+    {{&permutations[0], &permutations[11], &permutations[14], &permutations[12], &permutations[15]}, 20},
+    {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14], &permutations[15]}, 21},
 
     // etc.
 
     // etc.
-    { { &permutations[0], &permutations[1], &permutations[2] }, 1 },
-    { { &permutations[0], &permutations[1], &permutations[3] }, 1 },
-    { { &permutations[0], &permutations[1], &permutations[2], &permutations[3] }, 1 },
+    {{&permutations[0], &permutations[1], &permutations[2]}, 1},
+    {{&permutations[0], &permutations[1], &permutations[3]}, 1},
+    {{&permutations[0], &permutations[1], &permutations[2], &permutations[3]}, 1},
+
+    // occlusion
+    {{&permutations[0], &permutations[16]}, 22},
   };
   };
-  for(auto& ps: permSets)
+
+  for(auto& ps : permSets)
   {
     printf("%ld\n", &ps - permSets);
 
   {
     printf("%ld\n", &ps - permSets);
 
-    auto modelNode = new ModelNode();
-    modelNode->mMeshIdx = 0;
+    auto modelNode          = new ModelNode();
+    modelNode->mMeshIdx     = 0;
     modelNode->mMaterialIdx = 0;
 
     NodeDefinition nodeDef;
     nodeDef.mRenderable.reset(modelNode);
 
     modelNode->mMaterialIdx = 0;
 
     NodeDefinition nodeDef;
     nodeDef.mRenderable.reset(modelNode);
 
-    auto& meshDef = NewMeshDefinition(ctx.resources);
-    auto& materialDef = NewMaterialDefinition(ctx.resources);
-    ShaderParameters sp{ meshDef, materialDef, nodeDef };
+    auto&            meshDef     = NewMeshDefinition(ctx.resources);
+    auto&            materialDef = NewMaterialDefinition(ctx.resources);
+    ShaderParameters sp{meshDef, materialDef, nodeDef};
 
     std::set<std::string> defines;
 
     std::set<std::string> defines;
-    RendererState::Type rendererState = 0;
-    for (auto p : ps.permutations)
+    RendererState::Type   rendererState = 0;
+    for(auto p : ps.permutations)
     {
       p->configureFn(sp);
       defines.insert(p->defines.begin(), p->defines.end());
     {
       p->configureFn(sp);
       defines.insert(p->defines.begin(), p->defines.end());
@@ -303,10 +286,10 @@ int UtcDaliShaderDefinitionFactoryProduceShader(void)
     DALI_TEST_EQUAL(shaderDef.mRendererState, rendererState);
 
     uint32_t definesUnmatched = shaderDef.mDefines.size();
     DALI_TEST_EQUAL(shaderDef.mRendererState, rendererState);
 
     uint32_t definesUnmatched = shaderDef.mDefines.size();
-    for (auto& d: shaderDef.mDefines)
+    for(auto& d : shaderDef.mDefines)
     {
       auto iFind = defines.find(d);
     {
       auto iFind = defines.find(d);
-      if (iFind != defines.end())
+      if(iFind != defines.end())
       {
         defines.erase(iFind);
         --definesUnmatched;
       {
         defines.erase(iFind);
         --definesUnmatched;
index 48a82c3..3031c5e 100644 (file)
@@ -1014,6 +1014,14 @@ void DliLoader::Impl::ParseMaterials(const TreeNode* materials, ConvertColorCode
       materialDef.mFlags |= semantic;
     }
 
       materialDef.mFlags |= semantic;
     }
 
+    if(ReadString(node.GetChild("occlusionMap"), texturePath))
+    {
+      ToUnixFileSeparators(texturePath);
+      const auto semantic = MaterialDefinition::OCCLUSION;
+      materialDef.mTextureStages.push_back({semantic, TextureDefinition{std::move(texturePath)}});
+      materialDef.mFlags |= semantic;
+    }
+
     if(ReadColorCodeOrColor(&node, materialDef.mColor, convertColorCode) &&
        materialDef.mColor.a < 1.0f)
     {
     if(ReadColorCodeOrColor(&node, materialDef.mColor, convertColorCode) &&
        materialDef.mColor.a < 1.0f)
     {
index c0e816c..3c7a391 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -217,6 +217,12 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath) const
     ++iTexture;
   }
 
     ++iTexture;
   }
 
+  if(checkStage(OCCLUSION))
+  {
+    raw.mTextures.push_back({SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags});
+    ++iTexture;
+  }
+
   return raw;
 }
 
   return raw;
 }
 
index 843fbcf..bd6b168 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.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -96,6 +96,11 @@ uint64_t HashNode(const NodeDefinition& nodeDef, const MaterialDefinition& mater
     hash.Add("SSS");
   }
 
     hash.Add("SSS");
   }
 
+  if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION))
+  {
+    hash.Add("OCCL" /*USION*/);
+  }
+
   if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS))
   {
     hash.Add("GLTF" /*_CHANNELS*/);
   if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS))
   {
     hash.Add("GLTF" /*_CHANNELS*/);
@@ -217,6 +222,11 @@ Index ShaderDefinitionFactory::ProduceShader(const NodeDefinition& nodeDef)
     shaderDef.mDefines.push_back("SSS");
   }
 
     shaderDef.mDefines.push_back("SSS");
   }
 
+  if(MaskMatch(receiver.mMaterialDef->mFlags, MaterialDefinition::OCCLUSION))
+  {
+    shaderDef.mDefines.push_back("OCCLUSION");
+  }
+
   if(MaskMatch(receiver.mMaterialDef->mFlags, MaterialDefinition::GLTF_CHANNELS))
   {
     shaderDef.mDefines.push_back("GLTF_CHANNELS");
   if(MaskMatch(receiver.mMaterialDef->mFlags, MaterialDefinition::GLTF_CHANNELS))
   {
     shaderDef.mDefines.push_back("GLTF_CHANNELS");