[dali_2.3.24] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / common / model-load-task.cpp
index bfd9256..10e0aba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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/internal/common/model-load-task.h>
 
 // EXTERNAL INCLUDES
-#include <filesystem>
 #include <dali/integration-api/debug.h>
-
-// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/loader/animation-definition.h>
-#include <dali-scene3d/public-api/loader/camera-parameters.h>
-#include <dali-scene3d/public-api/loader/cube-map-loader.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>
-
+#include <filesystem>
 
 namespace Dali
 {
@@ -42,92 +31,71 @@ 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),
+: AsyncTask(callback, AsyncTask::PriorityType::LOW),
   mModelUrl(modelUrl),
   mResourceDirectoryUrl(resourceDirectoryUrl),
+  mModelCacheManager(Scene3D::Internal::ModelCacheManager::Get()),
+  mLoadResult(mModelCacheManager.GetModelLoadResult(mModelUrl)),
   mHasSucceeded(false)
 {
+  mModelCacheManager.ReferenceModelCache(mModelUrl);
 }
 
 ModelLoadTask::~ModelLoadTask()
 {
+  mModelCacheManager.UnreferenceModelCache(mModelUrl);
 }
 
 void ModelLoadTask::Process()
 {
-  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)
-  {
+  Dali::Scene3D::Loader::ResourceBundle::PathProvider pathProvider = [&](Dali::Scene3D::Loader::ResourceType::Value type) {
     return mResourceDirectoryUrl;
   };
-  mAnimations.clear();
-
-  std::filesystem::path metaDataUrl = modelUrl;
-  metaDataUrl.replace_extension(METADATA_EXTENSION.data());
-
-  Dali::Scene3D::Loader::LoadSceneMetadata(metaDataUrl.c_str(), mMetaData);
 
-  Dali::Scene3D::Loader::LoadResult result{mResources, mScene, mMetaData, mAnimations, mAnimGroups, mCameraParameters, mLights};
+  mModelLoader = std::make_shared<Dali::Scene3D::Loader::ModelLoader>(mModelUrl, mResourceDirectoryUrl, mLoadResult);
 
-  if(extension == DLI_EXTENSION)
+  bool loadSucceeded = false;
   {
-    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, result};
-    if(!loader.LoadScene(mModelUrl, loadParams))
+    // Lock model url during process, so let we do not try to load same model multiple times.
+    mModelCacheManager.LockModelLoadScene(mModelUrl);
+    if(mModelCacheManager.IsSceneLoaded(mModelUrl))
     {
-      DALI_LOG_ERROR("Failed to load scene from '%s': %s\n", mModelUrl.c_str(), loader.GetParseError().c_str());
-      return;
+      loadSucceeded = true;
     }
-  }
-  else if(extension == GLTF_EXTENSION)
-  {
-    Dali::Scene3D::Loader::ShaderDefinitionFactory sdf;
-    sdf.SetResources(mResources);
-    Dali::Scene3D::Loader::LoadGltfScene(mModelUrl, sdf, result);
-  }
-  else
-  {
-    DALI_LOG_ERROR("Unsupported model type.\n");
-    return;
-  }
+    else
+    {
+      mModelCacheManager.SetSceneLoading(mModelUrl, true);
 
-  for(auto iRoot : mScene.GetRoots())
-  {
-    mResourceRefCounts.push_back(mResources.CreateRefCounter());
-    mScene.CountResourceRefs(iRoot, mResourceChoices, mResourceRefCounts.back());
-    mResources.CountEnvironmentReferences(mResourceRefCounts.back());
+      loadSucceeded = mModelLoader->LoadModel(pathProvider, true);
 
-    mResources.LoadRawResources(mResourceRefCounts.back(), pathProvider);
+      // 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)
+      {
+        env.first.mYDirection = Y_DIRECTION;
+      }
 
-    // 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 : mResources.mEnvironmentMaps)
-    {
-      env.first.mYDirection = Y_DIRECTION;
+      mModelCacheManager.SetSceneLoading(mModelUrl, false);
+      mModelCacheManager.SetSceneLoaded(mModelUrl, loadSucceeded);
     }
+    mModelCacheManager.UnlockModelLoadScene(mModelUrl);
   }
+
+  if(!loadSucceeded)
+  {
+    DALI_LOG_ERROR("Failed to load scene from '%s'\n", mModelUrl.c_str());
+    return;
+  }
+
   mHasSucceeded = true;
 }
 
@@ -141,6 +109,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