X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-scene3d%2Finternal%2Fcontrols%2Fmodel%2Fmodel-impl.cpp;h=d9362713402c517f69321187022e1ef3238af557;hb=d3ab7a4cc307562e687de2b2751f2f0a687c2835;hp=ed5d3bdc93c4818f802ac11cac4a03661df61a3e;hpb=352af592adca3b68694d0d10552f490044005043;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-scene3d/internal/controls/model/model-impl.cpp b/dali-scene3d/internal/controls/model/model-impl.cpp index ed5d3bd..d936271 100644 --- a/dali-scene3d/internal/controls/model/model-impl.cpp +++ b/dali-scene3d/internal/controls/model/model-impl.cpp @@ -22,14 +22,17 @@ #include #include #include +#include #include +#include #include #include +#include #include // INTERNAL INCLUDES -#include #include +#include #include #include #include @@ -65,10 +68,8 @@ static constexpr uint32_t OFFSET_FOR_SPECULAR_CUBE_TEXTURE = 1u; static constexpr Vector3 Y_DIRECTION(1.0f, -1.0f, 1.0f); -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"; +static constexpr bool DEFAULT_MODEL_CHILDREN_SENSITIVE = false; +static constexpr bool DEFAULT_MODEL_CHILDREN_FOCUSABLE = false; struct BoundingVolume { @@ -100,7 +101,7 @@ struct BoundingVolume for(uint32_t i = 0; i < 3; ++i) { // To avoid divid by zero - if(pointMin[i] == pointMax[i]) + if(Dali::Equals(pointMin[i], pointMax[i])) { pivot[i] = 0.5f; } @@ -178,14 +179,21 @@ Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUr mModelRoot(), mNaturalSize(Vector3::ZERO), mModelPivot(AnchorPoint::CENTER), + mSceneIblScaleFactor(1.0f), mIblScaleFactor(1.0f), + 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) @@ -206,38 +214,147 @@ const Actor Model::GetModelRoot() const return mModelRoot; } -void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor) +void Model::SetChildrenSensitive(bool enable) +{ + if(mModelChildrenSensitive != enable) + { + mModelChildrenSensitive = enable; + if(mModelRoot) + { + mModelRoot.SetProperty(Dali::Actor::Property::SENSITIVE, mModelChildrenSensitive); + } + } +} + +bool Model::GetChildrenSensitive() const { - mIBLResourceReady = false; - Texture diffuseTexture = Dali::Scene3D::Loader::LoadCubeMap(diffuseUrl); - Texture specularTexture = Dali::Scene3D::Loader::LoadCubeMap(specularUrl); - SetImageBasedLightTexture(diffuseTexture, specularTexture, scaleFactor); - mIBLResourceReady = true; + return mModelChildrenSensitive; +} - // If Model resource is already ready, then set resource ready. - // If Model resource is still not ready, wait for model resource ready. - if(IsResourceReady()) +void Model::SetChildrenFocusable(bool enable) +{ + if(mModelChildrenFocusable != enable) { - SetResourceReady(false); + mModelChildrenFocusable = enable; + if(mModelRoot) + { + mModelRoot.SetProperty(Dali::Actor::Property::KEYBOARD_FOCUSABLE, mModelChildrenFocusable); + mModelRoot.SetProperty(Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN, mModelChildrenFocusable); + } } } -void Model::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor) +bool Model::GetChildrenFocusable() const { - if(diffuseTexture && specularTexture) + return mModelChildrenFocusable; +} + +void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor) +{ + bool needIblReset = false; + bool isOnScene = Self().GetProperty(Dali::Actor::Property::CONNECTED_TO_SCENE); + if(mDiffuseIblUrl != diffuseUrl) { - if(mDiffuseTexture != diffuseTexture || mSpecularTexture != specularTexture) + mDiffuseIblUrl = diffuseUrl; + if(mDiffuseIblUrl.empty()) { - mDiffuseTexture = diffuseTexture; - mSpecularTexture = specularTexture; - UpdateImageBasedLightTexture(); + needIblReset = true; + } + else + { + mIblDiffuseDirty = true; + mIblDiffuseResourceReady = false; + } + } + + if(mSpecularIblUrl != specularUrl) + { + mSpecularIblUrl = specularUrl; + if(mSpecularIblUrl.empty()) + { + needIblReset = true; } - if(mIblScaleFactor != scaleFactor) + else { - mIblScaleFactor = scaleFactor; - UpdateImageBasedLightScaleFactor(); + 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 diffuse and specular textures are already loaded, emits resource ready signal here. + if(IsResourceReady()) + { + Control::SetResourceReady(false); + } +} + +void Model::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor) +{ + // If input texture is wrong, Model is rendered with SceneView's IBL. + if(mDiffuseTexture != diffuseTexture || mSpecularTexture != specularTexture) + { + mDiffuseTexture = diffuseTexture; + mSpecularTexture = specularTexture; + mIblScaleFactor = scaleFactor; + UpdateImageBasedLightTexture(); } } @@ -292,11 +409,24 @@ Dali::Animation Model::GetAnimation(const std::string& name) const // Private methods // +void Model::OnInitialize() +{ + // Make ParentOrigin as Center. + Self().SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); +} + 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(); @@ -305,7 +435,7 @@ void Model::OnSceneConnection(int depth) Scene3D::SceneView sceneView = Scene3D::SceneView::DownCast(parent); if(sceneView) { - GetImpl(sceneView).RegisterModel(Scene3D::Model::DownCast(Self())); + GetImpl(sceneView).RegisterSceneItem(this); mParentSceneView = sceneView; break; } @@ -320,7 +450,7 @@ void Model::OnSceneDisconnection() Scene3D::SceneView sceneView = mParentSceneView.GetHandle(); if(sceneView) { - GetImpl(sceneView).UnregisterModel(Scene3D::Model::DownCast(Self())); + GetImpl(sceneView).UnregisterSceneItem(this); mParentSceneView.Reset(); } Control::OnSceneDisconnection(); @@ -330,7 +460,8 @@ Vector3 Model::GetNaturalSize() { if(!mModelRoot) { - LoadModel(); + DALI_LOG_ERROR("Model is still not loaded.\n"); + return Vector3::ZERO; } return mNaturalSize; @@ -358,107 +489,201 @@ 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(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 animGroups; - std::vector cameraParameters; - std::vector lights; +void Model::CollectRenderableActor(Actor actor) +{ + uint32_t rendererCount = actor.GetRendererCount(); + if(rendererCount) + { + mRenderableActors.push_back(actor); + } - std::vector animations; - animations.clear(); + uint32_t childrenCount = actor.GetChildCount(); + for(uint32_t i = 0; i < childrenCount; ++i) + { + CollectRenderableActor(actor.GetChildAt(i)); + } +} - Dali::Scene3D::Loader::LoadResult output{resources, scene, animations, animGroups, cameraParameters, lights}; +void Model::UpdateImageBasedLightTexture() +{ + Dali::Texture currentDiffuseTexture = (mDiffuseTexture && mSpecularTexture) ? mDiffuseTexture : mSceneDiffuseTexture; + Dali::Texture currentSpecularTexture = (mDiffuseTexture && mSpecularTexture) ? mSpecularTexture : mSceneSpecularTexture; + float currentIblScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor; - if(extension == DLI_EXTENSION) + if(!currentDiffuseTexture || !currentSpecularTexture) { - 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)) + currentDiffuseTexture = mDefaultDiffuseTexture; + currentSpecularTexture = mDefaultSpecularTexture; + currentIblScaleFactor = Dali::Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity(); + } + + for(auto&& actor : mRenderableActors) + { + Actor renderableActor = actor.GetHandle(); + if(renderableActor) { - Dali::Scene3D::Loader::ExceptionFlinger(ASSERT_LOCATION) << "Failed to load scene from '" << mModelUrl << "': " << loader.GetParseError(); + 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); } } - 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::UpdateImageBasedLightScaleFactor() +{ + if((!mDiffuseTexture || !mSpecularTexture) && + (!mSceneDiffuseTexture || !mSceneSpecularTexture)) + { + return; } - else + + float currentIblScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor; + for(auto&& actor : mRenderableActors) { - DALI_LOG_ERROR("Unsupported model type.\n"); + Actor renderableActor = actor.GetHandle(); + if(renderableActor) + { + renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIblScaleFactor); + } } +} - 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::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(); + } + } +} - mModelRoot = Actor::New(); +void Model::NotifyImageBasedLightScaleFactor(float scaleFactor) +{ + mSceneIblScaleFactor = scaleFactor; + if(mSceneDiffuseTexture && mSceneSpecularTexture) + { + UpdateImageBasedLightScaleFactor(); + } +} - BoundingVolume AABB; - for(auto iRoot : scene.GetRoots()) +void Model::OnModelLoadComplete() +{ + if(!mModelLoadTask->HasSucceeded()) { - auto resourceRefs = resources.CreateRefCounter(); - scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); + ResetResourceTasks(); + return; + } - resources.LoadResources(resourceRefs, pathProvider); + mModelRoot = Actor::New(); + mModelRoot.SetProperty(Actor::Property::COLOR_MODE, ColorMode::USE_OWN_MULTIPLY_PARENT_COLOR); - // 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) - { - env.first.mYDirection = Y_DIRECTION; - } + 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()) + { + resources->GenerateResources(mModelLoadTask->mResourceRefCounts[rootCount]); - if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) + if(auto actor = scene->CreateNodes(iRoot, mModelLoadTask->mResourceChoices, 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()) + { + mDefaultDiffuseTexture = resources->mEnvironmentMaps.front().second.mDiffuse; + mDefaultSpecularTexture = resources->mEnvironmentMaps.front().second.mSpecular; } - if(!animations.empty()) + if(!mModelLoadTask->mAnimations.empty()) { - auto getActor = [&](const std::string& name) { - return mModelRoot.FindChildByName(name); + auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property) + { + Dali::Actor actor; + if(property.mNodeIndex != Scene3D::Loader::INVALID_INDEX) + { + auto* node = scene->GetNode(property.mNodeIndex); + if(node != nullptr) + { + actor = mModelRoot.FindChildById(node->mNodeId); + } + } + else + { + actor = mModelRoot.FindChildByName(property.mNodeName); + } + return actor; }; mAnimations.clear(); - for(auto&& animation : animations) + for(auto&& animation : mModelLoadTask->mAnimations) { Dali::Animation anim = animation.ReAnimate(getActor); @@ -468,6 +693,7 @@ void Model::LoadModel() mRenderableActors.clear(); CollectRenderableActor(mModelRoot); + UpdateImageBasedLightTexture(); UpdateImageBasedLightScaleFactor(); @@ -475,7 +701,7 @@ void Model::LoadModel() mModelPivot = AABB.CalculatePivot(); mModelRoot.SetProperty(Dali::Actor::Property::SIZE, mNaturalSize); Vector3 controlSize = Self().GetProperty(Dali::Actor::Property::SIZE); - if(controlSize.x == 0.0f || controlSize.y == 0.0f) + if(Dali::EqualsZero(controlSize.x) || Dali::EqualsZero(controlSize.y)) { Self().SetProperty(Dali::Actor::Property::SIZE, mNaturalSize); } @@ -483,106 +709,73 @@ void Model::LoadModel() FitModelPosition(); ScaleModel(); + mModelRoot.SetProperty(Dali::Actor::Property::SENSITIVE, mModelChildrenSensitive); + mModelRoot.SetProperty(Dali::Actor::Property::KEYBOARD_FOCUSABLE, mModelChildrenFocusable); + mModelRoot.SetProperty(Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN, mModelChildrenFocusable); + Self().Add(mModelRoot); - Self().SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); Self().SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3(mModelPivot.x, 1.0f - mModelPivot.y, mModelPivot.z)); mModelResourceReady = true; - Control::SetResourceReady(false); -} - -void Model::ScaleModel() -{ - if(mModelRoot) + if(IsResourceReady()) { - float scale = 1.0f; - Vector3 size = Self().GetProperty(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() { - if(!mDiffuseTexture || !mSpecularTexture) - { - return; - } + 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, mDiffuseTexture); - textures.SetTexture(textureCount - OFFSET_FOR_SPECULAR_CUBE_TEXTURE, mSpecularTexture); - } - } - } - } - } + Control::SetResourceReady(false); } } -void Model::UpdateImageBasedLightScaleFactor() +void Model::ResetResourceTasks() { - if(!mDiffuseTexture || !mSpecularTexture) + if(Dali::Adaptor::IsAvailable()) { - return; - } - for(auto&& actor : mRenderableActors) - { - Actor renderableActor = actor.GetHandle(); - if(renderableActor) + if(mModelLoadTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mModelLoadTask); + mModelLoadTask.Reset(); + } + if(mIblDiffuseLoadTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask); + mIblDiffuseLoadTask.Reset(); + } + if(mIblSpecularLoadTask) { - renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), mIblScaleFactor); + Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask); + mIblSpecularLoadTask.Reset(); } } }