Asynchronous loading of Scene3D resources
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / controls / model / model-impl.cpp
index bed5f34..d936271 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali/public-api/math/math-utils.h>
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <filesystem>
 
 // INTERNAL INCLUDES
@@ -70,11 +71,6 @@ static constexpr Vector3 Y_DIRECTION(1.0f, -1.0f, 1.0f);
 static constexpr bool DEFAULT_MODEL_CHILDREN_SENSITIVE = false;
 static constexpr bool DEFAULT_MODEL_CHILDREN_FOCUSABLE = false;
 
-static constexpr std::string_view KTX_EXTENSION  = ".ktx";
-static constexpr std::string_view OBJ_EXTENSION  = ".obj";
-static constexpr std::string_view GLTF_EXTENSION = ".gltf";
-static constexpr std::string_view DLI_EXTENSION  = ".dli";
-
 struct BoundingVolume
 {
   void Init()
@@ -188,12 +184,16 @@ Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUr
   mModelChildrenSensitive(DEFAULT_MODEL_CHILDREN_SENSITIVE),
   mModelChildrenFocusable(DEFAULT_MODEL_CHILDREN_FOCUSABLE),
   mModelResourceReady(false),
-  mIBLResourceReady(true)
+  mIblDiffuseResourceReady(true),
+  mIblSpecularResourceReady(true),
+  mIblDiffuseDirty(false),
+  mIblSpecularDirty(false)
 {
 }
 
 Model::~Model()
 {
+  ResetResourceTasks();
 }
 
 Dali::Scene3D::Model Model::New(const std::string& modelUrl, const std::string& resourceDirectoryUrl)
@@ -251,17 +251,98 @@ bool Model::GetChildrenFocusable() const
 
 void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor)
 {
-  mIBLResourceReady       = false;
-  Texture diffuseTexture  = (!diffuseUrl.empty()) ? Dali::Scene3D::Loader::LoadCubeMap(diffuseUrl) : Texture();
-  Texture specularTexture = (!specularUrl.empty()) ? Dali::Scene3D::Loader::LoadCubeMap(specularUrl) : Texture();
-  SetImageBasedLightTexture(diffuseTexture, specularTexture, scaleFactor);
-  mIBLResourceReady = true;
+  bool needIblReset = false;
+  bool isOnScene = Self().GetProperty<bool>(Dali::Actor::Property::CONNECTED_TO_SCENE);
+  if(mDiffuseIblUrl != diffuseUrl)
+  {
+    mDiffuseIblUrl = diffuseUrl;
+    if(mDiffuseIblUrl.empty())
+    {
+      needIblReset             = true;
+    }
+    else
+    {
+      mIblDiffuseDirty         = true;
+      mIblDiffuseResourceReady = false;
+    }
+  }
+
+  if(mSpecularIblUrl != specularUrl)
+  {
+    mSpecularIblUrl = specularUrl;
+    if(mSpecularIblUrl.empty())
+    {
+      needIblReset              = true;
+    }
+    else
+    {
+      mIblSpecularDirty         = true;
+      mIblSpecularResourceReady = false;
+    }
+  }
+
+  // If one or both of diffuse url and specular url are empty,
+  // we don't need to request to load texture.
+  if(needIblReset)
+  {
+    if(mIblDiffuseLoadTask)
+    {
+      Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask);
+      mIblDiffuseLoadTask.Reset();
+    }
+
+    if(mIblSpecularLoadTask)
+    {
+      Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask);
+      mIblSpecularLoadTask.Reset();
+    }
+
+    mIblDiffuseDirty          = false;
+    mIblSpecularDirty         = false;
+    mIblDiffuseResourceReady  = true;
+    mIblSpecularResourceReady = true;
+
+    mDiffuseTexture.Reset();
+    mSpecularTexture.Reset();
+    UpdateImageBasedLightTexture();
+  }
+  else
+  {
+    if(isOnScene && mIblDiffuseDirty)
+    {
+      if(mIblDiffuseLoadTask)
+      {
+        Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask);
+        mIblDiffuseLoadTask.Reset();
+      }
+      mIblDiffuseLoadTask = new EnvironmentMapLoadTask(mDiffuseIblUrl, MakeCallback(this, &Model::OnIblDiffuseLoadComplete));
+      Dali::AsyncTaskManager::Get().AddTask(mIblDiffuseLoadTask);
+      mIblDiffuseDirty = false;
+    }
+
+    if(isOnScene && mIblSpecularDirty)
+    {
+      if(mIblSpecularLoadTask)
+      {
+        Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask);
+        mIblSpecularLoadTask.Reset();
+      }
+      mIblSpecularLoadTask = new EnvironmentMapLoadTask(mSpecularIblUrl, MakeCallback(this, &Model::OnIblSpecularLoadComplete));
+      Dali::AsyncTaskManager::Get().AddTask(mIblSpecularLoadTask);
+      mIblSpecularDirty = false;
+    }
+  }
+
+  if(!Dali::Equals(mIblScaleFactor, scaleFactor))
+  {
+    mIblScaleFactor = scaleFactor;
+    UpdateImageBasedLightScaleFactor();
+  }
 
-  // If Model resource is already ready, then set resource ready.
-  // If Model resource is still not ready, wait for model resource ready.
+  // If diffuse and specular textures are already loaded, emits resource ready signal here.
   if(IsResourceReady())
   {
-    SetResourceReady(false);
+    Control::SetResourceReady(false);
   }
 }
 
@@ -336,9 +417,16 @@ void Model::OnInitialize()
 
 void Model::OnSceneConnection(int depth)
 {
-  if(!mModelRoot)
+  if(!mModelLoadTask && !mModelRoot)
+  {
+    Scene3D::Loader::InitializeGltfLoader();
+    mModelLoadTask = new ModelLoadTask(mModelUrl, mResourceDirectoryUrl, MakeCallback(this, &Model::OnModelLoadComplete));
+    Dali::AsyncTaskManager::Get().AddTask(mModelLoadTask);
+  }
+  // If diffuse and specular url is not valid, IBL does not need to be loaded.
+  if(!mDiffuseIblUrl.empty() && !mSpecularIblUrl.empty())
   {
-    LoadModel();
+    SetImageBasedLightSource(mDiffuseIblUrl, mSpecularIblUrl, mIblScaleFactor);
   }
 
   Actor parent = Self().GetParent();
@@ -372,7 +460,8 @@ Vector3 Model::GetNaturalSize()
 {
   if(!mModelRoot)
   {
-    LoadModel();
+    DALI_LOG_ERROR("Model is still not loaded.\n");
+    return Vector3::ZERO;
   }
 
   return mNaturalSize;
@@ -400,121 +489,187 @@ void Model::OnRelayout(const Vector2& size, RelayoutContainer& container)
 
 bool Model::IsResourceReady() const
 {
-  return mModelResourceReady && mIBLResourceReady;
+  return mModelResourceReady && mIblDiffuseResourceReady && mIblSpecularResourceReady;
 }
 
-void Model::LoadModel()
+void Model::ScaleModel()
 {
-  std::filesystem::path modelUrl(mModelUrl);
-  if(mResourceDirectoryUrl.empty())
+  if(mModelRoot)
   {
-    mResourceDirectoryUrl = std::string(modelUrl.parent_path()) + "/";
+    float   scale = 1.0f;
+    Vector3 size  = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
+    if(size.x > 0.0f && size.y > 0.0f)
+    {
+      scale = MAXFLOAT;
+      scale = std::min(size.x / mNaturalSize.x, scale);
+      scale = std::min(size.y / mNaturalSize.y, scale);
+    }
+    // Models in glTF and dli are defined as right hand coordinate system.
+    // DALi uses left hand coordinate system. Scaling negative is for change winding order.
+    mModelRoot.SetProperty(Dali::Actor::Property::SCALE, Y_DIRECTION * scale);
   }
-  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;
-  };
+void Model::FitModelPosition()
+{
+  if(mModelRoot)
+  {
+    // Loaded model pivot is not the model center.
+    mModelRoot.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+    mModelRoot.SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3::ONE - mModelPivot);
+  }
+}
 
-  Dali::Scene3D::Loader::ResourceBundle                        resources;
-  Dali::Scene3D::Loader::SceneDefinition                       scene;
-  std::vector<Dali::Scene3D::Loader::AnimationGroupDefinition> animGroups;
-  std::vector<Dali::Scene3D::Loader::CameraParameters>         cameraParameters;
-  std::vector<Dali::Scene3D::Loader::LightParameters>          lights;
+void Model::CollectRenderableActor(Actor actor)
+{
+  uint32_t rendererCount = actor.GetRendererCount();
+  if(rendererCount)
+  {
+    mRenderableActors.push_back(actor);
+  }
 
-  std::vector<Dali::Scene3D::Loader::AnimationDefinition> animations;
-  animations.clear();
+  uint32_t childrenCount = actor.GetChildCount();
+  for(uint32_t i = 0; i < childrenCount; ++i)
+  {
+    CollectRenderableActor(actor.GetChildAt(i));
+  }
+}
 
-  Dali::Scene3D::Loader::SceneMetadata metaData;
+void Model::UpdateImageBasedLightTexture()
+{
+  Dali::Texture currentDiffuseTexture  = (mDiffuseTexture && mSpecularTexture) ? mDiffuseTexture : mSceneDiffuseTexture;
+  Dali::Texture currentSpecularTexture = (mDiffuseTexture && mSpecularTexture) ? mSpecularTexture : mSceneSpecularTexture;
+  float         currentIblScaleFactor  = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor;
 
-  std::filesystem::path metaDataUrl = modelUrl;
-  metaDataUrl.replace_extension("metadata");
+  if(!currentDiffuseTexture || !currentSpecularTexture)
+  {
+    currentDiffuseTexture  = mDefaultDiffuseTexture;
+    currentSpecularTexture = mDefaultSpecularTexture;
+    currentIblScaleFactor  = Dali::Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity();
+  }
 
-  Dali::Scene3D::Loader::LoadSceneMetadata(metaDataUrl.c_str(), metaData);
+  for(auto&& actor : mRenderableActors)
+  {
+    Actor renderableActor = actor.GetHandle();
+    if(renderableActor)
+    {
+      uint32_t rendererCount = renderableActor.GetRendererCount();
+      for(uint32_t i = 0; i < rendererCount; ++i)
+      {
+        Dali::Renderer renderer = renderableActor.GetRendererAt(i);
+        if(renderer)
+        {
+          Dali::TextureSet textures = renderer.GetTextures();
+          if(textures)
+          {
+            uint32_t textureCount = textures.GetTextureCount();
+            // EnvMap requires at least 2 texture, diffuse and specular
+            if(textureCount > 2u)
+            {
+              textures.SetTexture(textureCount - OFFSET_FOR_DIFFUSE_CUBE_TEXTURE, currentDiffuseTexture);
+              textures.SetTexture(textureCount - OFFSET_FOR_SPECULAR_CUBE_TEXTURE, currentSpecularTexture);
+            }
+          }
+        }
+      }
+      renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIblScaleFactor);
+    }
+  }
+}
 
-  Dali::Scene3D::Loader::LoadResult output{resources, scene, metaData, animations, animGroups, cameraParameters, lights};
+void Model::UpdateImageBasedLightScaleFactor()
+{
+  if((!mDiffuseTexture || !mSpecularTexture) &&
+     (!mSceneDiffuseTexture || !mSceneSpecularTexture))
+  {
+    return;
+  }
 
-  if(extension == DLI_EXTENSION)
+  float currentIblScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor;
+  for(auto&& actor : mRenderableActors)
   {
-    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, output};
-    if(!loader.LoadScene(mModelUrl, loadParams))
+    Actor renderableActor = actor.GetHandle();
+    if(renderableActor)
     {
-      Dali::Scene3D::Loader::ExceptionFlinger(ASSERT_LOCATION) << "Failed to load scene from '" << mModelUrl << "': " << loader.GetParseError();
+      renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIblScaleFactor);
     }
   }
-  else if(extension == GLTF_EXTENSION)
-  {
-    Dali::Scene3D::Loader::ShaderDefinitionFactory sdf;
-    sdf.SetResources(resources);
-    Dali::Scene3D::Loader::LoadGltfScene(mModelUrl, sdf, output);
+}
 
-    resources.mEnvironmentMaps.push_back({});
+void Model::NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor)
+{
+  if(mSceneDiffuseTexture != diffuseTexture || mSceneSpecularTexture != specularTexture)
+  {
+    mSceneDiffuseTexture  = diffuseTexture;
+    mSceneSpecularTexture = specularTexture;
+    mSceneIblScaleFactor  = scaleFactor;
+    // If Model IBL is not set, use SceneView's IBL.
+    if(!mDiffuseTexture || !mSpecularTexture)
+    {
+      UpdateImageBasedLightTexture();
+    }
   }
-  else
+}
+
+void Model::NotifyImageBasedLightScaleFactor(float scaleFactor)
+{
+  mSceneIblScaleFactor = scaleFactor;
+  if(mSceneDiffuseTexture && mSceneSpecularTexture)
   {
-    DALI_LOG_ERROR("Unsupported model type.\n");
+    UpdateImageBasedLightScaleFactor();
   }
+}
 
-  Dali::Scene3D::Loader::Transforms                   xforms{Dali::Scene3D::Loader::MatrixStack{}, Dali::Scene3D::Loader::ViewProjection{}};
-  Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{resources, xforms, {}, {}, {}};
-  Dali::Scene3D::Loader::Customization::Choices       choices;
+void Model::OnModelLoadComplete()
+{
+  if(!mModelLoadTask->HasSucceeded())
+  {
+    ResetResourceTasks();
+    return;
+  }
 
   mModelRoot = Actor::New();
   mModelRoot.SetProperty(Actor::Property::COLOR_MODE, ColorMode::USE_OWN_MULTIPLY_PARENT_COLOR);
 
-  BoundingVolume AABB;
-  for(auto iRoot : scene.GetRoots())
+  BoundingVolume                                      AABB;
+  auto*                                               resources = &(mModelLoadTask->mResources);
+  auto*                                               scene     = &(mModelLoadTask->mScene);
+  Dali::Scene3D::Loader::Transforms                   xforms{Dali::Scene3D::Loader::MatrixStack{}, Dali::Scene3D::Loader::ViewProjection{}};
+  Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{*resources, xforms, {}, {}, {}};
+  uint32_t rootCount = 0u;
+  for(auto iRoot : scene->GetRoots())
   {
-    auto resourceRefs = resources.CreateRefCounter();
-    scene.CountResourceRefs(iRoot, choices, resourceRefs);
-    resources.CountEnvironmentReferences(resourceRefs);
-
-    resources.LoadResources(resourceRefs, pathProvider);
+    resources->GenerateResources(mModelLoadTask->mResourceRefCounts[rootCount]);
 
-    // 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 : resources.mEnvironmentMaps)
+    if(auto actor = scene->CreateNodes(iRoot, mModelLoadTask->mResourceChoices, nodeParams))
     {
-      env.first.mYDirection = Y_DIRECTION;
-    }
-
-    if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
-    {
-      scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
-      scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
-      ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests));
+      scene->ConfigureSkeletonJoints(iRoot, resources->mSkeletons, actor);
+      scene->ConfigureSkinningShaders(*resources, actor, std::move(nodeParams.mSkinnables));
+      ConfigureBlendShapeShaders(*resources, *scene, actor, std::move(nodeParams.mBlendshapeRequests));
 
-      scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
+      scene->ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
 
       mModelRoot.Add(actor);
     }
 
-    AddModelTreeToAABB(AABB, scene, choices, iRoot, nodeParams, Matrix::IDENTITY);
+    AddModelTreeToAABB(AABB, *scene, mModelLoadTask->mResourceChoices, iRoot, nodeParams, Matrix::IDENTITY);
+    rootCount++;
   }
 
-  if(!resources.mEnvironmentMaps.empty())
+  if(!resources->mEnvironmentMaps.empty())
   {
-    mDefaultDiffuseTexture  = resources.mEnvironmentMaps.front().second.mDiffuse;
-    mDefaultSpecularTexture = resources.mEnvironmentMaps.front().second.mSpecular;
+    mDefaultDiffuseTexture  = resources->mEnvironmentMaps.front().second.mDiffuse;
+    mDefaultSpecularTexture = resources->mEnvironmentMaps.front().second.mSpecular;
   }
 
-  if(!animations.empty())
+  if(!mModelLoadTask->mAnimations.empty())
   {
     auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property)
     {
       Dali::Actor actor;
       if(property.mNodeIndex != Scene3D::Loader::INVALID_INDEX)
       {
-        auto* node = scene.GetNode(property.mNodeIndex);
+        auto* node = scene->GetNode(property.mNodeIndex);
         if(node != nullptr)
         {
           actor = mModelRoot.FindChildById(node->mNodeId);
@@ -528,7 +683,7 @@ void Model::LoadModel()
     };
 
     mAnimations.clear();
-    for(auto&& animation : animations)
+    for(auto&& animation : mModelLoadTask->mAnimations)
     {
       Dali::Animation anim = animation.ReAnimate(getActor);
 
@@ -538,6 +693,7 @@ void Model::LoadModel()
 
   mRenderableActors.clear();
   CollectRenderableActor(mModelRoot);
+
   UpdateImageBasedLightTexture();
   UpdateImageBasedLightScaleFactor();
 
@@ -563,129 +719,64 @@ void Model::LoadModel()
 
   mModelResourceReady = true;
 
-  Control::SetResourceReady(false);
-}
-
-void Model::ScaleModel()
-{
-  if(mModelRoot)
+  if(IsResourceReady())
   {
-    float   scale = 1.0f;
-    Vector3 size  = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
-    if(size.x > 0.0f && size.y > 0.0f)
-    {
-      scale = MAXFLOAT;
-      scale = std::min(size.x / mNaturalSize.x, scale);
-      scale = std::min(size.y / mNaturalSize.y, scale);
-    }
-    // Models in glTF and dli are defined as right hand coordinate system.
-    // DALi uses left hand coordinate system. Scaling negative is for change winding order.
-    mModelRoot.SetProperty(Dali::Actor::Property::SCALE, Y_DIRECTION * scale);
+    Control::SetResourceReady(false);
   }
+  mModelLoadTask.Reset();
 }
 
-void Model::FitModelPosition()
+void Model::OnIblDiffuseLoadComplete()
 {
-  if(mModelRoot)
+  mDiffuseTexture = (mIblDiffuseLoadTask->HasSucceeded()) ? mIblDiffuseLoadTask->GetEnvironmentMap().CreateTexture() : Texture();
+  mIblDiffuseResourceReady = true;
+  if(mIblDiffuseResourceReady && mIblSpecularResourceReady)
   {
-    // Loaded model pivot is not the model center.
-    mModelRoot.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
-    mModelRoot.SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3::ONE - mModelPivot);
+    OnIblLoadComplete();
   }
+  mIblDiffuseLoadTask.Reset();
 }
 
-void Model::CollectRenderableActor(Actor actor)
+void Model::OnIblSpecularLoadComplete()
 {
-  uint32_t rendererCount = actor.GetRendererCount();
-  if(rendererCount)
+  mSpecularTexture = (mIblSpecularLoadTask->HasSucceeded()) ? mIblSpecularLoadTask->GetEnvironmentMap().CreateTexture() : Texture();
+  mIblSpecularResourceReady = true;
+  if(mIblDiffuseResourceReady && mIblSpecularResourceReady)
   {
-    mRenderableActors.push_back(actor);
-  }
-
-  uint32_t childrenCount = actor.GetChildCount();
-  for(uint32_t i = 0; i < childrenCount; ++i)
-  {
-    CollectRenderableActor(actor.GetChildAt(i));
+    OnIblLoadComplete();
   }
+  mIblSpecularLoadTask.Reset();
 }
 
-void Model::UpdateImageBasedLightTexture()
+void Model::OnIblLoadComplete()
 {
-  Dali::Texture currentDiffuseTexture  = (mDiffuseTexture) ? mDiffuseTexture : mSceneDiffuseTexture;
-  Dali::Texture currentSpecularTexture = (mSpecularTexture) ? mSpecularTexture : mSceneSpecularTexture;
-  float         currentIBLScaleFactor  = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor;
-  if(!currentDiffuseTexture || !currentSpecularTexture)
-  {
-    currentDiffuseTexture  = mDefaultDiffuseTexture;
-    currentSpecularTexture = mDefaultSpecularTexture;
-    currentIBLScaleFactor  = Dali::Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity();
-  }
+  UpdateImageBasedLightTexture();
 
-  for(auto&& actor : mRenderableActors)
+  if(IsResourceReady())
   {
-    Actor renderableActor = actor.GetHandle();
-    if(renderableActor)
-    {
-      uint32_t rendererCount = renderableActor.GetRendererCount();
-      for(uint32_t i = 0; i < rendererCount; ++i)
-      {
-        Dali::Renderer renderer = renderableActor.GetRendererAt(i);
-        if(renderer)
-        {
-          Dali::TextureSet textures = renderer.GetTextures();
-          if(textures)
-          {
-            uint32_t textureCount = textures.GetTextureCount();
-            // EnvMap requires at least 2 texture, diffuse and specular
-            if(textureCount > 2u)
-            {
-              textures.SetTexture(textureCount - OFFSET_FOR_DIFFUSE_CUBE_TEXTURE, currentDiffuseTexture);
-              textures.SetTexture(textureCount - OFFSET_FOR_SPECULAR_CUBE_TEXTURE, currentSpecularTexture);
-            }
-          }
-        }
-      }
-      renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIBLScaleFactor);
-    }
+    Control::SetResourceReady(false);
   }
 }
 
-void Model::UpdateImageBasedLightScaleFactor()
+void Model::ResetResourceTasks()
 {
-  if((!mDiffuseTexture || !mSpecularTexture) &&
-     (!mSceneDiffuseTexture || !mSceneSpecularTexture))
+  if(Dali::Adaptor::IsAvailable())
   {
-    return;
-  }
-
-  float currentIBLScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor;
-  for(auto&& actor : mRenderableActors)
-  {
-    Actor renderableActor = actor.GetHandle();
-    if(renderableActor)
+    if(mModelLoadTask)
     {
-      renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIBLScaleFactor);
+      Dali::AsyncTaskManager::Get().RemoveTask(mModelLoadTask);
+      mModelLoadTask.Reset();
+    }
+    if(mIblDiffuseLoadTask)
+    {
+      Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask);
+      mIblDiffuseLoadTask.Reset();
+    }
+    if(mIblSpecularLoadTask)
+    {
+      Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask);
+      mIblSpecularLoadTask.Reset();
     }
-  }
-}
-
-void Model::NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor)
-{
-  if(mSceneDiffuseTexture != diffuseTexture || mSceneSpecularTexture != specularTexture)
-  {
-    mSceneDiffuseTexture  = diffuseTexture;
-    mSceneSpecularTexture = specularTexture;
-    mSceneIblScaleFactor  = scaleFactor;
-    UpdateImageBasedLightTexture();
-  }
-}
-
-void Model::NotifyImageBasedLightScaleFactor(float scaleFactor)
-{
-  mSceneIblScaleFactor = scaleFactor;
-  if(mSceneDiffuseTexture && mSceneSpecularTexture)
-  {
-    UpdateImageBasedLightScaleFactor();
   }
 }