From 41524c0feada4a684fe34d4afc2baf37b6d26e1b Mon Sep 17 00:00:00 2001 From: seungho baek Date: Mon, 20 Feb 2023 15:57:09 +0900 Subject: [PATCH] Refactoring model-impl.cpp - Extract some method to reduce duplicated code. - Reduce braces depth - Use return early for easy understanding - Separate too long method Change-Id: I54e09138ae968a15be274fe415cfd3fd245047f8 --- .../internal/common/environment-map-load-task.cpp | 4 +- .../internal/common/environment-map-load-task.h | 7 +- .../internal/controls/model/model-impl.cpp | 313 ++++++++++----------- dali-scene3d/internal/controls/model/model-impl.h | 25 ++ .../controls/scene-view/scene-view-impl.cpp | 6 +- 5 files changed, 186 insertions(+), 169 deletions(-) diff --git a/dali-scene3d/internal/common/environment-map-load-task.cpp b/dali-scene3d/internal/common/environment-map-load-task.cpp index d230e99..d847f46 100644 --- a/dali-scene3d/internal/common/environment-map-load-task.cpp +++ b/dali-scene3d/internal/common/environment-map-load-task.cpp @@ -58,9 +58,9 @@ bool EnvironmentMapLoadTask::HasSucceeded() const return mHasSucceeded; } -Dali::Scene3D::Loader::EnvironmentMapData& EnvironmentMapLoadTask::GetEnvironmentMap() +Dali::Texture EnvironmentMapLoadTask::GetLoadedTexture() { - return mEnvironmentMapData; + return (HasSucceeded()) ? mEnvironmentMapData.GetTexture() : Texture();; } } // namespace Internal diff --git a/dali-scene3d/internal/common/environment-map-load-task.h b/dali-scene3d/internal/common/environment-map-load-task.h index d9a936b..446665c 100644 --- a/dali-scene3d/internal/common/environment-map-load-task.h +++ b/dali-scene3d/internal/common/environment-map-load-task.h @@ -71,10 +71,11 @@ public: bool HasSucceeded() const; /** - * Retrieves loaded Environment Map - * @return EnvironmentMapData that is loaded from url. + * Retrieves loaded Ibl Texture + * @return Texture that is loaded from url. + * @note Do not call this method in worker thread. */ - Dali::Scene3D::Loader::EnvironmentMapData& GetEnvironmentMap(); + Dali::Texture GetLoadedTexture(); private: // Undefined diff --git a/dali-scene3d/internal/controls/model/model-impl.cpp b/dali-scene3d/internal/controls/model/model-impl.cpp index 3345bfc..31e75e5 100644 --- a/dali-scene3d/internal/controls/model/model-impl.cpp +++ b/dali-scene3d/internal/controls/model/model-impl.cpp @@ -23,11 +23,11 @@ #include #include #include +#include #include #include #include #include -#include #include // INTERNAL INCLUDES @@ -116,7 +116,8 @@ void ConfigureBlendShapeShaders( Dali::Scene3D::Loader::ResourceBundle& resources, const Dali::Scene3D::Loader::SceneDefinition& scene, Actor root, std::vector&& requests) { std::vector 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); @@ -251,13 +252,13 @@ bool Model::GetChildrenFocusable() const 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); + bool isOnScene = Self().GetProperty(Dali::Actor::Property::CONNECTED_TO_SCENE); if(mDiffuseIblUrl != diffuseUrl) { mDiffuseIblUrl = diffuseUrl; if(mDiffuseIblUrl.empty()) { - needIblReset = true; + needIblReset = true; } else { @@ -271,7 +272,7 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s mSpecularIblUrl = specularUrl; if(mSpecularIblUrl.empty()) { - needIblReset = true; + needIblReset = true; } else { @@ -284,17 +285,8 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s // 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(); - } + ResetResourceTask(mIblDiffuseLoadTask); + ResetResourceTask(mIblSpecularLoadTask); mIblDiffuseDirty = false; mIblSpecularDirty = false; @@ -309,11 +301,7 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s { if(isOnScene && mIblDiffuseDirty) { - if(mIblDiffuseLoadTask) - { - Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask); - mIblDiffuseLoadTask.Reset(); - } + ResetResourceTask(mIblDiffuseLoadTask); mIblDiffuseLoadTask = new EnvironmentMapLoadTask(mDiffuseIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &Model::OnIblDiffuseLoadComplete)); Dali::AsyncTaskManager::Get().AddTask(mIblDiffuseLoadTask); mIblDiffuseDirty = false; @@ -321,11 +309,7 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s if(isOnScene && mIblSpecularDirty) { - if(mIblSpecularLoadTask) - { - Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask); - mIblSpecularLoadTask.Reset(); - } + ResetResourceTask(mIblSpecularLoadTask); mIblSpecularLoadTask = new EnvironmentMapLoadTask(mSpecularIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &Model::OnIblSpecularLoadComplete)); Dali::AsyncTaskManager::Get().AddTask(mIblSpecularLoadTask); mIblSpecularDirty = false; @@ -339,10 +323,7 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s } // If diffuse and specular textures are already loaded, emits resource ready signal here. - if(IsResourceReady()) - { - Control::SetResourceReady(false); - } + NotifyResourceReady(); } void Model::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor) @@ -493,30 +474,33 @@ bool Model::IsResourceReady() const void Model::ScaleModel() { - if(mModelRoot) + if(!mModelRoot) { - 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); + return; } + + 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); } void Model::FitModelPosition() { - if(mModelRoot) + 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); + return; } + // 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); } void Model::CollectRenderableActor(Actor actor) @@ -550,29 +534,33 @@ void Model::UpdateImageBasedLightTexture() for(auto&& actor : mRenderableActors) { Actor renderableActor = actor.GetHandle(); - if(renderableActor) + if(!renderableActor) + { + continue; + } + + uint32_t rendererCount = renderableActor.GetRendererCount(); + for(uint32_t i = 0; i < rendererCount; ++i) { - uint32_t rendererCount = renderableActor.GetRendererCount(); - for(uint32_t i = 0; i < rendererCount; ++i) + Dali::Renderer renderer = renderableActor.GetRendererAt(i); + if(!renderer) { - 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); - } - } - } + continue; + } + Dali::TextureSet textures = renderer.GetTextures(); + if(!textures) + { + continue; + } + 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); } + renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIblScaleFactor); } } @@ -627,154 +615,157 @@ void Model::OnModelLoadComplete() return; } - mModelRoot = Actor::New(); - mModelRoot.SetProperty(Actor::Property::COLOR_MODE, ColorMode::USE_OWN_MULTIPLY_PARENT_COLOR); - - 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, 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->ApplyConstraints(actor, std::move(nodeParams.mConstrainables)); - - mModelRoot.Add(actor); - } - - AddModelTreeToAABB(AABB, *scene, mModelLoadTask->mResourceChoices, iRoot, nodeParams, Matrix::IDENTITY); - rootCount++; - } + CreateModel(); + mRenderableActors.clear(); + CollectRenderableActor(mModelRoot); + auto* resources = &(mModelLoadTask->mResources); + auto* scene = &(mModelLoadTask->mScene); + CreateAnimations(*scene); if(!resources->mEnvironmentMaps.empty()) { mDefaultDiffuseTexture = resources->mEnvironmentMaps.front().second.mDiffuse; mDefaultSpecularTexture = resources->mEnvironmentMaps.front().second.mSpecular; } - 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); - if(node != nullptr) - { - actor = mModelRoot.FindChildById(node->mNodeId); - } - } - else - { - actor = mModelRoot.FindChildByName(property.mNodeName); - } - return actor; - }; - - mAnimations.clear(); - for(auto&& animation : mModelLoadTask->mAnimations) - { - Dali::Animation anim = animation.ReAnimate(getActor); - - mAnimations.push_back({animation.mName, anim}); - } - } - - mRenderableActors.clear(); - CollectRenderableActor(mModelRoot); - UpdateImageBasedLightTexture(); UpdateImageBasedLightScaleFactor(); - mNaturalSize = AABB.CalculateSize(); - mModelPivot = AABB.CalculatePivot(); - mModelRoot.SetProperty(Dali::Actor::Property::SIZE, mNaturalSize); - Vector3 controlSize = Self().GetProperty(Dali::Actor::Property::SIZE); - if(Dali::EqualsZero(controlSize.x) || Dali::EqualsZero(controlSize.y)) - { - Self().SetProperty(Dali::Actor::Property::SIZE, mNaturalSize); - } - - 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::ANCHOR_POINT, Vector3(mModelPivot.x, 1.0f - mModelPivot.y, mModelPivot.z)); mModelResourceReady = true; - - if(IsResourceReady()) - { - Control::SetResourceReady(false); - } - mModelLoadTask.Reset(); + NotifyResourceReady(); + ResetResourceTask(mModelLoadTask); } void Model::OnIblDiffuseLoadComplete() { - mDiffuseTexture = (mIblDiffuseLoadTask->HasSucceeded()) ? mIblDiffuseLoadTask->GetEnvironmentMap().GetTexture() : Texture(); + mDiffuseTexture = mIblDiffuseLoadTask->GetLoadedTexture(); + ResetResourceTask(mIblDiffuseLoadTask); mIblDiffuseResourceReady = true; if(mIblDiffuseResourceReady && mIblSpecularResourceReady) { OnIblLoadComplete(); } - mIblDiffuseLoadTask.Reset(); } void Model::OnIblSpecularLoadComplete() { - mSpecularTexture = (mIblSpecularLoadTask->HasSucceeded()) ? mIblSpecularLoadTask->GetEnvironmentMap().GetTexture() : Texture(); + mSpecularTexture = mIblSpecularLoadTask->GetLoadedTexture(); + ResetResourceTask(mIblSpecularLoadTask); mIblSpecularResourceReady = true; if(mIblDiffuseResourceReady && mIblSpecularResourceReady) { OnIblLoadComplete(); } - mIblSpecularLoadTask.Reset(); } void Model::OnIblLoadComplete() { UpdateImageBasedLightTexture(); + NotifyResourceReady(); +} - if(IsResourceReady()) +void Model::ResetResourceTasks() +{ + if(!Dali::Adaptor::IsAvailable()) { - Control::SetResourceReady(false); + return; } + ResetResourceTask(mModelLoadTask); + ResetResourceTask(mIblDiffuseLoadTask); + ResetResourceTask(mIblSpecularLoadTask); } -void Model::ResetResourceTasks() +void Model::ResetResourceTask(IntrusivePtr asyncTask) { - if(Dali::Adaptor::IsAvailable()) + if(!asyncTask) { - if(mModelLoadTask) + return; + } + Dali::AsyncTaskManager::Get().RemoveTask(asyncTask); + asyncTask.Reset(); +} + +void Model::NotifyResourceReady() +{ + if(!IsResourceReady()) + { + return; + } + Control::SetResourceReady(false); +} + +void Model::CreateModel() +{ + mModelRoot = Actor::New(); + mModelRoot.SetProperty(Actor::Property::COLOR_MODE, ColorMode::USE_OWN_MULTIPLY_PARENT_COLOR); + + 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, mModelLoadTask->mResourceChoices, nodeParams)) { - Dali::AsyncTaskManager::Get().RemoveTask(mModelLoadTask); - mModelLoadTask.Reset(); + 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)); + + mModelRoot.Add(actor); } - if(mIblDiffuseLoadTask) + + AddModelTreeToAABB(AABB, *scene, mModelLoadTask->mResourceChoices, iRoot, nodeParams, Matrix::IDENTITY); + rootCount++; + } + + mNaturalSize = AABB.CalculateSize(); + mModelPivot = AABB.CalculatePivot(); + mModelRoot.SetProperty(Dali::Actor::Property::SIZE, mNaturalSize); + Vector3 controlSize = Self().GetProperty(Dali::Actor::Property::SIZE); + if(Dali::EqualsZero(controlSize.x) || Dali::EqualsZero(controlSize.y)) + { + Self().SetProperty(Dali::Actor::Property::SIZE, mNaturalSize); + } + FitModelPosition(); + ScaleModel(); +} + +void Model::CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene) +{ + if(!mModelLoadTask->mAnimations.empty()) + { + auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property) { - Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask); - mIblDiffuseLoadTask.Reset(); - } - if(mIblSpecularLoadTask) + if(property.mNodeIndex == Scene3D::Loader::INVALID_INDEX) + { + return mModelRoot.FindChildByName(property.mNodeName); + } + auto* node = scene.GetNode(property.mNodeIndex); + if(node == nullptr) + { + return Dali::Actor(); + } + return mModelRoot.FindChildById(node->mNodeId); + }; + + mAnimations.clear(); + for(auto&& animation : mModelLoadTask->mAnimations) { - Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask); - mIblSpecularLoadTask.Reset(); + Dali::Animation anim = animation.ReAnimate(getActor); + mAnimations.push_back({animation.mName, anim}); } } } diff --git a/dali-scene3d/internal/controls/model/model-impl.h b/dali-scene3d/internal/controls/model/model-impl.h index e4f1f08..36e3a9a 100644 --- a/dali-scene3d/internal/controls/model/model-impl.h +++ b/dali-scene3d/internal/controls/model/model-impl.h @@ -229,6 +229,31 @@ private: */ void ResetResourceTasks(); + /** + * @brief Reset a Resource loading task. + */ + void ResetResourceTask(IntrusivePtr asyncTask); + + /** + * @brief Request to load a Ibl texture asynchronously + */ + void RequestLoadIblTexture(EnvironmentMapLoadTaskPtr asyncLoadTask, const std::string& url); + + /** + * @brief Notify Resource Ready signal. + */ + void NotifyResourceReady(); + + /** + * @brief Create Model from loaded SceneDefinition. + */ + void CreateModel(); + + /** + * @brief Create Dali::Animation from loaded AnimationDefinitions. + */ + void CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene); + private: std::string mModelUrl; std::string mResourceDirectoryUrl; diff --git a/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp b/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp index 1c4a9a8..a4158e1 100644 --- a/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp +++ b/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp @@ -789,7 +789,7 @@ void SceneView::OnSkyboxLoadComplete() Control::SetResourceReady(false); } - mSkyboxTexture = (mSkyboxLoadTask->HasSucceeded()) ? mSkyboxLoadTask->GetEnvironmentMap().GetTexture() : Texture(); + mSkyboxTexture = mSkyboxLoadTask->GetLoadedTexture(); Shader skyboxShader; if(mSkyboxEnvironmentMapType == Scene3D::EnvironmentMapType::CUBEMAP) { @@ -814,7 +814,7 @@ void SceneView::OnSkyboxLoadComplete() void SceneView::OnIblDiffuseLoadComplete() { - mDiffuseTexture = (mIblDiffuseLoadTask->HasSucceeded()) ? mIblDiffuseLoadTask->GetEnvironmentMap().GetTexture() : Texture(); + mDiffuseTexture = mIblDiffuseLoadTask->GetLoadedTexture(); mIblDiffuseResourceReady = true; if(mIblDiffuseResourceReady && mIblSpecularResourceReady) { @@ -825,7 +825,7 @@ void SceneView::OnIblDiffuseLoadComplete() void SceneView::OnIblSpecularLoadComplete() { - mSpecularTexture = (mIblSpecularLoadTask->HasSucceeded()) ? mIblSpecularLoadTask->GetEnvironmentMap().GetTexture() : Texture(); + mSpecularTexture = mIblSpecularLoadTask->GetLoadedTexture(); mIblSpecularResourceReady = true; if(mIblDiffuseResourceReady && mIblSpecularResourceReady) { -- 2.7.4