[dali_2.2.17] Merge branch 'devel/master' 25/289625/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 10 Mar 2023 10:30:38 +0000 (10:30 +0000)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 10 Mar 2023 10:30:38 +0000 (10:30 +0000)
Change-Id: I5c75b28be1202aa04454b11c09ef37632e4ee94e

118 files changed:
automated-tests/resources/BoxAnimated.glb [new file with mode: 0644]
automated-tests/src/dali-scene3d-internal/CMakeLists.txt
automated-tests/src/dali-scene3d-internal/utc-Dali-DliLoaderImpl.cpp [moved from automated-tests/src/dali-scene3d/utc-Dali-DliLoader.cpp with 92% similarity]
automated-tests/src/dali-scene3d-internal/utc-Dali-GlbLoaderImpl.cpp [new file with mode: 0644]
automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp [moved from automated-tests/src/dali-scene3d/utc-Dali-Gltf2Loader.cpp with 91% similarity]
automated-tests/src/dali-scene3d/CMakeLists.txt
automated-tests/src/dali-scene3d/utc-Dali-Model.cpp
automated-tests/src/dali-scene3d/utc-Dali-ResourceBundle.cpp
automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionFactory.cpp
dali-scene3d/internal/algorithm/navigation-mesh-impl.cpp
dali-scene3d/internal/algorithm/navigation-mesh-impl.h
dali-scene3d/internal/algorithm/path-finder-djikstra.cpp
dali-scene3d/internal/algorithm/path-finder-spfa-double-way.cpp
dali-scene3d/internal/algorithm/path-finder-spfa.cpp
dali-scene3d/internal/algorithm/path-finder-waypoint-data.h
dali-scene3d/internal/common/environment-map-load-task.cpp
dali-scene3d/internal/common/model-cache-manager.cpp
dali-scene3d/internal/common/model-cache-manager.h
dali-scene3d/internal/common/model-load-task.cpp
dali-scene3d/internal/common/model-load-task.h
dali-scene3d/internal/controls/model/model-impl.cpp
dali-scene3d/internal/controls/model/model-impl.h
dali-scene3d/internal/file.list
dali-scene3d/internal/loader/dli-loader-impl.cpp [moved from dali-scene3d/public-api/loader/dli-loader.cpp with 90% similarity]
dali-scene3d/internal/loader/dli-loader-impl.h [new file with mode: 0644]
dali-scene3d/internal/loader/glb-loader-impl.cpp [new file with mode: 0644]
dali-scene3d/internal/loader/glb-loader-impl.h [new file with mode: 0644]
dali-scene3d/internal/loader/gltf2-asset.h
dali-scene3d/internal/loader/gltf2-loader-impl.cpp [new file with mode: 0644]
dali-scene3d/internal/loader/gltf2-loader-impl.h [new file with mode: 0644]
dali-scene3d/internal/loader/gltf2-util.cpp [new file with mode: 0644]
dali-scene3d/internal/loader/gltf2-util.h [new file with mode: 0644]
dali-scene3d/internal/loader/hash.cpp
dali-scene3d/internal/loader/hash.h
dali-scene3d/internal/loader/json-reader.cpp
dali-scene3d/internal/loader/json-reader.h
dali-scene3d/internal/loader/json-util.cpp
dali-scene3d/internal/loader/json-util.h
dali-scene3d/internal/loader/model-loader-impl.h [new file with mode: 0644]
dali-scene3d/public-api/algorithm/navigation-mesh.h
dali-scene3d/public-api/algorithm/path-finder-waypoint.cpp
dali-scene3d/public-api/algorithm/path-finder-waypoint.h
dali-scene3d/public-api/algorithm/path-finder.cpp
dali-scene3d/public-api/controls/model/model.h
dali-scene3d/public-api/controls/scene-view/scene-view.h
dali-scene3d/public-api/file.list
dali-scene3d/public-api/loader/alpha-function-helper.cpp
dali-scene3d/public-api/loader/alpha-function-helper.h
dali-scene3d/public-api/loader/animated-property.cpp
dali-scene3d/public-api/loader/animated-property.h
dali-scene3d/public-api/loader/animation-definition.cpp
dali-scene3d/public-api/loader/animation-definition.h
dali-scene3d/public-api/loader/blend-shape-details.cpp
dali-scene3d/public-api/loader/blend-shape-details.h
dali-scene3d/public-api/loader/buffer-definition.cpp
dali-scene3d/public-api/loader/buffer-definition.h
dali-scene3d/public-api/loader/bvh-loader.cpp
dali-scene3d/public-api/loader/bvh-loader.h
dali-scene3d/public-api/loader/camera-parameters.cpp
dali-scene3d/public-api/loader/customization.cpp
dali-scene3d/public-api/loader/customization.h
dali-scene3d/public-api/loader/dli-input-parameter.h [new file with mode: 0644]
dali-scene3d/public-api/loader/dli-loader.h [deleted file]
dali-scene3d/public-api/loader/environment-definition.cpp
dali-scene3d/public-api/loader/environment-definition.h
dali-scene3d/public-api/loader/environment-map-data.cpp
dali-scene3d/public-api/loader/environment-map-data.h
dali-scene3d/public-api/loader/environment-map-loader.cpp
dali-scene3d/public-api/loader/environment-map-loader.h
dali-scene3d/public-api/loader/gltf2-loader.cpp [deleted file]
dali-scene3d/public-api/loader/gltf2-loader.h [deleted file]
dali-scene3d/public-api/loader/index.h
dali-scene3d/public-api/loader/ktx-loader.h
dali-scene3d/public-api/loader/light-parameters.h
dali-scene3d/public-api/loader/load-result.h
dali-scene3d/public-api/loader/material-definition.cpp
dali-scene3d/public-api/loader/material-definition.h
dali-scene3d/public-api/loader/matrix-stack.cpp
dali-scene3d/public-api/loader/matrix-stack.h
dali-scene3d/public-api/loader/mesh-definition.cpp
dali-scene3d/public-api/loader/mesh-definition.h
dali-scene3d/public-api/loader/mesh-geometry.h
dali-scene3d/public-api/loader/model-loader.cpp [new file with mode: 0644]
dali-scene3d/public-api/loader/model-loader.h [new file with mode: 0644]
dali-scene3d/public-api/loader/navigation-mesh-factory.cpp
dali-scene3d/public-api/loader/navigation-mesh-factory.h
dali-scene3d/public-api/loader/node-definition.cpp
dali-scene3d/public-api/loader/node-definition.h
dali-scene3d/public-api/loader/parse-renderer-state.cpp
dali-scene3d/public-api/loader/parse-renderer-state.h
dali-scene3d/public-api/loader/renderer-state.cpp
dali-scene3d/public-api/loader/renderer-state.h
dali-scene3d/public-api/loader/resource-bundle.cpp
dali-scene3d/public-api/loader/resource-bundle.h
dali-scene3d/public-api/loader/scene-definition.cpp
dali-scene3d/public-api/loader/scene-definition.h
dali-scene3d/public-api/loader/shader-definition-factory.cpp
dali-scene3d/public-api/loader/shader-definition-factory.h
dali-scene3d/public-api/loader/shader-definition.cpp
dali-scene3d/public-api/loader/shader-definition.h
dali-scene3d/public-api/loader/skeleton-definition.h
dali-scene3d/public-api/loader/skinning-details.cpp
dali-scene3d/public-api/loader/skinning-details.h
dali-scene3d/public-api/loader/string-callback.cpp
dali-scene3d/public-api/loader/string-callback.h
dali-scene3d/public-api/loader/utils.cpp
dali-scene3d/public-api/loader/utils.h
dali-scene3d/public-api/loader/view-projection.cpp
dali-scene3d/public-api/loader/view-projection.h
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/image-view/image-view-impl.h
dali-toolkit/internal/image-loader/loading-task.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

diff --git a/automated-tests/resources/BoxAnimated.glb b/automated-tests/resources/BoxAnimated.glb
new file mode 100644 (file)
index 0000000..69481ec
Binary files /dev/null and b/automated-tests/resources/BoxAnimated.glb differ
index 5af964f..a7a419e 100755 (executable)
@@ -7,7 +7,10 @@ SET(CAPI_LIB "dali-scene3d")
 
 # List of test case sources (Only these get parsed for test cases)
 SET(TC_SOURCES
+  utc-Dali-DliLoaderImpl.cpp
+  utc-Dali-GlbLoaderImpl.cpp
   utc-Dali-Gltf2Asset.cpp
+  utc-Dali-Gltf2LoaderImpl.cpp
   utc-Dali-Hash.cpp
   utc-Dali-JsonReader.cpp
   utc-Dali-JsonUtil.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -18,8 +18,8 @@
 // Enable debug log for test coverage
 #define DEBUG_ENABLED 1
 
+#include <dali-scene3d/internal/loader/dli-loader-impl.h>
 #include <dali-scene3d/internal/loader/json-util.h>
-#include <dali-scene3d/public-api/loader/dli-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>
@@ -34,7 +34,8 @@ namespace
 void ConfigureBlendShapeShaders(ResourceBundle& resources, const SceneDefinition& scene, Actor root, std::vector<BlendshapeShaderConfigurationRequest>&& requests)
 {
   std::vector<std::string> errors;
-  auto                     onError = [&errors](const std::string& msg) {
+  auto                     onError = [&errors](const std::string& msg)
+  {
     errors.push_back(msg);
   };
 
@@ -50,7 +51,8 @@ void ConfigureBlendShapeShaders(ResourceBundle& resources, const SceneDefinition
 
 struct Context
 {
-  ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) {
+  ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type)
+  {
     return TEST_RESOURCE_DIR "/";
   };
 
@@ -72,26 +74,21 @@ struct Context
     cameraParameters,
     lights};
 
-  DliLoader::InputParams input{
-    pathProvider(ResourceType::Mesh),
-    nullptr,
-    {},
-    {},
-    nullptr,
-  };
-  DliLoader::LoadParams loadParams{input, output};
-
-  std::vector<std::string> errors;
-  DliLoader                loader;
+  Dali::Scene3D::Loader::DliInputParameter       input;
+  std::vector<std::string>                       errors;
+  Dali::Scene3D::Loader::Internal::DliLoaderImpl loader;
 
-  StringCallback onError = [this](const std::string& error) {
+  StringCallback onError = [this](const std::string& error)
+  {
     errors.push_back(error);
     printf("%s\n", error.c_str());
   };
 
   Context()
   {
+    input.mAnimationsPath = pathProvider(ResourceType::Mesh);
     loader.SetErrorCallback(onError);
+    loader.SetInputParameter(input);
   }
 };
 
@@ -115,7 +112,7 @@ int UtcDaliDliLoaderLoadSceneNotFound(void)
 {
   Context ctx;
 
-  DALI_TEST_EQUAL(ctx.loader.LoadScene("does_not_exist.dli", ctx.loadParams), false);
+  DALI_TEST_EQUAL(ctx.loader.LoadModel("does_not_exist.dli", ctx.output), false);
 
   auto error = ctx.loader.GetParseError();
   DALI_TEST_CHECK(StringHasTokens(error.c_str(), {"Empty source buffer to parse."}));
@@ -128,7 +125,7 @@ int UtcDaliDliLoaderLoadSceneFailParse(void)
   Context ctx;
 
   auto path = ctx.pathProvider(ResourceType::Mesh) + "invalid.gltf";
-  DALI_TEST_EQUAL(ctx.loader.LoadScene(path, ctx.loadParams), false);
+  DALI_TEST_EQUAL(ctx.loader.LoadModel(path, ctx.output), false);
 
   auto error = ctx.loader.GetParseError();
   DALI_TEST_CHECK(StringHasTokens(error.c_str(), {"Unexpected character."}));
@@ -177,7 +174,7 @@ int UtcDaliDliLoaderLoadSceneAssertions(void)
 
     auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/" + i.first + ".dli";
     printf("\n\n%s: %s\n", path.c_str(), i.second.c_str());
-    DALI_TEST_ASSERTION(ctx.loader.LoadScene(path, ctx.loadParams), i.second.c_str());
+    DALI_TEST_ASSERTION(ctx.loader.LoadModel(path, ctx.output), i.second.c_str());
   }
 
   END_TEST;
@@ -188,7 +185,7 @@ int UtcDaliDliLoaderLoadSceneExercise(void)
   Context ctx;
 
   auto path = ctx.pathProvider(ResourceType::Mesh) + "exercise.dli";
-  DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+  DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output));
   DALI_TEST_CHECK(ctx.errors.empty());
 
   auto& scene = ctx.scene;
@@ -230,8 +227,9 @@ int UtcDaliDliLoaderLoadSceneExercise(void)
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    resources.CountEnvironmentReferences(resourceRefs);
-    resources.LoadResources(resourceRefs, ctx.pathProvider);
+    resources.mReferenceCounts = std::move(resourceRefs);
+    resources.CountEnvironmentReferences();
+    resources.LoadResources(ctx.pathProvider);
     if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
@@ -256,7 +254,8 @@ int UtcDaliDliLoaderLoadSceneMorph(void)
   std::vector<std::string> metadata;
   uint32_t                 metadataCount = 0;
   ctx.input.mPreNodeCategoryProcessors.push_back({"metadata",
-                                                  [&](const Property::Array& array, StringCallback) {
+                                                  [&](const Property::Array& array, StringCallback)
+                                                  {
                                                     std::string key, value;
                                                     for(uint32_t i0 = 0, i1 = array.Count(); i0 < i1; ++i0)
                                                     {
@@ -277,7 +276,8 @@ int UtcDaliDliLoaderLoadSceneMorph(void)
   std::vector<std::string> behaviors;
   uint32_t                 behaviorCount = 0;
   ctx.input.mPostNodeCategoryProcessors.push_back({"behaviors",
-                                                   [&](const Property::Array& array, StringCallback) {
+                                                   [&](const Property::Array& array, StringCallback)
+                                                   {
                                                      for(uint32_t i0 = 0, i1 = array.Count(); i0 < i1; ++i0)
                                                      {
                                                        auto& data = array.GetElementAt(i0);
@@ -295,12 +295,13 @@ int UtcDaliDliLoaderLoadSceneMorph(void)
                                                    }});
 
   size_t numNodes                  = 0;
-  ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, const Property::Map&, StringCallback) {
+  ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, const Property::Map&, StringCallback)
+  {
     ++numNodes;
   };
 
   auto path = ctx.pathProvider(ResourceType::Mesh) + "morph.dli";
-  DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+  DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output));
   DALI_TEST_CHECK(ctx.errors.empty());
 
   auto& scene = ctx.scene;
@@ -345,8 +346,9 @@ int UtcDaliDliLoaderLoadSceneMorph(void)
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    resources.CountEnvironmentReferences(resourceRefs);
-    resources.LoadResources(resourceRefs, ctx.pathProvider);
+    resources.mReferenceCounts = std::move(resourceRefs);
+    resources.CountEnvironmentReferences();
+    resources.LoadResources(ctx.pathProvider);
     if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
@@ -368,7 +370,7 @@ int UtcDaliDliLoaderLoadSceneArc(void)
   Context ctx;
 
   auto path = ctx.pathProvider(ResourceType::Mesh) + "arc.dli";
-  DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+  DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output));
   DALI_TEST_CHECK(ctx.errors.empty());
 
   auto& scene = ctx.scene;
@@ -409,8 +411,9 @@ int UtcDaliDliLoaderLoadSceneArc(void)
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    resources.CountEnvironmentReferences(resourceRefs);
-    resources.LoadResources(resourceRefs, ctx.pathProvider);
+    resources.mReferenceCounts = std::move(resourceRefs);
+    resources.CountEnvironmentReferences();
+    resources.LoadResources(ctx.pathProvider);
     if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
@@ -432,7 +435,7 @@ int UtcDaliDliLoaderLoadSceneShaderUniforms(void)
   Context ctx;
 
   auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/shader-uniforms.dli";
-  DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+  DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output));
   DALI_TEST_EQUAL(ctx.errors.size(), 1u);
   DALI_TEST_CHECK(ctx.errors[0].find("failed to infer type") != std::string::npos);
 
@@ -475,7 +478,7 @@ int UtcDaliDliLoaderLoadSceneExtras(void)
   Context ctx;
 
   auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/extras.dli";
-  DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+  DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output));
   DALI_TEST_EQUAL(ctx.errors.size(), 3u);
   DALI_TEST_CHECK(ctx.errors[0].find("already defined; overriding") != std::string::npos);
   DALI_TEST_CHECK(ctx.errors[1].find("empty string is invalid for name") != std::string::npos);
@@ -518,7 +521,7 @@ int UtcDaliDliLoaderLoadSceneConstraints(void)
   Context ctx;
 
   auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/constraints.dli";
-  DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+  DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output));
   DALI_TEST_EQUAL(ctx.errors.size(), 1u);
   DALI_TEST_CHECK(ctx.errors[0].find("invalid", ctx.errors[0].find("node ID")) != std::string::npos);
 
@@ -576,12 +579,13 @@ int UtcDaliDliLoaderNodeProcessor(void)
   Context ctx;
 
   std::vector<Property::Map> nodeMaps;
-  ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, Property::Map&& map, StringCallback) {
+  ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, Property::Map&& map, StringCallback)
+  {
     nodeMaps.push_back(map);
   };
 
   auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/node-processor.dli";
-  DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+  DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output));
 
   DALI_TEST_EQUAL(nodeMaps.size(), 2u);
   DALI_TEST_EQUAL(nodeMaps[0].Count(), 5u);
@@ -636,7 +640,7 @@ 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.loader.LoadModel(path, ctx.output));
   DALI_TEST_CHECK(ctx.errors.empty());
 
   auto& scene = ctx.scene;
@@ -688,8 +692,9 @@ int UtcDaliDliLoaderLoadCoverageTest(void)
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    resources.CountEnvironmentReferences(resourceRefs);
-    resources.LoadResources(resourceRefs, ctx.pathProvider);
+    resources.mReferenceCounts = std::move(resourceRefs);
+    resources.CountEnvironmentReferences();
+    resources.LoadResources(ctx.pathProvider);
     if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
diff --git a/automated-tests/src/dali-scene3d-internal/utc-Dali-GlbLoaderImpl.cpp b/automated-tests/src/dali-scene3d-internal/utc-Dali-GlbLoaderImpl.cpp
new file mode 100644 (file)
index 0000000..f3d8a93
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include <dali-scene3d/internal/loader/glb-loader-impl.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>
+
+using namespace Dali;
+using namespace Dali::Scene3D::Loader;
+
+#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__);              \
+  }
+
+namespace
+{
+struct Context
+{
+  ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) {
+    return TEST_RESOURCE_DIR "/";
+  };
+
+  ResourceBundle  resources;
+  SceneDefinition scene;
+  SceneMetadata   metaData;
+
+  std::vector<AnimationDefinition>      animations;
+  std::vector<AnimationGroupDefinition> animationGroups;
+  std::vector<CameraParameters>         cameras;
+  std::vector<LightParameters>          lights;
+
+  LoadResult loadResult{
+    resources,
+    scene,
+    metaData,
+    animations,
+    animationGroups,
+    cameras,
+    lights};
+
+  Dali::Scene3D::Loader::Internal::GlbLoaderImpl loader;
+};
+
+struct ExceptionMessageStartsWith
+{
+  const std::string_view expected;
+
+  bool operator()(const std::runtime_error& e)
+  {
+    const bool success = (0 == strncmp(e.what(), expected.data(), expected.size()));
+    if(!success)
+    {
+      printf("Expected: %s, got: %s.\n", expected.data(), e.what());
+    }
+    return success;
+  }
+};
+
+} // namespace
+
+int UtcDaliGlbLoaderFailedToLoad(void)
+{
+  Context ctx;
+
+  DALI_TEST_EQUAL(ctx.loader.LoadModel("non-existent.glb", ctx.loadResult), false);
+
+  DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
+  DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
+
+  DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size());
+  DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size());
+  DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size());
+  DALI_TEST_EQUAL(0, ctx.resources.mShaders.size());
+  DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size());
+
+  DALI_TEST_EQUAL(0, ctx.cameras.size());
+  DALI_TEST_EQUAL(0, ctx.lights.size());
+  DALI_TEST_EQUAL(0, ctx.animations.size());
+  DALI_TEST_EQUAL(0, ctx.animationGroups.size());
+
+  END_TEST;
+}
+
+int UtcDaliGlbLoaderFailedToParse(void)
+{
+  Context ctx;
+
+  ShaderDefinitionFactory sdf;
+  sdf.SetResources(ctx.resources);
+
+  DALI_TEST_EQUAL(ctx.loader.LoadModel(TEST_RESOURCE_DIR "/invalid.glb", ctx.loadResult), false);
+
+  DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
+  DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
+
+  DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size());
+  DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size());
+  DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size());
+  DALI_TEST_EQUAL(0, ctx.resources.mShaders.size());
+  DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size());
+
+  DALI_TEST_EQUAL(0, ctx.cameras.size());
+  DALI_TEST_EQUAL(0, ctx.lights.size());
+  DALI_TEST_EQUAL(0, ctx.animations.size());
+  DALI_TEST_EQUAL(0, ctx.animationGroups.size());
+
+  END_TEST;
+}
+
+int UtcDaliGlbLoaderSuccess1(void)
+{
+  Context                 ctx;
+  ShaderDefinitionFactory sdf;
+  sdf.SetResources(ctx.resources);
+
+  ctx.loader.LoadModel(TEST_RESOURCE_DIR "/BoxAnimated.glb", ctx.loadResult);
+
+  DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
+  DALI_TEST_EQUAL(5u, 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.mReferenceCounts = std::move(resourceRefs);
+    ctx.resources.LoadResources(ctx.pathProvider);
+  }
+
+  DALI_TEST_EQUAL(true, ctx.resources.mMeshes[0u].first.mPositions.IsDefined());
+  DALI_TEST_EQUAL(1152, ctx.resources.mMeshes[0u].first.mPositions.mBlob.mLength);
+
+  END_TEST;
+}
@@ -18,7 +18,7 @@
 // Enable debug log for test coverage
 #define DEBUG_ENABLED 1
 
-#include <dali-scene3d/public-api/loader/gltf2-loader.h>
+#include <dali-scene3d/internal/loader/gltf2-loader-impl.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>
@@ -55,7 +55,8 @@ namespace
 {
 struct Context
 {
-  ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) {
+  ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type)
+  {
     return TEST_RESOURCE_DIR "/";
   };
 
@@ -76,6 +77,8 @@ struct Context
     animationGroups,
     cameras,
     lights};
+
+  Dali::Scene3D::Loader::Internal::Gltf2LoaderImpl loader;
 };
 
 struct ExceptionMessageStartsWith
@@ -99,13 +102,7 @@ int UtcDaliGltfLoaderFailedToLoad(void)
 {
   Context ctx;
 
-  ShaderDefinitionFactory sdf;
-  sdf.SetResources(ctx.resources);
-
-  InitializeGltfLoader();
-  DALI_TEST_THROW(LoadGltfScene("non-existent.gltf", sdf, ctx.loadResult),
-                  std::runtime_error,
-                  ExceptionMessageStartsWith{"Failed to load"});
+  DALI_TEST_EQUAL(ctx.loader.LoadModel("non-existent.gltf", ctx.loadResult), false);
 
   DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
   DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
@@ -131,10 +128,7 @@ int UtcDaliGltfLoaderFailedToParse(void)
   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"});
+  DALI_TEST_EQUAL(ctx.loader.LoadModel(TEST_RESOURCE_DIR "/invalid.gltf", ctx.loadResult), false);
 
   DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
   DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
@@ -172,11 +166,7 @@ int UtcDaliGltfLoaderSuccess1(void)
     ++metaData;
   }
 
-  ShaderDefinitionFactory sdf;
-  sdf.SetResources(ctx.resources);
-
-  InitializeGltfLoader();
-  LoadGltfScene(TEST_RESOURCE_DIR "/AnimatedCube.gltf", sdf, ctx.loadResult);
+  ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AnimatedCube.gltf", ctx.loadResult);
 
   DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
   DALI_TEST_EQUAL(9u, ctx.scene.GetNodeCount());
@@ -191,8 +181,9 @@ int UtcDaliGltfLoaderSuccess1(void)
   {
     auto resourceRefs = ctx.resources.CreateRefCounter();
     ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    ctx.resources.CountEnvironmentReferences(resourceRefs);
-    ctx.resources.LoadResources(resourceRefs, ctx.pathProvider);
+    ctx.resources.mReferenceCounts = std::move(resourceRefs);
+    ctx.resources.CountEnvironmentReferences();
+    ctx.resources.LoadResources(ctx.pathProvider);
   }
 
   auto& materials = ctx.resources.mMaterials;
@@ -466,8 +457,7 @@ int UtcDaliGltfLoaderSuccess2(void)
   ShaderDefinitionFactory sdf;
   sdf.SetResources(ctx.resources);
 
-  InitializeGltfLoader();
-  LoadGltfScene(TEST_RESOURCE_DIR "/AnimatedCubeStride.gltf", sdf, ctx.loadResult);
+  ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AnimatedCubeStride.gltf", ctx.loadResult);
 
   DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
   DALI_TEST_EQUAL(1u, ctx.scene.GetNodeCount());
@@ -479,7 +469,8 @@ int UtcDaliGltfLoaderSuccess2(void)
   {
     auto resourceRefs = ctx.resources.CreateRefCounter();
     ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    ctx.resources.LoadResources(resourceRefs, ctx.pathProvider);
+    ctx.resources.mReferenceCounts = std::move(resourceRefs);
+    ctx.resources.LoadResources(ctx.pathProvider);
   }
 
   DALI_TEST_EQUAL(true, ctx.resources.mMeshes[0u].first.mPositions.IsDefined());
@@ -493,7 +484,8 @@ int UtcDaliGltfLoaderSuccessShort(void)
   TestApplication app;
 
   const std::string resourcePath = TEST_RESOURCE_DIR "/";
-  auto              pathProvider = [resourcePath](ResourceType::Value) {
+  auto              pathProvider = [resourcePath](ResourceType::Value)
+  {
     return resourcePath;
   };
 
@@ -517,16 +509,11 @@ int UtcDaliGltfLoaderSuccessShort(void)
   {
     Context ctx;
 
-    ShaderDefinitionFactory sdf;
-
     auto& resources = ctx.resources;
     resources.mEnvironmentMaps.push_back({});
 
-    sdf.SetResources(resources);
-
     printf("%s\n", modelName);
-    InitializeGltfLoader();
-    LoadGltfScene(resourcePath + modelName + ".gltf", sdf, ctx.loadResult);
+    ctx.loader.LoadModel(resourcePath + modelName + ".gltf", ctx.loadResult);
     DALI_TEST_CHECK(ctx.scene.GetNodeCount() > 0);
 
     auto& scene = ctx.scene;
@@ -587,8 +574,7 @@ int UtcDaliGltfLoaderMRendererTest(void)
   sdf.SetResources(ctx.resources);
   auto& resources = ctx.resources;
 
-  InitializeGltfLoader();
-  LoadGltfScene(TEST_RESOURCE_DIR "/MRendererTest.gltf", sdf, ctx.loadResult);
+  ctx.loader.LoadModel(TEST_RESOURCE_DIR "/MRendererTest.gltf", ctx.loadResult);
 
   auto& scene = ctx.scene;
   auto& roots = scene.GetRoots();
@@ -617,8 +603,9 @@ int UtcDaliGltfLoaderMRendererTest(void)
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    resources.CountEnvironmentReferences(resourceRefs);
-    resources.LoadResources(resourceRefs, ctx.pathProvider);
+    ctx.resources.mReferenceCounts = std::move(resourceRefs);
+    ctx.resources.CountEnvironmentReferences();
+    ctx.resources.LoadResources(ctx.pathProvider);
     if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
@@ -646,12 +633,9 @@ int UtcDaliGltfLoaderAnimationLoadingTest(void)
 {
   Context ctx;
 
-  ShaderDefinitionFactory sdf;
-  sdf.SetResources(ctx.resources);
   auto& resources = ctx.resources;
 
-  InitializeGltfLoader();
-  LoadGltfScene(TEST_RESOURCE_DIR "/CesiumMan_e.gltf", sdf, ctx.loadResult);
+  ctx.loader.LoadModel(TEST_RESOURCE_DIR "/CesiumMan_e.gltf", ctx.loadResult);
 
   auto& scene = ctx.scene;
   auto& roots = scene.GetRoots();
@@ -676,8 +660,9 @@ int UtcDaliGltfLoaderAnimationLoadingTest(void)
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    resources.CountEnvironmentReferences(resourceRefs);
-    resources.LoadResources(resourceRefs, ctx.pathProvider);
+    resources.mReferenceCounts = std::move(resourceRefs);
+    resources.CountEnvironmentReferences();
+    resources.LoadResources(ctx.pathProvider);
     if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
@@ -704,8 +689,7 @@ int UtcDaliGltfLoaderImageFromBufferView(void)
   sdf.SetResources(ctx.resources);
   auto& resources = ctx.resources;
 
-  InitializeGltfLoader();
-  LoadGltfScene(TEST_RESOURCE_DIR "/EnvironmentTest_b.gltf", sdf, ctx.loadResult);
+  ctx.loader.LoadModel(TEST_RESOURCE_DIR "/EnvironmentTest_b.gltf", ctx.loadResult);
 
   auto& scene = ctx.scene;
   auto& roots = scene.GetRoots();
@@ -730,8 +714,9 @@ int UtcDaliGltfLoaderImageFromBufferView(void)
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    resources.CountEnvironmentReferences(resourceRefs);
-    resources.LoadResources(resourceRefs, ctx.pathProvider);
+    resources.mReferenceCounts = std::move(resourceRefs);
+    resources.CountEnvironmentReferences();
+    resources.LoadResources(ctx.pathProvider);
     if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
@@ -752,12 +737,9 @@ int UtcDaliGltfLoaderUint8Indices(void)
 {
   Context ctx;
 
-  ShaderDefinitionFactory sdf;
-  sdf.SetResources(ctx.resources);
   auto& resources = ctx.resources;
 
-  InitializeGltfLoader();
-  LoadGltfScene(TEST_RESOURCE_DIR "/AlphaBlendModeTest.gltf", sdf, ctx.loadResult);
+  ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AlphaBlendModeTest.gltf", ctx.loadResult);
 
   auto& scene = ctx.scene;
   auto& roots = scene.GetRoots();
@@ -782,8 +764,9 @@ int UtcDaliGltfLoaderUint8Indices(void)
   {
     auto resourceRefs = resources.CreateRefCounter();
     scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    resources.CountEnvironmentReferences(resourceRefs);
-    resources.LoadResources(resourceRefs, ctx.pathProvider);
+    resources.mReferenceCounts = std::move(resourceRefs);
+    resources.CountEnvironmentReferences();
+    resources.LoadResources(ctx.pathProvider);
     if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
     {
       scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
index 707bdd5..66a766a 100755 (executable)
@@ -13,10 +13,8 @@ SET(TC_SOURCES
   utc-Dali-BvhLoader.cpp
   utc-Dali-CameraParameters.cpp
   utc-Dali-EnvironmentMapLoader.cpp
-  utc-Dali-DliLoader.cpp
   utc-Dali-EnvironmentDefinition.cpp
   utc-Dali-FacialAnimation.cpp
-  utc-Dali-Gltf2Loader.cpp
   utc-Dali-KtxLoader.cpp
   utc-Dali-Model.cpp
   utc-Dali-SceneView.cpp
index 7840c74..28b929e 100644 (file)
@@ -54,12 +54,8 @@ const char* TEST_GLTF_FILE_NAME                    = TEST_RESOURCE_DIR "/Animate
 const char* TEST_GLTF_ANIMATION_TEST_FILE_NAME     = TEST_RESOURCE_DIR "/animationTest.gltf";
 const char* TEST_GLTF_MULTIPLE_PRIMITIVE_FILE_NAME = TEST_RESOURCE_DIR "/simpleMultiplePrimitiveTest.gltf";
 const char* TEST_DLI_FILE_NAME                     = TEST_RESOURCE_DIR "/arc.dli";
-// @TODO: The test cases for loading the DLI model below is temporarily disabled.
-// Need to fix how resources are loaded when a model contains multiple scenes and
-// each scene has its own root node.
-#ifdef MULTIPLE_SCENES_MODEL_SUPPORT
 const char* TEST_DLI_EXERCISE_FILE_NAME = TEST_RESOURCE_DIR "/exercise.dli";
-#endif
+
 /**
  * For the diffuse and specular cube map texture.
  * These textures are based off version of Wave engine sample
@@ -1011,7 +1007,6 @@ int UtcDaliModelAnimation02(void)
 
 int UtcDaliModelAnimation03(void)
 {
-#ifdef MULTIPLE_SCENES_MODEL_SUPPORT
   ToolkitTestApplication application;
 
   Scene3D::Model model = Scene3D::Model::New(TEST_DLI_EXERCISE_FILE_NAME);
@@ -1040,16 +1035,12 @@ int UtcDaliModelAnimation03(void)
   Animation animationByName = model.GetAnimation("idleClip");
   DALI_TEST_CHECK(animationByName);
   DALI_TEST_EQUALS(animationByIndex, animationByName, TEST_LOCATION);
-#else
-  tet_result(TET_PASS);
-#endif
 
   END_TEST;
 }
 
 int UtcDaliModelCameraGenerate01(void)
 {
-#ifdef MULTIPLE_SCENES_MODEL_SUPPORT
   ToolkitTestApplication application;
 
   Scene3D::Model model = Scene3D::Model::New(TEST_DLI_EXERCISE_FILE_NAME);
@@ -1077,9 +1068,6 @@ int UtcDaliModelCameraGenerate01(void)
 
   generatedCamera = model.GenerateCamera(1u); // Fail to generate camera
   DALI_TEST_CHECK(!generatedCamera);
-#else
-  tet_result(TET_PASS);
-#endif
 
   END_TEST;
 }
index 20c1bcb..162e48e 100644 (file)
 // Enable debug log for test coverage
 #define DEBUG_ENABLED 1
 
-#include "dali-scene3d/public-api/loader/resource-bundle.h"
-#include "dali-scene3d/public-api/loader/utils.h"
 #include <dali-test-suite-utils.h>
 #include <string_view>
+#include "dali-scene3d/public-api/loader/resource-bundle.h"
+#include "dali-scene3d/public-api/loader/utils.h"
 
 using namespace Dali;
 using namespace Dali::Scene3D::Loader;
@@ -34,9 +34,9 @@ int UtcDaliResourceRefCounts(void)
   resourceBundle.mMeshes.resize(17);
   resourceBundle.mMaterials.resize(19);
 
-  int i = 0;
+  int              i = 0;
   std::vector<int> testEnvironmentReferences(resourceBundle.mEnvironmentMaps.size());
-  for (auto& m : resourceBundle.mMaterials)
+  for(auto& m : resourceBundle.mMaterials)
   {
     Index iEnv = 0;
     iEnv += (i % 3) == 0;
@@ -56,9 +56,12 @@ int UtcDaliResourceRefCounts(void)
   DALI_TEST_EQUAL(counter[ResourceType::Material].Size(), resourceBundle.mMaterials.size());
 
   std::fill(counter[ResourceType::Material].begin(), counter[ResourceType::Material].end(), 1u);
-  resourceBundle.CountEnvironmentReferences(counter);
-  i = 0;
-  for (auto& er: counter[ResourceType::Environment])
+  resourceBundle.mReferenceCounts = std::move(counter);
+  resourceBundle.CountEnvironmentReferences();
+
+  const ResourceRefCounts& referenceCounts = resourceBundle.mReferenceCounts;
+  i                                        = 0;
+  for(auto& er : referenceCounts[ResourceType::Environment])
   {
     DALI_TEST_EQUAL(er, testEnvironmentReferences[i]);
     ++i;
index 12f9605..0a269a5 100644 (file)
@@ -24,7 +24,6 @@
 #include <dali-test-suite-utils.h>
 #include <set>
 #include <string_view>
-#include "dali-scene3d/public-api/loader/gltf2-loader.h"
 #include "dali-scene3d/public-api/loader/node-definition.h"
 #include "dali-scene3d/public-api/loader/resource-bundle.h"
 #include "dali-scene3d/public-api/loader/shader-definition-factory.h"
index 7e78094..e3b72d2 100644 (file)
  * limitations under the License.
  */
 
-// INTERNAL INCLUDES
+// CLASS HEADER
 #include <dali-scene3d/internal/algorithm/navigation-mesh-impl.h>
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 
-#include <filesystem>
 #include <algorithm>
 #include <cerrno>
 #include <cstdio>
 #include <cstring>
+#include <filesystem>
 
 using Dali::Vector3;
 
 namespace Dali::Scene3D::Internal::Algorithm
 {
-
-using Poly = Dali::Scene3D::Algorithm::NavigationMesh::Face;
-using Edge = Dali::Scene3D::Algorithm::NavigationMesh::Edge;
+using Poly   = Dali::Scene3D::Algorithm::NavigationMesh::Face;
+using Edge   = Dali::Scene3D::Algorithm::NavigationMesh::Edge;
 using Vertex = Dali::Scene3D::Algorithm::NavigationMesh::Vertex;
 
 // Internal Navigation ray structure
 struct NavigationRay
 {
-  Dali::Vector3 origin; // Origin of ray
+  Dali::Vector3 origin;    // Origin of ray
   Dali::Vector3 direction; // Direction of ray
 };
 
@@ -96,7 +95,7 @@ NavigationMesh::NavigationMesh(const std::vector<uint8_t>& buffer)
   std::copy(buffer.begin(), buffer.end(), mBuffer.begin());
 
   // Setup header from the buffer
-  mHeader = *reinterpret_cast<NavigationMeshHeader_V10*>(mBuffer.data());
+  mHeader      = *reinterpret_cast<NavigationMeshHeader_V10*>(mBuffer.data());
   mCurrentFace = Scene3D::Algorithm::NavigationMesh::NULL_FACE;
 }
 
@@ -225,8 +224,7 @@ bool NavigationMesh::FindFloor(const Dali::Vector3& position, Dali::Vector3& out
     return false;
   }
 
-  std::sort(results.begin(), results.end(), [](const IntersectResult& lhs, const IntersectResult& rhs)
-            { return lhs.distance < rhs.distance; });
+  std::sort(results.begin(), results.end(), [](const IntersectResult& lhs, const IntersectResult& rhs) { return lhs.distance < rhs.distance; });
 
   outPosition  = PointLocalToScene(results.front().point);
   faceIndex    = results.front().faceIndex;
@@ -291,7 +289,7 @@ Dali::Vector3 NavigationMesh::PointLocalToScene(const Dali::Vector3& point)
 
 Dali::Vector3 NavigationMesh::GetGravityVector() const
 {
-  return Dali::Vector3( mHeader.gravityVector );
+  return Dali::Vector3(mHeader.gravityVector);
 }
 
-}
\ No newline at end of file
+} // namespace Dali::Scene3D::Internal::Algorithm
\ No newline at end of file
index 2ba1b6d..f61a922 100644 (file)
  * limitations under the License.
  */
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/algorithm/navigation-mesh.h>
-#include <dali-scene3d/public-api/algorithm/path-finder.h>
-
-// INTERNAL EXTERNAL
+// EXTERNAL EXTERNAL
 #include <dali/public-api/actors/actor.h>
+#include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/math/matrix.h>
 #include <dali/public-api/math/vector3.h>
 #include <dali/public-api/math/vector4.h>
 #include <cinttypes>
 #include <cstdio>
 #include <mutex>
-#include <vector>
-#include "navigation-mesh-header.h"
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/algorithm/navigation-mesh-header.h>
+#include <dali-scene3d/public-api/algorithm/navigation-mesh.h>
+#include <dali-scene3d/public-api/algorithm/path-finder.h>
 
 namespace Dali::Scene3D::Loader
 {
@@ -40,7 +40,6 @@ class NavigationMeshFactory;
 
 namespace Dali::Scene3D::Internal::Algorithm
 {
-
 class NavigationRay;
 
 /**
@@ -54,7 +53,6 @@ public:
   using Vertex = Dali::Scene3D::Algorithm::NavigationMesh::Vertex;
 
 private:
-
   friend class Scene3D::Loader::NavigationMeshFactory;
 
   /**
@@ -63,7 +61,6 @@ private:
   NavigationMesh(const std::vector<uint8_t>& buffer);
 
 public:
-
   /**
    * Destructor
    */
@@ -157,11 +154,11 @@ public:
   [[nodiscard]] Dali::Vector3 GetGravityVector() const;
 
 private:
-  std::vector<uint8_t> mBuffer;                    //< Data buffer
-  NavigationMeshHeader_V10 mHeader;                //< Navigation mesh header
-  uint16_t             mCurrentFace;               //< Current face (last floor position)
-  Dali::Matrix         mTransform;                 //< Transform matrix
-  Dali::Matrix         mTransformInverse;          //< Inverse of the transform matrix
+  std::vector<uint8_t>     mBuffer;           //< Data buffer
+  NavigationMeshHeader_V10 mHeader;           //< Navigation mesh header
+  uint16_t                 mCurrentFace;      //< Current face (last floor position)
+  Dali::Matrix             mTransform;        //< Transform matrix
+  Dali::Matrix             mTransformInverse; //< Inverse of the transform matrix
 };
 
 inline Internal::Algorithm::NavigationMesh& GetImplementation(Dali::Scene3D::Algorithm::NavigationMesh& navigationMesh)
index 0da6568..7c751ad 100644 (file)
  * limitations under the License.
  */
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/algorithm/path-finder-waypoint.h>
+// CLASS HEADER
 #include <dali-scene3d/internal/algorithm/path-finder-djikstra.h>
-#include <dali-scene3d/internal/algorithm/path-finder-waypoint-data.h>
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 #include <limits>
-#include <vector>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/algorithm/path-finder-waypoint-data.h>
+#include <dali-scene3d/public-api/algorithm/path-finder-waypoint.h>
 
 using WayPointList = Dali::Scene3D::Algorithm::WayPointList;
 
 namespace Dali::Scene3D::Internal::Algorithm
 {
-
 PathFinderAlgorithmDjikstra::PathFinderAlgorithmDjikstra(Dali::Scene3D::Algorithm::NavigationMesh& navMesh)
 : mNavigationMesh(&GetImplementation(navMesh))
 {
@@ -40,7 +41,7 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::FindPath(const Dal
 {
   Dali::Vector3 outPosFrom;
   uint32_t      polyIndexFrom;
-  auto result = mNavigationMesh->FindFloor(positionFrom, outPosFrom, polyIndexFrom);
+  auto          result = mNavigationMesh->FindFloor(positionFrom, outPosFrom, polyIndexFrom);
 
   Scene3D::Algorithm::WayPointList waypoints;
 
@@ -57,7 +58,7 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::FindPath(const Dal
 
       // replace first and last waypoint
       auto& wpFrom = static_cast<WayPointData&>(waypoints[0]);
-      auto& wpTo = static_cast<WayPointData&>(waypoints.back());
+      auto& wpTo   = static_cast<WayPointData&>(waypoints.back());
 
       Vector2 fromCenter(wpFrom.point3d.x, wpFrom.point3d.y);
       wpFrom.point3d = outPosFrom;
@@ -100,8 +101,7 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::FindPath(uint32_t
   dist[sourcePolyIndex] = 0.0f;
 
   // TO OPTIMIZE WITH PRIORITY QUEUE
-  auto FindMinDistance = [&nodeQueue](decltype(dist)& dist)
-  {
+  auto FindMinDistance = [&nodeQueue](decltype(dist)& dist) {
     float w     = std::numeric_limits<float>::max();
     int   index = -1;
     for(auto i = 0u; i < dist.size(); ++i)
@@ -215,7 +215,7 @@ void PathFinderAlgorithmDjikstra::PrepareData()
       auto        p2   = edge->face[1];
 
       // One of faces is current face so ignore it
-      auto p                   = ((p1 != i) ? p1 : p2);
+      auto p                = ((p1 != i) ? p1 : p2);
       node.faces[edgeIndex] = p;
       if(p != ::Dali::Scene3D::Algorithm::NavigationMesh::NULL_FACE)
       {
@@ -248,7 +248,7 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::OptimizeWaypoints(
   bool finished = false;
   for(auto j = 0; !finished; ++j)
   {
-    auto& startWaypoint = optimizedWaypoints.back();
+    auto&       startWaypoint     = optimizedWaypoints.back();
     const auto& startWaypointData = static_cast<const WayPointData&>(startWaypoint);
 
     // add new-last waypoint which will be overriden as long as intersection takes place
@@ -277,8 +277,8 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::OptimizeWaypoints(
         {
           continue;
         }
-        auto Pb0 = mNavigationMesh->GetVertex(wp.edge->vertex[0]);
-        auto Pb1 = mNavigationMesh->GetVertex(wp.edge->vertex[1]);
+        auto Pb0  = mNavigationMesh->GetVertex(wp.edge->vertex[0]);
+        auto Pb1  = mNavigationMesh->GetVertex(wp.edge->vertex[1]);
         auto vPb0 = Dali::Vector2(Pb0->x, Pb0->y);
         auto vPb1 = Dali::Vector2(Pb1->x, Pb1->y);
 
@@ -292,7 +292,7 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::OptimizeWaypoints(
       if(!doesIntersect)
       {
         optimizedWaypoints.back() = waypoints[wpIndex - 1];
-        startIndex = wpIndex - 1;
+        startIndex                = wpIndex - 1;
         break;
       }
     }
@@ -300,11 +300,11 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::OptimizeWaypoints(
 
   for(auto& wp : optimizedWaypoints)
   {
-    auto& wpData = static_cast<WayPointData&>(wp);
+    auto& wpData   = static_cast<WayPointData&>(wp);
     wpData.point3d = mNavigationMesh->PointLocalToScene(Dali::Vector3(wpData.face->center));
     wpData.point2d = Vector2::ZERO;
   }
 
   return optimizedWaypoints;
 }
-}
+} // namespace Dali::Scene3D::Internal::Algorithm
index d29a6f2..3b5f844 100644 (file)
  * limitations under the License.
  */
 
-// INTERNAL INCLUDES
+// CLASS HEADER
 #include <dali-scene3d/internal/algorithm/path-finder-spfa-double-way.h>
-#include <dali-scene3d/internal/algorithm/path-finder-waypoint-data.h>
-#include <dali-scene3d/public-api/algorithm/path-finder-waypoint.h>
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 #include <limits>
 #include <unordered_set>
-#include <vector>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/algorithm/path-finder-waypoint-data.h>
+#include <dali-scene3d/public-api/algorithm/path-finder-waypoint.h>
 
 using WayPointList = Dali::Scene3D::Algorithm::WayPointList;
 
index 977eb90..aa8b3bd 100644 (file)
  * limitations under the License.
  */
 
-// INTERNAL INCLUDES
+// CLASS HEADER
 #include <dali-scene3d/internal/algorithm/path-finder-spfa.h>
-#include <dali-scene3d/internal/algorithm/path-finder-waypoint-data.h>
-#include <dali-scene3d/public-api/algorithm/path-finder-waypoint.h>
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 #include <limits>
-#include <vector>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/algorithm/path-finder-waypoint-data.h>
+#include <dali-scene3d/public-api/algorithm/path-finder-waypoint.h>
 
 using WayPointList = Dali::Scene3D::Algorithm::WayPointList;
 
index 53df123..ab5c3b0 100644 (file)
  * limitations under the License.
  */
 
-// CLASS HEADER
-#include <dali-scene3d/public-api/algorithm/path-finder-waypoint.h>
-
 // INTERNAL INCLUDES
 #include <dali-scene3d/internal/algorithm/navigation-mesh-impl.h>
+#include <dali-scene3d/public-api/algorithm/path-finder-waypoint.h>
 
 // EXTERNAL INCLUDES
 #include <cinttypes>
@@ -51,6 +49,6 @@ struct WayPointData
   // internal data needed for processing
   const NavigationMesh::Edge* edge; ///< Edge between this face and next face
 };
-}
+} // namespace Dali::Scene3D::Internal::Algorithm
 
 #endif // DALI_SCENE3D_INTERNAL_PATH_FINDER_WAYPOINT_DATA_H
index d847f46..5ff0d51 100644 (file)
 // INTERNAL INCLUDES
 #include <dali-scene3d/public-api/loader/environment-map-loader.h>
 
-
 namespace Dali
 {
 namespace Scene3D
 {
 namespace Internal
 {
-
 EnvironmentMapLoadTask::EnvironmentMapLoadTask(const std::string& environmentMapUrl, Dali::Scene3D::EnvironmentMapType environmentMapType, CallbackBase* callback)
 : AsyncTask(callback),
   mEnvironmentMapUrl(environmentMapUrl),
@@ -60,7 +58,7 @@ bool EnvironmentMapLoadTask::HasSucceeded() const
 
 Dali::Texture EnvironmentMapLoadTask::GetLoadedTexture()
 {
-  return (HasSucceeded()) ? mEnvironmentMapData.GetTexture() : Texture();;
+  return (HasSucceeded()) ? mEnvironmentMapData.GetTexture() : Texture();
 }
 
 } // namespace Internal
index 01d2eba..0a26bcc 100644 (file)
@@ -57,12 +57,6 @@ public:
     return cache.loadSceneConditionalWait;
   }
 
-  Dali::ConditionalWait& GetLoadRawResourceConditionalWaitInstance(std::string modelUri)
-  {
-    ModelCache& cache = mModelCache[modelUri];
-    return cache.loadRawResourceConditionalWait;
-  }
-
   void ReferenceModelCache(std::string modelUri)
   {
     ModelCache& cache = mModelCache[modelUri];
@@ -129,7 +123,6 @@ private:
 
     uint32_t              refCount{0};                      ///< The reference count of this model cache.
     Dali::ConditionalWait loadSceneConditionalWait{};       ///< The conditionalWait instance used to synchronise the loading of the scene for the same model in different threads.
-    Dali::ConditionalWait loadRawResourceConditionalWait{}; ///< The conditionalWait instance used to synchronise the loading of the shared raw resources for the same model in different threads.
 
     bool isSceneLoaded{false};  ///< Whether the scene of the model has been loaded.
     bool isSceneLoading{false}; ///< Whether the scene loading of the model is in progress.
@@ -192,12 +185,6 @@ Dali::ConditionalWait& ModelCacheManager::GetLoadSceneConditionalWaitInstance(st
   return impl.GetLoadSceneConditionalWaitInstance(modelUri);
 }
 
-Dali::ConditionalWait& ModelCacheManager::GetLoadRawResourceConditionalWaitInstance(std::string modelUri)
-{
-  ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
-  return impl.GetLoadRawResourceConditionalWaitInstance(modelUri);
-}
-
 void ModelCacheManager::ReferenceModelCache(std::string modelUri)
 {
   ModelCacheManager::Impl& impl = static_cast<ModelCacheManager::Impl&>(GetBaseObject());
index a427945..0d30b26 100644 (file)
@@ -86,14 +86,6 @@ public:
   Dali::ConditionalWait& GetLoadSceneConditionalWaitInstance(std::string modelUri);
 
   /**
-   * @brief Retrieves the ConditionalWait object to synchronize the raw resources loading of the
-   * model with the given URI between multiple threads.
-   * @param[in] modelUri The unique model URI with its absolute path.
-   * @return The ConditionalWait object.
-   */
-  Dali::ConditionalWait& GetLoadRawResourceConditionalWaitInstance(std::string modelUri);
-
-  /**
    * @brief Reference the cache of the model with the given URI.
    * This will increment the reference count of the load result by 1.
    * @param[in] modelUri The model URI.
index aaec429..6456b6d 100644 (file)
 #include <dali/integration-api/debug.h>
 #include <filesystem>
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/internal/common/model-cache-manager.h>
-#include <dali-scene3d/public-api/loader/animation-definition.h>
-#include <dali-scene3d/public-api/loader/camera-parameters.h>
-#include <dali-scene3d/public-api/loader/dli-loader.h>
-#include <dali-scene3d/public-api/loader/gltf2-loader.h>
-#include <dali-scene3d/public-api/loader/light-parameters.h>
-#include <dali-scene3d/public-api/loader/node-definition.h>
-#include <dali-scene3d/public-api/loader/shader-definition-factory.h>
-
 namespace Dali
 {
 namespace Scene3D
@@ -41,20 +31,15 @@ namespace Internal
 namespace
 {
 static constexpr Vector3 Y_DIRECTION(1.0f, -1.0f, 1.0f);
-
-static constexpr std::string_view OBJ_EXTENSION      = ".obj";
-static constexpr std::string_view GLTF_EXTENSION     = ".gltf";
-static constexpr std::string_view DLI_EXTENSION      = ".dli";
-static constexpr std::string_view METADATA_EXTENSION = "metadata";
 } // namespace
 
 ModelLoadTask::ModelLoadTask(const std::string& modelUrl, const std::string& resourceDirectoryUrl, CallbackBase* callback)
 : AsyncTask(callback),
   mModelUrl(modelUrl),
   mResourceDirectoryUrl(resourceDirectoryUrl),
-  mHasSucceeded(false),
-  mModelCacheManager(ModelCacheManager::Get()),
-  mLoadResult(mModelCacheManager.GetModelLoadResult(modelUrl))
+  mModelCacheManager(Scene3D::Internal::ModelCacheManager::Get()),
+  mLoadResult(mModelCacheManager.GetModelLoadResult(mModelUrl)),
+  mHasSucceeded(false)
 {
 }
 
@@ -64,124 +49,50 @@ ModelLoadTask::~ModelLoadTask()
 
 void ModelLoadTask::Process()
 {
-  uint32_t               cacheRefCount                  = mModelCacheManager.GetModelCacheRefCount(mModelUrl);
-  Dali::ConditionalWait& loadSceneConditionalWait       = mModelCacheManager.GetLoadSceneConditionalWaitInstance(mModelUrl);
-  Dali::ConditionalWait& loadRawResourceConditionalWait = mModelCacheManager.GetLoadRawResourceConditionalWaitInstance(mModelUrl);
-
-  std::filesystem::path modelUrl(mModelUrl);
   if(mResourceDirectoryUrl.empty())
   {
+    std::filesystem::path modelUrl(mModelUrl);
     mResourceDirectoryUrl = std::string(modelUrl.parent_path()) + "/";
   }
-  std::string extension = modelUrl.extension();
-  std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
 
   Dali::Scene3D::Loader::ResourceBundle::PathProvider pathProvider = [&](Dali::Scene3D::Loader::ResourceType::Value type) {
     return mResourceDirectoryUrl;
   };
 
+  mModelLoader = std::make_shared<Dali::Scene3D::Loader::ModelLoader>(mModelUrl, mResourceDirectoryUrl, mLoadResult);
+
+  bool                   loadSucceeded            = false;
+  Dali::ConditionalWait& loadSceneConditionalWait = mModelCacheManager.GetLoadSceneConditionalWaitInstance(mModelUrl);
   {
     ConditionalWait::ScopedLock lock(loadSceneConditionalWait);
-
-    while(cacheRefCount > 1 && mModelCacheManager.IsSceneLoading(mModelUrl))
+    if(mModelCacheManager.IsSceneLoaded(mModelUrl))
     {
-      loadSceneConditionalWait.Wait();
+      loadSucceeded = true;
     }
-  }
-
-  {
-    ConditionalWait::ScopedLock lock(loadSceneConditionalWait);
-
-    if(!mModelCacheManager.IsSceneLoaded(mModelUrl))
+    else
     {
       mModelCacheManager.SetSceneLoading(mModelUrl, true);
 
-      std::filesystem::path metaDataUrl = modelUrl;
-      metaDataUrl.replace_extension(METADATA_EXTENSION.data());
+      loadSucceeded = mModelLoader->LoadModel(pathProvider, true);
 
-      Dali::Scene3D::Loader::LoadSceneMetadata(metaDataUrl.c_str(), mLoadResult.mSceneMetadata);
-
-      mLoadResult.mAnimationDefinitions.clear();
-
-      if(extension == DLI_EXTENSION)
+      // Mesh of glTF and dli is defined in right hand coordinate system, with positive Y for Up direction.
+      // Because DALi uses left hand system, Y direciton will be flipped for environment map sampling.
+      for(auto&& env : GetResources().mEnvironmentMaps)
       {
-        Dali::Scene3D::Loader::DliLoader              loader;
-        Dali::Scene3D::Loader::DliLoader::InputParams input{
-          pathProvider(Dali::Scene3D::Loader::ResourceType::Mesh),
-          nullptr,
-          {},
-          {},
-          nullptr,
-          {}};
-        Dali::Scene3D::Loader::DliLoader::LoadParams loadParams{input, mLoadResult};
-        if(!loader.LoadScene(mModelUrl, loadParams))
-        {
-          DALI_LOG_ERROR("Failed to load scene from '%s': %s\n", mModelUrl.c_str(), loader.GetParseError().c_str());
-
-          mModelCacheManager.SetSceneLoaded(mModelUrl, false);
-          mModelCacheManager.SetSceneLoading(mModelUrl, false);
-          mModelCacheManager.UnreferenceModelCache(mModelUrl);
-
-          return;
-        }
+        env.first.mYDirection = Y_DIRECTION;
       }
-      else if(extension == GLTF_EXTENSION)
-      {
-        Dali::Scene3D::Loader::ShaderDefinitionFactory sdf;
-        sdf.SetResources(mLoadResult.mResources);
-        Dali::Scene3D::Loader::LoadGltfScene(mModelUrl, sdf, mLoadResult);
-      }
-      else
-      {
-        DALI_LOG_ERROR("Unsupported model type.\n");
-
-        mModelCacheManager.SetSceneLoaded(mModelUrl, false);
-        mModelCacheManager.SetSceneLoading(mModelUrl, false);
-        mModelCacheManager.UnreferenceModelCache(mModelUrl);
 
-        return;
-      }
-
-      mModelCacheManager.SetSceneLoaded(mModelUrl, true);
       mModelCacheManager.SetSceneLoading(mModelUrl, false);
+      mModelCacheManager.SetSceneLoaded(mModelUrl, loadSucceeded);
     }
   }
 
-  loadSceneConditionalWait.Notify();
-
-  {
-    ConditionalWait::ScopedLock lock(loadRawResourceConditionalWait);
-
-    while(cacheRefCount > 1 && mLoadResult.mResources.mRawResourcesLoading)
-    {
-      loadRawResourceConditionalWait.Wait();
-    }
-  }
-
+  if(!loadSucceeded)
   {
-    ConditionalWait::ScopedLock lock(loadRawResourceConditionalWait);
-
-    mResourceRefCount = std::move(mLoadResult.mResources.CreateRefCounter());
-
-    for(auto iRoot : mLoadResult.mScene.GetRoots())
-    {
-      mLoadResult.mScene.CountResourceRefs(iRoot, mResourceChoices, mResourceRefCount);
-    }
-
-    mLoadResult.mResources.CountEnvironmentReferences(mResourceRefCount);
-
-    mLoadResult.mResources.LoadRawResources(mResourceRefCount, pathProvider);
-
-    // glTF Mesh is defined in right hand coordinate system, with positive Y for Up direction.
-    // Because DALi uses left hand system, Y direciton will be flipped for environment map sampling.
-    for(auto&& env : mLoadResult.mResources.mEnvironmentMaps)
-    {
-      env.first.mYDirection = Y_DIRECTION;
-    }
+    DALI_LOG_ERROR("Failed to load scene from '%s'\n", mModelUrl.c_str());
+    return;
   }
 
-  loadRawResourceConditionalWait.Notify();
-
   mHasSucceeded = true;
 }
 
@@ -195,6 +106,31 @@ bool ModelLoadTask::HasSucceeded() const
   return mHasSucceeded;
 }
 
+Dali::Scene3D::Loader::SceneDefinition& ModelLoadTask::GetScene() const
+{
+  return mModelLoader->GetScene();
+}
+
+Dali::Scene3D::Loader::ResourceBundle& ModelLoadTask::GetResources() const
+{
+  return mModelLoader->GetResources();
+}
+
+std::vector<Dali::Scene3D::Loader::AnimationDefinition>& ModelLoadTask::GetAnimations() const
+{
+  return mModelLoader->GetAnimations();
+}
+
+std::vector<Dali::Scene3D::Loader::CameraParameters>& ModelLoadTask::GetCameras() const
+{
+  return mModelLoader->GetCameras();
+}
+
+Dali::Scene3D::Loader::Customization::Choices& ModelLoadTask::GetResourceChoices()
+{
+  return mModelLoader->GetResourceChoices();
+}
+
 } // namespace Internal
 
 } // namespace Scene3D
index bfafeb0..a880748 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/async-task-manager.h>
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/images/pixel-data.h>
@@ -26,9 +27,9 @@
 // INTERNAL INCLUDES
 #include <dali-scene3d/internal/common/model-cache-manager.h>
 #include <dali-scene3d/public-api/loader/load-result.h>
+#include <dali-scene3d/public-api/loader/model-loader.h>
 #include <dali-scene3d/public-api/loader/scene-definition.h>
 #include <dali/devel-api/threading/conditional-wait.h>
-#include <dali/public-api/adaptor-framework/async-task-manager.h>
 
 namespace Dali
 {
@@ -72,6 +73,36 @@ public:
    */
   bool HasSucceeded() const;
 
+  /**
+   * @brief Retrieves loaded scene
+   * @return SceneDefinition that is loaded from file
+   */
+  Dali::Scene3D::Loader::SceneDefinition& GetScene() const;
+
+  /**
+   * @brief Retrieves resource bunder that includes resource information
+   * @return ResourceBundle for model resources
+   */
+  Dali::Scene3D::Loader::ResourceBundle& GetResources() const;
+
+  /**
+   * @brief Retrieves loaded AnimationDefinition
+   * @return AnimationDefinition that is loaded from file
+   */
+  std::vector<Dali::Scene3D::Loader::AnimationDefinition>& GetAnimations() const;
+
+  /**
+   * @brief Retrieves loaded CameraParameters
+   * @return CameraParameters list that is loaded from file
+   */
+  std::vector<Dali::Scene3D::Loader::CameraParameters>& GetCameras() const;
+
+  /**
+   * @brief Retrieves ResourceChoices
+   * @return Choices for loaded Resources
+   */
+  Dali::Scene3D::Loader::Customization::Choices& GetResourceChoices();
+
 private:
   // Undefined
   ModelLoadTask(const ModelLoadTask& task) = delete;
@@ -79,16 +110,12 @@ private:
   // Undefined
   ModelLoadTask& operator=(const ModelLoadTask& task) = delete;
 
-public:
-  std::string mModelUrl;
-  std::string mResourceDirectoryUrl;
-
-  Dali::Scene3D::Loader::Customization::Choices mResourceChoices;
-  Dali::Scene3D::Loader::ResourceRefCounts      mResourceRefCount;
-  bool                                          mHasSucceeded;
-
-  ModelCacheManager                 mModelCacheManager;
-  Dali::Scene3D::Loader::LoadResult mLoadResult;
+  std::string                                         mModelUrl;
+  std::string                                         mResourceDirectoryUrl;
+  std::shared_ptr<Dali::Scene3D::Loader::ModelLoader> mModelLoader;
+  ModelCacheManager                                   mModelCacheManager;
+  Dali::Scene3D::Loader::LoadResult                   mLoadResult;
+  bool                                                mHasSucceeded;
 };
 
 } // namespace Internal
index b7cb6ef..5aa4a5f 100644 (file)
@@ -36,8 +36,6 @@
 #include <dali-scene3d/public-api/controls/model/model.h>
 #include <dali-scene3d/public-api/loader/animation-definition.h>
 #include <dali-scene3d/public-api/loader/camera-parameters.h>
-#include <dali-scene3d/public-api/loader/dli-loader.h>
-#include <dali-scene3d/public-api/loader/gltf2-loader.h>
 #include <dali-scene3d/public-api/loader/light-parameters.h>
 #include <dali-scene3d/public-api/loader/load-result.h>
 #include <dali-scene3d/public-api/loader/node-definition.h>
@@ -117,7 +115,8 @@ void ConfigureBlendShapeShaders(
   Dali::Scene3D::Loader::ResourceBundle& resources, const Dali::Scene3D::Loader::SceneDefinition& scene, Actor root, std::vector<Dali::Scene3D::Loader::BlendshapeShaderConfigurationRequest>&& requests)
 {
   std::vector<std::string> errors;
-  auto                     onError = [&errors](const std::string& msg) { errors.push_back(msg); };
+  auto                     onError = [&errors](const std::string& msg)
+  { errors.push_back(msg); };
   if(!scene.ConfigureBlendshapeShaders(resources, root, std::move(requests), onError))
   {
     Dali::Scene3D::Loader::ExceptionFlinger flinger(ASSERT_LOCATION);
@@ -447,8 +446,6 @@ void Model::OnSceneConnection(int depth)
     {
       ModelCacheManager::Get().ReferenceModelCache(mModelUrl);
     }
-
-    Scene3D::Loader::InitializeGltfLoader();
     mModelLoadTask = new ModelLoadTask(mModelUrl, mResourceDirectoryUrl, MakeCallback(this, &Model::OnModelLoadComplete));
     Dali::AsyncTaskManager::Get().AddTask(mModelLoadTask);
   }
@@ -732,13 +729,14 @@ void Model::OnModelLoadComplete()
   mRenderableActors.clear();
   CollectRenderableActor(mModelRoot);
 
-  CreateAnimations(mModelLoadTask->mLoadResult.mScene);
+  auto& resources = mModelLoadTask->GetResources();
+  auto& scene     = mModelLoadTask->GetScene();
+  CreateAnimations(scene);
   ResetCameraParameters();
-
-  if(!mModelLoadTask->mLoadResult.mResources.mEnvironmentMaps.empty())
+  if(!resources.mEnvironmentMaps.empty())
   {
-    mDefaultDiffuseTexture  = mModelLoadTask->mLoadResult.mResources.mEnvironmentMaps.front().second.mDiffuse;
-    mDefaultSpecularTexture = mModelLoadTask->mLoadResult.mResources.mEnvironmentMaps.front().second.mSpecular;
+    mDefaultDiffuseTexture  = resources.mEnvironmentMaps.front().second.mDiffuse;
+    mDefaultSpecularTexture = resources.mEnvironmentMaps.front().second.mSpecular;
   }
 
   UpdateImageBasedLightTexture();
@@ -820,26 +818,28 @@ void Model::CreateModel()
   mModelRoot.SetProperty(Actor::Property::COLOR_MODE, ColorMode::USE_OWN_MULTIPLY_PARENT_COLOR);
 
   BoundingVolume                                      AABB;
+  auto&                                               resources        = mModelLoadTask->GetResources();
+  auto&                                               scene            = mModelLoadTask->GetScene();
+  auto&                                               resourceChoices  = mModelLoadTask->GetResourceChoices();
   Dali::Scene3D::Loader::Transforms                   xforms{Dali::Scene3D::Loader::MatrixStack{}, Dali::Scene3D::Loader::ViewProjection{}};
-  Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{mModelLoadTask->mLoadResult.mResources, xforms, {}, {}, {}};
+  Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{resources, xforms, {}, {}, {}};
 
   // Generate Dali handles from resource bundle. Note that we generate all scene's resouce immediatly.
-  mModelLoadTask->mLoadResult.mResources.GenerateResources(mModelLoadTask->mResourceRefCount);
-
-  for(auto iRoot : mModelLoadTask->mLoadResult.mScene.GetRoots())
+  resources.GenerateResources();
+  for(auto iRoot : scene.GetRoots())
   {
-    if(auto actor = mModelLoadTask->mLoadResult.mScene.CreateNodes(iRoot, mModelLoadTask->mResourceChoices, nodeParams))
+    if(auto actor = scene.CreateNodes(iRoot, resourceChoices, nodeParams))
     {
-      mModelLoadTask->mLoadResult.mScene.ConfigureSkeletonJoints(iRoot, mModelLoadTask->mLoadResult.mResources.mSkeletons, actor);
-      mModelLoadTask->mLoadResult.mScene.ConfigureSkinningShaders(mModelLoadTask->mLoadResult.mResources, actor, std::move(nodeParams.mSkinnables));
-      ConfigureBlendShapeShaders(mModelLoadTask->mLoadResult.mResources, mModelLoadTask->mLoadResult.mScene, actor, std::move(nodeParams.mBlendshapeRequests));
+      scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
+      scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
+      ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests));
 
-      mModelLoadTask->mLoadResult.mScene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
+      scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
 
       mModelRoot.Add(actor);
     }
 
-    AddModelTreeToAABB(AABB, mModelLoadTask->mLoadResult.mScene, mModelLoadTask->mResourceChoices, iRoot, nodeParams, Matrix::IDENTITY);
+    AddModelTreeToAABB(AABB, scene, resourceChoices, iRoot, nodeParams, Matrix::IDENTITY);
   }
 
   mNaturalSize = AABB.CalculateSize();
@@ -857,9 +857,10 @@ void Model::CreateModel()
 void Model::CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene)
 {
   mAnimations.clear();
-  if(!mModelLoadTask->mLoadResult.mAnimationDefinitions.empty())
+  if(!mModelLoadTask->GetAnimations().empty())
   {
-    auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property) {
+    auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property)
+    {
       if(property.mNodeIndex == Scene3D::Loader::INVALID_INDEX)
       {
         return mModelRoot.FindChildByName(property.mNodeName);
@@ -872,7 +873,7 @@ void Model::CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene)
       return mModelRoot.FindChildById(node->mNodeId);
     };
 
-    for(auto&& animation : mModelLoadTask->mLoadResult.mAnimationDefinitions)
+    for(auto&& animation : mModelLoadTask->GetAnimations())
     {
       Dali::Animation anim = animation.ReAnimate(getActor);
       mAnimations.push_back({animation.mName, anim});
@@ -883,10 +884,10 @@ void Model::CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene)
 void Model::ResetCameraParameters()
 {
   mCameraParameters.clear();
-  if(!mModelLoadTask->mLoadResult.mCameraParameters.empty())
+  if(!mModelLoadTask->GetCameras().empty())
   {
     // Copy camera parameters.
-    std::copy(mModelLoadTask->mLoadResult.mCameraParameters.begin(), mModelLoadTask->mLoadResult.mCameraParameters.end(), std::back_inserter(mCameraParameters));
+    std::copy(mModelLoadTask->GetCameras().begin(), mModelLoadTask->GetCameras().end(), std::back_inserter(mCameraParameters));
   }
 }
 
index cd1daf5..939de84 100644 (file)
@@ -263,11 +263,6 @@ private:
   void ResetResourceTask(IntrusivePtr<AsyncTask> asyncTask);
 
   /**
-   * @brief Request to load a Ibl texture asynchronously
-   */
-  void RequestLoadIblTexture(EnvironmentMapLoadTaskPtr asyncLoadTask, const std::string& url);
-
-  /**
    * @brief Notify Resource Ready signal.
    */
   void NotifyResourceReady();
index 85b5cbc..7a6c868 100644 (file)
@@ -10,7 +10,11 @@ set(scene3d_src_files ${scene3d_src_files}
        ${scene3d_internal_dir}/common/model-load-task.cpp
        ${scene3d_internal_dir}/controls/model/model-impl.cpp
        ${scene3d_internal_dir}/controls/scene-view/scene-view-impl.cpp
+       ${scene3d_internal_dir}/loader/dli-loader-impl.cpp
        ${scene3d_internal_dir}/loader/gltf2-asset.cpp
+       ${scene3d_internal_dir}/loader/gltf2-util.cpp
+       ${scene3d_internal_dir}/loader/gltf2-loader-impl.cpp
+       ${scene3d_internal_dir}/loader/glb-loader-impl.cpp
        ${scene3d_internal_dir}/loader/hash.cpp
        ${scene3d_internal_dir}/loader/json-reader.cpp
        ${scene3d_internal_dir}/loader/json-util.cpp
  */
 
 // CLASS HEADER
-#include "dali-scene3d/public-api/loader/dli-loader.h"
+#include <dali-scene3d/internal/loader/dli-loader-impl.h>
 
 // EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/builder/json-parser.h>
+#include <dali/devel-api/common/map-wrapper.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/object/property-array.h>
+
 #include <algorithm>
 #include <cmath>
+#include <filesystem>
 #include <fstream>
 #include <limits>
 #include <memory>
-#include "dali-toolkit/devel-api/builder/json-parser.h"
-#include "dali/devel-api/common/map-wrapper.h"
-#include "dali/integration-api/debug.h"
-#include "dali/public-api/object/property-array.h"
 
 // INTERNAL INCLUDES
-#include "dali-scene3d/internal/loader/json-util.h"
-#include "dali-scene3d/public-api/loader/alpha-function-helper.h"
-#include "dali-scene3d/public-api/loader/animation-definition.h"
-#include "dali-scene3d/public-api/loader/blend-shape-details.h"
-#include "dali-scene3d/public-api/loader/camera-parameters.h"
-#include "dali-scene3d/public-api/loader/ktx-loader.h"
-#include "dali-scene3d/public-api/loader/light-parameters.h"
-#include "dali-scene3d/public-api/loader/load-result.h"
-#include "dali-scene3d/public-api/loader/parse-renderer-state.h"
-#include "dali-scene3d/public-api/loader/scene-definition.h"
-#include "dali-scene3d/public-api/loader/skinning-details.h"
-#include "dali-scene3d/public-api/loader/utils.h"
+#include <dali-scene3d/internal/loader/json-util.h>
+#include <dali-scene3d/public-api/loader/alpha-function-helper.h>
+#include <dali-scene3d/public-api/loader/animation-definition.h>
+#include <dali-scene3d/public-api/loader/blend-shape-details.h>
+#include <dali-scene3d/public-api/loader/camera-parameters.h>
+#include <dali-scene3d/public-api/loader/ktx-loader.h>
+#include <dali-scene3d/public-api/loader/light-parameters.h>
+#include <dali-scene3d/public-api/loader/load-result.h>
+#include <dali-scene3d/public-api/loader/parse-renderer-state.h>
+#include <dali-scene3d/public-api/loader/scene-definition.h>
+#include <dali-scene3d/public-api/loader/skinning-details.h>
+#include <dali-scene3d/public-api/loader/utils.h>
 
 #define DLI_0_1_COMPATIBILITY
 
@@ -53,6 +55,8 @@ namespace Scene3D
 {
 namespace Loader
 {
+namespace Internal
+{
 namespace rs = RendererState;
 
 namespace
@@ -109,7 +113,7 @@ bool ReadAttribAccessor(const TreeNode* node, MeshDefinition::Accessor& accessor
   return ReadBlob(node, accessor.mBlob.mOffset, accessor.mBlob.mLength);
 }
 
-bool ReadColorCode(const TreeNode* node, Vector4& color, DliLoader::ConvertColorCode convertColorCode)
+bool ReadColorCode(const TreeNode* node, Vector4& color, DliInputParameter::ConvertColorCode convertColorCode)
 {
   if(!node || !convertColorCode)
   {
@@ -121,7 +125,7 @@ bool ReadColorCode(const TreeNode* node, Vector4& color, DliLoader::ConvertColor
   return true;
 }
 
-bool ReadColorCodeOrColor(const TreeNode* node, Vector4& color, DliLoader::ConvertColorCode convertColorCode)
+bool ReadColorCodeOrColor(const TreeNode* node, Vector4& color, DliInputParameter::ConvertColorCode convertColorCode)
 {
   return ReadColorCode(node->GetChild("colorCode"), color, convertColorCode) ||
          ReadColor(node->GetChild("color"), color);
@@ -302,7 +306,7 @@ void ParseProperties(const Toolkit::TreeNode& node, Property::Array& array)
 
 } // namespace
 
-struct DliLoader::Impl
+struct DliLoaderImpl::Impl
 {
   StringCallback      mOnError = DefaultErrorCallback;
   Toolkit::JsonParser mParser;
@@ -342,9 +346,9 @@ private:
    */
   void ParseSceneInternal(Index iScene, const Toolkit::TreeNode* tnScenes, const Toolkit::TreeNode* tnNodes, LoadParams& params);
 
-  void ParseSkeletons(const Toolkit::TreeNode* skeletons, SceneDefinition& scene, ResourceBundle& resources);
-  void ParseEnvironments(const Toolkit::TreeNode* environments, ResourceBundle& resources);
-  void ParseMaterials(const Toolkit::TreeNode* materials, ConvertColorCode convertColorCode, ResourceBundle& resources);
+  void ParseSkeletons(const Toolkit::TreeNode* skeletons, Dali::Scene3D::Loader::SceneDefinition& scene, Dali::Scene3D::Loader::ResourceBundle& resources);
+  void ParseEnvironments(const Toolkit::TreeNode* environments, Dali::Scene3D::Loader::ResourceBundle& resources);
+  void ParseMaterials(const Toolkit::TreeNode* materials, DliInputParameter::ConvertColorCode convertColorCode, Dali::Scene3D::Loader::ResourceBundle& resources);
 
   void ParseNodes(const Toolkit::TreeNode* nodes, Index index, LoadParams& params);
   void ParseNodesInternal(const Toolkit::TreeNode* nodes, Index index, std::vector<Index>& inOutParentStack, LoadParams& params, IIndexMapper& indexMapper);
@@ -352,26 +356,26 @@ private:
   void ParseAnimations(const Toolkit::TreeNode* animations, LoadParams& params);
   void ParseAnimationGroups(const Toolkit::TreeNode* animationGroups, LoadParams& params);
 
-  void ParseShaders(const Toolkit::TreeNode* shaders, ResourceBundle& resources);
-  void ParseMeshes(const Toolkit::TreeNode* meshes, ResourceBundle& resources);
+  void ParseShaders(const Toolkit::TreeNode* shaders, Dali::Scene3D::Loader::ResourceBundle& resources);
+  void ParseMeshes(const Toolkit::TreeNode* meshes, Dali::Scene3D::Loader::ResourceBundle& resources);
 
-  void GetCameraParameters(std::vector<CameraParameters>& cameras) const;
-  void GetLightParameters(std::vector<LightParameters>& lights) const;
+  void GetCameraParameters(std::vector<Dali::Scene3D::Loader::CameraParameters>& cameras) const;
+  void GetLightParameters(std::vector<Dali::Scene3D::Loader::LightParameters>& lights) const;
 };
 
-DliLoader::DliLoader()
+DliLoaderImpl::DliLoaderImpl()
 : mImpl{new Impl}
 {
 }
 
-DliLoader::~DliLoader() = default;
+DliLoaderImpl::~DliLoaderImpl() = default;
 
-void DliLoader::SetErrorCallback(StringCallback onError)
+void DliLoaderImpl::SetErrorCallback(StringCallback onError)
 {
   mImpl->mOnError = onError;
 }
 
-bool DliLoader::LoadScene(const std::string& uri, LoadParams& params)
+bool DliLoaderImpl::LoadModel(const std::string& uri, Dali::Scene3D::Loader::LoadResult& result)
 {
   std::string daliBuffer = LoadTextFile(uri.c_str());
 
@@ -382,11 +386,25 @@ bool DliLoader::LoadScene(const std::string& uri, LoadParams& params)
     return false;
   }
 
-  mImpl->ParseScene(params);
+  std::filesystem::path                    modelPath(uri);
+  Dali::Scene3D::Loader::DliInputParameter input;
+  LoadParams                               loadParams;
+  if(mInputParameter)
+  {
+    loadParams.input = static_cast<DliInputParameter*>(mInputParameter);
+  }
+  else
+  {
+    input.mAnimationsPath = std::string(modelPath.parent_path()) + "/";
+    loadParams.input      = &input;
+  }
+  loadParams.output = &result;
+
+  mImpl->ParseScene(loadParams);
   return true;
 }
 
-std::string DliLoader::GetParseError() const
+std::string DliLoaderImpl::GetParseError() const
 {
   std::stringstream stream;
 
@@ -399,10 +417,10 @@ std::string DliLoader::GetParseError() const
   return stream.str();
 }
 
-void DliLoader::Impl::ParseScene(LoadParams& params)
+void DliLoaderImpl::Impl::ParseScene(LoadParams& params)
 {
-  auto& input  = params.input;
-  auto& output = params.output;
+  auto& input  = *params.input;
+  auto& output = *params.output;
 
   // get index of root node.
   auto docRoot = mParser.GetRoot();
@@ -482,7 +500,7 @@ void DliLoader::Impl::ParseScene(LoadParams& params)
   }
 }
 
-void DliLoader::Impl::ParseSceneInternal(Index iScene, const Toolkit::TreeNode* tnScenes, const Toolkit::TreeNode* tnNodes, LoadParams& params)
+void DliLoaderImpl::Impl::ParseSceneInternal(Index iScene, const Toolkit::TreeNode* tnScenes, const Toolkit::TreeNode* tnNodes, LoadParams& params)
 {
   auto getSceneRootIdx = [tnScenes, tnNodes](Index iScene) {
     auto tn = GetNthChild(tnScenes, iScene); // now a "scene" object
@@ -526,7 +544,7 @@ void DliLoader::Impl::ParseSceneInternal(Index iScene, const Toolkit::TreeNode*
   Index iRootNode = getSceneRootIdx(iScene);
   ParseNodes(tnNodes, iRootNode, params);
 
-  auto& scene = params.output.mScene;
+  auto& scene = params.output->mScene;
   scene.AddRootNode(0);
 
   for(Index i = 0; i < iScene; ++i)
@@ -547,7 +565,7 @@ void DliLoader::Impl::ParseSceneInternal(Index iScene, const Toolkit::TreeNode*
   }
 }
 
-void DliLoader::Impl::ParseSkeletons(const TreeNode* skeletons, SceneDefinition& scene, ResourceBundle& resources)
+void DliLoaderImpl::Impl::ParseSkeletons(const TreeNode* skeletons, Dali::Scene3D::Loader::SceneDefinition& scene, Dali::Scene3D::Loader::ResourceBundle& resources)
 {
   if(skeletons)
   {
@@ -611,7 +629,7 @@ void DliLoader::Impl::ParseSkeletons(const TreeNode* skeletons, SceneDefinition&
   }
 }
 
-void DliLoader::Impl::ParseEnvironments(const TreeNode* environments, ResourceBundle& resources)
+void DliLoaderImpl::Impl::ParseEnvironments(const TreeNode* environments, Dali::Scene3D::Loader::ResourceBundle& resources)
 {
   Matrix cubeOrientation(Matrix::IDENTITY);
 
@@ -641,7 +659,7 @@ void DliLoader::Impl::ParseEnvironments(const TreeNode* environments, ResourceBu
   }
 }
 
-void DliLoader::Impl::ParseShaders(const TreeNode* shaders, ResourceBundle& resources)
+void DliLoaderImpl::Impl::ParseShaders(const TreeNode* shaders, Dali::Scene3D::Loader::ResourceBundle& resources)
 {
   uint32_t iShader = 0;
   for(auto i0 = shaders->CBegin(), i1 = shaders->CEnd(); i0 != i1; ++i0, ++iShader)
@@ -760,7 +778,7 @@ void DliLoader::Impl::ParseShaders(const TreeNode* shaders, ResourceBundle& reso
   }
 }
 
-void DliLoader::Impl::ParseMeshes(const TreeNode* meshes, ResourceBundle& resources)
+void DliLoaderImpl::Impl::ParseMeshes(const TreeNode* meshes, Dali::Scene3D::Loader::ResourceBundle& resources)
 {
   for(auto i0 = meshes->CBegin(), i1 = meshes->CEnd(); i0 != i1; ++i0)
   {
@@ -918,7 +936,7 @@ void DliLoader::Impl::ParseMeshes(const TreeNode* meshes, ResourceBundle& resour
   }
 }
 
-void DliLoader::Impl::ParseMaterials(const TreeNode* materials, ConvertColorCode convertColorCode, ResourceBundle& resources)
+void DliLoaderImpl::Impl::ParseMaterials(const TreeNode* materials, DliInputParameter::ConvertColorCode convertColorCode, Dali::Scene3D::Loader::ResourceBundle& resources)
 {
   for(auto i0 = materials->CBegin(), i1 = materials->CEnd(); i0 != i1; ++i0)
   {
@@ -1048,7 +1066,7 @@ void DliLoader::Impl::ParseMaterials(const TreeNode* materials, ConvertColorCode
   }
 }
 
-void DliLoader::Impl::ParseNodes(const TreeNode* const nodes, Index index, LoadParams& params)
+void DliLoaderImpl::Impl::ParseNodes(const TreeNode* const nodes, Index index, LoadParams& params)
 {
   std::vector<Index> parents;
   parents.reserve(8);
@@ -1097,7 +1115,7 @@ void DliLoader::Impl::ParseNodes(const TreeNode* const nodes, Index index, LoadP
   } mapper(nodes->Size());
   ParseNodesInternal(nodes, index, parents, params, mapper);
 
-  auto& scene = params.output.mScene;
+  auto& scene = params.output->mScene;
   for(size_t i0 = 0, i1 = scene.GetNodeCount(); i0 < i1; ++i0)
   {
     for(auto& c : scene.GetNode(i0)->mConstraints)
@@ -1107,7 +1125,7 @@ void DliLoader::Impl::ParseNodes(const TreeNode* const nodes, Index index, LoadP
   }
 }
 
-void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index index, std::vector<Index>& inOutParentStack, LoadParams& params, IIndexMapper& mapper)
+void DliLoaderImpl::Impl::ParseNodesInternal(const TreeNode* const nodes, Index index, std::vector<Index>& inOutParentStack, LoadParams& params, IIndexMapper& mapper)
 {
   // Properties that may be resolved from a JSON value with ReadInt() -- or default to 0.
   struct IndexProperty
@@ -1121,7 +1139,7 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde
 
   if(auto node = GetNthChild(nodes, index))
   {
-    NodeDefinition nodeDef;
+    Dali::Scene3D::Loader::NodeDefinition nodeDef;
     nodeDef.mParentIdx = inOutParentStack.empty() ? INVALID_INDEX : inOutParentStack.back();
 
     // name
@@ -1151,13 +1169,13 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde
       std::string tag;
       if(ReadString(eCustomization->GetChild("tag"), tag))
       {
-        nodeDef.mCustomization.reset(new NodeDefinition::CustomizationDefinition{tag});
+        nodeDef.mCustomization.reset(new Dali::Scene3D::Loader::NodeDefinition::CustomizationDefinition{tag});
       }
     }
     else // something renderable maybe
     {
-      std::unique_ptr<NodeDefinition::Renderable> renderable;
-      ModelRenderable*                            modelRenderable = nullptr; // no ownership, aliasing renderable for the right type.
+      std::unique_ptr<Dali::Scene3D::Loader::NodeDefinition::Renderable> renderable;
+      ModelRenderable*                                                   modelRenderable = nullptr; // no ownership, aliasing renderable for the right type.
 
       const TreeNode* eRenderable = nullptr;
       if((eRenderable = node->GetChild("model")))
@@ -1212,9 +1230,9 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde
             resourceIds.push_back({ResourceType::Material, eMaterial, modelRenderable->mMaterialIdx});
           }
 
-          if(!ReadColorCodeOrColor(eRenderable, modelRenderable->mColor, params.input.mConvertColorCode))
+          if(!ReadColorCodeOrColor(eRenderable, modelRenderable->mColor, params.input->mConvertColorCode))
           {
-            ReadColorCodeOrColor(node, modelRenderable->mColor, params.input.mConvertColorCode);
+            ReadColorCodeOrColor(node, modelRenderable->mColor, params.input->mConvertColorCode);
           }
         }
 
@@ -1230,15 +1248,15 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde
       switch(idRes.type)
       {
         case ResourceType::Shader:
-          iCheck = output.mResources.mShaders.size();
+          iCheck = output->mResources.mShaders.size();
           break;
 
         case ResourceType::Mesh:
-          iCheck = output.mResources.mMeshes.size();
+          iCheck = output->mResources.mMeshes.size();
           break;
 
         case ResourceType::Material:
-          iCheck = output.mResources.mMaterials.size();
+          iCheck = output->mResources.mMaterials.size();
           break;
 
         default:
@@ -1273,7 +1291,7 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde
 
       for(auto i0 = eExtras->CBegin(), i1 = eExtras->CEnd(); i0 != i1; ++i0)
       {
-        NodeDefinition::Extra e;
+        Dali::Scene3D::Loader::NodeDefinition::Extra e;
 
         auto eExtra = *i0;
         e.mKey      = eExtra.first;
@@ -1350,7 +1368,7 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde
     }
 
     // Determine index for mapping
-    const unsigned int myIndex = output.mScene.GetNodeCount();
+    const unsigned int myIndex = output->mScene.GetNodeCount();
     if(!mapper.Map(index, myIndex))
     {
       mOnError(FormatString("node %d: error mapping dli index %d: node has multiple parents. Ignoring subtree.", index, myIndex));
@@ -1365,7 +1383,7 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde
     }
 
     // Register nodeDef
-    auto rawDef = output.mScene.AddNode(std::make_unique<NodeDefinition>(std::move(nodeDef)));
+    auto rawDef = output->mScene.AddNode(std::make_unique<Dali::Scene3D::Loader::NodeDefinition>(std::move(nodeDef)));
     if(rawDef) // NOTE: no ownership. Guaranteed to stay in scope.
     {
       // ...And only then parse children.
@@ -1396,7 +1414,7 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde
         mOnError(FormatString("node %d: not an actual customization without children.", index));
       }
 
-      if(auto proc = params.input.mNodePropertyProcessor) // optional processing
+      if(auto proc = params.input->mNodePropertyProcessor) // optional processing
       {
         // WARNING: constraint IDs are not resolved at this point.
         Property::Map nodeData;
@@ -1411,9 +1429,9 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde
   }
 }
 
-void DliLoader::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams& params)
+void DliLoaderImpl::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams& params)
 {
-  auto& definitions = params.output.mAnimationDefinitions;
+  auto& definitions = params.output->mAnimationDefinitions;
   definitions.reserve(definitions.size() + tnAnimations->Size());
 
   for(TreeNode::ConstIterator iAnim = tnAnimations->CBegin(), iAnimEnd = tnAnimations->CEnd();
@@ -1532,7 +1550,7 @@ void DliLoader::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams&
           std::string   animationFilename;
           if(ReadString(tnKeyFramesBin->GetChild(URL), animationFilename))
           {
-            std::string animationFullPath = params.input.mAnimationsPath + animationFilename;
+            std::string animationFullPath = params.input->mAnimationsPath + animationFilename;
             binAniFile.open(animationFullPath, std::ios::binary);
             if(binAniFile.fail())
             {
@@ -1663,7 +1681,7 @@ void DliLoader::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams&
       iFind = definitions.insert(iFind, std::move(animDef));
     }
 
-    if(auto proc = params.input.mAnimationPropertyProcessor) // optional processing
+    if(auto proc = params.input->mAnimationPropertyProcessor) // optional processing
     {
       Property::Map map;
       ParseProperties(tnAnim, map);
@@ -1672,9 +1690,9 @@ void DliLoader::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams&
   }
 }
 
-void DliLoader::Impl::ParseAnimationGroups(const Toolkit::TreeNode* tnAnimationGroups, LoadParams& params)
+void DliLoaderImpl::Impl::ParseAnimationGroups(const Toolkit::TreeNode* tnAnimationGroups, LoadParams& params)
 {
-  auto& animGroups = params.output.mAnimationGroupDefinitions;
+  auto& animGroups = params.output->mAnimationGroupDefinitions;
 
   int numGroups = 0;
   for(auto iGroups = tnAnimationGroups->CBegin(), iGroupsEnd = tnAnimationGroups->CEnd();
@@ -1715,7 +1733,7 @@ void DliLoader::Impl::ParseAnimationGroups(const Toolkit::TreeNode* tnAnimationG
   }
 }
 
-void DliLoader::Impl::GetCameraParameters(std::vector<CameraParameters>& cameras) const
+void DliLoaderImpl::Impl::GetCameraParameters(std::vector<Dali::Scene3D::Loader::CameraParameters>& cameras) const
 {
   if(mParser.GetRoot())
   {
@@ -1751,7 +1769,7 @@ void DliLoader::Impl::GetCameraParameters(std::vector<CameraParameters>& cameras
   }
 }
 
-void DliLoader::Impl::GetLightParameters(std::vector<LightParameters>& lights) const
+void DliLoaderImpl::Impl::GetLightParameters(std::vector<Dali::Scene3D::Loader::LightParameters>& lights) const
 {
   if(mParser.GetRoot())
   {
@@ -1821,6 +1839,7 @@ void DliLoader::Impl::GetLightParameters(std::vector<LightParameters>& lights) c
   }
 }
 
+} // namespace Internal
 } // namespace Loader
 } // namespace Scene3D
 } // namespace Dali
diff --git a/dali-scene3d/internal/loader/dli-loader-impl.h b/dali-scene3d/internal/loader/dli-loader-impl.h
new file mode 100644 (file)
index 0000000..ba6b117
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef DALI_SCENE3D_LOADER_DLI_LOADER_IMPL_H
+#define DALI_SCENE3D_LOADER_DLI_LOADER_IMPL_H
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/loader/model-loader-impl.h>
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/animation-definition.h>
+#include <dali-scene3d/public-api/loader/customization.h>
+#include <dali-scene3d/public-api/loader/dli-input-parameter.h>
+#include <dali-scene3d/public-api/loader/index.h>
+#include <dali-scene3d/public-api/loader/node-definition.h>
+#include <dali-scene3d/public-api/loader/string-callback.h>
+
+namespace Dali::Scene3D::Loader::Internal
+{
+typedef std::pair<std::string, std::string> Metadata;
+
+// Forward declarations
+struct LoadResult;
+
+class DliLoaderImpl : public ModelLoaderImpl
+{
+public:
+  struct LoadParams
+  {
+    Dali::Scene3D::Loader::DliInputParameter* input;
+    Dali::Scene3D::Loader::LoadResult*        output;
+  };
+
+  DliLoaderImpl();
+  ~DliLoaderImpl();
+
+  /**
+   * @brief Sets the callback that messages from non-fatal errors get posted to.
+   *  Uses DefaultErrorCallback by default.
+   */
+  void SetErrorCallback(StringCallback onError);
+
+  /**
+   * @copydoc Dali::Scene3D::Loader::Internal::ModelLoaderImpl::LoadMode()
+   */
+  bool LoadModel(const std::string& uri, Dali::Scene3D::Loader::LoadResult& result) override;
+
+  /**
+   * @return The error string describing how the parse has failed, if any.
+   */
+  std::string GetParseError() const;
+
+private:
+  struct Impl;
+  const std::unique_ptr<Impl> mImpl;
+};
+
+} // namespace Dali::Scene3D::Loader::Internal
+
+#endif // DALI_SCENE3D_LOADER_DLI_LOADER_IMPL_H
diff --git a/dali-scene3d/internal/loader/glb-loader-impl.cpp b/dali-scene3d/internal/loader/glb-loader-impl.cpp
new file mode 100644 (file)
index 0000000..deaa91e
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-scene3d/internal/loader/glb-loader-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/file-stream.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/loader/gltf2-util.h>
+#include <dali-scene3d/public-api/loader/load-result.h>
+#include <dali-scene3d/public-api/loader/utils.h>
+
+namespace gt = gltf2;
+namespace js = json;
+
+namespace Dali::Scene3D::Loader::Internal
+{
+namespace
+{
+static constexpr uint32_t GLB_MAGIC       = 0x46546C67;
+static constexpr uint32_t JSON_CHUNK_TYPE = 0x4E4F534A;
+static constexpr uint32_t DATA_CHUNK_TYPE = 0x004E4942;
+
+struct GlbHeader
+{
+  uint32_t magic;
+  uint32_t version;
+  uint32_t length;
+};
+
+struct ChunkHeader
+{
+  uint32_t chunkLength;
+  uint32_t chunkType;
+};
+
+} // namespace
+
+bool GlbLoaderImpl::LoadModel(const std::string& url, Dali::Scene3D::Loader::LoadResult& result)
+{
+  Dali::FileStream fileStream(url, FileStream::READ | FileStream::BINARY);
+  auto&            stream = fileStream.GetStream();
+  if(!stream.rdbuf()->in_avail())
+  {
+    DALI_LOG_ERROR("Load Model file is failed, url : %s\n", url.c_str());
+    return false;
+  }
+
+  GlbHeader glbHeader;
+  stream.clear();
+  stream.seekg(0u, stream.beg);
+  stream.read(reinterpret_cast<char*>(&glbHeader), sizeof(GlbHeader));
+
+  if(glbHeader.magic != GLB_MAGIC)
+  {
+    DALI_LOG_ERROR("Wrong file format, url : %s\n", url.c_str());
+    return false;
+  }
+
+  ChunkHeader jsonChunkHeader;
+  stream.read(reinterpret_cast<char*>(&jsonChunkHeader), sizeof(ChunkHeader));
+
+  if(jsonChunkHeader.chunkType != JSON_CHUNK_TYPE)
+  {
+    DALI_LOG_ERROR("Glb files first chunk is not a json chunk.\n");
+    return false;
+  }
+
+  std::vector<uint8_t> jsonChunkData;
+  jsonChunkData.resize(jsonChunkHeader.chunkLength);
+  stream.read(reinterpret_cast<char*>(&jsonChunkData[0]), static_cast<std::streamsize>(static_cast<size_t>(jsonChunkHeader.chunkLength)));
+  std::string gltfText(jsonChunkData.begin(), jsonChunkData.end());
+
+  uint32_t             binaryChunkOffset = sizeof(GlbHeader) + sizeof(ChunkHeader) + jsonChunkHeader.chunkLength;
+  std::vector<uint8_t> binaryChunkData;
+  if(glbHeader.length > binaryChunkOffset)
+  {
+    ChunkHeader binaryChunkHeader;
+    stream.read(reinterpret_cast<char*>(&binaryChunkHeader), sizeof(ChunkHeader));
+
+    if(binaryChunkHeader.chunkType != DATA_CHUNK_TYPE)
+    {
+      DALI_LOG_ERROR("Glb files has wrong binary chunk data.\n");
+      return false;
+    }
+
+    binaryChunkData.resize(binaryChunkHeader.chunkLength);
+    stream.read(reinterpret_cast<char*>(&binaryChunkData[0]), static_cast<std::streamsize>(static_cast<size_t>(binaryChunkHeader.chunkLength)));
+  }
+
+  json::unique_ptr root(json_parse(gltfText.c_str(), gltfText.size()));
+  if(!root)
+  {
+    DALI_LOG_ERROR("Failed to parse %s\n", url.c_str());
+    return false;
+  }
+
+  gt::Document document;
+
+  bool isMRendererModel(false);
+  if(!Gltf2Util::GenerateDocument(root, document, isMRendererModel))
+  {
+    DALI_LOG_ERROR("Failed to parse %s\n", url.c_str());
+    return false;
+  }
+
+  auto                         path = url.substr(0, url.rfind('/') + 1);
+  Gltf2Util::ConversionContext context{result, path, INVALID_INDEX};
+
+  auto& outBuffers = context.mOutput.mResources.mBuffers;
+  outBuffers.reserve(document.mBuffers.size());
+  if(!binaryChunkData.empty())
+  {
+    BufferDefinition dataBuffer(binaryChunkData);
+    outBuffers.emplace_back(std::move(dataBuffer));
+  }
+
+  Gltf2Util::ConvertGltfToContext(document, context, isMRendererModel);
+
+  return true;
+}
+
+} // namespace Dali::Scene3D::Loader::Internal
diff --git a/dali-scene3d/internal/loader/glb-loader-impl.h b/dali-scene3d/internal/loader/glb-loader-impl.h
new file mode 100644 (file)
index 0000000..05c9d9c
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef DALI_SCENE3D_LOADER_GLB_LOADER_IMPL_H
+#define DALI_SCENE3D_LOADER_GLB_LOADER_IMPL_H
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/threading/mutex.h>
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/loader/model-loader-impl.h>
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader::Internal
+{
+class GlbLoaderImpl : public ModelLoaderImpl
+{
+public:
+  /**
+   * @copydoc Dali::Scene3D::Loader::Internal::ModelLoaderImpl::LoadMode()
+   */
+  bool LoadModel(const std::string& url, Dali::Scene3D::Loader::LoadResult& result) override;
+};
+
+} // namespace Dali::Scene3D::Loader::Internal
+
+#endif // DALI_SCENE3D_LOADER_GLB_LOADER_IMPL_H
index 6576803..7a8af2b 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/internal/loader/json-reader.h>
-#include <dali-scene3d/public-api/loader/index.h>
-
 // EXTERNAL INCLUDES
 #include <dali/devel-api/common/map-wrapper.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <cstdint>
 #include <memory>
 
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/loader/json-reader.h>
+#include <dali-scene3d/public-api/loader/index.h>
+
 #define ENUM_STRING_MAPPING(t, x) \
   {                               \
 #x, t::x                      \
diff --git a/dali-scene3d/internal/loader/gltf2-loader-impl.cpp b/dali-scene3d/internal/loader/gltf2-loader-impl.cpp
new file mode 100644 (file)
index 0000000..d4e0614
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-scene3d/internal/loader/gltf2-loader-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/loader/gltf2-util.h>
+#include <dali-scene3d/public-api/loader/load-result.h>
+#include <dali-scene3d/public-api/loader/utils.h>
+
+namespace gt = gltf2;
+namespace js = json;
+
+namespace Dali::Scene3D::Loader::Internal
+{
+bool Gltf2LoaderImpl::LoadModel(const std::string& url, Dali::Scene3D::Loader::LoadResult& result)
+{
+  bool failed   = false;
+  auto gltfText = LoadTextFile(url.c_str(), &failed);
+  if(failed)
+  {
+    DALI_LOG_ERROR("Failed to load %s\n", url.c_str());
+    return false;
+  }
+
+  json::unique_ptr root(json_parse(gltfText.c_str(), gltfText.size()));
+  if(!root)
+  {
+    DALI_LOG_ERROR("Failed to parse %s\n", url.c_str());
+    return false;
+  }
+
+  gt::Document document;
+
+  bool isMRendererModel(false);
+  if(!Gltf2Util::GenerateDocument(root, document, isMRendererModel))
+  {
+    return false;
+  }
+
+  auto                         path = url.substr(0, url.rfind('/') + 1);
+  Gltf2Util::ConversionContext context{result, path, INVALID_INDEX};
+
+  Gltf2Util::ConvertGltfToContext(document, context, isMRendererModel);
+
+  return true;
+}
+
+} // namespace Dali::Scene3D::Loader::Internal
diff --git a/dali-scene3d/internal/loader/gltf2-loader-impl.h b/dali-scene3d/internal/loader/gltf2-loader-impl.h
new file mode 100644 (file)
index 0000000..a4dfc6e
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef DALI_SCENE3D_LOADER_GLTF2_LOADER_IMPL_H
+#define DALI_SCENE3D_LOADER_GLTF2_LOADER_IMPL_H
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/threading/mutex.h>
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/loader/model-loader-impl.h>
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader::Internal
+{
+class Gltf2LoaderImpl : public ModelLoaderImpl
+{
+public:
+  /**
+   * @copydoc Dali::Scene3D::Loader::Internal::ModelLoaderImpl::LoadMode()
+   */
+  bool LoadModel(const std::string& url, Dali::Scene3D::Loader::LoadResult& result) override;
+};
+
+} // namespace Dali::Scene3D::Loader::Internal
+
+#endif // DALI_SCENE3D_LOADER_GLTF2_LOADER_IMPL_H
diff --git a/dali-scene3d/internal/loader/gltf2-util.cpp b/dali-scene3d/internal/loader/gltf2-util.cpp
new file mode 100644 (file)
index 0000000..96925cc
--- /dev/null
@@ -0,0 +1,1321 @@
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/internal/loader/gltf2-util.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+using namespace Dali::Scene3D::Loader;
+
+namespace Dali::Scene3D::Loader::Internal
+{
+namespace Gltf2Util
+{
+static constexpr std::string_view MRENDERER_MODEL_IDENTIFICATION = "M-Renderer";
+static constexpr std::string_view POSITION_PROPERTY              = "position";
+static constexpr std::string_view ORIENTATION_PROPERTY           = "orientation";
+static constexpr std::string_view SCALE_PROPERTY                 = "scale";
+static constexpr std::string_view BLEND_SHAPE_WEIGHTS_UNIFORM    = "uBlendShapeWeight";
+static constexpr std::string_view ROOT_NODE_NAME                 = "RootNode";
+static const Vector3              SCALE_TO_ADJUST(100.0f, 100.0f, 100.0f);
+
+static const Geometry::Type GLTF2_TO_DALI_PRIMITIVES[]{
+  Geometry::POINTS,
+  Geometry::LINES,
+  Geometry::LINE_LOOP,
+  Geometry::LINE_STRIP,
+  Geometry::TRIANGLES,
+  Geometry::TRIANGLE_STRIP,
+  Geometry::TRIANGLE_FAN}; //...because Dali swaps the last two.
+
+static struct AttributeMapping
+{
+  gltf2::Attribute::Type   mType;
+  MeshDefinition::Accessor MeshDefinition::*mAccessor;
+  uint16_t                                  mElementSizeRequired;
+} ATTRIBUTE_MAPPINGS[]{
+  {gltf2::Attribute::NORMAL, &MeshDefinition::mNormals, sizeof(Vector3)},
+  {gltf2::Attribute::TANGENT, &MeshDefinition::mTangents, sizeof(Vector3)},
+  {gltf2::Attribute::TEXCOORD_0, &MeshDefinition::mTexCoords, sizeof(Vector2)},
+  {gltf2::Attribute::COLOR_0, &MeshDefinition::mColors, sizeof(Vector4)},
+  {gltf2::Attribute::JOINTS_0, &MeshDefinition::mJoints0, sizeof(Vector4)},
+  {gltf2::Attribute::WEIGHTS_0, &MeshDefinition::mWeights0, sizeof(Vector4)},
+};
+
+std::vector<gltf2::Animation> ReadAnimationArray(const json_value_s& j)
+{
+  auto results = json::Read::Array<gltf2::Animation, json::ObjectReader<gltf2::Animation>::Read>(j);
+
+  for(auto& animation : results)
+  {
+    for(auto& channel : animation.mChannels)
+    {
+      channel.mSampler.UpdateVector(animation.mSamplers);
+    }
+  }
+
+  return results;
+}
+
+void ApplyAccessorMinMax(const gltf2::Accessor& acc, float* values)
+{
+  DALI_ASSERT_ALWAYS(acc.mMax.empty() || gltf2::AccessorType::ElementCount(acc.mType) == acc.mMax.size());
+  DALI_ASSERT_ALWAYS(acc.mMin.empty() || gltf2::AccessorType::ElementCount(acc.mType) == acc.mMin.size());
+  MeshDefinition::Blob::ApplyMinMax(acc.mMin, acc.mMax, acc.mCount, values);
+}
+
+const auto BUFFER_READER = std::move(json::Reader<gltf2::Buffer>()
+                                       .Register(*json::MakeProperty("byteLength", json::Read::Number<uint32_t>, &gltf2::Buffer::mByteLength))
+                                       .Register(*json::MakeProperty("uri", json::Read::StringView, &gltf2::Buffer::mUri)));
+
+const auto BUFFER_VIEW_READER = std::move(json::Reader<gltf2::BufferView>()
+                                            .Register(*json::MakeProperty("buffer", gltf2::RefReader<gltf2::Document>::Read<gltf2::Buffer, &gltf2::Document::mBuffers>, &gltf2::BufferView::mBuffer))
+                                            .Register(*json::MakeProperty("byteOffset", json::Read::Number<uint32_t>, &gltf2::BufferView::mByteOffset))
+                                            .Register(*json::MakeProperty("byteLength", json::Read::Number<uint32_t>, &gltf2::BufferView::mByteLength))
+                                            .Register(*json::MakeProperty("byteStride", json::Read::Number<uint32_t>, &gltf2::BufferView::mByteStride))
+                                            .Register(*json::MakeProperty("target", json::Read::Number<uint32_t>, &gltf2::BufferView::mTarget)));
+
+const auto BUFFER_VIEW_CLIENT_READER = std::move(json::Reader<gltf2::BufferViewClient>()
+                                                   .Register(*json::MakeProperty("bufferView", gltf2::RefReader<gltf2::Document>::Read<gltf2::BufferView, &gltf2::Document::mBufferViews>, &gltf2::BufferViewClient::mBufferView))
+                                                   .Register(*json::MakeProperty("byteOffset", json::Read::Number<uint32_t>, &gltf2::BufferViewClient::mByteOffset)));
+
+const auto COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER = std::move(json::Reader<gltf2::ComponentTypedBufferViewClient>()
+                                                                   .Register(*new json::Property<gltf2::ComponentTypedBufferViewClient, gltf2::Ref<gltf2::BufferView>>("bufferView", gltf2::RefReader<gltf2::Document>::Read<gltf2::BufferView, &gltf2::Document::mBufferViews>, &gltf2::ComponentTypedBufferViewClient::mBufferView))
+                                                                   .Register(*new json::Property<gltf2::ComponentTypedBufferViewClient, uint32_t>("byteOffset", json::Read::Number<uint32_t>, &gltf2::ComponentTypedBufferViewClient::mByteOffset))
+                                                                   .Register(*json::MakeProperty("componentType", json::Read::Enum<gltf2::Component::Type>, &gltf2::ComponentTypedBufferViewClient::mComponentType)));
+
+const auto ACCESSOR_SPARSE_READER = std::move(json::Reader<gltf2::Accessor::Sparse>()
+                                                .Register(*json::MakeProperty("count", json::Read::Number<uint32_t>, &gltf2::Accessor::Sparse::mCount))
+                                                .Register(*json::MakeProperty("indices", json::ObjectReader<gltf2::ComponentTypedBufferViewClient>::Read, &gltf2::Accessor::Sparse::mIndices))
+                                                .Register(*json::MakeProperty("values", json::ObjectReader<gltf2::BufferViewClient>::Read, &gltf2::Accessor::Sparse::mValues)));
+
+const auto ACCESSOR_READER = std::move(json::Reader<gltf2::Accessor>()
+                                         .Register(*new json::Property<gltf2::Accessor, gltf2::Ref<gltf2::BufferView>>("bufferView",
+                                                                                                                       gltf2::RefReader<gltf2::Document>::Read<gltf2::BufferView, &gltf2::Document::mBufferViews>,
+                                                                                                                       &gltf2::Accessor::mBufferView))
+                                         .Register(*new json::Property<gltf2::Accessor, uint32_t>("byteOffset",
+                                                                                                  json::Read::Number<uint32_t>,
+                                                                                                  &gltf2::Accessor::mByteOffset))
+                                         .Register(*new json::Property<gltf2::Accessor, gltf2::Component::Type>("componentType",
+                                                                                                                json::Read::Enum<gltf2::Component::Type>,
+                                                                                                                &gltf2::Accessor::mComponentType))
+                                         .Register(*new json::Property<gltf2::Accessor, std::string_view>("name", json::Read::StringView, &gltf2::Accessor::mName))
+                                         .Register(*json::MakeProperty("count", json::Read::Number<uint32_t>, &gltf2::Accessor::mCount))
+                                         .Register(*json::MakeProperty("normalized", json::Read::Boolean, &gltf2::Accessor::mNormalized))
+                                         .Register(*json::MakeProperty("type", gltf2::ReadStringEnum<gltf2::AccessorType>, &gltf2::Accessor::mType))
+                                         .Register(*json::MakeProperty("min", json::Read::Array<float, json::Read::Number>, &gltf2::Accessor::mMin))
+                                         .Register(*json::MakeProperty("max", json::Read::Array<float, json::Read::Number>, &gltf2::Accessor::mMax))
+                                         .Register(*new json::Property<gltf2::Accessor, gltf2::Accessor::Sparse>("sparse", json::ObjectReader<gltf2::Accessor::Sparse>::Read, &gltf2::Accessor::SetSparse)));
+
+const auto IMAGE_READER = std::move(json::Reader<gltf2::Image>()
+                                      .Register(*new json::Property<gltf2::Image, std::string_view>("name", json::Read::StringView, &gltf2::Material::mName))
+                                      .Register(*json::MakeProperty("uri", json::Read::StringView, &gltf2::Image::mUri))
+                                      .Register(*json::MakeProperty("mimeType", json::Read::StringView, &gltf2::Image::mMimeType))
+                                      .Register(*json::MakeProperty("bufferView", gltf2::RefReader<gltf2::Document>::Read<gltf2::BufferView, &gltf2::Document::mBufferViews>, &gltf2::Image::mBufferView)));
+
+const auto SAMPLER_READER = std::move(json::Reader<gltf2::Sampler>()
+                                        .Register(*json::MakeProperty("minFilter", json::Read::Enum<gltf2::Filter::Type>, &gltf2::Sampler::mMinFilter))
+                                        .Register(*json::MakeProperty("magFilter", json::Read::Enum<gltf2::Filter::Type>, &gltf2::Sampler::mMagFilter))
+                                        .Register(*json::MakeProperty("wrapS", json::Read::Enum<gltf2::Wrap::Type>, &gltf2::Sampler::mWrapS))
+                                        .Register(*json::MakeProperty("wrapT", json::Read::Enum<gltf2::Wrap::Type>, &gltf2::Sampler::mWrapT)));
+
+const auto TEXURE_READER = std::move(json::Reader<gltf2::Texture>()
+                                       .Register(*json::MakeProperty("source", gltf2::RefReader<gltf2::Document>::Read<gltf2::Image, &gltf2::Document::mImages>, &gltf2::Texture::mSource))
+                                       .Register(*json::MakeProperty("sampler", gltf2::RefReader<gltf2::Document>::Read<gltf2::Sampler, &gltf2::Document::mSamplers>, &gltf2::Texture::mSampler)));
+
+const auto TEXURE_INFO_READER = std::move(json::Reader<gltf2::TextureInfo>()
+                                            .Register(*json::MakeProperty("index", gltf2::RefReader<gltf2::Document>::Read<gltf2::Texture, &gltf2::Document::mTextures>, &gltf2::TextureInfo::mTexture))
+                                            .Register(*json::MakeProperty("texCoord", json::Read::Number<uint32_t>, &gltf2::TextureInfo::mTexCoord))
+                                            .Register(*json::MakeProperty("scale", json::Read::Number<float>, &gltf2::TextureInfo::mScale))
+                                            .Register(*json::MakeProperty("strength", json::Read::Number<float>, &gltf2::TextureInfo::mStrength)));
+
+const auto MATERIAL_PBR_READER = std::move(json::Reader<gltf2::Material::Pbr>()
+                                             .Register(*json::MakeProperty("baseColorFactor", gltf2::ReadDaliVector<Vector4>, &gltf2::Material::Pbr::mBaseColorFactor))
+                                             .Register(*json::MakeProperty("baseColorTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::Material::Pbr::mBaseColorTexture))
+                                             .Register(*json::MakeProperty("metallicFactor", json::Read::Number<float>, &gltf2::Material::Pbr::mMetallicFactor))
+                                             .Register(*json::MakeProperty("roughnessFactor", json::Read::Number<float>, &gltf2::Material::Pbr::mRoughnessFactor))
+                                             .Register(*json::MakeProperty("metallicRoughnessTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::Material::Pbr::mMetallicRoughnessTexture)));
+
+const auto MATERIAL_SPECULAR_READER = std::move(json::Reader<gltf2::MaterialSpecular>()
+                                                  .Register(*json::MakeProperty("specularFactor", json::Read::Number<float>, &gltf2::MaterialSpecular::mSpecularFactor))
+                                                  .Register(*json::MakeProperty("specularTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::MaterialSpecular::mSpecularTexture))
+                                                  .Register(*json::MakeProperty("specularColorFactor", gltf2::ReadDaliVector<Vector3>, &gltf2::MaterialSpecular::mSpecularColorFactor))
+                                                  .Register(*json::MakeProperty("specularColorTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::MaterialSpecular::mSpecularColorTexture)));
+
+const auto MATERIAL_IOR_READER = std::move(json::Reader<gltf2::MaterialIor>()
+                                             .Register(*json::MakeProperty("ior", json::Read::Number<float>, &gltf2::MaterialIor::mIor)));
+
+const auto MATERIAL_EXTENSION_READER = std::move(json::Reader<gltf2::MaterialExtensions>()
+                                                   .Register(*json::MakeProperty("KHR_materials_ior", json::ObjectReader<gltf2::MaterialIor>::Read, &gltf2::MaterialExtensions::mMaterialIor))
+                                                   .Register(*json::MakeProperty("KHR_materials_specular", json::ObjectReader<gltf2::MaterialSpecular>::Read, &gltf2::MaterialExtensions::mMaterialSpecular)));
+
+const auto MATERIAL_READER = std::move(json::Reader<gltf2::Material>()
+                                         .Register(*new json::Property<gltf2::Material, std::string_view>("name", json::Read::StringView, &gltf2::Material::mName))
+                                         .Register(*json::MakeProperty("pbrMetallicRoughness", json::ObjectReader<gltf2::Material::Pbr>::Read, &gltf2::Material::mPbrMetallicRoughness))
+                                         .Register(*json::MakeProperty("normalTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::Material::mNormalTexture))
+                                         .Register(*json::MakeProperty("occlusionTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::Material::mOcclusionTexture))
+                                         .Register(*json::MakeProperty("emissiveTexture", json::ObjectReader<gltf2::TextureInfo>::Read, &gltf2::Material::mEmissiveTexture))
+                                         .Register(*json::MakeProperty("emissiveFactor", gltf2::ReadDaliVector<Vector3>, &gltf2::Material::mEmissiveFactor))
+                                         .Register(*json::MakeProperty("alphaMode", gltf2::ReadStringEnum<gltf2::AlphaMode>, &gltf2::Material::mAlphaMode))
+                                         .Register(*json::MakeProperty("alphaCutoff", json::Read::Number<float>, &gltf2::Material::mAlphaCutoff))
+                                         .Register(*json::MakeProperty("doubleSided", json::Read::Boolean, &gltf2::Material::mDoubleSided))
+                                         .Register(*json::MakeProperty("extensions", json::ObjectReader<gltf2::MaterialExtensions>::Read, &gltf2::Material::mMaterialExtensions)));
+
+std::map<gltf2::Attribute::Type, gltf2::Ref<gltf2::Accessor>> ReadMeshPrimitiveAttributes(const json_value_s& j)
+{
+  auto&                                                         jo = json::Cast<json_object_s>(j);
+  std::map<gltf2::Attribute::Type, gltf2::Ref<gltf2::Accessor>> result;
+
+  auto i = jo.start;
+  while(i)
+  {
+    auto jstr                                                           = *i->name;
+    result[gltf2::Attribute::FromString(jstr.string, jstr.string_size)] = gltf2::RefReader<gltf2::Document>::Read<gltf2::Accessor, &gltf2::Document::mAccessors>(*i->value);
+    i                                                                   = i->next;
+  }
+  return result;
+}
+
+std::vector<std::map<gltf2::Attribute::Type, gltf2::Ref<gltf2::Accessor>>> ReadMeshPrimitiveTargets(const json_value_s& j)
+{
+  auto&                                                                      jo = json::Cast<json_array_s>(j);
+  std::vector<std::map<gltf2::Attribute::Type, gltf2::Ref<gltf2::Accessor>>> result;
+
+  result.reserve(jo.length);
+
+  auto i = jo.start;
+  while(i)
+  {
+    result.push_back(std::move(ReadMeshPrimitiveAttributes(*i->value)));
+    i = i->next;
+  }
+
+  return result;
+}
+
+const auto MESH_PRIMITIVE_READER = std::move(json::Reader<gltf2::Mesh::Primitive>()
+                                               .Register(*json::MakeProperty("attributes", ReadMeshPrimitiveAttributes, &gltf2::Mesh::Primitive::mAttributes))
+                                               .Register(*json::MakeProperty("indices", gltf2::RefReader<gltf2::Document>::Read<gltf2::Accessor, &gltf2::Document::mAccessors>, &gltf2::Mesh::Primitive::mIndices))
+                                               .Register(*json::MakeProperty("material", gltf2::RefReader<gltf2::Document>::Read<gltf2::Material, &gltf2::Document::mMaterials>, &gltf2::Mesh::Primitive::mMaterial))
+                                               .Register(*json::MakeProperty("mode", json::Read::Enum<gltf2::Mesh::Primitive::Mode>, &gltf2::Mesh::Primitive::mMode))
+                                               .Register(*json::MakeProperty("targets", ReadMeshPrimitiveTargets, &gltf2::Mesh::Primitive::mTargets)));
+
+const auto MESH_READER = std::move(json::Reader<gltf2::Mesh>()
+                                     .Register(*new json::Property<gltf2::Mesh, std::string_view>("name", json::Read::StringView, &gltf2::Mesh::mName))
+                                     .Register(*json::MakeProperty("primitives",
+                                                                   json::Read::Array<gltf2::Mesh::Primitive, json::ObjectReader<gltf2::Mesh::Primitive>::Read>,
+                                                                   &gltf2::Mesh::mPrimitives))
+                                     .Register(*json::MakeProperty("weights", json::Read::Array<float, json::Read::Number>, &gltf2::Mesh::mWeights)));
+
+const auto SKIN_READER = std::move(json::Reader<gltf2::Skin>()
+                                     .Register(*new json::Property<gltf2::Skin, std::string_view>("name", json::Read::StringView, &gltf2::Skin::mName))
+                                     .Register(*json::MakeProperty("inverseBindMatrices",
+                                                                   gltf2::RefReader<gltf2::Document>::Read<gltf2::Accessor, &gltf2::Document::mAccessors>,
+                                                                   &gltf2::Skin::mInverseBindMatrices))
+                                     .Register(*json::MakeProperty("skeleton",
+                                                                   gltf2::RefReader<gltf2::Document>::Read<gltf2::Node, &gltf2::Document::mNodes>,
+                                                                   &gltf2::Skin::mSkeleton))
+                                     .Register(*json::MakeProperty("joints",
+                                                                   json::Read::Array<gltf2::Ref<gltf2::Node>, gltf2::RefReader<gltf2::Document>::Read<gltf2::Node, &gltf2::Document::mNodes>>,
+                                                                   &gltf2::Skin::mJoints)));
+
+const auto CAMERA_PERSPECTIVE_READER = std::move(json::Reader<gltf2::Camera::Perspective>()
+                                                   .Register(*json::MakeProperty("aspectRatio", json::Read::Number<float>, &gltf2::Camera::Perspective::mAspectRatio))
+                                                   .Register(*json::MakeProperty("yfov", json::Read::Number<float>, &gltf2::Camera::Perspective::mYFov))
+                                                   .Register(*json::MakeProperty("zfar", json::Read::Number<float>, &gltf2::Camera::Perspective::mZFar))
+                                                   .Register(*json::MakeProperty("znear", json::Read::Number<float>, &gltf2::Camera::Perspective::mZNear))); // TODO: infinite perspective projection, where znear is omitted
+
+const auto CAMERA_ORTHOGRAPHIC_READER = std::move(json::Reader<gltf2::Camera::Orthographic>()
+                                                    .Register(*json::MakeProperty("xmag", json::Read::Number<float>, &gltf2::Camera::Orthographic::mXMag))
+                                                    .Register(*json::MakeProperty("ymag", json::Read::Number<float>, &gltf2::Camera::Orthographic::mYMag))
+                                                    .Register(*json::MakeProperty("zfar", json::Read::Number<float>, &gltf2::Camera::Orthographic::mZFar))
+                                                    .Register(*json::MakeProperty("znear", json::Read::Number<float>, &gltf2::Camera::Orthographic::mZNear)));
+
+const auto CAMERA_READER = std::move(json::Reader<gltf2::Camera>()
+                                       .Register(*new json::Property<gltf2::Camera, std::string_view>("name", json::Read::StringView, &gltf2::Camera::mName))
+                                       .Register(*json::MakeProperty("type", json::Read::StringView, &gltf2::Camera::mType))
+                                       .Register(*json::MakeProperty("perspective", json::ObjectReader<gltf2::Camera::Perspective>::Read, &gltf2::Camera::mPerspective))
+                                       .Register(*json::MakeProperty("orthographic", json::ObjectReader<gltf2::Camera::Orthographic>::Read, &gltf2::Camera::mOrthographic)));
+
+const auto NODE_READER = std::move(json::Reader<gltf2::Node>()
+                                     .Register(*new json::Property<gltf2::Node, std::string_view>("name", json::Read::StringView, &gltf2::Node::mName))
+                                     .Register(*json::MakeProperty("translation", gltf2::ReadDaliVector<Vector3>, &gltf2::Node::mTranslation))
+                                     .Register(*json::MakeProperty("rotation", gltf2::ReadQuaternion, &gltf2::Node::mRotation))
+                                     .Register(*json::MakeProperty("scale", gltf2::ReadDaliVector<Vector3>, &gltf2::Node::mScale))
+                                     .Register(*new json::Property<gltf2::Node, Matrix>("matrix", gltf2::ReadDaliVector<Matrix>, &gltf2::Node::SetMatrix))
+                                     .Register(*json::MakeProperty("camera", gltf2::RefReader<gltf2::Document>::Read<gltf2::Camera, &gltf2::Document::mCameras>, &gltf2::Node::mCamera))
+                                     .Register(*json::MakeProperty("children", json::Read::Array<gltf2::Ref<gltf2::Node>, gltf2::RefReader<gltf2::Document>::Read<gltf2::Node, &gltf2::Document::mNodes>>, &gltf2::Node::mChildren))
+                                     .Register(*json::MakeProperty("mesh", gltf2::RefReader<gltf2::Document>::Read<gltf2::Mesh, &gltf2::Document::mMeshes>, &gltf2::Node::mMesh))
+                                     .Register(*json::MakeProperty("skin", gltf2::RefReader<gltf2::Document>::Read<gltf2::Skin, &gltf2::Document::mSkins>, &gltf2::Node::mSkin)));
+
+const auto ANIMATION_SAMPLER_READER = std::move(json::Reader<gltf2::Animation::Sampler>()
+                                                  .Register(*json::MakeProperty("input", gltf2::RefReader<gltf2::Document>::Read<gltf2::Accessor, &gltf2::Document::mAccessors>, &gltf2::Animation::Sampler::mInput))
+                                                  .Register(*json::MakeProperty("output", gltf2::RefReader<gltf2::Document>::Read<gltf2::Accessor, &gltf2::Document::mAccessors>, &gltf2::Animation::Sampler::mOutput))
+                                                  .Register(*json::MakeProperty("interpolation", gltf2::ReadStringEnum<gltf2::Animation::Sampler::Interpolation>, &gltf2::Animation::Sampler::mInterpolation)));
+
+const auto ANIMATION_TARGET_READER = std::move(json::Reader<gltf2::Animation::Channel::Target>()
+                                                 .Register(*json::MakeProperty("node", gltf2::RefReader<gltf2::Document>::Read<gltf2::Node, &gltf2::Document::mNodes>, &gltf2::Animation::Channel::Target::mNode))
+                                                 .Register(*json::MakeProperty("path", gltf2::ReadStringEnum<gltf2::Animation::Channel::Target>, &gltf2::Animation::Channel::Target::mPath)));
+
+const auto ANIMATION_CHANNEL_READER = std::move(json::Reader<gltf2::Animation::Channel>()
+                                                  .Register(*json::MakeProperty("target", json::ObjectReader<gltf2::Animation::Channel::Target>::Read, &gltf2::Animation::Channel::mTarget))
+                                                  .Register(*json::MakeProperty("sampler", gltf2::RefReader<gltf2::Animation>::Read<gltf2::Animation::Sampler, &gltf2::Animation::mSamplers>, &gltf2::Animation::Channel::mSampler)));
+
+const auto ANIMATION_READER = std::move(json::Reader<gltf2::Animation>()
+                                          .Register(*new json::Property<gltf2::Animation, std::string_view>("name", json::Read::StringView, &gltf2::Animation::mName))
+                                          .Register(*json::MakeProperty("samplers",
+                                                                        json::Read::Array<gltf2::Animation::Sampler, json::ObjectReader<gltf2::Animation::Sampler>::Read>,
+                                                                        &gltf2::Animation::mSamplers))
+                                          .Register(*json::MakeProperty("channels",
+                                                                        json::Read::Array<gltf2::Animation::Channel, json::ObjectReader<gltf2::Animation::Channel>::Read>,
+                                                                        &gltf2::Animation::mChannels)));
+
+const auto SCENE_READER = std::move(json::Reader<gltf2::Scene>()
+                                      .Register(*new json::Property<gltf2::Scene, std::string_view>("name", json::Read::StringView, &gltf2::Scene::mName))
+                                      .Register(*json::MakeProperty("nodes",
+                                                                    json::Read::Array<gltf2::Ref<gltf2::Node>, gltf2::RefReader<gltf2::Document>::Read<gltf2::Node, &gltf2::Document::mNodes>>,
+                                                                    &gltf2::Scene::mNodes)));
+
+const auto DOCUMENT_READER = std::move(json::Reader<gltf2::Document>()
+                                         .Register(*json::MakeProperty("buffers",
+                                                                       json::Read::Array<gltf2::Buffer, json::ObjectReader<gltf2::Buffer>::Read>,
+                                                                       &gltf2::Document::mBuffers))
+                                         .Register(*json::MakeProperty("bufferViews",
+                                                                       json::Read::Array<gltf2::BufferView, json::ObjectReader<gltf2::BufferView>::Read>,
+                                                                       &gltf2::Document::mBufferViews))
+                                         .Register(*json::MakeProperty("accessors",
+                                                                       json::Read::Array<gltf2::Accessor, json::ObjectReader<gltf2::Accessor>::Read>,
+                                                                       &gltf2::Document::mAccessors))
+                                         .Register(*json::MakeProperty("images",
+                                                                       json::Read::Array<gltf2::Image, json::ObjectReader<gltf2::Image>::Read>,
+                                                                       &gltf2::Document::mImages))
+                                         .Register(*json::MakeProperty("samplers",
+                                                                       json::Read::Array<gltf2::Sampler, json::ObjectReader<gltf2::Sampler>::Read>,
+                                                                       &gltf2::Document::mSamplers))
+                                         .Register(*json::MakeProperty("textures",
+                                                                       json::Read::Array<gltf2::Texture, json::ObjectReader<gltf2::Texture>::Read>,
+                                                                       &gltf2::Document::mTextures))
+                                         .Register(*json::MakeProperty("materials",
+                                                                       json::Read::Array<gltf2::Material, json::ObjectReader<gltf2::Material>::Read>,
+                                                                       &gltf2::Document::mMaterials))
+                                         .Register(*json::MakeProperty("meshes",
+                                                                       json::Read::Array<gltf2::Mesh, json::ObjectReader<gltf2::Mesh>::Read>,
+                                                                       &gltf2::Document::mMeshes))
+                                         .Register(*json::MakeProperty("skins",
+                                                                       json::Read::Array<gltf2::Skin, json::ObjectReader<gltf2::Skin>::Read>,
+                                                                       &gltf2::Document::mSkins))
+                                         .Register(*json::MakeProperty("cameras",
+                                                                       json::Read::Array<gltf2::Camera, json::ObjectReader<gltf2::Camera>::Read>,
+                                                                       &gltf2::Document::mCameras))
+                                         .Register(*json::MakeProperty("nodes",
+                                                                       json::Read::Array<gltf2::Node, json::ObjectReader<gltf2::Node>::Read>,
+                                                                       &gltf2::Document::mNodes))
+                                         .Register(*json::MakeProperty("animations",
+                                                                       ReadAnimationArray,
+                                                                       &gltf2::Document::mAnimations))
+                                         .Register(*json::MakeProperty("scenes",
+                                                                       json::Read::Array<gltf2::Scene, json::ObjectReader<gltf2::Scene>::Read>,
+                                                                       &gltf2::Document::mScenes))
+                                         .Register(*json::MakeProperty("scene", gltf2::RefReader<gltf2::Document>::Read<gltf2::Scene, &gltf2::Document::mScenes>, &gltf2::Document::mScene)));
+
+void ConvertBuffer(const gltf2::Buffer& buffer, decltype(ResourceBundle::mBuffers)& outBuffers, const std::string& resourcePath)
+{
+  BufferDefinition bufferDefinition;
+
+  bufferDefinition.mResourcePath = resourcePath;
+  bufferDefinition.mUri          = buffer.mUri;
+  bufferDefinition.mByteLength   = buffer.mByteLength;
+
+  outBuffers.emplace_back(std::move(bufferDefinition));
+}
+
+void ConvertBuffers(const gltf2::Document& doc, ConversionContext& context)
+{
+  auto& outBuffers = context.mOutput.mResources.mBuffers;
+  outBuffers.reserve(doc.mBuffers.size());
+
+  for(auto& buffer : doc.mBuffers)
+  {
+    if(buffer.mUri.empty())
+    {
+      continue;
+    }
+    ConvertBuffer(buffer, outBuffers, context.mPath);
+  }
+}
+
+SamplerFlags::Type ConvertWrapMode(gltf2::Wrap::Type wrapMode)
+{
+  switch(wrapMode)
+  {
+    case gltf2::Wrap::REPEAT:
+      return SamplerFlags::WRAP_REPEAT;
+    case gltf2::Wrap::CLAMP_TO_EDGE:
+      return SamplerFlags::WRAP_CLAMP;
+    case gltf2::Wrap::MIRRORED_REPEAT:
+      return SamplerFlags::WRAP_MIRROR;
+    default:
+      throw std::runtime_error("Invalid wrap type.");
+  }
+}
+
+SamplerFlags::Type ConvertSampler(const gltf2::Ref<gltf2::Sampler>& sampler)
+{
+  if(sampler)
+  {
+    return ((sampler->mMinFilter < gltf2::Filter::NEAREST_MIPMAP_NEAREST) ? (sampler->mMinFilter - gltf2::Filter::NEAREST) : ((sampler->mMinFilter - gltf2::Filter::NEAREST_MIPMAP_NEAREST) + 2)) |
+           ((sampler->mMagFilter - gltf2::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) |
+           (ConvertWrapMode(sampler->mWrapS) << SamplerFlags::WRAP_S_SHIFT) |
+           (ConvertWrapMode(sampler->mWrapT) << SamplerFlags::WRAP_T_SHIFT);
+  }
+  else
+  {
+    // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#texturesampler
+    // "The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used."
+    // "What is an auto filtering", I hear you ask. Since there's nothing else to determine mipmapping from - including glTF image
+    // properties, if not in some extension -, we will simply assume linear filtering.
+    return SamplerFlags::FILTER_LINEAR | (SamplerFlags::FILTER_LINEAR << SamplerFlags::FILTER_MAG_SHIFT) |
+           (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_S_SHIFT) | (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_T_SHIFT);
+  }
+}
+
+TextureDefinition ConvertTextureInfo(const gltf2::TextureInfo& mm, ConversionContext& context, const ImageMetadata& metaData = ImageMetadata())
+{
+  TextureDefinition textureDefinition;
+  std::string       uri = std::string(mm.mTexture->mSource->mUri);
+  if(uri.empty())
+  {
+    uint32_t bufferIndex = mm.mTexture->mSource->mBufferView->mBuffer.GetIndex();
+    if(bufferIndex != INVALID_INDEX && context.mOutput.mResources.mBuffers[bufferIndex].IsAvailable())
+    {
+      auto& stream = context.mOutput.mResources.mBuffers[bufferIndex].GetBufferStream();
+      stream.clear();
+      stream.seekg(mm.mTexture->mSource->mBufferView->mByteOffset, stream.beg);
+      std::vector<uint8_t> dataBuffer;
+      dataBuffer.resize(mm.mTexture->mSource->mBufferView->mByteLength);
+      stream.read(reinterpret_cast<char*>(dataBuffer.data()), static_cast<std::streamsize>(static_cast<size_t>(mm.mTexture->mSource->mBufferView->mByteLength)));
+      return TextureDefinition{std::move(dataBuffer), ConvertSampler(mm.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode};
+    }
+    return TextureDefinition();
+  }
+  else
+  {
+    return TextureDefinition{uri, ConvertSampler(mm.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode};
+  }
+}
+
+void ConvertMaterial(const gltf2::Material& material, const std::unordered_map<std::string, ImageMetadata>& imageMetaData, decltype(ResourceBundle::mMaterials)& outMaterials, ConversionContext& context)
+{
+  auto getTextureMetaData = [](const std::unordered_map<std::string, ImageMetadata>& metaData, const gltf2::TextureInfo& info) {
+    if(!info.mTexture->mSource->mUri.empty())
+    {
+      if(auto search = metaData.find(info.mTexture->mSource->mUri.data()); search != metaData.end())
+      {
+        return search->second;
+      }
+    }
+    return ImageMetadata();
+  };
+
+  MaterialDefinition matDef;
+
+  auto& pbr = material.mPbrMetallicRoughness;
+  if(material.mAlphaMode == gltf2::AlphaMode::BLEND)
+  {
+    matDef.mIsOpaque = false;
+    matDef.mFlags |= MaterialDefinition::TRANSPARENCY;
+  }
+  else if(material.mAlphaMode == gltf2::AlphaMode::MASK)
+  {
+    matDef.mIsMask = true;
+    matDef.SetAlphaCutoff(std::min(1.f, std::max(0.f, material.mAlphaCutoff)));
+  }
+
+  matDef.mBaseColorFactor = pbr.mBaseColorFactor;
+
+  matDef.mTextureStages.reserve(!!pbr.mBaseColorTexture + !!pbr.mMetallicRoughnessTexture + !!material.mNormalTexture + !!material.mOcclusionTexture + !!material.mEmissiveTexture);
+  if(pbr.mBaseColorTexture)
+  {
+    const auto semantic = MaterialDefinition::ALBEDO;
+    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(pbr.mBaseColorTexture, context, getTextureMetaData(imageMetaData, pbr.mBaseColorTexture))});
+    // TODO: and there had better be one
+    matDef.mFlags |= semantic;
+  }
+  else
+  {
+    matDef.mNeedAlbedoTexture = false;
+  }
+
+  matDef.mMetallic  = pbr.mMetallicFactor;
+  matDef.mRoughness = pbr.mRoughnessFactor;
+
+  if(pbr.mMetallicRoughnessTexture)
+  {
+    const auto semantic = MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+                          MaterialDefinition::GLTF_CHANNELS;
+    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(pbr.mMetallicRoughnessTexture, context, getTextureMetaData(imageMetaData, pbr.mMetallicRoughnessTexture))});
+    // TODO: and there had better be one
+    matDef.mFlags |= semantic;
+  }
+  else
+  {
+    matDef.mNeedMetallicRoughnessTexture = false;
+  }
+
+  matDef.mNormalScale = material.mNormalTexture.mScale;
+  if(material.mNormalTexture)
+  {
+    const auto semantic = MaterialDefinition::NORMAL;
+    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mNormalTexture, context, getTextureMetaData(imageMetaData, material.mNormalTexture))});
+    // TODO: and there had better be one
+    matDef.mFlags |= semantic;
+  }
+  else
+  {
+    matDef.mNeedNormalTexture = false;
+  }
+
+  if(material.mOcclusionTexture)
+  {
+    const auto semantic = MaterialDefinition::OCCLUSION;
+    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mOcclusionTexture, context, getTextureMetaData(imageMetaData, material.mOcclusionTexture))});
+    // TODO: and there had better be one
+    matDef.mFlags |= semantic;
+    matDef.mOcclusionStrength = material.mOcclusionTexture.mStrength;
+  }
+
+  if(material.mEmissiveTexture)
+  {
+    const auto semantic = MaterialDefinition::EMISSIVE;
+    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mEmissiveTexture, context, getTextureMetaData(imageMetaData, material.mEmissiveTexture))});
+    // TODO: and there had better be one
+    matDef.mFlags |= semantic;
+    matDef.mEmissiveFactor = material.mEmissiveFactor;
+  }
+
+  if(!Dali::Equals(material.mMaterialExtensions.mMaterialIor.mIor, gltf2::UNDEFINED_FLOAT_VALUE))
+  {
+    float ior                  = material.mMaterialExtensions.mMaterialIor.mIor;
+    matDef.mDielectricSpecular = powf((ior - 1.0f) / (ior + 1.0f), 2.0f);
+  }
+  matDef.mSpecularFactor      = material.mMaterialExtensions.mMaterialSpecular.mSpecularFactor;
+  matDef.mSpecularColorFactor = material.mMaterialExtensions.mMaterialSpecular.mSpecularColorFactor;
+
+  if(material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture)
+  {
+    const auto semantic = MaterialDefinition::SPECULAR;
+    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture, context, getTextureMetaData(imageMetaData, material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture))});
+    matDef.mFlags |= semantic;
+  }
+
+  if(material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture)
+  {
+    const auto semantic = MaterialDefinition::SPECULAR_COLOR;
+    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture, context, getTextureMetaData(imageMetaData, material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture))});
+    matDef.mFlags |= semantic;
+  }
+
+  matDef.mDoubleSided = material.mDoubleSided;
+
+  outMaterials.emplace_back(std::move(matDef), TextureSet());
+}
+
+void ConvertMaterials(const gltf2::Document& doc, ConversionContext& context)
+{
+  auto& imageMetaData = context.mOutput.mSceneMetadata.mImageMetadata;
+
+  auto& outMaterials = context.mOutput.mResources.mMaterials;
+  outMaterials.reserve(doc.mMaterials.size());
+
+  for(auto& m : doc.mMaterials)
+  {
+    ConvertMaterial(m, imageMetaData, outMaterials, context);
+  }
+}
+
+MeshDefinition::Accessor ConvertMeshPrimitiveAccessor(const gltf2::Accessor& acc)
+{
+  DALI_ASSERT_ALWAYS((acc.mBufferView &&
+                      (acc.mBufferView->mByteStride < std::numeric_limits<uint16_t>::max())) ||
+                     (acc.mSparse && !acc.mBufferView));
+
+  DALI_ASSERT_ALWAYS(!acc.mSparse ||
+                     ((acc.mSparse->mIndices.mBufferView && (acc.mSparse->mIndices.mBufferView->mByteStride < std::numeric_limits<uint16_t>::max())) &&
+                      (acc.mSparse->mValues.mBufferView && (acc.mSparse->mValues.mBufferView->mByteStride < std::numeric_limits<uint16_t>::max()))));
+
+  MeshDefinition::SparseBlob sparseBlob;
+  if(acc.mSparse)
+  {
+    const gltf2::Accessor::Sparse&               sparse  = *acc.mSparse;
+    const gltf2::ComponentTypedBufferViewClient& indices = sparse.mIndices;
+    const gltf2::BufferViewClient&               values  = sparse.mValues;
+
+    MeshDefinition::Blob indicesBlob(
+      indices.mBufferView->mByteOffset + indices.mByteOffset,
+      sparse.mCount * indices.GetBytesPerComponent(),
+      static_cast<uint16_t>(indices.mBufferView->mByteStride),
+      static_cast<uint16_t>(indices.GetBytesPerComponent()),
+      {},
+      {});
+    MeshDefinition::Blob valuesBlob(
+      values.mBufferView->mByteOffset + values.mByteOffset,
+      sparse.mCount * acc.GetElementSizeBytes(),
+      static_cast<uint16_t>(values.mBufferView->mByteStride),
+      static_cast<uint16_t>(acc.GetElementSizeBytes()),
+      {},
+      {});
+
+    sparseBlob = std::move(MeshDefinition::SparseBlob(std::move(indicesBlob), std::move(valuesBlob), acc.mSparse->mCount));
+  }
+
+  uint32_t bufferViewOffset = 0u;
+  uint32_t bufferViewStride = 0u;
+  if(acc.mBufferView)
+  {
+    bufferViewOffset = acc.mBufferView->mByteOffset;
+    bufferViewStride = acc.mBufferView->mByteStride;
+  }
+
+  return MeshDefinition::Accessor{
+    std::move(MeshDefinition::Blob{bufferViewOffset + acc.mByteOffset,
+                                   acc.GetBytesLength(),
+                                   static_cast<uint16_t>(bufferViewStride),
+                                   static_cast<uint16_t>(acc.GetElementSizeBytes()),
+                                   acc.mMin,
+                                   acc.mMax}),
+    std::move(sparseBlob),
+    acc.mBufferView ? acc.mBufferView->mBuffer.GetIndex() : 0};
+}
+
+void ConvertMeshes(const gltf2::Document& doc, ConversionContext& context)
+{
+  uint32_t meshCount = 0;
+  context.mMeshIds.reserve(doc.mMeshes.size());
+  for(auto& mesh : doc.mMeshes)
+  {
+    context.mMeshIds.push_back(meshCount);
+    meshCount += mesh.mPrimitives.size();
+  }
+
+  auto& outMeshes = context.mOutput.mResources.mMeshes;
+  outMeshes.reserve(meshCount);
+  for(auto& mesh : doc.mMeshes)
+  {
+    for(auto& primitive : mesh.mPrimitives)
+    {
+      MeshDefinition meshDefinition;
+
+      auto& attribs                 = primitive.mAttributes;
+      meshDefinition.mPrimitiveType = GLTF2_TO_DALI_PRIMITIVES[primitive.mMode];
+
+      auto& accPositions        = *attribs.find(gltf2::Attribute::POSITION)->second;
+      meshDefinition.mPositions = ConvertMeshPrimitiveAccessor(accPositions);
+      // glTF2 support vector4 tangent for mesh.
+      // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#meshes-overview
+      meshDefinition.mTangentType = Property::VECTOR4;
+
+      const bool needNormalsTangents = accPositions.mType == gltf2::AccessorType::VEC3;
+      for(auto& am : ATTRIBUTE_MAPPINGS)
+      {
+        auto iFind = attribs.find(am.mType);
+        if(iFind != attribs.end())
+        {
+          auto& accessor = meshDefinition.*(am.mAccessor);
+          accessor       = ConvertMeshPrimitiveAccessor(*iFind->second);
+
+          if(iFind->first == gltf2::Attribute::JOINTS_0)
+          {
+            meshDefinition.mFlags |= (iFind->second->mComponentType == gltf2::Component::UNSIGNED_SHORT) * MeshDefinition::U16_JOINT_IDS;
+            meshDefinition.mFlags |= (iFind->second->mComponentType == gltf2::Component::UNSIGNED_BYTE) * MeshDefinition::U8_JOINT_IDS;
+            DALI_ASSERT_DEBUG(MaskMatch(meshDefinition.mFlags, MeshDefinition::U16_JOINT_IDS) || MaskMatch(meshDefinition.mFlags, MeshDefinition::U8_JOINT_IDS) || iFind->second->mComponentType == gltf2::Component::FLOAT);
+          }
+        }
+        else if(needNormalsTangents)
+        {
+          switch(am.mType)
+          {
+            case gltf2::Attribute::NORMAL:
+              meshDefinition.RequestNormals();
+              break;
+
+            case gltf2::Attribute::TANGENT:
+              meshDefinition.RequestTangents();
+              break;
+
+            default:
+              break;
+          }
+        }
+      }
+
+      if(primitive.mIndices)
+      {
+        meshDefinition.mIndices = ConvertMeshPrimitiveAccessor(*primitive.mIndices);
+        meshDefinition.mFlags |= (primitive.mIndices->mComponentType == gltf2::Component::UNSIGNED_INT) * MeshDefinition::U32_INDICES;
+        meshDefinition.mFlags |= (primitive.mIndices->mComponentType == gltf2::Component::UNSIGNED_BYTE) * MeshDefinition::U8_INDICES;
+        DALI_ASSERT_DEBUG(MaskMatch(meshDefinition.mFlags, MeshDefinition::U32_INDICES) || MaskMatch(meshDefinition.mFlags, MeshDefinition::U8_INDICES) || primitive.mIndices->mComponentType == gltf2::Component::UNSIGNED_SHORT);
+      }
+
+      if(!primitive.mTargets.empty())
+      {
+        meshDefinition.mBlendShapes.reserve(primitive.mTargets.size());
+        meshDefinition.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0;
+        for(const auto& target : primitive.mTargets)
+        {
+          MeshDefinition::BlendShape blendShape;
+
+          auto endIt = target.end();
+          auto it    = target.find(gltf2::Attribute::POSITION);
+          if(it != endIt)
+          {
+            blendShape.deltas = ConvertMeshPrimitiveAccessor(*it->second);
+          }
+          it = target.find(gltf2::Attribute::NORMAL);
+          if(it != endIt)
+          {
+            blendShape.normals = ConvertMeshPrimitiveAccessor(*it->second);
+          }
+          it = target.find(gltf2::Attribute::TANGENT);
+          if(it != endIt)
+          {
+            blendShape.tangents = ConvertMeshPrimitiveAccessor(*it->second);
+          }
+
+          if(!mesh.mWeights.empty())
+          {
+            blendShape.weight = mesh.mWeights[meshDefinition.mBlendShapes.size()];
+          }
+
+          meshDefinition.mBlendShapes.push_back(std::move(blendShape));
+        }
+      }
+
+      outMeshes.push_back({std::move(meshDefinition), MeshGeometry{}});
+    }
+  }
+}
+
+ModelRenderable* MakeModelRenderable(const gltf2::Mesh::Primitive& prim, ConversionContext& context)
+{
+  auto modelRenderable = new ModelRenderable();
+
+  modelRenderable->mShaderIdx = 0; // TODO: further thought
+
+  auto materialIdx = prim.mMaterial.GetIndex();
+  if(INVALID_INDEX == materialIdx)
+  {
+    // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#default-material
+    if(INVALID_INDEX == context.mDefaultMaterial)
+    {
+      auto& outMaterials       = context.mOutput.mResources.mMaterials;
+      context.mDefaultMaterial = outMaterials.size();
+
+      ConvertMaterial(gltf2::Material{}, context.mOutput.mSceneMetadata.mImageMetadata, outMaterials, context);
+    }
+
+    materialIdx = context.mDefaultMaterial;
+  }
+
+  modelRenderable->mMaterialIdx = materialIdx;
+
+  return modelRenderable;
+}
+
+void ConvertCamera(const gltf2::Camera& camera, CameraParameters& camParams)
+{
+  camParams.isPerspective = camera.mType.compare("perspective") == 0;
+  if(camParams.isPerspective)
+  {
+    auto& perspective = camera.mPerspective;
+    if(!Dali::Equals(perspective.mYFov, gltf2::UNDEFINED_FLOAT_VALUE))
+    {
+      camParams.yFovDegree = Degree(Radian(perspective.mYFov));
+    }
+    else
+    {
+      camParams.yFovDegree = Degree(gltf2::UNDEFINED_FLOAT_VALUE);
+    }
+    camParams.zNear = perspective.mZNear;
+    camParams.zFar  = perspective.mZFar;
+    // TODO: yes, we seem to ignore aspectRatio in CameraParameters.
+  }
+  else
+  {
+    auto& ortho = camera.mOrthographic;
+    if(!Dali::Equals(ortho.mYMag, gltf2::UNDEFINED_FLOAT_VALUE) && !Dali::Equals(ortho.mXMag, gltf2::UNDEFINED_FLOAT_VALUE))
+    {
+      camParams.orthographicSize = ortho.mYMag * .5f;
+      camParams.aspectRatio      = ortho.mXMag / ortho.mYMag;
+    }
+    else
+    {
+      camParams.orthographicSize = gltf2::UNDEFINED_FLOAT_VALUE;
+      camParams.aspectRatio      = gltf2::UNDEFINED_FLOAT_VALUE;
+    }
+    camParams.zNear = ortho.mZNear;
+    camParams.zFar  = ortho.mZFar;
+  }
+}
+
+void ConvertNode(gltf2::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& context, bool isMRendererModel)
+{
+  auto& output    = context.mOutput;
+  auto& scene     = output.mScene;
+  auto& resources = output.mResources;
+
+  const auto idx      = scene.GetNodeCount();
+  auto       weakNode = scene.AddNode([&]() {
+    std::unique_ptr<NodeDefinition> nodeDef{new NodeDefinition()};
+
+    nodeDef->mParentIdx = parentIdx;
+    nodeDef->mName      = node.mName;
+    if(nodeDef->mName.empty())
+    {
+      // TODO: Production quality generation of unique names.
+      nodeDef->mName = std::to_string(reinterpret_cast<uintptr_t>(nodeDef.get()));
+    }
+
+    if(!node.mSkin) // Nodes with skinned meshes are not supposed to have local transforms.
+    {
+      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; }());
+  if(!weakNode)
+  {
+    ExceptionFlinger(ASSERT_LOCATION) << "Node name '" << node.mName << "' is not unique; scene is invalid.";
+  }
+
+  context.mNodeIndices.RegisterMapping(gltfIdx, idx);
+
+  Index skeletonIdx = node.mSkin ? node.mSkin.GetIndex() : INVALID_INDEX;
+  if(node.mMesh)
+  {
+    auto&    mesh           = *node.mMesh;
+    uint32_t primitiveCount = mesh.mPrimitives.size();
+    auto     meshIdx        = context.mMeshIds[node.mMesh.GetIndex()];
+    weakNode->mRenderables.reserve(primitiveCount);
+    for(uint32_t i = 0; i < primitiveCount; ++i)
+    {
+      std::unique_ptr<NodeDefinition::Renderable> renderable;
+      auto                                        modelRenderable = MakeModelRenderable(mesh.mPrimitives[i], context);
+      modelRenderable->mMeshIdx                                   = meshIdx + i;
+
+      DALI_ASSERT_DEBUG(resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx == INVALID_INDEX ||
+                        resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx == skeletonIdx);
+      resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx = skeletonIdx;
+
+      renderable.reset(modelRenderable);
+      weakNode->mRenderables.push_back(std::move(renderable));
+    }
+  }
+
+  if(node.mCamera)
+  {
+    CameraParameters camParams;
+    ConvertCamera(*node.mCamera, camParams);
+
+    camParams.matrix.SetTransformComponents(node.mScale, node.mRotation, node.mTranslation);
+    output.mCameraParameters.push_back(camParams);
+  }
+
+  for(auto& n : node.mChildren)
+  {
+    ConvertNode(*n, n.GetIndex(), idx, context, isMRendererModel);
+  }
+}
+
+void ConvertSceneNodes(const gltf2::Scene& scene, ConversionContext& context, bool isMRendererModel)
+{
+  auto& outScene = context.mOutput.mScene;
+  Index rootIdx  = outScene.GetNodeCount();
+  switch(scene.mNodes.size())
+  {
+    case 0:
+      break;
+
+    case 1:
+      ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, context, isMRendererModel);
+      outScene.AddRootNode(rootIdx);
+      break;
+
+    default:
+    {
+      std::unique_ptr<NodeDefinition> sceneRoot{new NodeDefinition()};
+      sceneRoot->mName = "GLTF_LOADER_SCENE_ROOT_" + std::to_string(outScene.GetRoots().size());
+
+      outScene.AddNode(std::move(sceneRoot));
+      outScene.AddRootNode(rootIdx);
+
+      for(auto& n : scene.mNodes)
+      {
+        ConvertNode(*n, n.GetIndex(), rootIdx, context, isMRendererModel);
+      }
+      break;
+    }
+  }
+}
+
+void ConvertNodes(const gltf2::Document& doc, ConversionContext& context, bool isMRendererModel)
+{
+  if(!doc.mScenes.empty())
+  {
+    uint32_t rootSceneIndex = 0u;
+    if(doc.mScene)
+    {
+      rootSceneIndex = doc.mScene.GetIndex();
+    }
+    ConvertSceneNodes(doc.mScenes[rootSceneIndex], context, isMRendererModel);
+
+    for(uint32_t i = 0, i1 = rootSceneIndex; i < i1; ++i)
+    {
+      ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel);
+    }
+
+    for(uint32_t i = rootSceneIndex + 1; i < doc.mScenes.size(); ++i)
+    {
+      ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel);
+    }
+  }
+}
+
+template<typename T>
+void LoadDataFromAccessor(ConversionContext& context, uint32_t bufferIndex, Vector<T>& dataBuffer, uint32_t offset, uint32_t size)
+{
+  if(bufferIndex >= context.mOutput.mResources.mBuffers.size())
+  {
+    DALI_LOG_ERROR("Invailid buffer index\n");
+    return;
+  }
+
+  auto& buffer = context.mOutput.mResources.mBuffers[bufferIndex];
+  if(!buffer.IsAvailable())
+  {
+    DALI_LOG_ERROR("Failed to load from buffer stream.\n");
+  }
+  auto& stream = buffer.GetBufferStream();
+  stream.clear();
+  stream.seekg(offset, stream.beg);
+  stream.read(reinterpret_cast<char*>(dataBuffer.Begin()), static_cast<std::streamsize>(static_cast<size_t>(size)));
+}
+
+template<typename T>
+float LoadDataFromAccessors(ConversionContext& context, const gltf2::Accessor& input, const gltf2::Accessor& output, Vector<float>& inputDataBuffer, Vector<T>& outputDataBuffer)
+{
+  inputDataBuffer.Resize(input.mCount);
+  outputDataBuffer.Resize(output.mCount);
+
+  const uint32_t inputDataBufferSize  = input.GetBytesLength();
+  const uint32_t outputDataBufferSize = output.GetBytesLength();
+
+  LoadDataFromAccessor<float>(context, output.mBufferView->mBuffer.GetIndex(), inputDataBuffer, input.mBufferView->mByteOffset + input.mByteOffset, inputDataBufferSize);
+  LoadDataFromAccessor<T>(context, output.mBufferView->mBuffer.GetIndex(), outputDataBuffer, output.mBufferView->mByteOffset + output.mByteOffset, outputDataBufferSize);
+  ApplyAccessorMinMax(input, reinterpret_cast<float*>(inputDataBuffer.begin()));
+  ApplyAccessorMinMax(output, reinterpret_cast<float*>(outputDataBuffer.begin()));
+
+  return inputDataBuffer[input.mCount - 1u];
+}
+
+template<typename T>
+float LoadKeyFrames(ConversionContext& context, const gltf2::Animation::Channel& channel, KeyFrames& keyFrames, gltf2::Animation::Channel::Target::Type type)
+{
+  const gltf2::Accessor& input  = *channel.mSampler->mInput;
+  const gltf2::Accessor& output = *channel.mSampler->mOutput;
+
+  Vector<float> inputDataBuffer;
+  Vector<T>     outputDataBuffer;
+
+  const float duration = std::max(LoadDataFromAccessors<T>(context, input, output, inputDataBuffer, outputDataBuffer), AnimationDefinition::MIN_DURATION_SECONDS);
+
+  // Set first frame value as first keyframe (gltf animation spec)
+  if(input.mCount > 0 && !Dali::EqualsZero(inputDataBuffer[0]))
+  {
+    keyFrames.Add(0.0f, outputDataBuffer[0]);
+  }
+
+  for(uint32_t i = 0; i < input.mCount; ++i)
+  {
+    keyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i]);
+  }
+
+  return duration;
+}
+
+float LoadBlendShapeKeyFrames(ConversionContext& context, const gltf2::Animation::Channel& channel, Index nodeIndex, uint32_t& propertyIndex, std::vector<Dali::Scene3D::Loader::AnimatedProperty>& properties)
+{
+  const gltf2::Accessor& input  = *channel.mSampler->mInput;
+  const gltf2::Accessor& output = *channel.mSampler->mOutput;
+
+  Vector<float> inputDataBuffer;
+  Vector<float> outputDataBuffer;
+
+  const float duration = std::max(LoadDataFromAccessors<float>(context, input, output, inputDataBuffer, outputDataBuffer), AnimationDefinition::MIN_DURATION_SECONDS);
+
+  char        weightNameBuffer[32];
+  auto        prefixSize    = snprintf(weightNameBuffer, sizeof(weightNameBuffer), "%s[", BLEND_SHAPE_WEIGHTS_UNIFORM.data());
+  char* const pWeightName   = weightNameBuffer + prefixSize;
+  const auto  remainingSize = sizeof(weightNameBuffer) - prefixSize;
+  for(uint32_t weightIndex = 0u, endWeightIndex = channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount; weightIndex < endWeightIndex; ++weightIndex)
+  {
+    AnimatedProperty& animatedProperty = properties[propertyIndex++];
+
+    animatedProperty.mNodeIndex = nodeIndex;
+    snprintf(pWeightName, remainingSize, "%d]", weightIndex);
+    animatedProperty.mPropertyName = std::string(weightNameBuffer);
+
+    animatedProperty.mKeyFrames = KeyFrames::New();
+
+    // Set first frame value as first keyframe (gltf animation spec)
+    if(input.mCount > 0 && !Dali::EqualsZero(inputDataBuffer[0]))
+    {
+      animatedProperty.mKeyFrames.Add(0.0f, outputDataBuffer[weightIndex]);
+    }
+
+    for(uint32_t i = 0; i < input.mCount; ++i)
+    {
+      animatedProperty.mKeyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i * endWeightIndex + weightIndex]);
+    }
+
+    animatedProperty.mTimePeriod = {0.f, duration};
+  }
+
+  return duration;
+}
+
+void ConvertAnimations(const gltf2::Document& doc, ConversionContext& context)
+{
+  auto& output = context.mOutput;
+
+  output.mAnimationDefinitions.reserve(output.mAnimationDefinitions.size() + doc.mAnimations.size());
+
+  for(const auto& animation : doc.mAnimations)
+  {
+    AnimationDefinition animationDef;
+
+    if(!animation.mName.empty())
+    {
+      animationDef.mName = animation.mName;
+    }
+
+    uint32_t numberOfProperties = 0u;
+    for(const auto& channel : animation.mChannels)
+    {
+      if(channel.mTarget.mPath == gltf2::Animation::Channel::Target::WEIGHTS)
+      {
+        numberOfProperties += channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount;
+      }
+      else
+      {
+        numberOfProperties++;
+      }
+    }
+    animationDef.mProperties.resize(numberOfProperties);
+
+    Index propertyIndex = 0u;
+    for(const auto& channel : animation.mChannels)
+    {
+      Index nodeIndex = context.mNodeIndices.GetRuntimeId(channel.mTarget.mNode.GetIndex());
+      float duration  = 0.f;
+
+      switch(channel.mTarget.mPath)
+      {
+        case gltf2::Animation::Channel::Target::TRANSLATION:
+        {
+          AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex];
+
+          animatedProperty.mNodeIndex    = nodeIndex;
+          animatedProperty.mPropertyName = POSITION_PROPERTY;
+
+          animatedProperty.mKeyFrames = KeyFrames::New();
+          duration                    = LoadKeyFrames<Vector3>(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath);
+
+          animatedProperty.mTimePeriod = {0.f, duration};
+          break;
+        }
+        case gltf2::Animation::Channel::Target::ROTATION:
+        {
+          AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex];
+
+          animatedProperty.mNodeIndex    = nodeIndex;
+          animatedProperty.mPropertyName = ORIENTATION_PROPERTY;
+
+          animatedProperty.mKeyFrames = KeyFrames::New();
+          duration                    = LoadKeyFrames<Quaternion>(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath);
+
+          animatedProperty.mTimePeriod = {0.f, duration};
+          break;
+        }
+        case gltf2::Animation::Channel::Target::SCALE:
+        {
+          AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex];
+
+          animatedProperty.mNodeIndex    = nodeIndex;
+          animatedProperty.mPropertyName = SCALE_PROPERTY;
+
+          animatedProperty.mKeyFrames = KeyFrames::New();
+          duration                    = LoadKeyFrames<Vector3>(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath);
+
+          animatedProperty.mTimePeriod = {0.f, duration};
+          break;
+        }
+        case gltf2::Animation::Channel::Target::WEIGHTS:
+        {
+          duration = LoadBlendShapeKeyFrames(context, channel, nodeIndex, propertyIndex, animationDef.mProperties);
+
+          break;
+        }
+        default:
+        {
+          // nothing to animate.
+          break;
+        }
+      }
+
+      animationDef.mDuration = std::max(duration, animationDef.mDuration);
+
+      ++propertyIndex;
+    }
+
+    output.mAnimationDefinitions.push_back(std::move(animationDef));
+  }
+}
+
+void ProcessSkins(const gltf2::Document& doc, ConversionContext& context)
+{
+  // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skininversebindmatrices
+  // If an inverseBindMatrices accessor was provided, we'll load the joint data from the buffer,
+  // otherwise we'll set identity matrices for inverse bind pose.
+  struct IInverseBindMatrixProvider
+  {
+    virtual ~IInverseBindMatrixProvider()
+    {
+    }
+    virtual void Provide(Matrix& ibm) = 0;
+  };
+
+  struct InverseBindMatrixAccessor : public IInverseBindMatrixProvider
+  {
+    std::istream&  mStream;
+    const uint32_t mElementSizeBytes;
+
+    InverseBindMatrixAccessor(const gltf2::Accessor& accessor, ConversionContext& context)
+    : mStream(context.mOutput.mResources.mBuffers[accessor.mBufferView->mBuffer.GetIndex()].GetBufferStream()),
+      mElementSizeBytes(accessor.GetElementSizeBytes())
+    {
+      DALI_ASSERT_DEBUG(accessor.mType == gltf2::AccessorType::MAT4 && accessor.mComponentType == gltf2::Component::FLOAT);
+
+      if(!mStream.rdbuf()->in_avail())
+      {
+        DALI_LOG_ERROR("Failed to load from stream\n");
+      }
+      mStream.clear();
+      mStream.seekg(accessor.mBufferView->mByteOffset + accessor.mByteOffset, mStream.beg);
+    }
+
+    virtual void Provide(Matrix& ibm) override
+    {
+      DALI_ASSERT_ALWAYS(mStream.read(reinterpret_cast<char*>(ibm.AsFloat()), static_cast<std::streamsize>(static_cast<size_t>(mElementSizeBytes))));
+    }
+  };
+
+  struct DefaultInverseBindMatrixProvider : public IInverseBindMatrixProvider
+  {
+    virtual void Provide(Matrix& ibm) override
+    {
+      ibm = Matrix::IDENTITY;
+    }
+  };
+
+  auto& resources = context.mOutput.mResources;
+  resources.mSkeletons.reserve(doc.mSkins.size());
+
+  for(auto& skin : doc.mSkins)
+  {
+    std::unique_ptr<IInverseBindMatrixProvider> ibmProvider;
+    if(skin.mInverseBindMatrices)
+    {
+      ibmProvider.reset(new InverseBindMatrixAccessor(*skin.mInverseBindMatrices, context));
+    }
+    else
+    {
+      ibmProvider.reset(new DefaultInverseBindMatrixProvider());
+    }
+
+    SkeletonDefinition skeleton;
+    if(skin.mSkeleton.GetIndex() != INVALID_INDEX)
+    {
+      skeleton.mRootNodeIdx = context.mNodeIndices.GetRuntimeId(skin.mSkeleton.GetIndex());
+    }
+
+    skeleton.mJoints.resize(skin.mJoints.size());
+    auto iJoint = skeleton.mJoints.begin();
+    for(auto& joint : skin.mJoints)
+    {
+      iJoint->mNodeIdx = context.mNodeIndices.GetRuntimeId(joint.GetIndex());
+
+      ibmProvider->Provide(iJoint->mInverseBindMatrix);
+
+      ++iJoint;
+    }
+
+    resources.mSkeletons.push_back(std::move(skeleton));
+  }
+}
+
+void ProduceShaders(ShaderDefinitionFactory& shaderFactory, Dali::Scene3D::Loader::SceneDefinition& scene)
+{
+  uint32_t nodeCount = scene.GetNodeCount();
+  for(uint32_t i = 0; i < nodeCount; ++i)
+  {
+    auto nodeDef = scene.GetNode(i);
+    for(auto& renderable : nodeDef->mRenderables)
+    {
+      if(shaderFactory.ProduceShader(*renderable) == INVALID_INDEX)
+      {
+        DALI_LOG_ERROR("Fail to produce shader\n");
+      }
+    }
+  }
+}
+
+void SetObjectReaders()
+{
+  json::SetObjectReader(BUFFER_READER);
+  json::SetObjectReader(BUFFER_VIEW_READER);
+  json::SetObjectReader(BUFFER_VIEW_CLIENT_READER);
+  json::SetObjectReader(COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER);
+  json::SetObjectReader(ACCESSOR_SPARSE_READER);
+  json::SetObjectReader(ACCESSOR_READER);
+  json::SetObjectReader(IMAGE_READER);
+  json::SetObjectReader(SAMPLER_READER);
+  json::SetObjectReader(TEXURE_READER);
+  json::SetObjectReader(TEXURE_INFO_READER);
+  json::SetObjectReader(MATERIAL_PBR_READER);
+  json::SetObjectReader(MATERIAL_SPECULAR_READER);
+  json::SetObjectReader(MATERIAL_IOR_READER);
+  json::SetObjectReader(MATERIAL_EXTENSION_READER);
+  json::SetObjectReader(MATERIAL_READER);
+  json::SetObjectReader(MESH_PRIMITIVE_READER);
+  json::SetObjectReader(MESH_READER);
+  json::SetObjectReader(SKIN_READER);
+  json::SetObjectReader(CAMERA_PERSPECTIVE_READER);
+  json::SetObjectReader(CAMERA_ORTHOGRAPHIC_READER);
+  json::SetObjectReader(CAMERA_READER);
+  json::SetObjectReader(NODE_READER);
+  json::SetObjectReader(ANIMATION_SAMPLER_READER);
+  json::SetObjectReader(ANIMATION_TARGET_READER);
+  json::SetObjectReader(ANIMATION_CHANNEL_READER);
+  json::SetObjectReader(ANIMATION_READER);
+  json::SetObjectReader(SCENE_READER);
+}
+
+void SetDefaultEnvironmentMap(const gltf2::Document& doc, ConversionContext& context)
+{
+  EnvironmentDefinition envDef;
+  envDef.mUseBrdfTexture = true;
+  envDef.mIblIntensity   = Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity();
+  context.mOutput.mResources.mEnvironmentMaps.push_back({std::move(envDef), EnvironmentDefinition::Textures()});
+}
+
+void InitializeGltfLoader()
+{
+  static Dali::Mutex gInitializeMutex;
+  // Set ObjectReader only once (for all gltf loading).
+  static bool setObjectReadersRequired = true;
+  {
+    Mutex::ScopedLock lock(gInitializeMutex);
+    if(setObjectReadersRequired)
+    {
+      // NOTE: only referencing own, anonymous namespace, const objects; the pointers will never need to change.
+      SetObjectReaders();
+      setObjectReadersRequired = false;
+    }
+  }
+}
+
+const std::string_view GetRendererModelIdentification()
+{
+  return MRENDERER_MODEL_IDENTIFICATION;
+}
+
+void ReadDocument(const json_object_s& jsonObject, gltf2::Document& document)
+{
+  DOCUMENT_READER.Read(jsonObject, document);
+}
+
+void ReadDocumentFromParsedData(const json_object_s& jsonObject, gltf2::Document& document)
+{
+  static Dali::Mutex gReadMutex;
+  Mutex::ScopedLock  lock(gReadMutex);
+  gt::SetRefReaderObject(document);
+  Gltf2Util::ReadDocument(jsonObject, document);
+}
+
+bool GenerateDocument(json::unique_ptr& root, gt::Document& document, bool& isMRendererModel)
+{
+  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)
+  {
+    document.mAsset.mVersion = js::Read::StringView(*jsAssetVersion);
+  }
+
+  auto jsAssetGenerator = js::FindObjectChild("generator", js::Cast<json_object_s>(*jsAsset));
+  if(jsAssetGenerator)
+  {
+    document.mAsset.mGenerator = js::Read::StringView(*jsAssetGenerator);
+    isMRendererModel           = (document.mAsset.mGenerator.find(Gltf2Util::GetRendererModelIdentification().data()) != std::string_view::npos);
+  }
+
+  Gltf2Util::InitializeGltfLoader();
+  Gltf2Util::ReadDocumentFromParsedData(rootObj, document);
+
+  return true;
+}
+
+void ConvertGltfToContext(gt::Document& document, Gltf2Util::ConversionContext& context, bool isMRendererModel)
+{
+  Dali::Scene3D::Loader::ShaderDefinitionFactory shaderFactory;
+  shaderFactory.SetResources(context.mOutput.mResources);
+
+  Gltf2Util::ConvertBuffers(document, context);
+  Gltf2Util::ConvertMaterials(document, context);
+  Gltf2Util::ConvertMeshes(document, context);
+  Gltf2Util::ConvertNodes(document, context, isMRendererModel);
+  Gltf2Util::ConvertAnimations(document, context);
+  Gltf2Util::ProcessSkins(document, context);
+  Gltf2Util::ProduceShaders(shaderFactory, context.mOutput.mScene);
+  context.mOutput.mScene.EnsureUniqueSkinningShaderInstances(context.mOutput.mResources);
+
+  // Set Default Environment map
+  Gltf2Util::SetDefaultEnvironmentMap(document, context);
+}
+
+} // namespace Gltf2Util
+
+} // namespace Dali::Scene3D::Loader::Internal
\ No newline at end of file
diff --git a/dali-scene3d/internal/loader/gltf2-util.h b/dali-scene3d/internal/loader/gltf2-util.h
new file mode 100644 (file)
index 0000000..909ae59
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef DALI_SCENE3D_LOADER_GLTF2_UTIL_H
+#define DALI_SCENE3D_LOADER_GLTF2_UTIL_H
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/public-api/common/dali-common.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/loader/gltf2-asset.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>
+
+namespace gt = gltf2;
+namespace js = json;
+
+namespace Dali::Scene3D::Loader::Internal
+{
+namespace Gltf2Util
+{
+struct NodeMapping
+{
+  Index gltfIdx;
+  Index runtimeIdx;
+
+  bool operator<(Index gltfIdx) const
+  {
+    return this->gltfIdx < gltfIdx;
+  }
+};
+
+class NodeIndexMapper
+{
+public:
+  NodeIndexMapper()                       = default;
+  NodeIndexMapper(const NodeIndexMapper&) = delete;
+  NodeIndexMapper& operator=(const NodeIndexMapper&) = delete;
+
+  ///@brief Registers a mapping of the @a gltfIdx of a node to its @a runtimeIdx .
+  ///@note If the indices are the same, the registration is omitted, in order to
+  /// save growing a vector.
+  void RegisterMapping(Index gltfIdx, Index runtimeIdx)
+  {
+    if(gltfIdx != runtimeIdx)
+    {
+      auto iInsert = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx);
+      DALI_ASSERT_DEBUG(iInsert == mNodes.end() || iInsert->gltfIdx != gltfIdx);
+      mNodes.insert(iInsert, NodeMapping{gltfIdx, runtimeIdx});
+    }
+  }
+
+  ///@brief Retrieves the runtime index of a Node, mapped to the given @a gltfIdx.
+  Index GetRuntimeId(Index gltfIdx) const
+  {
+    auto iFind = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx); // using custom operator<
+    return (iFind != mNodes.end() && iFind->gltfIdx == gltfIdx) ? iFind->runtimeIdx : gltfIdx;
+  }
+
+private:
+  std::vector<NodeMapping> mNodes;
+};
+
+struct ConversionContext
+{
+  LoadResult& mOutput;
+
+  std::string mPath;
+  Index       mDefaultMaterial;
+
+  std::vector<Index> mMeshIds;
+  NodeIndexMapper    mNodeIndices;
+};
+
+void ConvertBuffers(const gt::Document& doc, ConversionContext& context);
+
+void ConvertMaterials(const gt::Document& doc, ConversionContext& context);
+
+void ConvertMeshes(const gt::Document& doc, ConversionContext& context);
+
+void ConvertCamera(const gt::Camera& camera, CameraParameters& camParams);
+
+void ConvertNodes(const gt::Document& doc, ConversionContext& context, bool isMRendererModel);
+
+void ConvertAnimations(const gt::Document& doc, ConversionContext& context);
+
+void ProcessSkins(const gt::Document& doc, ConversionContext& context);
+
+void ProduceShaders(ShaderDefinitionFactory& shaderFactory, SceneDefinition& scene);
+
+void SetDefaultEnvironmentMap(const gt::Document& doc, ConversionContext& context);
+
+const std::string_view GetRendererModelIdentification();
+
+void ReadDocument(const json_object_s& jsonObject, gt::Document& document);
+
+void InitializeGltfLoader();
+
+void ReadDocumentFromParsedData(const json_object_s& jsonObject, gltf2::Document& document);
+
+bool GenerateDocument(json::unique_ptr& root, gt::Document& document, bool& isMRendererModel);
+
+void ConvertGltfToContext(gt::Document& document, Gltf2Util::ConversionContext& context, bool isMRendererModel);
+
+} // namespace Gltf2Util
+
+} // namespace Dali::Scene3D::Loader::Internal
+
+#endif // DALI_SCENE3D_LOADER_GLTF2_UTIL_H
index d1ea70f..7abb277 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/internal/loader/hash.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// CLASS HEADER
+#include <dali-scene3d/internal/loader/hash.h>
+
+namespace Dali::Scene3D::Loader
 {
 Hash::Hash(uint64_t initial)
 : mValue(initial)
@@ -93,6 +91,4 @@ uint64_t Hash::Concatenate(uint64_t value)
   return mValue * 31 + value;
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index a5bba8e..0f63c94 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_HASH_H_
 #define DALI_SCENE3D_LOADER_HASH_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
+// EXTERNAL INCLUDES
 #include <cstdint>
 #include <cstring>
 #include <string>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Rudimentary hash generator that follows a builder pattern.
@@ -119,8 +116,6 @@ Hash& Hash::AddObjectBytes(const T& value)
   return *this;
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_HASH_H_
index ead6269..2ea2925 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2022 Samsung Electronics Co., Ltd.
+* Copyright (c) 2023 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.
 * limitations under the License.
 *
 */
-#include "dali-scene3d/internal/loader/json-reader.h"
+
+// CLASS HEADER
+#include <dali-scene3d/internal/loader/json-reader.h>
+
+// EXTERNAL INCLUDES
 #include <algorithm>
 #include <cstring>
 
index c0a8abd..100472a 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_JSON_READER_H_
 #define DALI_SCENE3D_LOADER_JSON_READER_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/third-party/json.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 #include <algorithm>
 #include <cstring>
 #include <map>
 #include <memory>
 #include <sstream>
 #include <string_view>
-#include "dali/public-api/common/vector-wrapper.h"
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/third-party/json.h> // TODO : Since license issue, We shoud replace this thing as <dali-toolkit/devel-api/builder/json-parser.h>
 
 namespace json
 {
index fcb91ad..ec6e95f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/internal/loader/json-util.h"
+
+// CLASS HEADER
+#include <dali-scene3d/internal/loader/json-util.h>
 
 // EXTERNAL INCLUDES
+#include <dali/devel-api/common/map-wrapper.h>
+#include <dali/public-api/common/extents.h>
+#include <dali/public-api/math/matrix.h>
+#include <dali/public-api/math/matrix3.h>
+#include <dali/public-api/math/quaternion.h>
+#include <dali/public-api/math/radian.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/math/vector3.h>
+#include <dali/public-api/object/property-value.h>
 #include <array>
-#include "dali/devel-api/common/map-wrapper.h"
-#include "dali/public-api/common/extents.h"
-#include "dali/public-api/math/matrix.h"
-#include "dali/public-api/math/matrix3.h"
-#include "dali/public-api/math/quaternion.h"
-#include "dali/public-api/math/radian.h"
-#include "dali/public-api/math/vector2.h"
-#include "dali/public-api/math/vector3.h"
-#include "dali/public-api/object/property-value.h"
 
 namespace Dali
 {
index 1d2b983..e7c222d 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_JSON_UTIL_H_
 #define DALI_SCENE3D_LOADER_JSON_UTIL_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/loader/index.h"
-
 // EXTERNAL INCLUDES
-#include "dali-toolkit/devel-api/builder/tree-node.h"
-#include "dali/public-api/animation/time-period.h"
-#include "dali/public-api/common/vector-wrapper.h"
-#include "dali/public-api/math/vector4.h"
-#include "dali/public-api/object/property.h"
+#include <dali-toolkit/devel-api/builder/tree-node.h>
+#include <dali/public-api/animation/time-period.h>
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/math/vector4.h>
+#include <dali/public-api/object/property.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/index.h>
+
+namespace Dali::Scene3D::Loader
 {
 bool ReadBool(const Toolkit::TreeNode* node, bool& num);
 
@@ -90,8 +86,6 @@ Property::Value ReadPropertyValue(const Property::Type& propType, const Toolkit:
  */
 Property::Value ReadPropertyValue(const Toolkit::TreeNode& tn);
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_JSON_UTIL_H_
diff --git a/dali-scene3d/internal/loader/model-loader-impl.h b/dali-scene3d/internal/loader/model-loader-impl.h
new file mode 100644 (file)
index 0000000..619cacb
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef DALI_SCENE3D_LOADER_MODEL_LOADER_IMPL_H
+#define DALI_SCENE3D_LOADER_MODEL_LOADER_IMPL_H
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/load-result.h>
+#include <dali-scene3d/public-api/loader/model-loader.h>
+#include <dali-scene3d/public-api/loader/resource-bundle.h>
+
+// EXTERNAL INCLUDES
+#include <string>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Loader
+{
+namespace Internal
+{
+class ModelLoaderImpl
+{
+public:
+  ModelLoaderImpl() = default;
+
+  /**
+   * @brief Set InputParameter.
+   * Thie method store only a pointer of InputParameter.
+   * The object of InputParameter should not be deleted until it is no longer used.
+   * @param[in] inputParameter Input parameters those can be used for model loading.
+   */
+  void SetInputParameter(Dali::Scene3D::Loader::ModelLoader::InputParameter& inputParameter)
+  {
+    mInputParameter = &inputParameter;
+  }
+
+  /**
+   * @brief Request to load model from url.
+   * @param[in] url model file url.
+   * @param[out] result loaded model data.
+   * @return True if model loading is successfully finished.
+   */
+  virtual bool LoadModel(const std::string& url, Dali::Scene3D::Loader::LoadResult& result) = 0;
+
+protected:
+  Dali::Scene3D::Loader::ModelLoader::InputParameter* mInputParameter{nullptr};
+};
+} // namespace Internal
+} // namespace Loader
+} // namespace Scene3D
+} // namespace Dali
+
+#endif // DALI_SCENE3D_LOADER_MODEL_LOADER_IMPL_H
index 12f3387..b2a0fd9 100644 (file)
  * limitations under the License.
  */
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/api.h>
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/math/matrix.h>
 #include <dali/public-api/math/vector3.h>
 #include <dali/public-api/math/vector4.h>
 
 #include <cinttypes>
 #include <cstdio>
-#include <vector>
 #include <memory>
 
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
 namespace Dali::Scene3D::Internal::Algorithm
 {
 class NavigationMesh;
@@ -41,9 +41,9 @@ class NavigationMeshFactory;
 }
 
 constexpr auto NAVIGATION_MESH_MAX_VERTICES_PER_FACE = 3u;
-constexpr auto NAVIGATION_MESH_MAX_EDGES_PER_FACE = 3u;
-constexpr auto NAVIGATION_MESH_MAX_COMPONENTS_3D = 3u;
-constexpr auto NAVIGATION_MESH_MAX_COMPONENTS_2D = 2u;
+constexpr auto NAVIGATION_MESH_MAX_EDGES_PER_FACE    = 3u;
+constexpr auto NAVIGATION_MESH_MAX_COMPONENTS_3D     = 3u;
+constexpr auto NAVIGATION_MESH_MAX_COMPONENTS_2D     = 2u;
 
 namespace Dali::Scene3D::Algorithm
 {
@@ -72,7 +72,6 @@ using NavigationMeshImpl = Dali::Scene3D::Internal::Algorithm::NavigationMesh;
 class DALI_SCENE3D_API NavigationMesh
 {
 public:
-
   /**
    * @struct Face
    *
@@ -81,9 +80,9 @@ public:
   struct Face
   {
     uint16_t vertex[NAVIGATION_MESH_MAX_VERTICES_PER_FACE]; ///< Vertices per face
-    uint16_t edge[NAVIGATION_MESH_MAX_EDGES_PER_FACE]; ///< Edges per face
-    float    normal[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Normal vector
-    float    center[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Barycentric coordinates
+    uint16_t edge[NAVIGATION_MESH_MAX_EDGES_PER_FACE];      ///< Edges per face
+    float    normal[NAVIGATION_MESH_MAX_COMPONENTS_3D];     ///< Normal vector
+    float    center[NAVIGATION_MESH_MAX_COMPONENTS_3D];     ///< Barycentric coordinates
   };
 
   /**
@@ -118,7 +117,6 @@ public:
   NavigationMesh() = delete;
 
 public:
-
   /**
    * @brief Destructor
    */
@@ -171,7 +169,6 @@ public:
    */
   bool FindFloorForFace(const Dali::Vector3& position, uint32_t faceIndex, bool dontCheckNeighbours, Dali::Vector3& outPosition);
 
-
   /**
    * @brief Returns pointer to Face structure
    * @param[in] index Index of face to retrieve
@@ -253,8 +250,7 @@ public:
   static constexpr uint16_t NULL_EDGE{0xffff}; ///< represents null edge
 
 public:
-
-  DALI_INTERNAL explicit NavigationMesh( NavigationMeshImpl* impl );
+  DALI_INTERNAL explicit NavigationMesh(NavigationMeshImpl* impl);
 
   std::unique_ptr<NavigationMeshImpl> mImpl;
 };
index 9254e04..edaf1e1 100644 (file)
 // CLASS HEADER
 #include <dali-scene3d/public-api/algorithm/path-finder-waypoint.h>
 
+// EXTERNAL INCLUDES
+#include <cinttypes>
+
 // INTERNAL INCLUDES
 #include <dali-scene3d/internal/algorithm/navigation-mesh-impl.h>
 #include <dali-scene3d/internal/algorithm/path-finder-waypoint-data.h>
 
-// EXTERNAL INCLUDES
-#include <cinttypes>
-
 namespace Dali::Scene3D::Algorithm
 {
-
 WayPoint::WayPoint()
 {
   mImpl = std::make_unique<Scene3D::Internal::Algorithm::WayPointData>();
@@ -51,13 +50,13 @@ Dali::Vector3 WayPoint::GetScenePosition() const
 
 WayPoint::WayPoint(const WayPoint& wp)
 {
-  mImpl = std::make_unique<Internal::Algorithm::WayPointData>();
+  mImpl  = std::make_unique<Internal::Algorithm::WayPointData>();
   *mImpl = *wp.mImpl;
 }
 
 WayPoint& WayPoint::operator=(const WayPoint& wp)
 {
-  mImpl = std::make_unique<Internal::Algorithm::WayPointData>();
+  mImpl  = std::make_unique<Internal::Algorithm::WayPointData>();
   *mImpl = *wp.mImpl;
   return *this;
 }
@@ -67,4 +66,4 @@ WayPoint::operator Internal::Algorithm::WayPointData&()
   return *mImpl;
 }
 
-}
+} // namespace Dali::Scene3D::Algorithm
index 201783c..ec07a5e 100644 (file)
@@ -17,9 +17,6 @@
  *  limitations under the License.
  */
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/api.h>
-
 // EXTERNAL INCLUDES
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/vector3.h>
@@ -27,6 +24,9 @@
 #include <cinttypes>
 #include <memory>
 
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
 namespace Dali::Scene3D::Internal::Algorithm
 {
 class WayPointData;
@@ -42,7 +42,6 @@ namespace Dali::Scene3D::Algorithm
 class DALI_SCENE3D_API WayPoint
 {
 public:
-
   /**
    * @brief Constructor
    */
@@ -101,14 +100,11 @@ public:
   WayPoint& operator=(const WayPoint&);
 
 private:
-
   std::unique_ptr<Internal::Algorithm::WayPointData> mImpl;
 
 public:
-
   DALI_INTERNAL operator Internal::Algorithm::WayPointData&();
-
 };
-}
+} // namespace Dali::Scene3D::Algorithm
 
 #endif // DALI_SCENE3D_PATH_FINDER_WAYPOINT_H
index f48ffb3..6f29448 100644 (file)
@@ -17,6 +17,7 @@
 // CLASS HEADER
 #include <dali-scene3d/public-api/algorithm/path-finder.h>
 
+// INTERNAL INCLUDES
 // default algorithm
 #include <dali-scene3d/internal/algorithm/path-finder-djikstra.h>
 #include <dali-scene3d/internal/algorithm/path-finder-spfa-double-way.h>
index ce723ea..da3f7a6 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/api.h>
-
 // EXTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control.h>
 #include <dali/public-api/actors/camera-actor.h>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/rendering/texture.h>
 
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
 namespace Dali
 {
 namespace Scene3D
index 1a3407f..f64715d 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/api.h>
-#include <dali-scene3d/public-api/common/environment-map.h>
-
 // EXTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control.h>
 #include <dali/public-api/actors/camera-actor.h>
 #include <dali/public-api/common/dali-common.h>
 
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/common/environment-map.h>
+
 namespace Dali
 {
 namespace Scene3D
index 95363dc..e812ae7 100644 (file)
@@ -16,15 +16,14 @@ set(scene3d_src_files ${scene3d_src_files}
        ${scene3d_public_api_dir}/loader/environment-map-data.cpp
        ${scene3d_public_api_dir}/loader/environment-map-loader.cpp
        ${scene3d_public_api_dir}/loader/customization.cpp
-       ${scene3d_public_api_dir}/loader/dli-loader.cpp
        ${scene3d_public_api_dir}/loader/environment-definition.cpp
        ${scene3d_public_api_dir}/loader/facial-animation-loader.cpp
-       ${scene3d_public_api_dir}/loader/gltf2-loader.cpp
        ${scene3d_public_api_dir}/loader/ktx-loader.cpp
        ${scene3d_public_api_dir}/loader/load-scene-metadata.cpp
        ${scene3d_public_api_dir}/loader/material-definition.cpp
        ${scene3d_public_api_dir}/loader/matrix-stack.cpp
        ${scene3d_public_api_dir}/loader/mesh-definition.cpp
+       ${scene3d_public_api_dir}/loader/model-loader.cpp
        ${scene3d_public_api_dir}/loader/navigation-mesh-factory.cpp
        ${scene3d_public_api_dir}/loader/node-definition.cpp
        ${scene3d_public_api_dir}/loader/parse-renderer-state.cpp
index 1ac61ee..2aecc50 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/public-api/loader/alpha-function-helper.h"
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/alpha-function-helper.h>
+
+// EXTERNAL INCLUDES
 #include <unordered_map>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -67,6 +67,4 @@ void RegisterAlphaFunction(const std::string& name, AlphaFunction alphaFn)
                      "Function with given key already exists.");
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index d421a3e..3fdb4ed 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_ALPHA_FUNCTION_HELPER_H_
 #define DALI_SCENE3D_LOADER_ALPHA_FUNCTION_HELPER_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-#include "dali-scene3d/public-api/api.h"
-
+// EXTERNAL INCLUDES
+#include <dali/public-api/animation/alpha-function.h>
 #include <string>
-#include "dali/public-api/animation/alpha-function.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @return Given a name, provide a AlphaFunction; if the name was not
@@ -40,8 +38,6 @@ AlphaFunction DALI_SCENE3D_API GetAlphaFunction(const std::string& name, bool* f
  */
 void DALI_SCENE3D_API RegisterAlphaFunction(const std::string& name, AlphaFunction alphaFn) noexcept(false);
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_ALPHA_FUNCTION_HELPER_H_
index 83ae2df..a3969ff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/public-api/loader/animated-property.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/animated-property.h>
+
+namespace Dali::Scene3D::Loader
 {
 void AnimatedProperty::Animate(Animation& anim, GetActor getActor)
 {
@@ -45,6 +43,4 @@ void AnimatedProperty::Animate(Animation& anim, GetActor getActor)
   }
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
\ No newline at end of file
index 87fe87a..07b251f 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_ANIMATED_PROPERTY_H
 #define DALI_SCENE3D_LOADER_ANIMATED_PROPERTY_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-#include "dali-scene3d/public-api/loader/index.h"
-
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/animation/animation.h>
+#include <dali/public-api/object/property.h>
 #include <functional>
 #include <memory>
-#include "dali/public-api/actors/actor.h"
-#include "dali/public-api/animation/animation.h"
-#include "dali/public-api/object/property.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/index.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Intermediate representation for a property that's given to
@@ -95,8 +90,6 @@ public: // DATA
   TimePeriod    mTimePeriod    = TimePeriod(0.f);
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_ANIMATED_PROPERTY_H
index c201314..31c5ed1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/public-api/loader/animation-definition.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/animation-definition.h>
+
+namespace Dali::Scene3D::Loader
 {
 const float AnimationDefinition::DEFAULT_DURATION_SECONDS = 1.f;
 const float AnimationDefinition::MIN_DURATION_SECONDS     = 1e-2f;
@@ -85,6 +83,4 @@ AnimationDefinition& AnimationDefinition::operator=(AnimationDefinition&& other)
   return *this;
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index cb8e5db..27fe2ac 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_ANIMATION_DEFINITION_H
 #define DALI_SCENE3D_LOADER_ANIMATION_DEFINITION_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-#include "dali-scene3d/public-api/api.h"
-#include "dali-scene3d/public-api/loader/animated-property.h"
-#include "dali/public-api/common/vector-wrapper.h"
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/animated-property.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Animation handle + name + definition of properties.
@@ -83,8 +82,6 @@ struct AnimationGroupDefinition
   std::vector<std::string> mAnimations;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_ANIMATION_DEFINITION_H
index 8e0353c..3ef97b2 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
-* Copyright (c) 2022 Samsung Electronics Co., Ltd.
+* Copyright (c) 2023 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.
 // INTERNAL INCLUDES
 #include <dali-scene3d/public-api/loader/resource-bundle.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 const char* BlendShapes::NUMBER_OF_BLEND_SHAPES("uNumberOfBlendShapes");
 const char* BlendShapes::UNNORMALIZE_FACTOR("uBlendShapeUnnormalizeFactor");
@@ -85,6 +81,4 @@ void BlendShapes::ConfigureProperties(const std::pair<MeshDefinition, MeshGeomet
   }
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index e2db2a0..b995ed3 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_BLEND_SHAPE_DETAILS_H
 #define DALI_SCENE3D_LOADER_BLEND_SHAPE_DETAILS_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/rendering/shader.h>
 #include <string>
-#include "dali/public-api/actors/actor.h"
-#include "dali/public-api/rendering/shader.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 struct MeshDefinition;
 struct MeshGeometry;
@@ -73,8 +69,6 @@ struct DALI_SCENE3D_API BlendShapes
   BlendShapes() = delete;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_BLEND_SHAPE_DETAILS_H
index 1704927..8f2bc57 100644 (file)
@@ -15,7 +15,7 @@
  *
  */
 
-// INTERNAL INCLUDES
+// CLASS HEADER
 #include <dali-scene3d/public-api/loader/buffer-definition.h>
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/file-stream.h>
 #include <dali/integration-api/debug.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -42,6 +38,14 @@ struct BufferDefinition::Impl
   std::shared_ptr<Dali::FileStream> stream;
 };
 
+BufferDefinition::BufferDefinition(std::vector<uint8_t>& buffer)
+: mImpl{new BufferDefinition::Impl}
+{
+  mImpl.get()->buffer = std::move(buffer);
+  mImpl.get()->stream = std::make_shared<Dali::FileStream>(reinterpret_cast<uint8_t*>(mImpl.get()->buffer.data()), mImpl.get()->buffer.size(), FileStream::READ | FileStream::BINARY);
+  mIsEmbedded         = true;
+}
+
 BufferDefinition::BufferDefinition()
 : mImpl{new BufferDefinition::Impl}
 {
@@ -103,6 +107,4 @@ void BufferDefinition::LoadBuffer()
   }
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index 8f6952a..533aa04 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/api.h>
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/common/vector-wrapper.h>
 #include <fstream>
 #include <memory>
-#include <vector>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Defines a buffer that is loaded from input uri.
@@ -40,9 +37,11 @@ struct DALI_SCENE3D_API BufferDefinition
   using Vector = std::vector<BufferDefinition>;
 
   BufferDefinition();
+  BufferDefinition(std::vector<uint8_t>& buffer);
+
   ~BufferDefinition();
 
-  BufferDefinition(const BufferDefinition& other)            = default;
+  BufferDefinition(const BufferDefinition& other) = default;
   BufferDefinition& operator=(const BufferDefinition& other) = default;
 
   BufferDefinition(BufferDefinition&& other);
@@ -86,8 +85,6 @@ private:
   bool mIsEmbedded{false};
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_BUFFER_DEFINITION_H
index 7d3b775..93a826d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
 #include <sstream>
 #include <string_view>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -340,6 +336,4 @@ AnimationDefinition LoadBvh(const std::string& path, const std::string& animatio
 
   return GenerateAnimation(animationName, rootJoint, frameCount, frameTime, scale);
 }
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
\ No newline at end of file
+} // namespace Dali::Scene3D::Loader
\ No newline at end of file
index 2c3dbc7..9830031 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_SCENE3D_LOADER_BVH_LOADER_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
 // INTERNAL INCLUDES
 #include <dali-scene3d/public-api/loader/animation-definition.h>
 
-namespace Dali
+namespace Dali::Scene3D::Loader
 {
-namespace Scene3D
-{
-namespace Loader
-{
-
 /**
  * @brief Loads motion capture data from bvh file format.
  *
@@ -38,8 +33,6 @@ namespace Loader
  */
 DALI_SCENE3D_API AnimationDefinition LoadBvh(const std::string& path, const std::string& animationName, const Vector3& scale = Vector3::ONE);
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_BVH_LOADER_H
\ No newline at end of file
index cc9a351..05bcef1 100644 (file)
 #include <dali-scene3d/internal/loader/gltf2-asset.h> // for gltf2::UNDEFINED_FLOAT_VALUE
 #include <dali-scene3d/public-api/loader/utils.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -270,6 +266,4 @@ bool CameraParameters::ConfigureCamera(CameraActor& camera, bool invertY) const
   return true;
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
\ No newline at end of file
index f48c191..7922400 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/public-api/loader/customization.h"
-#include "dali/devel-api/common/map-wrapper.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/customization.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/common/map-wrapper.h>
+
+namespace Dali::Scene3D::Loader
 {
 struct Customization::Map::Impl
 {
@@ -111,6 +111,4 @@ void Customization::Choices::Clear()
   mImpl->mOptions.clear();
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
\ No newline at end of file
index 667cada..90a42bf 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_CUSTOMIZATION_STATE_H_
 #define DALI_SCENE3D_LOADER_CUSTOMIZATION_STATE_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 #include <memory>
 #include <string>
-#include "dali/public-api/common/vector-wrapper.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Offers a description of an aspect of the scene that can be customized:
@@ -119,8 +115,6 @@ struct DALI_SCENE3D_API Customization
   std::vector<std::string> nodes; // to apply option to.
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_CUSTOMIZATION_STATE_H_
diff --git a/dali-scene3d/public-api/loader/dli-input-parameter.h b/dali-scene3d/public-api/loader/dli-input-parameter.h
new file mode 100644 (file)
index 0000000..1db4844
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef DALI_SCENE3D_LOADER_DLI_INPUT_PARAMETER_H
+#define DALI_SCENE3D_LOADER_DLI_INPUT_PARAMETER_H
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/model-loader.h>
+
+namespace Dali::Scene3D::Loader
+{
+class DliInputParameter : public ModelLoader::InputParameter
+{
+public:
+  using ConvertFontCode         = void (*)(const std::string& code, std::string& fontFamily, std::string& slant, std::string& weight, float& size);
+  using ConvertColorCode        = Vector4 (*)(const std::string& code);
+  using CategoryProcessor       = std::function<void(Property::Array&& categoryData, StringCallback onError)>;
+  using CategoryProcessorVector = std::vector<std::pair<std::string /*name*/, CategoryProcessor>>;
+  using NodeProcessor           = std::function<void(const Dali::Scene3D::Loader::NodeDefinition& nodeDef,
+                                           Property::Map&&                              nodeData,
+                                           StringCallback                               onError)>;
+  using AnimationProcessor      = std::function<void(const AnimationDefinition& animDef,
+                                                Property::Map&&            animData,
+                                                StringCallback             onError)>;
+
+public:
+  /**
+   * @brief The absolute path of animation binaries referenced in the .dli.
+   */
+  std::string mAnimationsPath;
+
+  /**
+   * @brief Provides a facility to determine a color from a code instead of RGB(A) values.
+   */
+  ConvertColorCode mConvertColorCode{nullptr};
+
+  /**
+   * @brief A collection of handlers, mapped to the names of the top level (i.e. below
+   *  root) element, whom they will attempt to process. This will take place before
+   *  the parsing of scene Nodes and Animations, but after skeletons, environment, mesh,
+   *  shader and material resources.
+   */
+  CategoryProcessorVector mPreNodeCategoryProcessors;
+
+  /**
+   * @brief A collection of handlers, mapped to the names of the top level (i.e. below
+   *  root) element, whom they will attempt to process. This will take place after
+   *  the parsing of the scene Nodes and Animations.
+   */
+  CategoryProcessorVector mPostNodeCategoryProcessors;
+
+  /**
+   * @brief Provides an extension point to nodes. If provided, this function will be
+   *  called with each JSON element and definition, of a scene node.
+   * @note Constraints rely on ID resolution (from .dli to scene definition), which
+   *  takes place after the parsing of the nodes; therefore AT THIS POINT the node
+   *  IDs seen in constraints will still be the .dli IDs - NOT to be relied on for
+   *  indexing into mScene.
+   */
+  NodeProcessor mNodePropertyProcessor{nullptr};
+
+  /**
+   * @brief Provides an extension point to animations. If provided, this function will be
+   *  called with each JSON element and fully processed definition, of an animation.
+   */
+  AnimationProcessor mAnimationPropertyProcessor;
+};
+
+} // namespace Dali::Scene3D::Loader
+
+#endif // DALI_SCENE3D_LOADER_DLI_INPUT_PARAMETER_H
diff --git a/dali-scene3d/public-api/loader/dli-loader.h b/dali-scene3d/public-api/loader/dli-loader.h
deleted file mode 100644 (file)
index c516f9a..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-#ifndef DALI_SCENE3D_LOADER_DLI_LOADER_H
-#define DALI_SCENE3D_LOADER_DLI_LOADER_H
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-#include "dali-scene3d/public-api/loader/animation-definition.h"
-#include "dali-scene3d/public-api/loader/customization.h"
-#include "dali-scene3d/public-api/loader/index.h"
-#include "dali-scene3d/public-api/loader/string-callback.h"
-
-// EXTERNAL INCLUDES
-#include "dali/public-api/common/vector-wrapper.h"
-
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
-{
-typedef std::pair<std::string, std::string> Metadata;
-
-// Forward declarations
-struct LoadResult;
-struct CameraParameters;
-struct LightParameters;
-struct TextParameters;
-
-class ResourceBundle;
-struct NodeDefinition;
-class SceneDefinition;
-
-class DALI_SCENE3D_API DliLoader
-{
-public:
-  using ConvertFontCode  = void (*)(const std::string& code, std::string& fontFamily, std::string& slant, std::string& weight, float& size);
-  using ConvertColorCode = Vector4 (*)(const std::string& code);
-
-  using CategoryProcessor       = std::function<void(Property::Array&& categoryData, StringCallback onError)>;
-  using CategoryProcessorVector = std::vector<std::pair<std::string /*name*/, CategoryProcessor>>;
-
-  using NodeProcessor = std::function<void(const NodeDefinition& nodeDef,
-                                           Property::Map&&       nodeData,
-                                           StringCallback        onError)>;
-
-  using AnimationProcessor = std::function<void(const AnimationDefinition& animDef,
-                                                Property::Map&&            animData,
-                                                StringCallback             onError)>;
-
-  struct InputParams
-  {
-    /**
-     * @brief The absolute path of animation binaries referenced in the .dli.
-     */
-    std::string mAnimationsPath;
-
-    /**
-     * @brief Provides a facility to determine a color from a code instead of RGB(A) values.
-     */
-    ConvertColorCode mConvertColorCode;
-
-    /**
-     * @brief A collection of handlers, mapped to the names of the top level (i.e. below
-     *  root) element, whom they will attempt to process. This will take place before
-     *  the parsing of scene Nodes and Animations, but after skeletons, environment, mesh,
-     *  shader and material resources.
-     */
-    CategoryProcessorVector mPreNodeCategoryProcessors;
-
-    /**
-     * @brief A collection of handlers, mapped to the names of the top level (i.e. below
-     *  root) element, whom they will attempt to process. This will take place after
-     *  the parsing of the scene Nodes and Animations.
-     */
-    CategoryProcessorVector mPostNodeCategoryProcessors;
-
-    /**
-     * @brief Provides an extension point to nodes. If provided, this function will be
-     *  called with each JSON element and definition, of a scene node.
-     * @note Constraints rely on ID resolution (from .dli to scene definition), which
-     *  takes place after the parsing of the nodes; therefore AT THIS POINT the node
-     *  IDs seen in constraints will still be the .dli IDs - NOT to be relied on for
-     *  indexing into mScene.
-     */
-    NodeProcessor mNodePropertyProcessor;
-
-    /**
-     * @brief Provides an extension point to animations. If provided, this function will be
-     *  called with each JSON element and fully processed definition, of an animation.
-     */
-    AnimationProcessor mAnimationPropertyProcessor;
-  };
-
-  struct LoadParams
-  {
-    InputParams const& input;
-    LoadResult&        output;
-  };
-
-  DliLoader();
-  ~DliLoader();
-
-  /**
-   * @brief Sets the callback that messages from non-fatal errors get posted to.
-   *  Uses DefaultErrorCallback by default.
-   */
-  void SetErrorCallback(StringCallback onError);
-
-  /**
-   * @brief Attempts to load and parse a .dli document into a DOM tree.
-   * @return Whether the operation was successful.
-   */
-  bool LoadScene(const std::string& uri, LoadParams& params);
-
-  /**
-   * @return The error string describing how the parse has failed, if any.
-   */
-  std::string GetParseError() const;
-
-private:
-  struct Impl;
-  const std::unique_ptr<Impl> mImpl;
-};
-
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
-
-#endif // DALI_SCENE3D_LOADER_DLI_LOADER_H
index 3dea7c9..16ec2df 100644 (file)
  *
  */
 
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/environment-definition.h>
+
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/environment-variable.h>
 #include <dali/devel-api/adaptor-framework/image-loading.h>
 
 // INTERNAL INCLUDES
-#include "dali-scene3d/public-api/loader/environment-map-loader.h"
-#include "dali-scene3d/public-api/loader/environment-definition.h"
-#include "dali-scene3d/public-api/loader/utils.h"
+#include <dali-scene3d/public-api/loader/environment-map-loader.h>
+#include <dali-scene3d/public-api/loader/utils.h>
 
 namespace
 {
@@ -35,11 +37,7 @@ std::string GetDaliImagePath()
 static constexpr float DEFAULT_INTENSITY = 1.0f;
 } // unnamed namespace
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -109,6 +107,4 @@ float EnvironmentDefinition::GetDefaultIntensity()
   return DEFAULT_INTENSITY;
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
\ No newline at end of file
index 8f1525d..3c4ceee 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-#include "dali-scene3d/public-api/loader/environment-map-data.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/math/quaternion.h>
+#include <dali/public-api/rendering/texture.h>
 #include <memory>
-#include "dali/public-api/math/quaternion.h"
-#include "dali/public-api/rendering/texture.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/environment-map-data.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Defines an environment map with either or both of radiance
@@ -62,10 +58,10 @@ struct DALI_SCENE3D_API EnvironmentDefinition
 
   EnvironmentDefinition() = default;
 
-  EnvironmentDefinition(const EnvironmentDefinition&)            = delete;
+  EnvironmentDefinition(const EnvironmentDefinition&) = delete;
   EnvironmentDefinition& operator=(const EnvironmentDefinition&) = delete;
 
-  EnvironmentDefinition(EnvironmentDefinition&&)            = default;
+  EnvironmentDefinition(EnvironmentDefinition&&) = default;
   EnvironmentDefinition& operator=(EnvironmentDefinition&&) = default;
 
   /**
@@ -97,8 +93,6 @@ public: // DATA
   bool                     mUseBrdfTexture  = false;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_ENVIRONMENT_DEFINITION_H
index fdbd159..cca2952 100644 (file)
 // INTERNAL INCLUDES
 #include <dali-scene3d/internal/graphics/builtin-shader-extern-gen.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 Texture EnvironmentMapData::GetTexture()
 {
@@ -67,6 +63,4 @@ Texture EnvironmentMapData::GetTexture()
   return mEnvironmentMapTexture;
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index 7f3ee8c..2feac5b 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/api.h>
-#include <dali-scene3d/public-api/common/environment-map.h>
-
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/images/pixel-data.h>
-#include <dali/public-api/rendering/texture.h>
 #include <dali/public-api/rendering/shader.h>
+#include <dali/public-api/rendering/texture.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/common/environment-map.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Stores the pixel data objects for environment map texture.
@@ -78,8 +74,6 @@ private:
   Dali::Scene3D::EnvironmentMapType mEnvironmentMapType{Dali::Scene3D::EnvironmentMapType::AUTO};
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_ENVIRONMENT_MAP_DATA_H
index 175c19a..7abff75 100644 (file)
 // FILE HEADER
 #include <dali-scene3d/public-api/loader/environment-map-loader.h>
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/loader/ktx-loader.h>
-
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/image-loading.h>
 #include <string.h>
 #include <filesystem>
 
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/ktx-loader.h>
+
 namespace Dali
 {
 namespace
@@ -45,21 +45,19 @@ static constexpr uint32_t CUBEMAP_INDEX_X[NUMBER_OF_CUBE_MAP_TYPE][6] = {{2, 0,
 static constexpr uint32_t CUBEMAP_INDEX_Y[NUMBER_OF_CUBE_MAP_TYPE][6] = {{1, 1, 0, 2, 1, 1}, {0, 0, 0, 0, 0, 0}, {1, 3, 0, 2, 1, 1}, {0, 1, 2, 3, 4, 5}};
 
 static constexpr Vector2 NUMBER_OF_CUBE_FACE[NUMBER_OF_CUBE_MAP_TYPE] =
-{
-  Vector2(4, 3),
-  Vector2(6, 1),
-  Vector2(3, 4),
-  Vector2(1, 6)
-};
+  {
+    Vector2(4, 3),
+    Vector2(6, 1),
+    Vector2(3, 4),
+    Vector2(1, 6)};
 
 static constexpr float expectedAspectRatios[NUMBER_OF_ENVIRONMENT_MAP_TYPE] =
-{
-  4.0f / 3.0f,
-  6.0f / 1.0f,
-  3.0f / 4.0f,
-  1.0f / 6.0f,
-  2.0f / 1.0f
-};
+  {
+    4.0f / 3.0f,
+    6.0f / 1.0f,
+    3.0f / 4.0f,
+    1.0f / 6.0f,
+    2.0f / 1.0f};
 
 enum CubeType
 {
@@ -189,7 +187,6 @@ namespace Scene3D
 {
 namespace Loader
 {
-
 bool LoadEnvironmentMap(const std::string& environmentMapUrl, EnvironmentMapData& environmentMapData)
 {
   std::filesystem::path modelPath(environmentMapUrl);
index 57047ea..f07f28c 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali-scene3d/public-api/api.h>
-#include <dali-scene3d/public-api/loader/environment-map-data.h>
 #include <dali-scene3d/public-api/common/environment-map.h>
+#include <dali-scene3d/public-api/loader/environment-map-data.h>
 
-namespace Dali
-{
-namespace Scene3D
+namespace Dali::Scene3D::Loader
 {
-namespace Loader
-{
-
 /**
  * @brief Loads environment map data from a environment map file.
  *
@@ -38,8 +33,6 @@ namespace Loader
  */
 bool DALI_SCENE3D_API LoadEnvironmentMap(const std::string& environmentMapUrl, EnvironmentMapData& environmentMapData);
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_ENVIRONMENT_MAP_LOADER_H
diff --git a/dali-scene3d/public-api/loader/gltf2-loader.cpp b/dali-scene3d/public-api/loader/gltf2-loader.cpp
deleted file mode 100644 (file)
index c0ca6cd..0000000
+++ /dev/null
@@ -1,1500 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// FILE HEADER
-#include <dali-scene3d/public-api/loader/gltf2-loader.h>
-
-// EXTERNAL INCLUDES
-#include <dali/devel-api/threading/mutex.h>
-#include <dali/integration-api/debug.h>
-#include <dali/public-api/images/image-operations.h>
-#include <dali/public-api/math/quaternion.h>
-#include <memory>
-
-// INTERNAL INCLUDES
-#include <dali-scene3d/internal/loader/gltf2-asset.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-scene3d/public-api/loader/utils.h>
-
-namespace gt = gltf2;
-namespace js = json;
-
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
-{
-namespace
-{
-Dali::Mutex gInitializeMutex;
-Dali::Mutex gReadMutex;
-
-const char*   POSITION_PROPERTY("position");
-const char*   ORIENTATION_PROPERTY("orientation");
-const char*   SCALE_PROPERTY("scale");
-const char*   BLEND_SHAPE_WEIGHTS_UNIFORM("uBlendShapeWeight");
-const char*   MRENDERER_MODEL_IDENTIFICATION("M-Renderer");
-const char*   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,
-  Geometry::LINE_LOOP,
-  Geometry::LINE_STRIP,
-  Geometry::TRIANGLES,
-  Geometry::TRIANGLE_STRIP,
-  Geometry::TRIANGLE_FAN}; //...because Dali swaps the last two.
-
-struct AttributeMapping
-{
-  gt::Attribute::Type      mType;
-  MeshDefinition::Accessor MeshDefinition::*mAccessor;
-  uint16_t                                  mElementSizeRequired;
-} ATTRIBUTE_MAPPINGS[]{
-  {gt::Attribute::NORMAL, &MeshDefinition::mNormals, sizeof(Vector3)},
-  {gt::Attribute::TANGENT, &MeshDefinition::mTangents, sizeof(Vector3)},
-  {gt::Attribute::TEXCOORD_0, &MeshDefinition::mTexCoords, sizeof(Vector2)},
-  {gt::Attribute::COLOR_0, &MeshDefinition::mColors, sizeof(Vector4)},
-  {gt::Attribute::JOINTS_0, &MeshDefinition::mJoints0, sizeof(Vector4)},
-  {gt::Attribute::WEIGHTS_0, &MeshDefinition::mWeights0, sizeof(Vector4)},
-};
-
-std::vector<gt::Animation> ReadAnimationArray(const json_value_s& j)
-{
-  auto results = js::Read::Array<gt::Animation, js::ObjectReader<gt::Animation>::Read>(j);
-
-  for(auto& animation : results)
-  {
-    for(auto& channel : animation.mChannels)
-    {
-      channel.mSampler.UpdateVector(animation.mSamplers);
-    }
-  }
-
-  return results;
-}
-
-void ApplyAccessorMinMax(const gt::Accessor& acc, float* values)
-{
-  DALI_ASSERT_ALWAYS(acc.mMax.empty() || gt::AccessorType::ElementCount(acc.mType) == acc.mMax.size());
-  DALI_ASSERT_ALWAYS(acc.mMin.empty() || gt::AccessorType::ElementCount(acc.mType) == acc.mMin.size());
-  MeshDefinition::Blob::ApplyMinMax(acc.mMin, acc.mMax, acc.mCount, values);
-}
-
-const js::Reader<gt::Buffer>& GetBufferReader()
-{
-  static const auto BUFFER_READER = std::move(js::Reader<gt::Buffer>()
-                                                 .Register(*js::MakeProperty("byteLength", js::Read::Number<uint32_t>, &gt::Buffer::mByteLength))
-                                                 .Register(*js::MakeProperty("uri", js::Read::StringView, &gt::Buffer::mUri)));
-  return BUFFER_READER;
-}
-
-const js::Reader<gt::BufferView>& GetBufferViewReader()
-{
-  static const auto BUFFER_VIEW_READER = std::move(js::Reader<gt::BufferView>()
-                                                      .Register(*js::MakeProperty("buffer", gt::RefReader<gt::Document>::Read<gt::Buffer, &gt::Document::mBuffers>, &gt::BufferView::mBuffer))
-                                                      .Register(*js::MakeProperty("byteOffset", js::Read::Number<uint32_t>, &gt::BufferView::mByteOffset))
-                                                      .Register(*js::MakeProperty("byteLength", js::Read::Number<uint32_t>, &gt::BufferView::mByteLength))
-                                                      .Register(*js::MakeProperty("byteStride", js::Read::Number<uint32_t>, &gt::BufferView::mByteStride))
-                                                      .Register(*js::MakeProperty("target", js::Read::Number<uint32_t>, &gt::BufferView::mTarget)));
-  return BUFFER_VIEW_READER;
-}
-
-const js::Reader<gt::BufferViewClient>& GetBufferViewClientReader()
-{
-  static const auto BUFFER_VIEW_CLIENT_READER = std::move(js::Reader<gt::BufferViewClient>()
-                                                   .Register(*js::MakeProperty("bufferView", gt::RefReader<gt::Document>::Read<gt::BufferView, &gt::Document::mBufferViews>, &gt::BufferViewClient::mBufferView))
-                                                   .Register(*js::MakeProperty("byteOffset", js::Read::Number<uint32_t>, &gt::BufferViewClient::mByteOffset)));
-  return BUFFER_VIEW_CLIENT_READER;
-}
-
-const js::Reader<gt::ComponentTypedBufferViewClient>& GetComponentTypedBufferViewClientReader()
-{
-  static const auto COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER = std::move(js::Reader<gt::ComponentTypedBufferViewClient>()
-                                                                   .Register(*new js::Property<gt::ComponentTypedBufferViewClient, gt::Ref<gt::BufferView>>("bufferView", gt::RefReader<gt::Document>::Read<gt::BufferView, &gt::Document::mBufferViews>, &gt::ComponentTypedBufferViewClient::mBufferView))
-                                                                   .Register(*new js::Property<gt::ComponentTypedBufferViewClient, uint32_t>("byteOffset", js::Read::Number<uint32_t>, &gt::ComponentTypedBufferViewClient::mByteOffset))
-                                                                   .Register(*js::MakeProperty("componentType", js::Read::Enum<gt::Component::Type>, &gt::ComponentTypedBufferViewClient::mComponentType)));
-  return COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER;
-}
-
-const js::Reader<gt::Accessor::Sparse>& GetAccessorSparseReader()
-{
-  static const auto ACCESSOR_SPARSE_READER = std::move(js::Reader<gt::Accessor::Sparse>()
-                                                .Register(*js::MakeProperty("count", js::Read::Number<uint32_t>, &gt::Accessor::Sparse::mCount))
-                                                .Register(*js::MakeProperty("indices", js::ObjectReader<gt::ComponentTypedBufferViewClient>::Read, &gt::Accessor::Sparse::mIndices))
-                                                .Register(*js::MakeProperty("values", js::ObjectReader<gt::BufferViewClient>::Read, &gt::Accessor::Sparse::mValues)));
-  return ACCESSOR_SPARSE_READER;
-}
-
-const js::Reader<gt::Accessor>& GetAccessorReader()
-{
-  static const auto ACCESSOR_READER = std::move(js::Reader<gt::Accessor>()
-                                         .Register(*new js::Property<gt::Accessor, gt::Ref<gt::BufferView>>("bufferView",
-                                                                                                            gt::RefReader<gt::Document>::Read<gt::BufferView, &gt::Document::mBufferViews>,
-                                                                                                            &gt::Accessor::mBufferView))
-                                         .Register(*new js::Property<gt::Accessor, uint32_t>("byteOffset",
-                                                                                             js::Read::Number<uint32_t>,
-                                                                                             &gt::Accessor::mByteOffset))
-                                         .Register(*new js::Property<gt::Accessor, gt::Component::Type>("componentType",
-                                                                                                        js::Read::Enum<gt::Component::Type>,
-                                                                                                        &gt::Accessor::mComponentType))
-                                         .Register(*new js::Property<gt::Accessor, std::string_view>("name", js::Read::StringView, &gt::Accessor::mName))
-                                         .Register(*js::MakeProperty("count", js::Read::Number<uint32_t>, &gt::Accessor::mCount))
-                                         .Register(*js::MakeProperty("normalized", js::Read::Boolean, &gt::Accessor::mNormalized))
-                                         .Register(*js::MakeProperty("type", gt::ReadStringEnum<gt::AccessorType>, &gt::Accessor::mType))
-                                         .Register(*js::MakeProperty("min", js::Read::Array<float, js::Read::Number>, &gt::Accessor::mMin))
-                                         .Register(*js::MakeProperty("max", js::Read::Array<float, js::Read::Number>, &gt::Accessor::mMax))
-                                         .Register(*new js::Property<gt::Accessor, gt::Accessor::Sparse>("sparse", js::ObjectReader<gt::Accessor::Sparse>::Read, &gt::Accessor::SetSparse)));
-  return ACCESSOR_READER;
-}
-
-const js::Reader<gt::Image>& GetImageReader()
-{
-  static const auto IMAGE_READER = std::move(js::Reader<gt::Image>()
-                                      .Register(*new js::Property<gt::Image, std::string_view>("name", js::Read::StringView, &gt::Material::mName))
-                                      .Register(*js::MakeProperty("uri", js::Read::StringView, &gt::Image::mUri))
-                                      .Register(*js::MakeProperty("mimeType", js::Read::StringView, &gt::Image::mMimeType))
-                                      .Register(*js::MakeProperty("bufferView", gt::RefReader<gt::Document>::Read<gt::BufferView, &gt::Document::mBufferViews>, &gt::Image::mBufferView)));
-  return IMAGE_READER;
-}
-
-const js::Reader<gt::Sampler>& GetSamplerReader()
-{
-  static const auto SAMPLER_READER = std::move(js::Reader<gt::Sampler>()
-                                        .Register(*js::MakeProperty("minFilter", js::Read::Enum<gt::Filter::Type>, &gt::Sampler::mMinFilter))
-                                        .Register(*js::MakeProperty("magFilter", js::Read::Enum<gt::Filter::Type>, &gt::Sampler::mMagFilter))
-                                        .Register(*js::MakeProperty("wrapS", js::Read::Enum<gt::Wrap::Type>, &gt::Sampler::mWrapS))
-                                        .Register(*js::MakeProperty("wrapT", js::Read::Enum<gt::Wrap::Type>, &gt::Sampler::mWrapT)));
-  return SAMPLER_READER;
-}
-
-const js::Reader<gt::Texture>& GetTextureReader()
-{
-  static const auto TEXURE_READER = std::move(js::Reader<gt::Texture>()
-                                       .Register(*js::MakeProperty("source", gt::RefReader<gt::Document>::Read<gt::Image, &gt::Document::mImages>, &gt::Texture::mSource))
-                                       .Register(*js::MakeProperty("sampler", gt::RefReader<gt::Document>::Read<gt::Sampler, &gt::Document::mSamplers>, &gt::Texture::mSampler)));
-  return TEXURE_READER;
-}
-
-const js::Reader<gt::TextureInfo>& GetTextureInfoReader()
-{
-  static const auto TEXURE_INFO_READER = std::move(js::Reader<gt::TextureInfo>()
-                                            .Register(*js::MakeProperty("index", gt::RefReader<gt::Document>::Read<gt::Texture, &gt::Document::mTextures>, &gt::TextureInfo::mTexture))
-                                            .Register(*js::MakeProperty("texCoord", js::Read::Number<uint32_t>, &gt::TextureInfo::mTexCoord))
-                                            .Register(*js::MakeProperty("scale", js::Read::Number<float>, &gt::TextureInfo::mScale))
-                                            .Register(*js::MakeProperty("strength", js::Read::Number<float>, &gt::TextureInfo::mStrength)));
-  return TEXURE_INFO_READER;
-}
-
-const js::Reader<gt::Material::Pbr>& GetMaterialPbrReader()
-{
-  static const auto MATERIAL_PBR_READER = std::move(js::Reader<gt::Material::Pbr>()
-                                             .Register(*js::MakeProperty("baseColorFactor", gt::ReadDaliVector<Vector4>, &gt::Material::Pbr::mBaseColorFactor))
-                                             .Register(*js::MakeProperty("baseColorTexture", js::ObjectReader<gt::TextureInfo>::Read, &gt::Material::Pbr::mBaseColorTexture))
-                                             .Register(*js::MakeProperty("metallicFactor", js::Read::Number<float>, &gt::Material::Pbr::mMetallicFactor))
-                                             .Register(*js::MakeProperty("roughnessFactor", js::Read::Number<float>, &gt::Material::Pbr::mRoughnessFactor))
-                                             .Register(*js::MakeProperty("metallicRoughnessTexture", js::ObjectReader<gt::TextureInfo>::Read, &gt::Material::Pbr::mMetallicRoughnessTexture)));
-  return MATERIAL_PBR_READER;
-}
-
-const js::Reader<gt::MaterialSpecular>& GetMaterialSpecularReader()
-{
-  static const auto MATERIAL_SPECULAR_READER = std::move(js::Reader<gt::MaterialSpecular>()
-                                                  .Register(*js::MakeProperty("specularFactor", js::Read::Number<float>, &gt::MaterialSpecular::mSpecularFactor))
-                                                  .Register(*js::MakeProperty("specularTexture", js::ObjectReader<gt::TextureInfo>::Read, &gt::MaterialSpecular::mSpecularTexture))
-                                                  .Register(*js::MakeProperty("specularColorFactor", gt::ReadDaliVector<Vector3>, &gt::MaterialSpecular::mSpecularColorFactor))
-                                                  .Register(*js::MakeProperty("specularColorTexture", js::ObjectReader<gt::TextureInfo>::Read, &gt::MaterialSpecular::mSpecularColorTexture)));
-  return MATERIAL_SPECULAR_READER;
-}
-
-const js::Reader<gt::MaterialIor>& GetMaterialIorReader()
-{
-  static const auto MATERIAL_IOR_READER = std::move(js::Reader<gt::MaterialIor>()
-                                             .Register(*js::MakeProperty("ior", js::Read::Number<float>, &gt::MaterialIor::mIor)));
-  return MATERIAL_IOR_READER;
-}
-
-const js::Reader<gt::MaterialExtensions>& GetMaterialExtensionsReader()
-{
-  static const auto MATERIAL_EXTENSION_READER = std::move(js::Reader<gt::MaterialExtensions>()
-                                                   .Register(*js::MakeProperty("KHR_materials_ior", js::ObjectReader<gt::MaterialIor>::Read, &gt::MaterialExtensions::mMaterialIor))
-                                                   .Register(*js::MakeProperty("KHR_materials_specular", js::ObjectReader<gt::MaterialSpecular>::Read, &gt::MaterialExtensions::mMaterialSpecular)));
-  return MATERIAL_EXTENSION_READER;
-}
-
-const js::Reader<gt::Material>& GetMaterialReader()
-{
-  static const auto MATERIAL_READER = std::move(js::Reader<gt::Material>()
-                                         .Register(*new js::Property<gt::Material, std::string_view>("name", js::Read::StringView, &gt::Material::mName))
-                                         .Register(*js::MakeProperty("pbrMetallicRoughness", js::ObjectReader<gt::Material::Pbr>::Read, &gt::Material::mPbrMetallicRoughness))
-                                         .Register(*js::MakeProperty("normalTexture", js::ObjectReader<gt::TextureInfo>::Read, &gt::Material::mNormalTexture))
-                                         .Register(*js::MakeProperty("occlusionTexture", js::ObjectReader<gt::TextureInfo>::Read, &gt::Material::mOcclusionTexture))
-                                         .Register(*js::MakeProperty("emissiveTexture", js::ObjectReader<gt::TextureInfo>::Read, &gt::Material::mEmissiveTexture))
-                                         .Register(*js::MakeProperty("emissiveFactor", gt::ReadDaliVector<Vector3>, &gt::Material::mEmissiveFactor))
-                                         .Register(*js::MakeProperty("alphaMode", gt::ReadStringEnum<gt::AlphaMode>, &gt::Material::mAlphaMode))
-                                         .Register(*js::MakeProperty("alphaCutoff", js::Read::Number<float>, &gt::Material::mAlphaCutoff))
-                                         .Register(*js::MakeProperty("doubleSided", js::Read::Boolean, &gt::Material::mDoubleSided))
-                                         .Register(*js::MakeProperty("extensions", js::ObjectReader<gt::MaterialExtensions>::Read, &gt::Material::mMaterialExtensions)));
-  return MATERIAL_READER;
-}
-
-std::map<gt::Attribute::Type, gt::Ref<gt::Accessor>> ReadMeshPrimitiveAttributes(const json_value_s& j)
-{
-  auto&                                                jo = js::Cast<json_object_s>(j);
-  std::map<gt::Attribute::Type, gt::Ref<gt::Accessor>> result;
-
-  auto i = jo.start;
-  while(i)
-  {
-    auto jstr                                                        = *i->name;
-    result[gt::Attribute::FromString(jstr.string, jstr.string_size)] = gt::RefReader<gt::Document>::Read<gt::Accessor, &gt::Document::mAccessors>(*i->value);
-    i                                                                = i->next;
-  }
-  return result;
-}
-
-std::vector<std::map<gt::Attribute::Type, gt::Ref<gt::Accessor>>> ReadMeshPrimitiveTargets(const json_value_s& j)
-{
-  auto&                                                             jo = js::Cast<json_array_s>(j);
-  std::vector<std::map<gt::Attribute::Type, gt::Ref<gt::Accessor>>> result;
-
-  result.reserve(jo.length);
-
-  auto i = jo.start;
-  while(i)
-  {
-    result.push_back(std::move(ReadMeshPrimitiveAttributes(*i->value)));
-    i = i->next;
-  }
-
-  return result;
-}
-
-const js::Reader<gt::Mesh::Primitive>& GetMeshPrimitiveReader()
-{
-  static const auto MESH_PRIMITIVE_READER = std::move(js::Reader<gt::Mesh::Primitive>()
-                                               .Register(*js::MakeProperty("attributes", ReadMeshPrimitiveAttributes, &gt::Mesh::Primitive::mAttributes))
-                                               .Register(*js::MakeProperty("indices", gt::RefReader<gt::Document>::Read<gt::Accessor, &gt::Document::mAccessors>, &gt::Mesh::Primitive::mIndices))
-                                               .Register(*js::MakeProperty("material", gt::RefReader<gt::Document>::Read<gt::Material, &gt::Document::mMaterials>, &gt::Mesh::Primitive::mMaterial))
-                                               .Register(*js::MakeProperty("mode", js::Read::Enum<gt::Mesh::Primitive::Mode>, &gt::Mesh::Primitive::mMode))
-                                               .Register(*js::MakeProperty("targets", ReadMeshPrimitiveTargets, &gt::Mesh::Primitive::mTargets)));
-  return MESH_PRIMITIVE_READER;
-}
-
-const js::Reader<gt::Mesh>& GetMeshReader()
-{
-  static const auto MESH_READER = std::move(js::Reader<gt::Mesh>()
-                                     .Register(*new js::Property<gt::Mesh, std::string_view>("name", js::Read::StringView, &gt::Mesh::mName))
-                                     .Register(*js::MakeProperty("primitives",
-                                                                 js::Read::Array<gt::Mesh::Primitive, js::ObjectReader<gt::Mesh::Primitive>::Read>,
-                                                                 &gt::Mesh::mPrimitives))
-                                     .Register(*js::MakeProperty("weights", js::Read::Array<float, js::Read::Number>, &gt::Mesh::mWeights)));
-  return MESH_READER;
-}
-
-const js::Reader<gt::Skin>& GetSkinReader()
-{
-  static const auto SKIN_READER = std::move(js::Reader<gt::Skin>()
-                                     .Register(*new js::Property<gt::Skin, std::string_view>("name", js::Read::StringView, &gt::Skin::mName))
-                                     .Register(*js::MakeProperty("inverseBindMatrices",
-                                                                 gt::RefReader<gt::Document>::Read<gt::Accessor, &gt::Document::mAccessors>,
-                                                                 &gt::Skin::mInverseBindMatrices))
-                                     .Register(*js::MakeProperty("skeleton",
-                                                                 gt::RefReader<gt::Document>::Read<gt::Node, &gt::Document::mNodes>,
-                                                                 &gt::Skin::mSkeleton))
-                                     .Register(*js::MakeProperty("joints",
-                                                                 js::Read::Array<gt::Ref<gt::Node>, gt::RefReader<gt::Document>::Read<gt::Node, &gt::Document::mNodes>>,
-                                                                 &gt::Skin::mJoints)));
-  return SKIN_READER;
-}
-
-const js::Reader<gt::Camera::Perspective>& GetCameraPerspectiveReader()
-{
-  static const auto CAMERA_PERSPECTIVE_READER = std::move(js::Reader<gt::Camera::Perspective>()
-                                                   .Register(*js::MakeProperty("aspectRatio", js::Read::Number<float>, &gt::Camera::Perspective::mAspectRatio))
-                                                   .Register(*js::MakeProperty("yfov", js::Read::Number<float>, &gt::Camera::Perspective::mYFov))
-                                                   .Register(*js::MakeProperty("zfar", js::Read::Number<float>, &gt::Camera::Perspective::mZFar))
-                                                   .Register(*js::MakeProperty("znear", js::Read::Number<float>, &gt::Camera::Perspective::mZNear))); // TODO: infinite perspective projection, where znear is omitted
-  return CAMERA_PERSPECTIVE_READER;
-}
-
-const js::Reader<gt::Camera::Orthographic>& GetCameraOrthographicReader()
-{
-  static const auto CAMERA_ORTHOGRAPHIC_READER = std::move(js::Reader<gt::Camera::Orthographic>()
-                                                    .Register(*js::MakeProperty("xmag", js::Read::Number<float>, &gt::Camera::Orthographic::mXMag))
-                                                    .Register(*js::MakeProperty("ymag", js::Read::Number<float>, &gt::Camera::Orthographic::mYMag))
-                                                    .Register(*js::MakeProperty("zfar", js::Read::Number<float>, &gt::Camera::Orthographic::mZFar))
-                                                    .Register(*js::MakeProperty("znear", js::Read::Number<float>, &gt::Camera::Orthographic::mZNear)));
-  return CAMERA_ORTHOGRAPHIC_READER;
-}
-
-const js::Reader<gt::Camera>& GetCameraReader()
-{
-  static const auto CAMERA_READER = std::move(js::Reader<gt::Camera>()
-                                       .Register(*new js::Property<gt::Camera, std::string_view>("name", js::Read::StringView, &gt::Camera::mName))
-                                       .Register(*js::MakeProperty("type", js::Read::StringView, &gt::Camera::mType))
-                                       .Register(*js::MakeProperty("perspective", js::ObjectReader<gt::Camera::Perspective>::Read, &gt::Camera::mPerspective))
-                                       .Register(*js::MakeProperty("orthographic", js::ObjectReader<gt::Camera::Orthographic>::Read, &gt::Camera::mOrthographic)));
-  return CAMERA_READER;
-}
-
-const js::Reader<gt::Node>& GetNodeReader()
-{
-  static const auto NODE_READER = std::move(js::Reader<gt::Node>()
-                                     .Register(*new js::Property<gt::Node, std::string_view>("name", js::Read::StringView, &gt::Node::mName))
-                                     .Register(*js::MakeProperty("translation", gt::ReadDaliVector<Vector3>, &gt::Node::mTranslation))
-                                     .Register(*js::MakeProperty("rotation", gt::ReadQuaternion, &gt::Node::mRotation))
-                                     .Register(*js::MakeProperty("scale", gt::ReadDaliVector<Vector3>, &gt::Node::mScale))
-                                     .Register(*new js::Property<gt::Node, Matrix>("matrix", gt::ReadDaliVector<Matrix>, &gt::Node::SetMatrix))
-                                     .Register(*js::MakeProperty("camera", gt::RefReader<gt::Document>::Read<gt::Camera, &gt::Document::mCameras>, &gt::Node::mCamera))
-                                     .Register(*js::MakeProperty("children", js::Read::Array<gt::Ref<gt::Node>, gt::RefReader<gt::Document>::Read<gt::Node, &gt::Document::mNodes>>, &gt::Node::mChildren))
-                                     .Register(*js::MakeProperty("mesh", gt::RefReader<gt::Document>::Read<gt::Mesh, &gt::Document::mMeshes>, &gt::Node::mMesh))
-                                     .Register(*js::MakeProperty("skin", gt::RefReader<gt::Document>::Read<gt::Skin, &gt::Document::mSkins>, &gt::Node::mSkin)));
-  return NODE_READER;
-}
-
-const js::Reader<gt::Animation::Sampler>& GetAnimationSamplerReader()
-{
-  static const auto ANIMATION_SAMPLER_READER = std::move(js::Reader<gt::Animation::Sampler>()
-                                                  .Register(*js::MakeProperty("input", gt::RefReader<gt::Document>::Read<gt::Accessor, &gt::Document::mAccessors>, &gt::Animation::Sampler::mInput))
-                                                  .Register(*js::MakeProperty("output", gt::RefReader<gt::Document>::Read<gt::Accessor, &gt::Document::mAccessors>, &gt::Animation::Sampler::mOutput))
-                                                  .Register(*js::MakeProperty("interpolation", gt::ReadStringEnum<gt::Animation::Sampler::Interpolation>, &gt::Animation::Sampler::mInterpolation)));
-  return ANIMATION_SAMPLER_READER;
-}
-
-const js::Reader<gt::Animation::Channel::Target>& GetAnimationChannelTargetReader()
-{
-  static const auto ANIMATION_TARGET_READER = std::move(js::Reader<gt::Animation::Channel::Target>()
-                                                 .Register(*js::MakeProperty("node", gt::RefReader<gt::Document>::Read<gt::Node, &gt::Document::mNodes>, &gt::Animation::Channel::Target::mNode))
-                                                 .Register(*js::MakeProperty("path", gt::ReadStringEnum<gt::Animation::Channel::Target>, &gt::Animation::Channel::Target::mPath)));
-  return ANIMATION_TARGET_READER;
-}
-
-const js::Reader<gt::Animation::Channel>& GetAnimationChannelReader()
-{
-  static const auto ANIMATION_CHANNEL_READER = std::move(js::Reader<gt::Animation::Channel>()
-                                                  .Register(*js::MakeProperty("target", js::ObjectReader<gt::Animation::Channel::Target>::Read, &gt::Animation::Channel::mTarget))
-                                                  .Register(*js::MakeProperty("sampler", gt::RefReader<gt::Animation>::Read<gt::Animation::Sampler, &gt::Animation::mSamplers>, &gt::Animation::Channel::mSampler)));
-  return ANIMATION_CHANNEL_READER;
-}
-
-const js::Reader<gt::Animation>& GetAnimationReader()
-{
-  static const auto ANIMATION_READER = std::move(js::Reader<gt::Animation>()
-                                          .Register(*new js::Property<gt::Animation, std::string_view>("name", js::Read::StringView, &gt::Animation::mName))
-                                          .Register(*js::MakeProperty("samplers",
-                                                                      js::Read::Array<gt::Animation::Sampler, js::ObjectReader<gt::Animation::Sampler>::Read>,
-                                                                      &gt::Animation::mSamplers))
-                                          .Register(*js::MakeProperty("channels",
-                                                                      js::Read::Array<gt::Animation::Channel, js::ObjectReader<gt::Animation::Channel>::Read>,
-                                                                      &gt::Animation::mChannels)));
-  return ANIMATION_READER;
-}
-
-const js::Reader<gt::Scene>& GetSceneReader()
-{
-  static const auto SCENE_READER = std::move(js::Reader<gt::Scene>()
-                                      .Register(*new js::Property<gt::Scene, std::string_view>("name", js::Read::StringView, &gt::Scene::mName))
-                                      .Register(*js::MakeProperty("nodes",
-                                                                  js::Read::Array<gt::Ref<gt::Node>, gt::RefReader<gt::Document>::Read<gt::Node, &gt::Document::mNodes>>,
-                                                                  &gt::Scene::mNodes)));
-  return SCENE_READER;
-}
-
-const js::Reader<gt::Document>& GetDocumentReader()
-{
-  static const auto DOCUMENT_READER = std::move(js::Reader<gt::Document>()
-                                         .Register(*js::MakeProperty("buffers",
-                                                                     js::Read::Array<gt::Buffer, js::ObjectReader<gt::Buffer>::Read>,
-                                                                     &gt::Document::mBuffers))
-                                         .Register(*js::MakeProperty("bufferViews",
-                                                                     js::Read::Array<gt::BufferView, js::ObjectReader<gt::BufferView>::Read>,
-                                                                     &gt::Document::mBufferViews))
-                                         .Register(*js::MakeProperty("accessors",
-                                                                     js::Read::Array<gt::Accessor, js::ObjectReader<gt::Accessor>::Read>,
-                                                                     &gt::Document::mAccessors))
-                                         .Register(*js::MakeProperty("images",
-                                                                     js::Read::Array<gt::Image, js::ObjectReader<gt::Image>::Read>,
-                                                                     &gt::Document::mImages))
-                                         .Register(*js::MakeProperty("samplers",
-                                                                     js::Read::Array<gt::Sampler, js::ObjectReader<gt::Sampler>::Read>,
-                                                                     &gt::Document::mSamplers))
-                                         .Register(*js::MakeProperty("textures",
-                                                                     js::Read::Array<gt::Texture, js::ObjectReader<gt::Texture>::Read>,
-                                                                     &gt::Document::mTextures))
-                                         .Register(*js::MakeProperty("materials",
-                                                                     js::Read::Array<gt::Material, js::ObjectReader<gt::Material>::Read>,
-                                                                     &gt::Document::mMaterials))
-                                         .Register(*js::MakeProperty("meshes",
-                                                                     js::Read::Array<gt::Mesh, js::ObjectReader<gt::Mesh>::Read>,
-                                                                     &gt::Document::mMeshes))
-                                         .Register(*js::MakeProperty("skins",
-                                                                     js::Read::Array<gt::Skin, js::ObjectReader<gt::Skin>::Read>,
-                                                                     &gt::Document::mSkins))
-                                         .Register(*js::MakeProperty("cameras",
-                                                                     js::Read::Array<gt::Camera, js::ObjectReader<gt::Camera>::Read>,
-                                                                     &gt::Document::mCameras))
-                                         .Register(*js::MakeProperty("nodes",
-                                                                     js::Read::Array<gt::Node, js::ObjectReader<gt::Node>::Read>,
-                                                                     &gt::Document::mNodes))
-                                         .Register(*js::MakeProperty("animations",
-                                                                     ReadAnimationArray,
-                                                                     &gt::Document::mAnimations))
-                                         .Register(*js::MakeProperty("scenes",
-                                                                     js::Read::Array<gt::Scene, js::ObjectReader<gt::Scene>::Read>,
-                                                                     &gt::Document::mScenes))
-                                         .Register(*js::MakeProperty("scene", gt::RefReader<gt::Document>::Read<gt::Scene, &gt::Document::mScenes>, &gt::Document::mScene)));
-  return DOCUMENT_READER;
-}
-
-struct NodeMapping
-{
-  Index gltfIdx;
-  Index runtimeIdx;
-};
-
-bool operator<(const NodeMapping& mapping, Index gltfIdx)
-{
-  return mapping.gltfIdx < gltfIdx;
-}
-
-class NodeIndexMapper
-{
-public:
-  NodeIndexMapper()                       = default;
-  NodeIndexMapper(const NodeIndexMapper&) = delete;
-  NodeIndexMapper& operator=(const NodeIndexMapper&) = delete;
-
-  ///@brief Registers a mapping of the @a gltfIdx of a node to its @a runtimeIdx .
-  ///@note If the indices are the same, the registration is omitted, in order to
-  /// save growing a vector.
-  void RegisterMapping(Index gltfIdx, Index runtimeIdx)
-  {
-    if(gltfIdx != runtimeIdx)
-    {
-      auto iInsert = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx);
-      DALI_ASSERT_DEBUG(iInsert == mNodes.end() || iInsert->gltfIdx != gltfIdx);
-      mNodes.insert(iInsert, NodeMapping{gltfIdx, runtimeIdx});
-    }
-  }
-
-  ///@brief Retrieves the runtime index of a Node, mapped to the given @a gltfIdx.
-  Index GetRuntimeId(Index gltfIdx) const
-  {
-    auto iFind = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx); // using custom operator<
-    return (iFind != mNodes.end() && iFind->gltfIdx == gltfIdx) ? iFind->runtimeIdx : gltfIdx;
-  }
-
-private:
-  std::vector<NodeMapping> mNodes;
-};
-
-struct ConversionContext
-{
-  LoadResult& mOutput;
-
-  std::string mPath;
-  Index       mDefaultMaterial;
-
-  std::vector<Index> mMeshIds;
-  NodeIndexMapper    mNodeIndices;
-};
-
-void ConvertBuffer(const gt::Buffer& buffer, decltype(ResourceBundle::mBuffers)& outBuffers, const std::string& resourcePath)
-{
-  BufferDefinition bufferDefinition;
-
-  bufferDefinition.mResourcePath = resourcePath;
-  bufferDefinition.mUri          = buffer.mUri;
-  bufferDefinition.mByteLength   = buffer.mByteLength;
-
-  outBuffers.emplace_back(std::move(bufferDefinition));
-}
-
-void ConvertBuffers(const gt::Document& doc, ConversionContext& context)
-{
-  auto& outBuffers = context.mOutput.mResources.mBuffers;
-  outBuffers.reserve(doc.mBuffers.size());
-
-  for(auto& buffer : doc.mBuffers)
-  {
-    ConvertBuffer(buffer, outBuffers, context.mPath);
-  }
-}
-
-SamplerFlags::Type ConvertWrapMode(gt::Wrap::Type wrapMode)
-{
-  switch(wrapMode)
-  {
-    case gt::Wrap::REPEAT:
-      return SamplerFlags::WRAP_REPEAT;
-    case gt::Wrap::CLAMP_TO_EDGE:
-      return SamplerFlags::WRAP_CLAMP;
-    case gt::Wrap::MIRRORED_REPEAT:
-      return SamplerFlags::WRAP_MIRROR;
-    default:
-      throw std::runtime_error("Invalid wrap type.");
-  }
-}
-
-SamplerFlags::Type ConvertSampler(const gt::Ref<gt::Sampler>& sampler)
-{
-  if(sampler)
-  {
-    return ((sampler->mMinFilter < gt::Filter::NEAREST_MIPMAP_NEAREST) ? (sampler->mMinFilter - gt::Filter::NEAREST) : ((sampler->mMinFilter - gt::Filter::NEAREST_MIPMAP_NEAREST) + 2)) |
-           ((sampler->mMagFilter - gt::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) |
-           (ConvertWrapMode(sampler->mWrapS) << SamplerFlags::WRAP_S_SHIFT) |
-           (ConvertWrapMode(sampler->mWrapT) << SamplerFlags::WRAP_T_SHIFT);
-  }
-  else
-  {
-    // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#texturesampler
-    // "The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used."
-    // "What is an auto filtering", I hear you ask. Since there's nothing else to determine mipmapping from - including glTF image
-    // properties, if not in some extension -, we will simply assume linear filtering.
-    return SamplerFlags::FILTER_LINEAR | (SamplerFlags::FILTER_LINEAR << SamplerFlags::FILTER_MAG_SHIFT) |
-           (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_S_SHIFT) | (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_T_SHIFT);
-  }
-}
-
-TextureDefinition ConvertTextureInfo(const gt::TextureInfo& mm, ConversionContext& context, const ImageMetadata& metaData = ImageMetadata())
-{
-  TextureDefinition textureDefinition;
-  std::string       uri = std::string(mm.mTexture->mSource->mUri);
-  if(uri.empty())
-  {
-    uint32_t bufferIndex = mm.mTexture->mSource->mBufferView->mBuffer.GetIndex();
-    if(bufferIndex != INVALID_INDEX && context.mOutput.mResources.mBuffers[bufferIndex].IsAvailable())
-    {
-      auto& stream = context.mOutput.mResources.mBuffers[bufferIndex].GetBufferStream();
-      stream.clear();
-      stream.seekg(mm.mTexture->mSource->mBufferView->mByteOffset, stream.beg);
-      std::vector<uint8_t> dataBuffer;
-      dataBuffer.resize(mm.mTexture->mSource->mBufferView->mByteLength);
-      stream.read(reinterpret_cast<char*>(dataBuffer.data()), static_cast<std::streamsize>(static_cast<size_t>(mm.mTexture->mSource->mBufferView->mByteLength)));
-      return TextureDefinition{std::move(dataBuffer), ConvertSampler(mm.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode};
-    }
-    return TextureDefinition();
-  }
-  else
-  {
-    return TextureDefinition{uri, ConvertSampler(mm.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode};
-  }
-}
-
-void ConvertMaterial(const gt::Material& material, const std::unordered_map<std::string, ImageMetadata>& imageMetaData, decltype(ResourceBundle::mMaterials)& outMaterials, ConversionContext& context)
-{
-  auto getTextureMetaData = [](const std::unordered_map<std::string, ImageMetadata>& metaData, const gt::TextureInfo& info) {
-    if(!info.mTexture->mSource->mUri.empty())
-    {
-      if(auto search = metaData.find(info.mTexture->mSource->mUri.data()); search != metaData.end())
-      {
-        return search->second;
-      }
-    }
-    return ImageMetadata();
-  };
-
-  MaterialDefinition matDef;
-
-  auto& pbr = material.mPbrMetallicRoughness;
-  if(material.mAlphaMode == gt::AlphaMode::BLEND)
-  {
-    matDef.mIsOpaque = false;
-    matDef.mFlags |= MaterialDefinition::TRANSPARENCY;
-  }
-  else if(material.mAlphaMode == gt::AlphaMode::MASK)
-  {
-    matDef.mIsMask = true;
-    matDef.SetAlphaCutoff(std::min(1.f, std::max(0.f, material.mAlphaCutoff)));
-  }
-
-  matDef.mBaseColorFactor = pbr.mBaseColorFactor;
-
-  matDef.mTextureStages.reserve(!!pbr.mBaseColorTexture + !!pbr.mMetallicRoughnessTexture + !!material.mNormalTexture + !!material.mOcclusionTexture + !!material.mEmissiveTexture);
-  if(pbr.mBaseColorTexture)
-  {
-    const auto semantic = MaterialDefinition::ALBEDO;
-    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(pbr.mBaseColorTexture, context, getTextureMetaData(imageMetaData, pbr.mBaseColorTexture))});
-    // TODO: and there had better be one
-    matDef.mFlags |= semantic;
-  }
-  else
-  {
-    matDef.mNeedAlbedoTexture = false;
-  }
-
-  matDef.mMetallic  = pbr.mMetallicFactor;
-  matDef.mRoughness = pbr.mRoughnessFactor;
-
-  if(pbr.mMetallicRoughnessTexture)
-  {
-    const auto semantic = MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
-                          MaterialDefinition::GLTF_CHANNELS;
-    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(pbr.mMetallicRoughnessTexture, context, getTextureMetaData(imageMetaData, pbr.mMetallicRoughnessTexture))});
-    // TODO: and there had better be one
-    matDef.mFlags |= semantic;
-  }
-  else
-  {
-    matDef.mNeedMetallicRoughnessTexture = false;
-  }
-
-  matDef.mNormalScale = material.mNormalTexture.mScale;
-  if(material.mNormalTexture)
-  {
-    const auto semantic = MaterialDefinition::NORMAL;
-    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mNormalTexture, context, getTextureMetaData(imageMetaData, material.mNormalTexture))});
-    // TODO: and there had better be one
-    matDef.mFlags |= semantic;
-  }
-  else
-  {
-    matDef.mNeedNormalTexture = false;
-  }
-
-  if(material.mOcclusionTexture)
-  {
-    const auto semantic = MaterialDefinition::OCCLUSION;
-    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mOcclusionTexture, context, getTextureMetaData(imageMetaData, material.mOcclusionTexture))});
-    // TODO: and there had better be one
-    matDef.mFlags |= semantic;
-    matDef.mOcclusionStrength = material.mOcclusionTexture.mStrength;
-  }
-
-  if(material.mEmissiveTexture)
-  {
-    const auto semantic = MaterialDefinition::EMISSIVE;
-    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mEmissiveTexture, context, getTextureMetaData(imageMetaData, material.mEmissiveTexture))});
-    // TODO: and there had better be one
-    matDef.mFlags |= semantic;
-    matDef.mEmissiveFactor = material.mEmissiveFactor;
-  }
-
-  if(!Dali::Equals(material.mMaterialExtensions.mMaterialIor.mIor, gltf2::UNDEFINED_FLOAT_VALUE))
-  {
-    float ior                  = material.mMaterialExtensions.mMaterialIor.mIor;
-    matDef.mDielectricSpecular = powf((ior - 1.0f) / (ior + 1.0f), 2.0f);
-  }
-  matDef.mSpecularFactor      = material.mMaterialExtensions.mMaterialSpecular.mSpecularFactor;
-  matDef.mSpecularColorFactor = material.mMaterialExtensions.mMaterialSpecular.mSpecularColorFactor;
-
-  if(material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture)
-  {
-    const auto semantic = MaterialDefinition::SPECULAR;
-    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture, context, getTextureMetaData(imageMetaData, material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture))});
-    matDef.mFlags |= semantic;
-  }
-
-  if(material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture)
-  {
-    const auto semantic = MaterialDefinition::SPECULAR_COLOR;
-    matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture, context, getTextureMetaData(imageMetaData, material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture))});
-    matDef.mFlags |= semantic;
-  }
-
-  matDef.mDoubleSided = material.mDoubleSided;
-
-  outMaterials.emplace_back(std::move(matDef), TextureSet());
-}
-
-void ConvertMaterials(const gt::Document& doc, ConversionContext& context)
-{
-  auto& imageMetaData = context.mOutput.mSceneMetadata.mImageMetadata;
-
-  auto& outMaterials = context.mOutput.mResources.mMaterials;
-  outMaterials.reserve(doc.mMaterials.size());
-
-  for(auto& m : doc.mMaterials)
-  {
-    ConvertMaterial(m, imageMetaData, outMaterials, context);
-  }
-}
-
-MeshDefinition::Accessor ConvertMeshPrimitiveAccessor(const gt::Accessor& acc)
-{
-  DALI_ASSERT_ALWAYS((acc.mBufferView &&
-                      (acc.mBufferView->mByteStride < std::numeric_limits<uint16_t>::max())) ||
-                     (acc.mSparse && !acc.mBufferView));
-
-  DALI_ASSERT_ALWAYS(!acc.mSparse ||
-                     ((acc.mSparse->mIndices.mBufferView && (acc.mSparse->mIndices.mBufferView->mByteStride < std::numeric_limits<uint16_t>::max())) &&
-                      (acc.mSparse->mValues.mBufferView && (acc.mSparse->mValues.mBufferView->mByteStride < std::numeric_limits<uint16_t>::max()))));
-
-  MeshDefinition::SparseBlob sparseBlob;
-  if(acc.mSparse)
-  {
-    const gt::Accessor::Sparse&               sparse  = *acc.mSparse;
-    const gt::ComponentTypedBufferViewClient& indices = sparse.mIndices;
-    const gt::BufferViewClient&               values  = sparse.mValues;
-
-    MeshDefinition::Blob indicesBlob(
-      indices.mBufferView->mByteOffset + indices.mByteOffset,
-      sparse.mCount * indices.GetBytesPerComponent(),
-      static_cast<uint16_t>(indices.mBufferView->mByteStride),
-      static_cast<uint16_t>(indices.GetBytesPerComponent()),
-      {},
-      {});
-    MeshDefinition::Blob valuesBlob(
-      values.mBufferView->mByteOffset + values.mByteOffset,
-      sparse.mCount * acc.GetElementSizeBytes(),
-      static_cast<uint16_t>(values.mBufferView->mByteStride),
-      static_cast<uint16_t>(acc.GetElementSizeBytes()),
-      {},
-      {});
-
-    sparseBlob = std::move(MeshDefinition::SparseBlob(std::move(indicesBlob), std::move(valuesBlob), acc.mSparse->mCount));
-  }
-
-  uint32_t bufferViewOffset = 0u;
-  uint32_t bufferViewStride = 0u;
-  if(acc.mBufferView)
-  {
-    bufferViewOffset = acc.mBufferView->mByteOffset;
-    bufferViewStride = acc.mBufferView->mByteStride;
-  }
-
-  return MeshDefinition::Accessor{
-    std::move(MeshDefinition::Blob{bufferViewOffset + acc.mByteOffset,
-                                   acc.GetBytesLength(),
-                                   static_cast<uint16_t>(bufferViewStride),
-                                   static_cast<uint16_t>(acc.GetElementSizeBytes()),
-                                   acc.mMin,
-                                   acc.mMax}),
-    std::move(sparseBlob),
-    acc.mBufferView ? acc.mBufferView->mBuffer.GetIndex() : 0};
-}
-
-void ConvertMeshes(const gt::Document& doc, ConversionContext& context)
-{
-  uint32_t meshCount = 0;
-  context.mMeshIds.reserve(doc.mMeshes.size());
-  for(auto& mesh : doc.mMeshes)
-  {
-    context.mMeshIds.push_back(meshCount);
-    meshCount += mesh.mPrimitives.size();
-  }
-
-  auto& outMeshes = context.mOutput.mResources.mMeshes;
-  outMeshes.reserve(meshCount);
-  for(auto& mesh : doc.mMeshes)
-  {
-    for(auto& primitive : mesh.mPrimitives)
-    {
-      MeshDefinition meshDefinition;
-
-      auto& attribs                 = primitive.mAttributes;
-      meshDefinition.mPrimitiveType = GLTF2_TO_DALI_PRIMITIVES[primitive.mMode];
-
-      auto& accPositions        = *attribs.find(gt::Attribute::POSITION)->second;
-      meshDefinition.mPositions = ConvertMeshPrimitiveAccessor(accPositions);
-      // glTF2 support vector4 tangent for mesh.
-      // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#meshes-overview
-      meshDefinition.mTangentType = Property::VECTOR4;
-
-      const bool needNormalsTangents = accPositions.mType == gt::AccessorType::VEC3;
-      for(auto& am : ATTRIBUTE_MAPPINGS)
-      {
-        auto iFind = attribs.find(am.mType);
-        if(iFind != attribs.end())
-        {
-          auto& accessor = meshDefinition.*(am.mAccessor);
-          accessor       = ConvertMeshPrimitiveAccessor(*iFind->second);
-
-          if(iFind->first == gt::Attribute::JOINTS_0)
-          {
-            meshDefinition.mFlags |= (iFind->second->mComponentType == gt::Component::UNSIGNED_SHORT) * MeshDefinition::U16_JOINT_IDS;
-            meshDefinition.mFlags |= (iFind->second->mComponentType == gt::Component::UNSIGNED_BYTE) * MeshDefinition::U8_JOINT_IDS;
-            DALI_ASSERT_DEBUG(MaskMatch(meshDefinition.mFlags, MeshDefinition::U16_JOINT_IDS) || MaskMatch(meshDefinition.mFlags, MeshDefinition::U8_JOINT_IDS) || iFind->second->mComponentType == gt::Component::FLOAT);
-          }
-        }
-        else if(needNormalsTangents)
-        {
-          switch(am.mType)
-          {
-            case gt::Attribute::NORMAL:
-              meshDefinition.RequestNormals();
-              break;
-
-            case gt::Attribute::TANGENT:
-              meshDefinition.RequestTangents();
-              break;
-
-            default:
-              break;
-          }
-        }
-      }
-
-      if(primitive.mIndices)
-      {
-        meshDefinition.mIndices = ConvertMeshPrimitiveAccessor(*primitive.mIndices);
-        meshDefinition.mFlags |= (primitive.mIndices->mComponentType == gt::Component::UNSIGNED_INT) * MeshDefinition::U32_INDICES;
-        meshDefinition.mFlags |= (primitive.mIndices->mComponentType == gt::Component::UNSIGNED_BYTE) * MeshDefinition::U8_INDICES;
-        DALI_ASSERT_DEBUG(MaskMatch(meshDefinition.mFlags, MeshDefinition::U32_INDICES) || MaskMatch(meshDefinition.mFlags, MeshDefinition::U8_INDICES) || primitive.mIndices->mComponentType == gt::Component::UNSIGNED_SHORT);
-      }
-
-      if(!primitive.mTargets.empty())
-      {
-        meshDefinition.mBlendShapes.reserve(primitive.mTargets.size());
-        meshDefinition.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0;
-        for(const auto& target : primitive.mTargets)
-        {
-          MeshDefinition::BlendShape blendShape;
-
-          auto endIt = target.end();
-          auto it    = target.find(gt::Attribute::POSITION);
-          if(it != endIt)
-          {
-            blendShape.deltas = ConvertMeshPrimitiveAccessor(*it->second);
-          }
-          it = target.find(gt::Attribute::NORMAL);
-          if(it != endIt)
-          {
-            blendShape.normals = ConvertMeshPrimitiveAccessor(*it->second);
-          }
-          it = target.find(gt::Attribute::TANGENT);
-          if(it != endIt)
-          {
-            blendShape.tangents = ConvertMeshPrimitiveAccessor(*it->second);
-          }
-
-          if(!mesh.mWeights.empty())
-          {
-            blendShape.weight = mesh.mWeights[meshDefinition.mBlendShapes.size()];
-          }
-
-          meshDefinition.mBlendShapes.push_back(std::move(blendShape));
-        }
-      }
-
-      outMeshes.push_back({std::move(meshDefinition), MeshGeometry{}});
-    }
-  }
-}
-
-ModelRenderable* MakeModelRenderable(const gt::Mesh::Primitive& prim, ConversionContext& context)
-{
-  auto modelRenderable = new ModelRenderable();
-
-  modelRenderable->mShaderIdx = 0; // TODO: further thought
-
-  auto materialIdx = prim.mMaterial.GetIndex();
-  if(INVALID_INDEX == materialIdx)
-  {
-    // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#default-material
-    if(INVALID_INDEX == context.mDefaultMaterial)
-    {
-      auto& outMaterials       = context.mOutput.mResources.mMaterials;
-      context.mDefaultMaterial = outMaterials.size();
-
-      ConvertMaterial(gt::Material{}, context.mOutput.mSceneMetadata.mImageMetadata, outMaterials, context);
-    }
-
-    materialIdx = context.mDefaultMaterial;
-  }
-
-  modelRenderable->mMaterialIdx = materialIdx;
-
-  return modelRenderable;
-}
-
-void ConvertCamera(const gt::Camera& camera, CameraParameters& camParams)
-{
-  camParams.isPerspective = camera.mType.compare("perspective") == 0;
-  if(camParams.isPerspective)
-  {
-    auto& perspective = camera.mPerspective;
-    if(!Dali::Equals(perspective.mYFov, gltf2::UNDEFINED_FLOAT_VALUE))
-    {
-      camParams.yFovDegree = Degree(Radian(perspective.mYFov));
-    }
-    else
-    {
-      camParams.yFovDegree = Degree(gltf2::UNDEFINED_FLOAT_VALUE);
-    }
-    camParams.zNear = perspective.mZNear;
-    camParams.zFar  = perspective.mZFar;
-    // TODO: yes, we seem to ignore aspectRatio in CameraParameters.
-  }
-  else
-  {
-    auto& ortho = camera.mOrthographic;
-    if(!Dali::Equals(ortho.mYMag, gltf2::UNDEFINED_FLOAT_VALUE) && !Dali::Equals(ortho.mXMag, gltf2::UNDEFINED_FLOAT_VALUE))
-    {
-      camParams.orthographicSize = ortho.mYMag * .5f;
-      camParams.aspectRatio      = ortho.mXMag / ortho.mYMag;
-    }
-    else
-    {
-      camParams.orthographicSize = gltf2::UNDEFINED_FLOAT_VALUE;
-      camParams.aspectRatio      = gltf2::UNDEFINED_FLOAT_VALUE;
-    }
-    camParams.zNear = ortho.mZNear;
-    camParams.zFar  = ortho.mZFar;
-  }
-}
-
-void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& context, bool isMRendererModel)
-{
-  auto& output    = context.mOutput;
-  auto& scene     = output.mScene;
-  auto& resources = output.mResources;
-
-  const auto idx      = scene.GetNodeCount();
-  auto       weakNode = scene.AddNode([&]() {
-    std::unique_ptr<NodeDefinition> nodeDef{new NodeDefinition()};
-
-    nodeDef->mParentIdx = parentIdx;
-    nodeDef->mName      = node.mName;
-    if(nodeDef->mName.empty())
-    {
-      // TODO: Production quality generation of unique names.
-      nodeDef->mName = std::to_string(reinterpret_cast<uintptr_t>(nodeDef.get()));
-    }
-
-    if(!node.mSkin) // Nodes with skinned meshes are not supposed to have local transforms.
-    {
-      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;
-  }());
-  if(!weakNode)
-  {
-    ExceptionFlinger(ASSERT_LOCATION) << "Node name '" << node.mName << "' is not unique; scene is invalid.";
-  }
-
-  context.mNodeIndices.RegisterMapping(gltfIdx, idx);
-
-  Index skeletonIdx = node.mSkin ? node.mSkin.GetIndex() : INVALID_INDEX;
-  if(node.mMesh)
-  {
-    auto&    mesh           = *node.mMesh;
-    uint32_t primitiveCount = mesh.mPrimitives.size();
-    auto     meshIdx        = context.mMeshIds[node.mMesh.GetIndex()];
-    weakNode->mRenderables.reserve(primitiveCount);
-    for(uint32_t i = 0; i < primitiveCount; ++i)
-    {
-      std::unique_ptr<NodeDefinition::Renderable> renderable;
-      auto                                        modelRenderable = MakeModelRenderable(mesh.mPrimitives[i], context);
-      modelRenderable->mMeshIdx                                   = meshIdx + i;
-
-      DALI_ASSERT_DEBUG(resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx == INVALID_INDEX ||
-                        resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx == skeletonIdx);
-      resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx = skeletonIdx;
-
-      renderable.reset(modelRenderable);
-      weakNode->mRenderables.push_back(std::move(renderable));
-    }
-  }
-
-  if(node.mCamera)
-  {
-    CameraParameters camParams;
-    ConvertCamera(*node.mCamera, camParams);
-
-    camParams.matrix.SetTransformComponents(node.mScale, node.mRotation, node.mTranslation);
-    output.mCameraParameters.push_back(camParams);
-  }
-
-  for(auto& n : node.mChildren)
-  {
-    ConvertNode(*n, n.GetIndex(), idx, context, isMRendererModel);
-  }
-}
-
-void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& context, bool isMRendererModel)
-{
-  auto& outScene = context.mOutput.mScene;
-  Index rootIdx  = outScene.GetNodeCount();
-  switch(scene.mNodes.size())
-  {
-    case 0:
-      break;
-
-    case 1:
-      ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, context, isMRendererModel);
-      outScene.AddRootNode(rootIdx);
-      break;
-
-    default:
-    {
-      std::unique_ptr<NodeDefinition> sceneRoot{new NodeDefinition()};
-      sceneRoot->mName = "GLTF_LOADER_SCENE_ROOT_" + std::to_string(outScene.GetRoots().size());
-
-      outScene.AddNode(std::move(sceneRoot));
-      outScene.AddRootNode(rootIdx);
-
-      for(auto& n : scene.mNodes)
-      {
-        ConvertNode(*n, n.GetIndex(), rootIdx, context, isMRendererModel);
-      }
-      break;
-    }
-  }
-}
-
-void ConvertNodes(const gt::Document& doc, ConversionContext& context, bool isMRendererModel)
-{
-  if(!doc.mScenes.empty())
-  {
-    uint32_t rootSceneIndex = 0u;
-    if(doc.mScene)
-    {
-      rootSceneIndex = doc.mScene.GetIndex();
-    }
-    ConvertSceneNodes(doc.mScenes[rootSceneIndex], context, isMRendererModel);
-
-    for(uint32_t i = 0, i1 = rootSceneIndex; i < i1; ++i)
-    {
-      ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel);
-    }
-
-    for(uint32_t i = rootSceneIndex + 1; i < doc.mScenes.size(); ++i)
-    {
-      ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel);
-    }
-  }
-}
-
-template<typename T>
-void LoadDataFromAccessor(ConversionContext& context, uint32_t bufferIndex, Vector<T>& dataBuffer, uint32_t offset, uint32_t size)
-{
-  if(bufferIndex >= context.mOutput.mResources.mBuffers.size())
-  {
-    DALI_LOG_ERROR("Invailid buffer index\n");
-    return;
-  }
-
-  auto& buffer = context.mOutput.mResources.mBuffers[bufferIndex];
-  if(!buffer.IsAvailable())
-  {
-    DALI_LOG_ERROR("Failed to load from buffer stream.\n");
-  }
-  auto& stream = buffer.GetBufferStream();
-  stream.clear();
-  stream.seekg(offset, stream.beg);
-  stream.read(reinterpret_cast<char*>(dataBuffer.Begin()), static_cast<std::streamsize>(static_cast<size_t>(size)));
-}
-
-template<typename T>
-float LoadDataFromAccessors(ConversionContext& context, const gltf2::Accessor& input, const gltf2::Accessor& output, Vector<float>& inputDataBuffer, Vector<T>& outputDataBuffer)
-{
-  inputDataBuffer.Resize(input.mCount);
-  outputDataBuffer.Resize(output.mCount);
-
-  const uint32_t inputDataBufferSize  = input.GetBytesLength();
-  const uint32_t outputDataBufferSize = output.GetBytesLength();
-
-  LoadDataFromAccessor<float>(context, output.mBufferView->mBuffer.GetIndex(), inputDataBuffer, input.mBufferView->mByteOffset + input.mByteOffset, inputDataBufferSize);
-  LoadDataFromAccessor<T>(context, output.mBufferView->mBuffer.GetIndex(), outputDataBuffer, output.mBufferView->mByteOffset + output.mByteOffset, outputDataBufferSize);
-  ApplyAccessorMinMax(input, reinterpret_cast<float*>(inputDataBuffer.begin()));
-  ApplyAccessorMinMax(output, reinterpret_cast<float*>(outputDataBuffer.begin()));
-
-  return inputDataBuffer[input.mCount - 1u];
-}
-
-template<typename T>
-float LoadKeyFrames(ConversionContext& context, const gt::Animation::Channel& channel, KeyFrames& keyFrames, gt::Animation::Channel::Target::Type type)
-{
-  const gltf2::Accessor& input  = *channel.mSampler->mInput;
-  const gltf2::Accessor& output = *channel.mSampler->mOutput;
-
-  Vector<float> inputDataBuffer;
-  Vector<T>     outputDataBuffer;
-
-  const float duration = std::max(LoadDataFromAccessors<T>(context, input, output, inputDataBuffer, outputDataBuffer), AnimationDefinition::MIN_DURATION_SECONDS);
-
-  // Set first frame value as first keyframe (gltf animation spec)
-  if(input.mCount > 0 && !Dali::EqualsZero(inputDataBuffer[0]))
-  {
-    keyFrames.Add(0.0f, outputDataBuffer[0]);
-  }
-
-  for(uint32_t i = 0; i < input.mCount; ++i)
-  {
-    keyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i]);
-  }
-
-  return duration;
-}
-
-float LoadBlendShapeKeyFrames(ConversionContext& context, const gt::Animation::Channel& channel, Index nodeIndex, uint32_t& propertyIndex, std::vector<Dali::Scene3D::Loader::AnimatedProperty>& properties)
-{
-  const gltf2::Accessor& input  = *channel.mSampler->mInput;
-  const gltf2::Accessor& output = *channel.mSampler->mOutput;
-
-  Vector<float> inputDataBuffer;
-  Vector<float> outputDataBuffer;
-
-  const float duration = std::max(LoadDataFromAccessors<float>(context, input, output, inputDataBuffer, outputDataBuffer), AnimationDefinition::MIN_DURATION_SECONDS);
-
-  char        weightNameBuffer[32];
-  auto        prefixSize    = snprintf(weightNameBuffer, sizeof(weightNameBuffer), "%s[", BLEND_SHAPE_WEIGHTS_UNIFORM);
-  char* const pWeightName   = weightNameBuffer + prefixSize;
-  const auto  remainingSize = sizeof(weightNameBuffer) - prefixSize;
-  for(uint32_t weightIndex = 0u, endWeightIndex = channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount; weightIndex < endWeightIndex; ++weightIndex)
-  {
-    AnimatedProperty& animatedProperty = properties[propertyIndex++];
-
-    animatedProperty.mNodeIndex = nodeIndex;
-    snprintf(pWeightName, remainingSize, "%d]", weightIndex);
-    animatedProperty.mPropertyName = std::string(weightNameBuffer);
-
-    animatedProperty.mKeyFrames = KeyFrames::New();
-
-    // Set first frame value as first keyframe (gltf animation spec)
-    if(input.mCount > 0 && !Dali::EqualsZero(inputDataBuffer[0]))
-    {
-      animatedProperty.mKeyFrames.Add(0.0f, outputDataBuffer[weightIndex]);
-    }
-
-    for(uint32_t i = 0; i < input.mCount; ++i)
-    {
-      animatedProperty.mKeyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i * endWeightIndex + weightIndex]);
-    }
-
-    animatedProperty.mTimePeriod = {0.f, duration};
-  }
-
-  return duration;
-}
-
-void ConvertAnimations(const gt::Document& doc, ConversionContext& context)
-{
-  auto& output = context.mOutput;
-
-  output.mAnimationDefinitions.reserve(output.mAnimationDefinitions.size() + doc.mAnimations.size());
-
-  for(const auto& animation : doc.mAnimations)
-  {
-    AnimationDefinition animationDef;
-
-    if(!animation.mName.empty())
-    {
-      animationDef.mName = animation.mName;
-    }
-
-    uint32_t numberOfProperties = 0u;
-    for(const auto& channel : animation.mChannels)
-    {
-      if(channel.mTarget.mPath == gt::Animation::Channel::Target::WEIGHTS)
-      {
-        numberOfProperties += channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount;
-      }
-      else
-      {
-        numberOfProperties++;
-      }
-    }
-    animationDef.mProperties.resize(numberOfProperties);
-
-    Index propertyIndex = 0u;
-    for(const auto& channel : animation.mChannels)
-    {
-      Index nodeIndex = context.mNodeIndices.GetRuntimeId(channel.mTarget.mNode.GetIndex());
-      float duration  = 0.f;
-
-      switch(channel.mTarget.mPath)
-      {
-        case gt::Animation::Channel::Target::TRANSLATION:
-        {
-          AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex];
-
-          animatedProperty.mNodeIndex    = nodeIndex;
-          animatedProperty.mPropertyName = POSITION_PROPERTY;
-
-          animatedProperty.mKeyFrames = KeyFrames::New();
-          duration                    = LoadKeyFrames<Vector3>(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath);
-
-          animatedProperty.mTimePeriod = {0.f, duration};
-          break;
-        }
-        case gt::Animation::Channel::Target::ROTATION:
-        {
-          AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex];
-
-          animatedProperty.mNodeIndex    = nodeIndex;
-          animatedProperty.mPropertyName = ORIENTATION_PROPERTY;
-
-          animatedProperty.mKeyFrames = KeyFrames::New();
-          duration                    = LoadKeyFrames<Quaternion>(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath);
-
-          animatedProperty.mTimePeriod = {0.f, duration};
-          break;
-        }
-        case gt::Animation::Channel::Target::SCALE:
-        {
-          AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex];
-
-          animatedProperty.mNodeIndex    = nodeIndex;
-          animatedProperty.mPropertyName = SCALE_PROPERTY;
-
-          animatedProperty.mKeyFrames = KeyFrames::New();
-          duration                    = LoadKeyFrames<Vector3>(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath);
-
-          animatedProperty.mTimePeriod = {0.f, duration};
-          break;
-        }
-        case gt::Animation::Channel::Target::WEIGHTS:
-        {
-          duration = LoadBlendShapeKeyFrames(context, channel, nodeIndex, propertyIndex, animationDef.mProperties);
-
-          break;
-        }
-        default:
-        {
-          // nothing to animate.
-          break;
-        }
-      }
-
-      animationDef.mDuration = std::max(duration, animationDef.mDuration);
-
-      ++propertyIndex;
-    }
-
-    output.mAnimationDefinitions.push_back(std::move(animationDef));
-  }
-}
-
-void ProcessSkins(const gt::Document& doc, ConversionContext& context)
-{
-  // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skininversebindmatrices
-  // If an inverseBindMatrices accessor was provided, we'll load the joint data from the buffer,
-  // otherwise we'll set identity matrices for inverse bind pose.
-  struct IInverseBindMatrixProvider
-  {
-    virtual ~IInverseBindMatrixProvider()
-    {
-    }
-    virtual void Provide(Matrix& ibm) = 0;
-  };
-
-  struct InverseBindMatrixAccessor : public IInverseBindMatrixProvider
-  {
-    std::istream&  mStream;
-    const uint32_t mElementSizeBytes;
-
-    InverseBindMatrixAccessor(const gt::Accessor& accessor, ConversionContext& context)
-    : mStream(context.mOutput.mResources.mBuffers[accessor.mBufferView->mBuffer.GetIndex()].GetBufferStream()),
-      mElementSizeBytes(accessor.GetElementSizeBytes())
-    {
-      DALI_ASSERT_DEBUG(accessor.mType == gt::AccessorType::MAT4 && accessor.mComponentType == gt::Component::FLOAT);
-
-      if(!mStream.rdbuf()->in_avail())
-      {
-        DALI_LOG_ERROR("Failed to load from stream\n");
-      }
-      mStream.clear();
-      mStream.seekg(accessor.mBufferView->mByteOffset + accessor.mByteOffset, mStream.beg);
-    }
-
-    virtual void Provide(Matrix& ibm) override
-    {
-      DALI_ASSERT_ALWAYS(mStream.read(reinterpret_cast<char*>(ibm.AsFloat()), static_cast<std::streamsize>(static_cast<size_t>(mElementSizeBytes))));
-    }
-  };
-
-  struct DefaultInverseBindMatrixProvider : public IInverseBindMatrixProvider
-  {
-    virtual void Provide(Matrix& ibm) override
-    {
-      ibm = Matrix::IDENTITY;
-    }
-  };
-
-  auto& resources = context.mOutput.mResources;
-  resources.mSkeletons.reserve(doc.mSkins.size());
-
-  for(auto& skin : doc.mSkins)
-  {
-    std::unique_ptr<IInverseBindMatrixProvider> ibmProvider;
-    if(skin.mInverseBindMatrices)
-    {
-      ibmProvider.reset(new InverseBindMatrixAccessor(*skin.mInverseBindMatrices, context));
-    }
-    else
-    {
-      ibmProvider.reset(new DefaultInverseBindMatrixProvider());
-    }
-
-    SkeletonDefinition skeleton;
-    if(skin.mSkeleton.GetIndex() != INVALID_INDEX)
-    {
-      skeleton.mRootNodeIdx = context.mNodeIndices.GetRuntimeId(skin.mSkeleton.GetIndex());
-    }
-
-    skeleton.mJoints.resize(skin.mJoints.size());
-    auto iJoint = skeleton.mJoints.begin();
-    for(auto& joint : skin.mJoints)
-    {
-      iJoint->mNodeIdx = context.mNodeIndices.GetRuntimeId(joint.GetIndex());
-
-      ibmProvider->Provide(iJoint->mInverseBindMatrix);
-
-      ++iJoint;
-    }
-
-    resources.mSkeletons.push_back(std::move(skeleton));
-  }
-}
-
-void ProduceShaders(ShaderDefinitionFactory& shaderFactory, SceneDefinition& scene)
-{
-  uint32_t nodeCount = scene.GetNodeCount();
-  for(uint32_t i = 0; i < nodeCount; ++i)
-  {
-    auto nodeDef = scene.GetNode(i);
-    for(auto& renderable : nodeDef->mRenderables)
-    {
-      if(shaderFactory.ProduceShader(*renderable) == INVALID_INDEX)
-      {
-        DALI_LOG_ERROR("Fail to produce shader\n");
-      }
-    }
-  }
-}
-
-void SetObjectReaders()
-{
-  js::SetObjectReader(GetBufferReader());
-  js::SetObjectReader(GetBufferViewReader());
-  js::SetObjectReader(GetBufferViewClientReader());
-  js::SetObjectReader(GetComponentTypedBufferViewClientReader());
-  js::SetObjectReader(GetAccessorSparseReader());
-  js::SetObjectReader(GetAccessorReader());
-  js::SetObjectReader(GetImageReader());
-  js::SetObjectReader(GetSamplerReader());
-  js::SetObjectReader(GetTextureReader());
-  js::SetObjectReader(GetTextureInfoReader());
-  js::SetObjectReader(GetMaterialPbrReader());
-  js::SetObjectReader(GetMaterialSpecularReader());
-  js::SetObjectReader(GetMaterialIorReader());
-  js::SetObjectReader(GetMaterialExtensionsReader());
-  js::SetObjectReader(GetMaterialReader());
-  js::SetObjectReader(GetMeshPrimitiveReader());
-  js::SetObjectReader(GetMeshReader());
-  js::SetObjectReader(GetSkinReader());
-  js::SetObjectReader(GetCameraPerspectiveReader());
-  js::SetObjectReader(GetCameraOrthographicReader());
-  js::SetObjectReader(GetCameraReader());
-  js::SetObjectReader(GetNodeReader());
-  js::SetObjectReader(GetAnimationSamplerReader());
-  js::SetObjectReader(GetAnimationChannelTargetReader());
-  js::SetObjectReader(GetAnimationChannelReader());
-  js::SetObjectReader(GetAnimationReader());
-  js::SetObjectReader(GetSceneReader());
-}
-
-void SetDefaultEnvironmentMap(const gt::Document& doc, ConversionContext& context)
-{
-  EnvironmentDefinition envDef;
-  envDef.mUseBrdfTexture = true;
-  envDef.mIblIntensity   = Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity();
-  context.mOutput.mResources.mEnvironmentMaps.push_back({std::move(envDef), EnvironmentDefinition::Textures()});
-}
-
-} // namespace
-
-void InitializeGltfLoader()
-{
-  // Set ObjectReader only once (for all gltf loading).
-  static bool setObjectReadersRequired = true;
-  {
-    Mutex::ScopedLock lock(gInitializeMutex);
-    if(setObjectReadersRequired)
-    {
-      // NOTE: only referencing own, anonymous namespace, const objects; the pointers will never need to change.
-      SetObjectReaders();
-      setObjectReadersRequired = false;
-    }
-  }
-}
-
-void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactory, LoadResult& params)
-{
-  bool failed = false;
-  auto js     = LoadTextFile(url.c_str(), &failed);
-  if(failed)
-  {
-    throw std::runtime_error("Failed to load " + url);
-  }
-
-  json::unique_ptr root(json_parse(js.c_str(), js.size()));
-  if(!root)
-  {
-    throw std::runtime_error("Failed to parse " + url);
-  }
-
-  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));
-  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);
-  }
-
-  {
-    Mutex::ScopedLock lock(gReadMutex);
-    gt::SetRefReaderObject(doc);
-    GetDocumentReader().Read(rootObj, doc);
-  }
-
-  auto              path = url.substr(0, url.rfind('/') + 1);
-  ConversionContext context{params, path, INVALID_INDEX};
-
-  ConvertBuffers(doc, context);
-  ConvertMaterials(doc, context);
-  ConvertMeshes(doc, context);
-  ConvertNodes(doc, context, isMRendererModel);
-  ConvertAnimations(doc, context);
-  ProcessSkins(doc, context);
-  ProduceShaders(shaderFactory, params.mScene);
-  params.mScene.EnsureUniqueSkinningShaderInstances(params.mResources);
-
-  // Set Default Environment map
-  SetDefaultEnvironmentMap(doc, context);
-}
-
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
diff --git a/dali-scene3d/public-api/loader/gltf2-loader.h b/dali-scene3d/public-api/loader/gltf2-loader.h
deleted file mode 100644 (file)
index dc7becf..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef DALI_SCENE3D_LOADER_GLTF2_LOADER_H
-#define DALI_SCENE3D_LOADER_GLTF2_LOADER_H
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
-// EXTERNAL INCLUDES
-#include <string>
-
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
-{
-struct CameraParameters;
-struct LoadResult;
-class ShaderDefinitionFactory;
-
-/**
- * @brief Initialize glTF Loader.
- * @note This method should be called once before LoadGltfScene() is called.
- */
-DALI_SCENE3D_API void InitializeGltfLoader();
-
-/**
- * @brief Loads the scene from the glTF file located at @a url, storing the results in @a params.
- * @note Will throw std::runtime_error for JSON entities with types mismatching expectations, carrying
- *  invalid values, or I/O errors.
- * @note InitializeGltfLoader() should be called once before this function is called.
- */
-DALI_SCENE3D_API void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactory, LoadResult& params);
-
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
-
-#endif //DALI_SCENE3D_LOADER_GLTF2_LOADER_H
index 3048def..cbf09a2 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_INDEX_H_
 #define DALI_SCENE3D_LOADER_INDEX_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
 #include <cstdint>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 using Index = uint32_t;
 
 constexpr Index INVALID_INDEX = static_cast<Index>(-1);
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_INDEX_H_
index fcb3b7d..d495ee0 100644 (file)
 #include <dali-scene3d/public-api/api.h>
 #include <dali-scene3d/public-api/loader/environment-map-data.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Loads cube map data texture from a ktx file.
@@ -36,8 +32,6 @@ namespace Loader
  */
 bool LoadKtxData(const std::string& path, EnvironmentMapData& environmentMapData);
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_KTX_LOADER_H
index 2fde52e..e148413 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_LIGHT_PARAMETERS_H
 #define DALI_SCENE3D_LOADER_LIGHT_PARAMETERS_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/math/matrix.h>
+#include <dali/public-api/math/vector3.h>
 #include <stdint.h>
-#include "dali/public-api/math/matrix.h"
-#include "dali/public-api/math/vector3.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 struct DALI_SCENE3D_API LightParameters
 {
@@ -42,8 +38,6 @@ struct DALI_SCENE3D_API LightParameters
   float    orthographicSize;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_LIGHT_PARAMETERS_H
index bd7e486..da05a36 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_OUTPUT_H
 #define DALI_SCENE3D_LOADER_OUTPUT_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
 #include <dali-scene3d/public-api/loader/light-parameters.h>
 #include <dali-scene3d/public-api/loader/load-scene-metadata.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 class ResourceBundle;
 class SceneDefinition;
@@ -74,8 +70,6 @@ struct DALI_SCENE3D_API LoadResult
   std::vector<LightParameters>& mLightParameters;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_OUTPUT_H
index 58ab65d..ac6b73a 100644 (file)
@@ -15,7 +15,7 @@
  *
  */
 
-// INTERNAL INCLUDES
+// CLASS HEADER
 #include <dali-scene3d/public-api/loader/material-definition.h>
 
 // EXTERNAL INCLUDES
index ca63129..b40a746 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H
 #define DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-#include "dali-scene3d/public-api/loader/environment-definition.h"
-#include "dali-scene3d/public-api/loader/index.h"
-#include "dali-scene3d/public-api/loader/utils.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/images/image-operations.h>
+#include <dali/public-api/math/vector4.h>
 #include <cmath>
-#include "dali/public-api/common/vector-wrapper.h"
-#include "dali/public-api/math/vector4.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/environment-definition.h>
+#include <dali-scene3d/public-api/loader/index.h>
+#include <dali-scene3d/public-api/loader/utils.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Helper enum for encoding and decoding sampler states.
@@ -254,8 +250,6 @@ public: // DATA
   std::vector<TextureStage> mTextureStages;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H
index a7b8870..146e4ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2022 Samsung Electronics Co., Ltd.
+* Copyright (c) 2023 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.
 * limitations under the License.
 *
 */
-#include "dali-scene3d/public-api/loader/matrix-stack.h"
-#include "dali-scene3d/public-api/loader/utils.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/matrix-stack.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/utils.h>
+
+namespace Dali::Scene3D::Loader
 {
 MatrixStack::MatrixStack()
 {
@@ -63,6 +63,4 @@ void MatrixStack::PopAll()
   mStack.clear();
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index 63bbc90..f34614b 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADERER_MATRIX_STACK_H_
 #define DALI_SCENE3D_LOADERER_MATRIX_STACK_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
-#include "dali/public-api/common/vector-wrapper.h"
-#include "dali/public-api/math/matrix.h"
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/math/matrix.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief A stack of matrices whereby each newly pushed matrix is stored
@@ -50,8 +46,6 @@ private:
   std::vector<Matrix> mStack;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADERER_MATRIX_STACK_H_
index 18093a5..3d5f6eb 100644 (file)
@@ -15,8 +15,8 @@
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/loader/mesh-definition.h"
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/mesh-definition.h>
 
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/file-stream.h>
 #include <fstream>
 #include <type_traits>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -1075,6 +1071,4 @@ MeshGeometry MeshDefinition::Load(RawData&& raw) const
   return meshGeometry;
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index bb4d716..7289b40 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-#include "dali-scene3d/public-api/loader/blend-shape-details.h"
-#include "dali-scene3d/public-api/loader/index.h"
-#include "dali-scene3d/public-api/loader/mesh-geometry.h"
-#include "dali-scene3d/public-api/loader/utils.h"
-#include <dali-scene3d/public-api/loader/buffer-definition.h>
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
 #include <memory>
-#include "dali/public-api/common/vector-wrapper.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/blend-shape-details.h>
+#include <dali-scene3d/public-api/loader/buffer-definition.h>
+#include <dali-scene3d/public-api/loader/index.h>
+#include <dali-scene3d/public-api/loader/mesh-geometry.h>
+#include <dali-scene3d/public-api/loader/utils.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Defines a mesh with its attributes, the primitive type to render it as,
@@ -177,10 +173,10 @@ struct DALI_SCENE3D_API MeshDefinition
 
     Accessor(const MeshDefinition::Blob&       blob,
              const MeshDefinition::SparseBlob& sparse,
-             Index bufferIndex = INVALID_INDEX);
+             Index                             bufferIndex = INVALID_INDEX);
     Accessor(MeshDefinition::Blob&&       blob,
              MeshDefinition::SparseBlob&& sparse,
-             Index bufferIndex = INVALID_INDEX);
+             Index                        bufferIndex = INVALID_INDEX);
 
     bool IsDefined() const
     {
@@ -295,8 +291,6 @@ public: // DATA
   Index mSkeletonIdx = INVALID_INDEX;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_MESH_DEFINITION_H
index 331acf7..1ce30a7 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADERER_MESH_GEOMETRY_H
 #define DALI_SCENE3D_LOADERER_MESH_GEOMETRY_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
-#include "dali/public-api/rendering/geometry.h"
-#include "dali/public-api/rendering/texture.h"
+#include <dali/public-api/rendering/geometry.h>
+#include <dali/public-api/rendering/texture.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 struct DALI_SCENE3D_API MeshGeometry
 {
@@ -38,8 +34,6 @@ struct DALI_SCENE3D_API MeshGeometry
   unsigned int  blendShapeBufferOffset{0};   ///< Offset used to calculate the start of each blend shape.
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADERER_MESH_GEOMETRY_H
diff --git a/dali-scene3d/public-api/loader/model-loader.cpp b/dali-scene3d/public-api/loader/model-loader.cpp
new file mode 100644 (file)
index 0000000..2f5c34e
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include <dali-scene3d/public-api/loader/model-loader.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <filesystem>
+#include <memory>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/loader/dli-loader-impl.h>
+#include <dali-scene3d/internal/loader/glb-loader-impl.h>
+#include <dali-scene3d/internal/loader/gltf2-loader-impl.h>
+#include <dali-scene3d/internal/loader/model-loader-impl.h>
+
+namespace Dali::Scene3D::Loader
+{
+namespace
+{
+static constexpr std::string_view OBJ_EXTENSION      = ".obj";
+static constexpr std::string_view GLTF_EXTENSION     = ".gltf";
+static constexpr std::string_view GLB_EXTENSION      = ".glb";
+static constexpr std::string_view DLI_EXTENSION      = ".dli";
+static constexpr std::string_view METADATA_EXTENSION = "metadata";
+} // namespace
+
+ModelLoader::ModelLoader(const std::string& modelUrl, const std::string& resourceDirectoryUrl, Dali::Scene3D::Loader::LoadResult& loadResult)
+: mModelUrl(modelUrl),
+  mResourceDirectoryUrl(resourceDirectoryUrl),
+  mLoadResult(loadResult)
+{
+  CreateModelLoader();
+}
+
+bool ModelLoader::LoadModel(Dali::Scene3D::Loader::ResourceBundle::PathProvider& pathProvider, bool loadOnlyRawResource)
+{
+  if(!mImpl)
+  {
+    return false;
+  }
+
+  bool loadSucceeded = false;
+
+  mLoadResult.mAnimationDefinitions.clear();
+  std::filesystem::path metaDataUrl(mModelUrl);
+  metaDataUrl.replace_extension(METADATA_EXTENSION.data());
+
+  Dali::Scene3D::Loader::LoadSceneMetadata(metaDataUrl.c_str(), mLoadResult.mSceneMetadata);
+  loadSucceeded = mImpl->LoadModel(mModelUrl, mLoadResult);
+  LoadResource(pathProvider, loadOnlyRawResource);
+
+  return loadSucceeded;
+}
+
+void ModelLoader::SetInputParameter(InputParameter& inputParameter)
+{
+  mImpl->SetInputParameter(inputParameter);
+}
+
+Dali::Scene3D::Loader::SceneDefinition& ModelLoader::GetScene()
+{
+  return mLoadResult.mScene;
+}
+
+Dali::Scene3D::Loader::ResourceBundle& ModelLoader::GetResources()
+{
+  return mLoadResult.mResources;
+}
+
+std::vector<Dali::Scene3D::Loader::AnimationDefinition>& ModelLoader::GetAnimations()
+{
+  return mLoadResult.mAnimationDefinitions;
+}
+
+std::vector<Dali::Scene3D::Loader::CameraParameters>& ModelLoader::GetCameras()
+{
+  return mLoadResult.mCameraParameters;
+}
+
+Dali::Scene3D::Loader::Customization::Choices& ModelLoader::GetResourceChoices()
+{
+  return mResourceChoices;
+}
+
+void ModelLoader::CreateModelLoader()
+{
+  std::filesystem::path modelPath(mModelUrl);
+  if(mResourceDirectoryUrl.empty())
+  {
+    mResourceDirectoryUrl = std::string(modelPath.parent_path()) + "/";
+  }
+  std::string extension = modelPath.extension();
+  std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
+
+  if(extension == DLI_EXTENSION)
+  {
+    mImpl = std::make_shared<Dali::Scene3D::Loader::Internal::DliLoaderImpl>();
+  }
+  else if(extension == GLTF_EXTENSION)
+  {
+    mImpl = std::make_shared<Dali::Scene3D::Loader::Internal::Gltf2LoaderImpl>();
+  }
+  else if(extension == GLB_EXTENSION)
+  {
+    mImpl = std::make_shared<Dali::Scene3D::Loader::Internal::GlbLoaderImpl>();
+  }
+  else
+  {
+    DALI_LOG_ERROR("Not supported model format : %s\n", extension.c_str());
+  }
+}
+
+void ModelLoader::LoadResource(Dali::Scene3D::Loader::ResourceBundle::PathProvider& pathProvider, bool loadOnlyRawResource)
+{
+  if(GetResources().mRawResourcesLoaded && loadOnlyRawResource)
+  {
+    return;
+  }
+
+  Dali::Scene3D::Loader::ResourceRefCounts resourceRefCount = std::move(mLoadResult.mResources.CreateRefCounter());
+  for(auto iRoot : GetScene().GetRoots())
+  {
+    GetScene().CountResourceRefs(iRoot, mResourceChoices, resourceRefCount);
+  }
+
+  GetResources().mReferenceCounts = std::move(resourceRefCount);
+  GetResources().CountEnvironmentReferences();
+
+  if(loadOnlyRawResource)
+  {
+    GetResources().LoadRawResources(pathProvider);
+  }
+  else
+  {
+    GetResources().LoadResources(pathProvider);
+  }
+}
+
+} // namespace Dali::Scene3D::Loader
diff --git a/dali-scene3d/public-api/loader/model-loader.h b/dali-scene3d/public-api/loader/model-loader.h
new file mode 100644 (file)
index 0000000..702b308
--- /dev/null
@@ -0,0 +1,120 @@
+#ifndef DALI_SCENE3D_LOADER_MODEL_LOADER_H
+#define DALI_SCENE3D_LOADER_MODEL_LOADER_H
+/*
+ * Copyright (c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/load-result.h>
+#include <dali-scene3d/public-api/loader/scene-definition.h>
+
+// EXTERNAL INCLUDES
+#include <string>
+
+namespace Dali::Scene3D::Loader
+{
+namespace Internal
+{
+class ModelLoaderImpl;
+}
+
+class DALI_SCENE3D_API ModelLoader
+{
+public:
+  class InputParameter
+  {
+  };
+
+  /**
+   * @brief ModelLoader Constructor.
+   * @param[in] modelUrl Url of the model file to be loaded
+   * @param[in] resourceDirectoryUrl Url of directory that contains resources.
+   * @param[out] loadResult Loaded result that includes scene tree and resources.
+   */
+  ModelLoader(const std::string& modelUrl, const std::string& resourceDirectoryUrl, Dali::Scene3D::Loader::LoadResult& loadResult);
+
+  /**
+   * @brief Request to load model from model url.
+   * @param[in] pathProvider Path provider that defines resource paths.
+   * @param[in] loadOnlyRawResource If true, load Raw resource only, and do not create Dali::Handle
+   * If false, this loader load Raw resource and create Dali::Handle too.
+   * Default value is false;
+   * @return True if model loading is successfully finished.
+   */
+  bool LoadModel(Dali::Scene3D::Loader::ResourceBundle::PathProvider& pathProvider, bool loadOnlyRawResource = false);
+
+  /**
+   * @brief Set InputParameter.
+   * Thie method store only a pointer of InputParameter.
+   * The object of InputParameter should not be deleted until it is no longer used.
+   * @param[in] inputParameter Input parameters that can be used in loading time.
+   */
+  void SetInputParameter(InputParameter& inputParameter);
+
+  /**
+   * @brief Retrieves loaded scene
+   * @return SceneDefinition that is loaded from file
+   */
+  Dali::Scene3D::Loader::SceneDefinition& GetScene();
+
+  /**
+   * @brief Retrieves resource bundle that includes resource information
+   * @return ResourceBundle for model resources
+   */
+  Dali::Scene3D::Loader::ResourceBundle& GetResources();
+
+  /**
+   * @brief Retrieves loaded AnimationDefinition
+   * @return AnimationDefinition that is loaded from file
+   */
+  std::vector<Dali::Scene3D::Loader::AnimationDefinition>& GetAnimations();
+
+  /**
+   * @brief Retrieves loaded CameraParameters
+   * @return CameraParameters list that is loaded from file
+   */
+  std::vector<Dali::Scene3D::Loader::CameraParameters>& GetCameras();
+
+  /**
+   * @brief Retrieves ResourceChoices
+   * @return Choices for loaded Resources
+   */
+  Dali::Scene3D::Loader::Customization::Choices& GetResourceChoices();
+
+private:
+  /**
+   * @brief Create model loader for each file format.
+   */
+  void CreateModelLoader();
+
+  /**
+   * @brief Load resource of the model.
+   */
+  void LoadResource(Dali::Scene3D::Loader::ResourceBundle::PathProvider& pathProvider, bool loadOnlyRawResource);
+
+private:
+  std::string mModelUrl;
+  std::string mResourceDirectoryUrl;
+
+  Dali::Scene3D::Loader::LoadResult             mLoadResult;
+  Dali::Scene3D::Loader::Customization::Choices mResourceChoices;
+
+  std::shared_ptr<Internal::ModelLoaderImpl> mImpl;
+};
+} // namespace Dali::Scene3D::Loader
+
+#endif // DALI_SCENE3D_LOADER_MODEL_LOADER_H
index 9d03f0d..5f66539 100644 (file)
 // CLASS HEADER
 #include <dali-scene3d/public-api/loader/navigation-mesh-factory.h>
 
-// INTERNAL INCLUDES
-#include <dali-scene3d/internal/algorithm/navigation-mesh-impl.h>
-
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/algorithm/navigation-mesh-impl.h>
+
 namespace Dali::Scene3D::Loader
 {
-
 std::unique_ptr<Algorithm::NavigationMesh> NavigationMeshFactory::CreateFromFile(std::string filename)
 {
   std::vector<uint8_t> buffer;
-  auto fin = fopen(filename.c_str(), "rb");
+  auto                 fin = fopen(filename.c_str(), "rb");
   if(!fin)
   {
     DALI_LOG_ERROR("NavigationMesh: Can't open %s for reading: %s", filename.c_str(), strerror(errno));
@@ -50,14 +49,14 @@ std::unique_ptr<Algorithm::NavigationMesh> NavigationMeshFactory::CreateFromFile
     }
     fclose(fin);
 
-    return CreateFromBuffer( buffer );
+    return CreateFromBuffer(buffer);
   }
 }
 
 std::unique_ptr<Algorithm::NavigationMesh> NavigationMeshFactory::CreateFromBuffer(const std::vector<uint8_t>& buffer)
 {
   auto impl = new Scene3D::Internal::Algorithm::NavigationMesh(buffer);
-  return std::unique_ptr<Algorithm::NavigationMesh>( new Algorithm::NavigationMesh(impl));
+  return std::unique_ptr<Algorithm::NavigationMesh>(new Algorithm::NavigationMesh(impl));
 }
 
-}
\ No newline at end of file
+} // namespace Dali::Scene3D::Loader
\ No newline at end of file
index 0bbe8a9..bbe5f00 100644 (file)
 * limitations under the License.
 */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/rendering/geometry.h>
+#include <dali/public-api/rendering/texture.h>
+
 // INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
 #include <dali-scene3d/public-api/algorithm/navigation-mesh.h>
+#include <dali-scene3d/public-api/api.h>
 
-// EXTERNAL INCLUDES
-#include "dali/public-api/rendering/geometry.h"
-#include "dali/public-api/rendering/texture.h"
-
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 struct DALI_SCENE3D_API NavigationMeshFactory
 {
@@ -49,10 +45,7 @@ public:
    * @return Valid NavigationMesh or nullptr
    */
   static std::unique_ptr<Algorithm::NavigationMesh> CreateFromBuffer(const std::vector<uint8_t>& buffer);
-
 };
-}
-}
-}
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_INTERNAL_LOADER_NAVIGATION_MESH_FACTORY_H
index 98405d7..f110150 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL
-#include "dali-scene3d/public-api/loader/node-definition.h"
-#include "dali-scene3d/public-api/loader/renderer-state.h"
-#include "dali-scene3d/public-api/loader/utils.h"
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/node-definition.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/renderer-state.h>
+#include <dali-scene3d/public-api/loader/utils.h>
 
 namespace Dali
 {
index 0e9a5d7..7474a5f 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_NODE_DEFINITION_H_
 #define DALI_SCENE3D_LOADER_NODE_DEFINITION_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/loader/customization.h"
-#include "dali-scene3d/public-api/loader/matrix-stack.h"
-#include "dali-scene3d/public-api/loader/resource-bundle.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/math/matrix.h>
+#include <dali/public-api/math/quaternion.h>
+#include <dali/public-api/math/vector4.h>
 #include <functional>
 #include <memory>
 #include <string>
-#include "dali/public-api/actors/actor.h"
-#include "dali/public-api/math/matrix.h"
-#include "dali/public-api/math/quaternion.h"
-#include "dali/public-api/math/vector4.h"
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/customization.h>
+#include <dali-scene3d/public-api/loader/matrix-stack.h>
+#include <dali-scene3d/public-api/loader/resource-bundle.h>
 
 namespace Dali
 {
index 3c01701..30b4d44 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-#include "dali-scene3d/public-api/loader/parse-renderer-state.h"
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/parse-renderer-state.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/common/map-wrapper.h>
 #include <cstring>
-#include "dali/devel-api/common/map-wrapper.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace RendererState
 {
@@ -168,6 +167,4 @@ Type Parse(const char* string, size_t length, StringCallback onError)
 }
 
 } // namespace RendererState
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index 43ca5b3..65a6269 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADERERER_INTERPRET_RENDERER_STATE_H
 #define DALI_SCENE3D_LOADERERER_INTERPRET_RENDERER_STATE_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-#include "dali-scene3d/public-api/loader/renderer-state.h"
-#include "dali-scene3d/public-api/loader/string-callback.h"
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/renderer-state.h>
+#include <dali-scene3d/public-api/loader/string-callback.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace RendererState
 {
@@ -44,8 +41,6 @@ namespace RendererState
 DALI_SCENE3D_API Type Parse(const char* string, size_t length = 0, StringCallback onError = DefaultErrorCallback);
 
 } // namespace RendererState
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADERERER_INTERPRET_RENDERER_STATE_H
index cc2837b..c14d8a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/public-api/loader/renderer-state.h"
-#include "dali-scene3d/public-api/loader/utils.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/renderer-state.h>
+
+// INTENRAL INCLUDES
+#include <dali-scene3d/public-api/loader/utils.h>
+
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -97,6 +97,4 @@ void Apply(Type rendererState, Renderer& renderer)
 
 } // namespace RendererState
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index 0dc3c52..240a343 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_RENDERER_STATE_H
 #define DALI_SCENE3D_LOADER_RENDERER_STATE_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
-#include "dali/public-api/rendering/renderer.h"
+#include <dali/public-api/rendering/renderer.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 /*
  * @brief Contains values for comparison functions used in depth and stencil testing.
@@ -158,8 +154,6 @@ DALI_SCENE3D_API void Apply(Type rendererState, Renderer& renderer);
 
 } // namespace RendererState
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_RENDERER_STATE_H
index 98c8de6..6b4dde6 100644 (file)
@@ -18,7 +18,7 @@
 // FILE HEADER
 #include <dali-scene3d/public-api/loader/resource-bundle.h>
 
-// EXTERNAL
+// EXTERNAL INCLUDES
 #include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
 #include <dali/public-api/rendering/sampler.h>
 #include <cstring>
@@ -53,9 +53,7 @@ ResourceBundle::ResourceBundle()
 : mRawResourcesLoading(false),
   mResourcesGenerating(false),
   mRawResourcesLoaded(false),
-  mResourcesGenerated(false)
-{
-};
+  mResourcesGenerated(false){};
 
 ResourceRefCounts ResourceBundle::CreateRefCounter() const
 {
@@ -67,11 +65,11 @@ ResourceRefCounts ResourceBundle::CreateRefCounter() const
   return refCounts;
 }
 
-void ResourceBundle::CountEnvironmentReferences(ResourceRefCounts& refCounts) const
+void ResourceBundle::CountEnvironmentReferences()
 {
-  auto& environmentRefCounts = refCounts[ResourceType::Environment];
+  auto& environmentRefCounts = mReferenceCounts[ResourceType::Environment];
 
-  const auto& materialRefs = refCounts[ResourceType::Material];
+  const auto& materialRefs = mReferenceCounts[ResourceType::Material];
   for(uint32_t i = 0, iEnd = materialRefs.Size(); i != iEnd; ++i)
   {
     if(materialRefs[i] > 0)
@@ -81,7 +79,7 @@ void ResourceBundle::CountEnvironmentReferences(ResourceRefCounts& refCounts) co
   }
 }
 
-void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvider pathProvider, Options::Type options)
+void ResourceBundle::LoadResources(PathProvider pathProvider, Options::Type options)
 {
   mRawResourcesLoading = true;
   mResourcesGenerating = true;
@@ -89,7 +87,7 @@ void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvi
   const auto kForceLoad  = MaskMatch(options, Options::ForceReload);
   const auto kKeepUnused = MaskMatch(options, Options::KeepUnused);
 
-  const auto& refCountEnvMaps  = refCounts[ResourceType::Environment];
+  const auto& refCountEnvMaps  = mReferenceCounts[ResourceType::Environment];
   auto        environmentsPath = pathProvider(ResourceType::Environment);
   for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
   {
@@ -107,7 +105,7 @@ void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvi
     }
   }
 
-  const auto& refCountShaders = refCounts[ResourceType::Shader];
+  const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
   auto        shadersPath     = pathProvider(ResourceType::Shader);
   for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
   {
@@ -124,7 +122,7 @@ void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvi
     }
   }
 
-  const auto& refCountMeshes = refCounts[ResourceType::Mesh];
+  const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
   auto        modelsPath     = pathProvider(ResourceType::Mesh);
   for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
   {
@@ -141,7 +139,7 @@ void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvi
     }
   }
 
-  const auto& refCountMaterials = refCounts[ResourceType::Material];
+  const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
   auto        imagesPath        = pathProvider(ResourceType::Material);
   for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
   {
@@ -165,7 +163,7 @@ void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvi
   mResourcesGenerated = true;
 }
 
-void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathProvider pathProvider, Options::Type options)
+void ResourceBundle::LoadRawResources(PathProvider pathProvider, Options::Type options)
 {
   const auto kForceLoad = MaskMatch(options, Options::ForceReload);
 
@@ -173,7 +171,7 @@ void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathPr
   {
     mRawResourcesLoading = true;
 
-    const auto& refCountEnvMaps  = refCounts[ResourceType::Environment];
+    const auto& refCountEnvMaps  = mReferenceCounts[ResourceType::Environment];
     auto        environmentsPath = pathProvider(ResourceType::Environment);
     for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
     {
@@ -185,7 +183,7 @@ void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathPr
       }
     }
 
-    const auto& refCountShaders = refCounts[ResourceType::Shader];
+    const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
     auto        shadersPath     = pathProvider(ResourceType::Shader);
     for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
     {
@@ -197,7 +195,7 @@ void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathPr
       }
     }
 
-    const auto& refCountMeshes = refCounts[ResourceType::Mesh];
+    const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
     auto        modelsPath     = pathProvider(ResourceType::Mesh);
     for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
     {
@@ -209,7 +207,7 @@ void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathPr
       }
     }
 
-    const auto& refCountMaterials = refCounts[ResourceType::Material];
+    const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
     auto        imagesPath        = pathProvider(ResourceType::Material);
     for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
     {
@@ -226,7 +224,7 @@ void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathPr
   }
 }
 
-void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Options::Type options)
+void ResourceBundle::GenerateResources(Options::Type options)
 {
   const auto kForceLoad = MaskMatch(options, Options::ForceReload);
 
@@ -236,7 +234,7 @@ void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Optio
     {
       mResourcesGenerating = true;
 
-      const auto& refCountEnvMaps = refCounts[ResourceType::Environment];
+      const auto& refCountEnvMaps = mReferenceCounts[ResourceType::Environment];
       for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
       {
         auto  refCount = refCountEnvMaps[i];
@@ -255,7 +253,7 @@ void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Optio
         }
       }
 
-      const auto& refCountShaders = refCounts[ResourceType::Shader];
+      const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
       for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
       {
         auto  refCount = refCountShaders[i];
@@ -273,7 +271,7 @@ void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Optio
         }
       }
 
-      const auto& refCountMeshes = refCounts[ResourceType::Mesh];
+      const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh];
       for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
       {
         auto  refCount = refCountMeshes[i];
@@ -291,7 +289,7 @@ void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Optio
         }
       }
 
-      const auto& refCountMaterials = refCounts[ResourceType::Material];
+      const auto& refCountMaterials = mReferenceCounts[ResourceType::Material];
       for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
       {
         auto  refCount  = refCountMaterials[i];
@@ -316,7 +314,7 @@ void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Optio
     {
       mResourcesGenerating = true;
 
-      const auto& refCountShaders = refCounts[ResourceType::Shader];
+      const auto& refCountShaders = mReferenceCounts[ResourceType::Shader];
       for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
       {
         auto  refCount = refCountShaders[i];
index 95c8609..fe386ca 100644 (file)
  *
  */
 
-// INTERNAL
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/rendering/shader.h>
+#include <dali/public-api/rendering/texture-set.h>
+#include <functional>
+#include <memory>
+
+// INTERNAL INCLUDES
 #include <dali-scene3d/public-api/loader/buffer-definition.h>
 #include <dali-scene3d/public-api/loader/environment-definition.h>
 #include <dali-scene3d/public-api/loader/material-definition.h>
 #include <dali-scene3d/public-api/loader/shader-definition.h>
 #include <dali-scene3d/public-api/loader/skeleton-definition.h>
 
-// EXTERNAL
-#include <dali/public-api/common/vector-wrapper.h>
-#include <dali/public-api/rendering/shader.h>
-#include <dali/public-api/rendering/texture-set.h>
-#include <functional>
-#include <memory>
-
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 /*
  * @brief The types of resources that .dli may define.
@@ -103,7 +99,7 @@ public:
    *  count of materials therein, it will calculate the reference count of
    *  environment maps.
    */
-  void CountEnvironmentReferences(ResourceRefCounts& refCounts) const;
+  void CountEnvironmentReferences();
 
   /**
    * @brief Performs the loading of all resources based on their respective
@@ -111,14 +107,12 @@ public:
    * loaded unless we already have a handle to them (OR the ForceReload option was specified).
    * Any handles we have to resources that come in with a zero ref count will be reset,
    * UNLESS the KeepUnused option was specified.
-   * @param[in] refCounts Reference Count that denote how many the resource is used.
    * @param[in] pathProvider path provider for resource data.
    * @param[in] options Option to load resource
    * @note This method creates DALi objects like Dali::Texture, Dali::Geometry, etc.
    */
-  void LoadResources(const ResourceRefCounts& refCounts,
-                     PathProvider             pathProvider,
-                     Options::Type            options = Options::None);
+  void LoadResources(PathProvider  pathProvider,
+                     Options::Type options = Options::None);
 
   /**
    * @brief Loads of all resources based on their respective
@@ -127,29 +121,26 @@ public:
    * Any handles we have to resources that come in with a zero ref count will be reset,
    * UNLESS the KeepUnused option was specified.
    * @note This method don't create any of DALi objects.
-   * @param[in] refCounts Reference Count that denote how many the resource is used.
    * @param[in] pathProvider path provider for resource data.
    * @param[in] options Option to load resource
    * @note This method only loads raw data from resource file, and
    * doesn't create any of DALi objects. GenerateResources() method is required to be called
    * after this method to create DALi objects.
    */
-  void LoadRawResources(const ResourceRefCounts& refCounts,
-                        PathProvider             pathProvider,
-                        Options::Type            options = Options::None);
+  void LoadRawResources(PathProvider  pathProvider,
+                        Options::Type options = Options::None);
 
   /**
    * @brief Generates DALi objects from already loaded Raw Resources.
-   * @param[in] refCounts Reference Count that denote how many the resource is used.
    * @param[in] options Option to load resource
    * @note This method generates DALi objects from raw data that is already
    * loaded by LoadRawResources method. Therefore, LoadRawResources should be called first
    * before this method is called.
    */
-  void GenerateResources(const ResourceRefCounts& refCounts,
-                         Options::Type            options = Options::None);
+  void GenerateResources(Options::Type options = Options::None);
 
 public: // DATA
+  ResourceRefCounts             mReferenceCounts;
   EnvironmentDefinition::Vector mEnvironmentMaps;
   ShaderDefinition::Vector      mShaders;
   MeshDefinition::Vector        mMeshes;
@@ -165,8 +156,6 @@ public: // DATA
   bool mResourcesGenerated;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADERERERERER_RESOURCE_BUNDLE_H_
index f41422e..f8377c3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// EXTERNAL
-#include "dali/devel-api/common/map-wrapper.h"
-#include "dali/public-api/animation/constraints.h"
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/scene-definition.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/common/map-wrapper.h>
+#include <dali/public-api/animation/constraints.h>
 
 // INTERNAL
-#include "dali-scene3d/internal/graphics/builtin-shader-extern-gen.h"
-#include "dali-scene3d/public-api/loader/blend-shape-details.h"
-#include "dali-scene3d/public-api/loader/scene-definition.h"
-#include "dali-scene3d/public-api/loader/skinning-details.h"
-#include "dali-scene3d/public-api/loader/utils.h"
+#include <dali-scene3d/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali-scene3d/public-api/loader/blend-shape-details.h>
+#include <dali-scene3d/public-api/loader/skinning-details.h>
+#include <dali-scene3d/public-api/loader/utils.h>
 
 //#define DEBUG_SCENE_DEFINITION
 //#define DEBUG_JOINTS
 
 #define LOGD(x) DEBUG_ONLY(printf x; printf("\n"); fflush(stdout))
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -1195,6 +1193,4 @@ bool SceneDefinition::FindNode(const std::string& name, std::unique_ptr<NodeDefi
   return success;
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index ecb5cff..d1ec3f1 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADERER_SCENE_DEFINITION_H_
 #define DALI_SCENE3D_LOADERER_SCENE_DEFINITION_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/loader/customization.h"
-#include "dali-scene3d/public-api/loader/node-definition.h"
-#include "dali-scene3d/public-api/loader/string-callback.h"
-#include "dali-scene3d/public-api/loader/utils.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/math/matrix.h>
+#include <dali/public-api/math/quaternion.h>
+#include <dali/public-api/math/vector4.h>
 #include <memory>
 #include <string>
-#include "dali/public-api/actors/actor.h"
-#include "dali/public-api/math/matrix.h"
-#include "dali/public-api/math/quaternion.h"
-#include "dali/public-api/math/vector4.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/customization.h>
+#include <dali-scene3d/public-api/loader/node-definition.h>
+#include <dali-scene3d/public-api/loader/string-callback.h>
+#include <dali-scene3d/public-api/loader/utils.h>
+
+namespace Dali::Scene3D::Loader
 {
 class MatrixStack;
 
@@ -274,8 +270,6 @@ private:                                               // DATA
   std::vector<Index>                           mRootNodeIds;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADERER_SCENE_DEFINITION_H_
index b5566e0..5db7ab0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/public-api/loader/shader-definition-factory.h"
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/shader-definition-factory.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/common/map-wrapper.h>
 #include <cstring>
-#include "dali-scene3d/internal/loader/hash.h"
-#include "dali-scene3d/public-api/loader/blend-shape-details.h"
-#include "dali-scene3d/public-api/loader/node-definition.h"
-#include "dali/devel-api/common/map-wrapper.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/loader/hash.h>
+#include <dali-scene3d/public-api/loader/blend-shape-details.h>
+#include <dali-scene3d/public-api/loader/node-definition.h>
+
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -375,6 +377,4 @@ Index ShaderDefinitionFactory::ProduceShader(NodeDefinition::Renderable& rendera
   return renderable.mShaderIdx;
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index b7e9195..273ac8f 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_SHADER_DEFINITION_FACTORY_H_
 #define DALI_SCENE3D_LOADER_SHADER_DEFINITION_FACTORY_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-#include "dali-scene3d/public-api/loader/index.h"
-#include <dali-scene3d/public-api/loader/node-definition.h>
-
 // EXTERNAL INCLUDER
 #include <memory>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/index.h>
+#include <dali-scene3d/public-api/loader/node-definition.h>
+
+namespace Dali::Scene3D::Loader
 {
 struct NodeDefinition;
 class ResourceBundle;
@@ -59,8 +55,6 @@ private:
   const std::unique_ptr<Impl> mImpl;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_SHADER_DEFINITION_FACTORY_H_
index a753155..2796340 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/shader-definition.h>
+
 // INTERNAL INCLUDES
-#include "dali-scene3d/public-api/loader/shader-definition.h"
 #include <dali-scene3d/internal/graphics/builtin-shader-extern-gen.h>
-#include "dali-scene3d/public-api/loader/utils.h"
+#include <dali-scene3d/public-api/loader/utils.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -144,6 +142,4 @@ Shader ShaderDefinition::Load(RawData&& raw) const
   return shader;
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index 3d3236b..27bb051 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_SHADER_DEFINITION_H
 #define DALI_SCENE3D_LOADER_SHADER_DEFINITION_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/loader/renderer-state.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/rendering/shader.h>
 #include <memory>
-#include "dali/public-api/common/vector-wrapper.h"
-#include "dali/public-api/rendering/shader.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/renderer-state.h>
+
+namespace Dali::Scene3D::Loader
 {
 /*
  * @brief Defines a shader with paths to the files which define its
@@ -56,7 +52,7 @@ struct DALI_SCENE3D_API ShaderDefinition
   ShaderDefinition(const ShaderDefinition& other);
   ShaderDefinition& operator=(const ShaderDefinition& other);
 
-  ShaderDefinition(ShaderDefinition&&)            = default;
+  ShaderDefinition(ShaderDefinition&&) = default;
   ShaderDefinition& operator=(ShaderDefinition&&) = default;
 
   /*
@@ -86,8 +82,6 @@ public: // DATA
   bool                     mUseBuiltInShader{false};
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_SHADER_DEFINITION_H
index b2d61a8..7161a34 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADERER_SKELETON_H
 #define DALI_SCENE3D_LOADERER_SKELETON_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  */
 
 // INTERNAL INCLUDES
-#include "dali-scene3d/public-api/loader/index.h"
+#include <dali-scene3d/public-api/loader/index.h>
 
 // EXTERNAL INCLUDES
-#include "dali/public-api/common/vector-wrapper.h"
-#include "dali/public-api/math/matrix.h"
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/math/matrix.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 /*
  * @brief A set of joints (stored as node indices), and an optional root node index.
@@ -50,8 +46,6 @@ struct DALI_SCENE3D_API SkeletonDefinition
   std::vector<Joint> mJoints;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADERER_SKELETON_H
index e100151..0e5e499 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/public-api/loader/skinning-details.h"
-#include "dali/public-api/animation/constraints.h"
-#include "dali/public-api/object/property.h"
-#include "dali/public-api/rendering/shader.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/skinning-details.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/animation/constraints.h>
+#include <dali/public-api/object/property.h>
+#include <dali/public-api/rendering/shader.h>
+
+namespace Dali::Scene3D::Loader
 {
 const unsigned int Skinning::MAX_JOINTS = 64;
 
 const char* Skinning::BONE_UNIFORM_NAME = "uBone";
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index d754f0c..41a9790 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_SKINNING_DETAILS_H_
 #define DALI_SCENE3D_LOADER_SKINNING_DETAILS_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/rendering/shader.h>
 #include <string>
-#include "dali/public-api/rendering/shader.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 struct DALI_SCENE3D_API Skinning
 {
@@ -45,8 +41,6 @@ struct DALI_SCENE3D_API Skinning
   Skinning() = delete;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif // DALI_SCENE3D_LOADER_SKINNING_DETAILS_H_
index 5d46cb7..eb85bad 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/public-api/loader/string-callback.h"
-#include "dali/integration-api/debug.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/string-callback.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+namespace Dali::Scene3D::Loader
 {
 void DefaultErrorCallback(const std::string& message)
 {
   DALI_LOG_ERROR("%s", message.c_str());
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index 4f00a10..7a3564d 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_STRING_CALLBACK_H
 #define DALI_SCENE3D_LOADER_STRING_CALLBACK_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
 #include <functional>
 #include <string>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 /*
  * @brief A callback to post strings to.
@@ -40,8 +36,6 @@ using StringCallback = std::function<void(const std::string&)>;
  */
 DALI_SCENE3D_API void DefaultErrorCallback(const std::string& message);
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_STRING_CALLBACK_H
index 14b4150..9120b65 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL
-#include "dali-scene3d/public-api/loader/utils.h"
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/utils.h>
 
-// EXTERNAL
+// EXTERNAL INCLUDES
+#include <dali/public-api/animation/constraints.h>
+#include <dali/public-api/common/vector-wrapper.h>
 #include <stdarg.h>
 #include <cstring>
 #include <fstream>
 #include <iostream>
-#include "dali/public-api/animation/constraints.h"
-#include "dali/public-api/common/vector-wrapper.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
 {
 namespace
 {
@@ -152,6 +148,4 @@ void ToUnixFileSeparators(std::string& path)
   std::replace(path.begin(), path.end(), '\\', '/');
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index 3a84f09..17d4261 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_UTILS_H_
 #define DALI_SCENE3D_LOADER_UTILS_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/rendering/renderer.h>
 #include <cctype>
 #include <sstream>
-#include "dali/public-api/actors/actor.h"
-#include "dali/public-api/common/dali-common.h"
-#include "dali/public-api/rendering/renderer.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 /*
  * @brief Fixed size backing buffer to use with std::ostreams where control over
@@ -199,8 +195,6 @@ DALI_SCENE3D_API Geometry MakeTexturedQuadGeometry(TexturedQuadOptions::Type opt
  */
 DALI_SCENE3D_API void ToUnixFileSeparators(std::string& path);
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif /* DALI_SCENE3D_LOADER_UTILS_H_ */
index ac970ca..259892f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  * limitations under the License.
  *
  */
-#include "dali-scene3d/public-api/loader/view-projection.h"
-#include "dali-scene3d/public-api/loader/utils.h"
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/view-projection.h>
+
+// INTERNAL INCLDUES
+#include <dali-scene3d/public-api/loader/utils.h>
+
+namespace Dali::Scene3D::Loader
 {
 void ViewProjection::Update()
 {
@@ -34,6 +34,4 @@ void ViewProjection::Update()
   }
 }
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
index db7be74..c1e5532 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_VIEW_PROJECTION_H_
 #define DALI_SCENE3D_LOADER_VIEW_PROJECTION_H_
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-
 // EXTERNAL INCLUDES
-#include "dali/public-api/math/matrix.h"
+#include <dali/public-api/math/matrix.h>
 
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali::Scene3D::Loader
 {
 /**
  * @brief Contains view and projection matrices, also caching the view-projection
@@ -74,8 +70,6 @@ private:
   Matrix mViewProjection;
 };
 
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader
 
 #endif //DALI_SCENE3D_LOADER_VIEW_PROJECTION_H_
index 1133211..7fcc702 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -267,9 +267,6 @@ void ImageView::OnRelayout(const Vector2& size, RelayoutContainer& container)
 
     bool zeroPadding = (padding == Extents());
 
-    Vector2 naturalSize;
-    mVisual.GetNaturalSize(naturalSize);
-
     Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
       Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
     if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
@@ -281,7 +278,7 @@ void ImageView::OnRelayout(const Vector2& size, RelayoutContainer& container)
     Vector2 finalSize   = size - Vector2(padding.start + padding.end, padding.top + padding.bottom);
     Vector2 finalOffset = Vector2(padding.start, padding.top);
 
-    ApplyFittingMode(finalSize, naturalSize, finalOffset, zeroPadding, transformMap);
+    ApplyFittingMode(finalSize, finalOffset, zeroPadding, transformMap);
 
     mVisual.SetTransformAndSize(transformMap, size);
 
@@ -413,7 +410,7 @@ void ImageView::SetTransformMapForFittingMode(Vector2 finalSize, Vector2 natural
   }
 }
 
-void ImageView::ApplyFittingMode(Vector2 finalSize, Vector2 naturalSize, Vector2 finalOffset, bool zeroPadding, Property::Map& transformMap)
+void ImageView::ApplyFittingMode(Vector2 finalSize, Vector2 finalOffset, bool zeroPadding, Property::Map& transformMap)
 {
   Visual::FittingMode fittingMode = Toolkit::GetImplementation(mVisual).GetFittingMode();
 
@@ -429,6 +426,14 @@ void ImageView::ApplyFittingMode(Vector2 finalSize, Vector2 naturalSize, Vector2
   {
     mImageVisualPaddingSetByTransform = true;
 
+    Vector2 naturalSize;
+    // NaturalSize will not be used for FILL fitting mode, which is default.
+    // Skip GetNaturalSize
+    if(fittingMode != Visual::FittingMode::FILL)
+    {
+      mVisual.GetNaturalSize(naturalSize);
+    }
+
     // If FittingMode use FIT_WIDTH or FIT_HEIGTH, it need to change proper fittingMode
     if(fittingMode == Visual::FittingMode::FIT_WIDTH)
     {
index 47f7283..7caf9eb 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_IMAGE_VIEW_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -177,12 +177,11 @@ private:
   /**
    * @brief Apply fittingMode
    * param[in] finalSize The size for fittingMode
-   * param[in] textureSize The size of texture
    * param[in] offset The offset for fittingMode
    * param[in] zeroPadding whether padding is zero
    * param[in] transformMap  The map for fitting image
    */
-  void ApplyFittingMode(Vector2 finalSize, Vector2 textureSize, Vector2 offset, bool zeroPadding, Property::Map& transformMap);
+  void ApplyFittingMode(Vector2 finalSize, Vector2 offset, bool zeroPadding, Property::Map& transformMap);
 
 private:
   // Undefined
index 11f83a8..e81b16f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -76,7 +76,7 @@ LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLo
 }
 
 LoadingTask::LoadingTask(uint32_t id, const VisualUrl& url, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, bool loadPlanes, CallbackBase* callback)
-: AsyncTask(callback),
+: AsyncTask(callback, url.GetProtocolType() == VisualUrl::ProtocolType::REMOTE ? AsyncTask::PriorityType::LOW : AsyncTask::PriorityType::HIGH),
   url(url),
   encodedImageBuffer(),
   id(id),
index 158ef83..40f1a64 100644 (file)
@@ -46,7 +46,7 @@ Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New(Debug::NoLogging,
 } // unnamed namespace
 
 VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache)
-: AsyncTask(MakeCallback(this, &VectorAnimationTask::TaskCompleted), AsyncTask::ThreadType::WORKER_THREAD),
+: AsyncTask(MakeCallback(this, &VectorAnimationTask::TaskCompleted), AsyncTask::PriorityType::HIGH, AsyncTask::ThreadType::WORKER_THREAD),
   mUrl(),
   mVectorRenderer(VectorAnimationRenderer::New()),
   mAnimationData(),
index 0669ed5..d5bc010 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -97,9 +97,6 @@ DALI_ENUM_TO_STRING_TABLE_END(RELEASE_POLICY)
 
 const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 
-const float PIXEL_ALIGN_ON  = 1.0f;
-const float PIXEL_ALIGN_OFF = 0.0f;
-
 constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u;
 
 Geometry CreateGeometry(VisualFactoryCache& factoryCache, ImageDimensions gridSize)
@@ -736,13 +733,6 @@ void ImageVisual::DoSetOnScene(Actor& actor)
   }
 
   mPlacementActor = actor;
-  // Search the Actor tree to find if Layer UI behaviour set.
-  Layer layer = actor.GetLayer();
-  if(layer && layer.GetProperty<Layer::Behavior>(Layer::Property::BEHAVIOR) == Layer::LAYER_3D)
-  {
-    // Layer 3D set, do not align pixels
-    mImpl->mRenderer.RegisterProperty(PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF);
-  }
 
   if(mPixelArea != FULL_TEXTURE_RECT)
   {
@@ -762,7 +752,7 @@ void ImageVisual::DoSetOnScene(Actor& actor)
     Vector2 imageSize = Vector2::ZERO;
     if(actor)
     {
-      imageSize  = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+      imageSize           = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
       mPlacementActorSize = imageSize;
     }
 
@@ -912,7 +902,7 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn
       Vector2 imageSize = Vector2::ZERO;
       if(actor)
       {
-        imageSize  = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
+        imageSize           = actor.GetProperty(Actor::Property::SIZE).Get<Vector2>();
         mPlacementActorSize = imageSize;
       }
       else
@@ -1161,11 +1151,6 @@ Shader ImageVisual::GenerateShader() const
     shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT);
   }
 
-  // Set pixel align off as default.
-  // ToDo: Pixel align causes issues such as rattling image animation.
-  // We should trun it off until issues are resolved
-  shader.RegisterProperty(PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF);
-
   return shader;
 }
 
index c79c9a6..ac898d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -95,7 +95,6 @@ const char* const WRAP_MODE_UNIFORM_NAME("wrapMode");
 const char* const IMAGE_WRAP_MODE_U("wrapModeU");
 const char* const IMAGE_WRAP_MODE_V("wrapModeV");
 const char* const IMAGE_BORDER("border");
-const char* const PIXEL_ALIGNED_UNIFORM_NAME("uPixelAligned");
 const char* const ANIMATED_IMAGE_URLS_NAME("urls");
 const char* const BATCH_SIZE_NAME("batchSize");
 const char* const CACHE_SIZE_NAME("cacheSize");
index b65292f..0bb5840 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_VISUAL_STRING_CONSTANTS_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -79,7 +79,6 @@ extern const char* const WRAP_MODE_UNIFORM_NAME;
 extern const char* const IMAGE_WRAP_MODE_U;
 extern const char* const IMAGE_WRAP_MODE_V;
 extern const char* const IMAGE_BORDER;
-extern const char* const PIXEL_ALIGNED_UNIFORM_NAME;
 extern const char* const ANIMATED_IMAGE_URLS_NAME;
 extern const char* const BATCH_SIZE_NAME;
 extern const char* const CACHE_SIZE_NAME;
index 15c7b41..7bc6ec0 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 16;
+const unsigned int TOOLKIT_MICRO_VERSION = 17;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index fb285c7..1bba007 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.2.16
+Version:    2.2.17
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT