2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-scene3d/internal/controls/model/model-impl.h>
22 #include <dali-toolkit/dali-toolkit.h>
23 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
24 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
25 #include <dali/devel-api/actors/actor-devel.h>
26 #include <dali/integration-api/debug.h>
27 #include <dali/public-api/math/math-utils.h>
28 #include <dali/public-api/object/type-registry-helper.h>
29 #include <dali/public-api/object/type-registry.h>
30 #include <dali/integration-api/adaptor-framework/adaptor.h>
34 #include <dali-scene3d/internal/controls/scene-view/scene-view-impl.h>
35 #include <dali-scene3d/public-api/controls/model/model.h>
36 #include <dali-scene3d/public-api/loader/animation-definition.h>
37 #include <dali-scene3d/public-api/loader/camera-parameters.h>
38 #include <dali-scene3d/public-api/loader/cube-map-loader.h>
39 #include <dali-scene3d/public-api/loader/dli-loader.h>
40 #include <dali-scene3d/public-api/loader/gltf2-loader.h>
41 #include <dali-scene3d/public-api/loader/light-parameters.h>
42 #include <dali-scene3d/public-api/loader/load-result.h>
43 #include <dali-scene3d/public-api/loader/node-definition.h>
44 #include <dali-scene3d/public-api/loader/scene-definition.h>
45 #include <dali-scene3d/public-api/loader/shader-definition-factory.h>
59 return Scene3D::Model::New(std::string());
62 // Setup properties, signals and actions using the type-registry.
63 DALI_TYPE_REGISTRATION_BEGIN(Scene3D::Model, Toolkit::Control, Create);
64 DALI_TYPE_REGISTRATION_END()
66 static constexpr uint32_t OFFSET_FOR_DIFFUSE_CUBE_TEXTURE = 2u;
67 static constexpr uint32_t OFFSET_FOR_SPECULAR_CUBE_TEXTURE = 1u;
69 static constexpr Vector3 Y_DIRECTION(1.0f, -1.0f, 1.0f);
71 static constexpr bool DEFAULT_MODEL_CHILDREN_SENSITIVE = false;
72 static constexpr bool DEFAULT_MODEL_CHILDREN_FOCUSABLE = false;
78 pointMin = Vector3(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
79 pointMax = Vector3(std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min());
82 void ConsiderNewPointInVolume(const Vector3& position)
84 pointMin.x = std::min(position.x, pointMin.x);
85 pointMin.y = std::min(position.y, pointMin.y);
86 pointMin.z = std::min(position.z, pointMin.z);
88 pointMax.x = std::max(position.x, pointMax.x);
89 pointMax.y = std::max(position.y, pointMax.y);
90 pointMax.z = std::max(position.z, pointMax.z);
93 Vector3 CalculateSize()
95 return pointMax - pointMin;
98 Vector3 CalculatePivot()
100 Vector3 pivot = pointMin / (pointMin - pointMax);
101 for(uint32_t i = 0; i < 3; ++i)
103 // To avoid divid by zero
104 if(Dali::Equals(pointMin[i], pointMax[i]))
116 void ConfigureBlendShapeShaders(
117 Dali::Scene3D::Loader::ResourceBundle& resources, const Dali::Scene3D::Loader::SceneDefinition& scene, Actor root, std::vector<Dali::Scene3D::Loader::BlendshapeShaderConfigurationRequest>&& requests)
119 std::vector<std::string> errors;
120 auto onError = [&errors](const std::string& msg) { errors.push_back(msg); };
121 if(!scene.ConfigureBlendshapeShaders(resources, root, std::move(requests), onError))
123 Dali::Scene3D::Loader::ExceptionFlinger flinger(ASSERT_LOCATION);
124 for(auto& msg : errors)
126 flinger << msg << '\n';
131 void AddModelTreeToAABB(BoundingVolume& AABB, const Dali::Scene3D::Loader::SceneDefinition& scene, const Dali::Scene3D::Loader::Customization::Choices& choices, Dali::Scene3D::Loader::Index iNode, Dali::Scene3D::Loader::NodeDefinition::CreateParams& nodeParams, Matrix parentMatrix)
133 static constexpr uint32_t BOX_POINT_COUNT = 8;
134 static uint32_t BBIndex[BOX_POINT_COUNT][3] = {{0, 0, 0}, {0, 1, 0}, {1, 0, 0}, {1, 1, 0}, {0, 0, 1}, {0, 1, 1}, {1, 0, 1}, {1, 1, 1}};
137 const Dali::Scene3D::Loader::NodeDefinition* node = scene.GetNode(iNode);
138 Matrix localMatrix = node->GetLocalSpace();
139 Matrix::Multiply(nodeMatrix, localMatrix, parentMatrix);
142 if(node->GetExtents(nodeParams.mResources, volume[0], volume[1]))
144 for(uint32_t i = 0; i < BOX_POINT_COUNT; ++i)
146 Vector4 position = Vector4(volume[BBIndex[i][0]].x, volume[BBIndex[i][1]].y, volume[BBIndex[i][2]].z, 1.0f);
147 Vector4 objectPosition = nodeMatrix * position;
148 objectPosition /= objectPosition.w;
150 AABB.ConsiderNewPointInVolume(Vector3(objectPosition));
154 if(node->mCustomization)
156 if(!node->mChildren.empty())
158 auto choice = choices.Get(node->mCustomization->mTag);
159 Dali::Scene3D::Loader::Index i = std::min(choice != Dali::Scene3D::Loader::Customization::NONE ? choice : 0, static_cast<Dali::Scene3D::Loader::Index>(node->mChildren.size() - 1));
161 AddModelTreeToAABB(AABB, scene, choices, node->mChildren[i], nodeParams, nodeMatrix);
166 for(auto i : node->mChildren)
168 AddModelTreeToAABB(AABB, scene, choices, i, nodeParams, nodeMatrix);
173 } // anonymous namespace
175 Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUrl)
176 : Control(ControlBehaviour(DISABLE_SIZE_NEGOTIATION | DISABLE_STYLE_CHANGE_SIGNALS)),
178 mResourceDirectoryUrl(resourceDirectoryUrl),
180 mNaturalSize(Vector3::ZERO),
181 mModelPivot(AnchorPoint::CENTER),
182 mSceneIblScaleFactor(1.0f),
183 mIblScaleFactor(1.0f),
184 mModelChildrenSensitive(DEFAULT_MODEL_CHILDREN_SENSITIVE),
185 mModelChildrenFocusable(DEFAULT_MODEL_CHILDREN_FOCUSABLE),
186 mModelResourceReady(false),
187 mIblDiffuseResourceReady(true),
188 mIblSpecularResourceReady(true),
189 mIblDiffuseDirty(false),
190 mIblSpecularDirty(false)
196 ResetResourceTasks();
199 Dali::Scene3D::Model Model::New(const std::string& modelUrl, const std::string& resourceDirectoryUrl)
201 Model* impl = new Model(modelUrl, resourceDirectoryUrl);
203 Dali::Scene3D::Model handle = Dali::Scene3D::Model(*impl);
205 // Second-phase init of the implementation
206 // This can only be done after the CustomActor connection has been made...
212 const Actor Model::GetModelRoot() const
217 void Model::SetChildrenSensitive(bool enable)
219 if(mModelChildrenSensitive != enable)
221 mModelChildrenSensitive = enable;
224 mModelRoot.SetProperty(Dali::Actor::Property::SENSITIVE, mModelChildrenSensitive);
229 bool Model::GetChildrenSensitive() const
231 return mModelChildrenSensitive;
234 void Model::SetChildrenFocusable(bool enable)
236 if(mModelChildrenFocusable != enable)
238 mModelChildrenFocusable = enable;
241 mModelRoot.SetProperty(Dali::Actor::Property::KEYBOARD_FOCUSABLE, mModelChildrenFocusable);
242 mModelRoot.SetProperty(Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN, mModelChildrenFocusable);
247 bool Model::GetChildrenFocusable() const
249 return mModelChildrenFocusable;
252 void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor)
254 bool needIblReset = false;
255 bool isOnScene = Self().GetProperty<bool>(Dali::Actor::Property::CONNECTED_TO_SCENE);
256 if(mDiffuseIblUrl != diffuseUrl)
258 mDiffuseIblUrl = diffuseUrl;
259 if(mDiffuseIblUrl.empty())
265 mIblDiffuseDirty = true;
266 mIblDiffuseResourceReady = false;
270 if(mSpecularIblUrl != specularUrl)
272 mSpecularIblUrl = specularUrl;
273 if(mSpecularIblUrl.empty())
279 mIblSpecularDirty = true;
280 mIblSpecularResourceReady = false;
284 // If one or both of diffuse url and specular url are empty,
285 // we don't need to request to load texture.
288 if(mIblDiffuseLoadTask)
290 Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask);
291 mIblDiffuseLoadTask.Reset();
294 if(mIblSpecularLoadTask)
296 Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask);
297 mIblSpecularLoadTask.Reset();
300 mIblDiffuseDirty = false;
301 mIblSpecularDirty = false;
302 mIblDiffuseResourceReady = true;
303 mIblSpecularResourceReady = true;
305 mDiffuseTexture.Reset();
306 mSpecularTexture.Reset();
307 UpdateImageBasedLightTexture();
311 if(isOnScene && mIblDiffuseDirty)
313 if(mIblDiffuseLoadTask)
315 Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask);
316 mIblDiffuseLoadTask.Reset();
318 mIblDiffuseLoadTask = new EnvironmentMapLoadTask(mDiffuseIblUrl, MakeCallback(this, &Model::OnIblDiffuseLoadComplete));
319 Dali::AsyncTaskManager::Get().AddTask(mIblDiffuseLoadTask);
320 mIblDiffuseDirty = false;
323 if(isOnScene && mIblSpecularDirty)
325 if(mIblSpecularLoadTask)
327 Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask);
328 mIblSpecularLoadTask.Reset();
330 mIblSpecularLoadTask = new EnvironmentMapLoadTask(mSpecularIblUrl, MakeCallback(this, &Model::OnIblSpecularLoadComplete));
331 Dali::AsyncTaskManager::Get().AddTask(mIblSpecularLoadTask);
332 mIblSpecularDirty = false;
336 if(!Dali::Equals(mIblScaleFactor, scaleFactor))
338 mIblScaleFactor = scaleFactor;
339 UpdateImageBasedLightScaleFactor();
342 // If diffuse and specular textures are already loaded, emits resource ready signal here.
343 if(IsResourceReady())
345 Control::SetResourceReady(false);
349 void Model::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor)
351 // If input texture is wrong, Model is rendered with SceneView's IBL.
352 if(mDiffuseTexture != diffuseTexture || mSpecularTexture != specularTexture)
354 mDiffuseTexture = diffuseTexture;
355 mSpecularTexture = specularTexture;
356 mIblScaleFactor = scaleFactor;
357 UpdateImageBasedLightTexture();
361 void Model::SetImageBasedLightScaleFactor(float scaleFactor)
363 mIblScaleFactor = scaleFactor;
364 if(mDiffuseTexture && mSpecularTexture)
366 UpdateImageBasedLightScaleFactor();
370 float Model::GetImageBasedLightScaleFactor() const
372 return mIblScaleFactor;
375 uint32_t Model::GetAnimationCount() const
377 return mAnimations.size();
380 Dali::Animation Model::GetAnimation(uint32_t index) const
382 Dali::Animation animation;
383 if(mAnimations.size() > index)
385 animation = mAnimations[index].second;
390 Dali::Animation Model::GetAnimation(const std::string& name) const
392 Dali::Animation animation;
395 for(auto&& animationData : mAnimations)
397 if(animationData.first == name)
399 animation = animationData.second;
407 ///////////////////////////////////////////////////////////
412 void Model::OnInitialize()
414 // Make ParentOrigin as Center.
415 Self().SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
418 void Model::OnSceneConnection(int depth)
420 if(!mModelLoadTask && !mModelRoot)
422 Scene3D::Loader::InitializeGltfLoader();
423 mModelLoadTask = new ModelLoadTask(mModelUrl, mResourceDirectoryUrl, MakeCallback(this, &Model::OnModelLoadComplete));
424 Dali::AsyncTaskManager::Get().AddTask(mModelLoadTask);
426 // If diffuse and specular url is not valid, IBL does not need to be loaded.
427 if(!mDiffuseIblUrl.empty() && !mSpecularIblUrl.empty())
429 SetImageBasedLightSource(mDiffuseIblUrl, mSpecularIblUrl, mIblScaleFactor);
432 Actor parent = Self().GetParent();
435 Scene3D::SceneView sceneView = Scene3D::SceneView::DownCast(parent);
438 GetImpl(sceneView).RegisterSceneItem(this);
439 mParentSceneView = sceneView;
442 parent = parent.GetParent();
445 Control::OnSceneConnection(depth);
448 void Model::OnSceneDisconnection()
450 Scene3D::SceneView sceneView = mParentSceneView.GetHandle();
453 GetImpl(sceneView).UnregisterSceneItem(this);
454 mParentSceneView.Reset();
456 Control::OnSceneDisconnection();
459 Vector3 Model::GetNaturalSize()
463 DALI_LOG_ERROR("Model is still not loaded.\n");
464 return Vector3::ZERO;
470 float Model::GetHeightForWidth(float width)
473 padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
474 return Control::GetHeightForWidth(width) + padding.top + padding.bottom;
477 float Model::GetWidthForHeight(float height)
480 padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
481 return Control::GetWidthForHeight(height) + padding.start + padding.end;
484 void Model::OnRelayout(const Vector2& size, RelayoutContainer& container)
486 Control::OnRelayout(size, container);
490 bool Model::IsResourceReady() const
492 return mModelResourceReady && mIblDiffuseResourceReady && mIblSpecularResourceReady;
495 void Model::ScaleModel()
500 Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
501 if(size.x > 0.0f && size.y > 0.0f)
504 scale = std::min(size.x / mNaturalSize.x, scale);
505 scale = std::min(size.y / mNaturalSize.y, scale);
507 // Models in glTF and dli are defined as right hand coordinate system.
508 // DALi uses left hand coordinate system. Scaling negative is for change winding order.
509 mModelRoot.SetProperty(Dali::Actor::Property::SCALE, Y_DIRECTION * scale);
513 void Model::FitModelPosition()
517 // Loaded model pivot is not the model center.
518 mModelRoot.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
519 mModelRoot.SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3::ONE - mModelPivot);
523 void Model::CollectRenderableActor(Actor actor)
525 uint32_t rendererCount = actor.GetRendererCount();
528 mRenderableActors.push_back(actor);
531 uint32_t childrenCount = actor.GetChildCount();
532 for(uint32_t i = 0; i < childrenCount; ++i)
534 CollectRenderableActor(actor.GetChildAt(i));
538 void Model::UpdateImageBasedLightTexture()
540 Dali::Texture currentDiffuseTexture = (mDiffuseTexture && mSpecularTexture) ? mDiffuseTexture : mSceneDiffuseTexture;
541 Dali::Texture currentSpecularTexture = (mDiffuseTexture && mSpecularTexture) ? mSpecularTexture : mSceneSpecularTexture;
542 float currentIblScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor;
544 if(!currentDiffuseTexture || !currentSpecularTexture)
546 currentDiffuseTexture = mDefaultDiffuseTexture;
547 currentSpecularTexture = mDefaultSpecularTexture;
548 currentIblScaleFactor = Dali::Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity();
551 for(auto&& actor : mRenderableActors)
553 Actor renderableActor = actor.GetHandle();
556 uint32_t rendererCount = renderableActor.GetRendererCount();
557 for(uint32_t i = 0; i < rendererCount; ++i)
559 Dali::Renderer renderer = renderableActor.GetRendererAt(i);
562 Dali::TextureSet textures = renderer.GetTextures();
565 uint32_t textureCount = textures.GetTextureCount();
566 // EnvMap requires at least 2 texture, diffuse and specular
567 if(textureCount > 2u)
569 textures.SetTexture(textureCount - OFFSET_FOR_DIFFUSE_CUBE_TEXTURE, currentDiffuseTexture);
570 textures.SetTexture(textureCount - OFFSET_FOR_SPECULAR_CUBE_TEXTURE, currentSpecularTexture);
575 renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIblScaleFactor);
580 void Model::UpdateImageBasedLightScaleFactor()
582 if((!mDiffuseTexture || !mSpecularTexture) &&
583 (!mSceneDiffuseTexture || !mSceneSpecularTexture))
588 float currentIblScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor;
589 for(auto&& actor : mRenderableActors)
591 Actor renderableActor = actor.GetHandle();
594 renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIblScaleFactor);
599 void Model::NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor)
601 if(mSceneDiffuseTexture != diffuseTexture || mSceneSpecularTexture != specularTexture)
603 mSceneDiffuseTexture = diffuseTexture;
604 mSceneSpecularTexture = specularTexture;
605 mSceneIblScaleFactor = scaleFactor;
606 // If Model IBL is not set, use SceneView's IBL.
607 if(!mDiffuseTexture || !mSpecularTexture)
609 UpdateImageBasedLightTexture();
614 void Model::NotifyImageBasedLightScaleFactor(float scaleFactor)
616 mSceneIblScaleFactor = scaleFactor;
617 if(mSceneDiffuseTexture && mSceneSpecularTexture)
619 UpdateImageBasedLightScaleFactor();
623 void Model::OnModelLoadComplete()
625 if(!mModelLoadTask->HasSucceeded())
627 ResetResourceTasks();
631 mModelRoot = Actor::New();
632 mModelRoot.SetProperty(Actor::Property::COLOR_MODE, ColorMode::USE_OWN_MULTIPLY_PARENT_COLOR);
635 auto* resources = &(mModelLoadTask->mResources);
636 auto* scene = &(mModelLoadTask->mScene);
637 Dali::Scene3D::Loader::Transforms xforms{Dali::Scene3D::Loader::MatrixStack{}, Dali::Scene3D::Loader::ViewProjection{}};
638 Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{*resources, xforms, {}, {}, {}};
639 uint32_t rootCount = 0u;
640 for(auto iRoot : scene->GetRoots())
642 resources->GenerateResources(mModelLoadTask->mResourceRefCounts[rootCount]);
644 if(auto actor = scene->CreateNodes(iRoot, mModelLoadTask->mResourceChoices, nodeParams))
646 scene->ConfigureSkeletonJoints(iRoot, resources->mSkeletons, actor);
647 scene->ConfigureSkinningShaders(*resources, actor, std::move(nodeParams.mSkinnables));
648 ConfigureBlendShapeShaders(*resources, *scene, actor, std::move(nodeParams.mBlendshapeRequests));
650 scene->ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
652 mModelRoot.Add(actor);
655 AddModelTreeToAABB(AABB, *scene, mModelLoadTask->mResourceChoices, iRoot, nodeParams, Matrix::IDENTITY);
659 if(!resources->mEnvironmentMaps.empty())
661 mDefaultDiffuseTexture = resources->mEnvironmentMaps.front().second.mDiffuse;
662 mDefaultSpecularTexture = resources->mEnvironmentMaps.front().second.mSpecular;
665 if(!mModelLoadTask->mAnimations.empty())
667 auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property)
670 if(property.mNodeIndex != Scene3D::Loader::INVALID_INDEX)
672 auto* node = scene->GetNode(property.mNodeIndex);
675 actor = mModelRoot.FindChildById(node->mNodeId);
680 actor = mModelRoot.FindChildByName(property.mNodeName);
686 for(auto&& animation : mModelLoadTask->mAnimations)
688 Dali::Animation anim = animation.ReAnimate(getActor);
690 mAnimations.push_back({animation.mName, anim});
694 mRenderableActors.clear();
695 CollectRenderableActor(mModelRoot);
697 UpdateImageBasedLightTexture();
698 UpdateImageBasedLightScaleFactor();
700 mNaturalSize = AABB.CalculateSize();
701 mModelPivot = AABB.CalculatePivot();
702 mModelRoot.SetProperty(Dali::Actor::Property::SIZE, mNaturalSize);
703 Vector3 controlSize = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
704 if(Dali::EqualsZero(controlSize.x) || Dali::EqualsZero(controlSize.y))
706 Self().SetProperty(Dali::Actor::Property::SIZE, mNaturalSize);
712 mModelRoot.SetProperty(Dali::Actor::Property::SENSITIVE, mModelChildrenSensitive);
713 mModelRoot.SetProperty(Dali::Actor::Property::KEYBOARD_FOCUSABLE, mModelChildrenFocusable);
714 mModelRoot.SetProperty(Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN, mModelChildrenFocusable);
716 Self().Add(mModelRoot);
718 Self().SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3(mModelPivot.x, 1.0f - mModelPivot.y, mModelPivot.z));
720 mModelResourceReady = true;
722 if(IsResourceReady())
724 Control::SetResourceReady(false);
726 mModelLoadTask.Reset();
729 void Model::OnIblDiffuseLoadComplete()
731 mDiffuseTexture = (mIblDiffuseLoadTask->HasSucceeded()) ? mIblDiffuseLoadTask->GetEnvironmentMap().CreateTexture() : Texture();
732 mIblDiffuseResourceReady = true;
733 if(mIblDiffuseResourceReady && mIblSpecularResourceReady)
737 mIblDiffuseLoadTask.Reset();
740 void Model::OnIblSpecularLoadComplete()
742 mSpecularTexture = (mIblSpecularLoadTask->HasSucceeded()) ? mIblSpecularLoadTask->GetEnvironmentMap().CreateTexture() : Texture();
743 mIblSpecularResourceReady = true;
744 if(mIblDiffuseResourceReady && mIblSpecularResourceReady)
748 mIblSpecularLoadTask.Reset();
751 void Model::OnIblLoadComplete()
753 UpdateImageBasedLightTexture();
755 if(IsResourceReady())
757 Control::SetResourceReady(false);
761 void Model::ResetResourceTasks()
763 if(Dali::Adaptor::IsAvailable())
767 Dali::AsyncTaskManager::Get().RemoveTask(mModelLoadTask);
768 mModelLoadTask.Reset();
770 if(mIblDiffuseLoadTask)
772 Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask);
773 mIblDiffuseLoadTask.Reset();
775 if(mIblSpecularLoadTask)
777 Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask);
778 mIblSpecularLoadTask.Reset();
783 } // namespace Internal
784 } // namespace Scene3D