X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-scene3d%2Finternal%2Fcontrols%2Fmodel%2Fmodel-impl.cpp;h=f012aa6ac9ce8668513f6801add26c9a90637705;hb=HEAD;hp=2763de68f600f1d8b3b212c8ce734217d6e10786;hpb=2c2fbd1d28d9c06454baa77e5c4ae620d56bcc83;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 2763de6..f012aa6 100644 --- a/dali-scene3d/internal/controls/model/model-impl.cpp +++ b/dali-scene3d/internal/controls/model/model-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 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. @@ -31,8 +31,10 @@ #include // INTERNAL INCLUDES +#include #include #include +#include #include #include #include @@ -44,7 +46,7 @@ #include #include #include - +#include using namespace Dali; namespace Dali @@ -233,6 +235,16 @@ void UpdateShadowMapTextureRecursively(Scene3D::ModelNode node, Dali::Texture sh } } +void ResetResourceTask(IntrusivePtr&& asyncTask) +{ + if(!asyncTask) + { + return; + } + Dali::AsyncTaskManager::Get().RemoveTask(asyncTask); + asyncTask.Reset(); +} + } // anonymous namespace Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUrl) @@ -253,7 +265,9 @@ Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUr mIblDiffuseResourceReady(true), mIblSpecularResourceReady(true), mIblDiffuseDirty(false), - mIblSpecularDirty(false) + mIblSpecularDirty(false), + mIsShadowCasting(true), + mIsShadowReceiving(true) { } @@ -311,14 +325,50 @@ void Model::AddModelNode(Scene3D::ModelNode modelNode) UpdateImageBasedLightScaleFactor(); } + GetImplementation(modelNode).SetRootModel(this); + + // If model has a collider mesh set, add it to the container + if(modelNode.HasColliderMesh()) + { + RegisterColliderMesh(modelNode); + Scene3D::ColliderMeshProcessor::Get().ColliderMeshChanged(Scene3D::Model::DownCast(Self())); + } + if(Self().GetProperty(Dali::Actor::Property::CONNECTED_TO_SCENE)) { NotifyResourceReady(); } } +void Model::RegisterColliderMesh(Scene3D::ModelNode& modelNode) +{ + mColliderMeshes[modelNode.GetProperty(Actor::Property::ID)] = modelNode; + + // Add processor + Scene3D::ColliderMeshProcessor::Get().ColliderMeshChanged(Scene3D::Model::DownCast(Self())); +} + +void Model::RemoveColliderMesh(Scene3D::ModelNode& node) +{ + auto id = node.GetProperty(Actor::Property::ID); + auto iter = std::find_if(mColliderMeshes.begin(), mColliderMeshes.end(), [id](auto& item) { + return item.first == id; + }); + if(iter != mColliderMeshes.end()) + { + mColliderMeshes.erase(iter); + } +} + void Model::RemoveModelNode(Scene3D::ModelNode modelNode) { + // remove collider mesh from the list if node is being removed + if(modelNode.HasColliderMesh()) + { + RemoveColliderMesh(modelNode); + GetImplementation(modelNode).SetRootModel(nullptr); + } + if(mModelRoot) { UpdateShaderRecursively(modelNode, nullptr); @@ -408,6 +458,9 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s mDiffuseTexture.Reset(); mSpecularTexture.Reset(); UpdateImageBasedLightTexture(); + + // Request image resource GC + Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect(); } else { @@ -417,6 +470,9 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s mIblDiffuseLoadTask = new EnvironmentMapLoadTask(mDiffuseIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &Model::OnIblDiffuseLoadComplete)); Dali::AsyncTaskManager::Get().AddTask(mIblDiffuseLoadTask); mIblDiffuseDirty = false; + + // Request image resource GC + Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect(); } if(isOnScene && mIblSpecularDirty) @@ -425,6 +481,9 @@ void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::s mIblSpecularLoadTask = new EnvironmentMapLoadTask(mSpecularIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &Model::OnIblSpecularLoadComplete)); Dali::AsyncTaskManager::Get().AddTask(mIblSpecularLoadTask); mIblSpecularDirty = false; + + // Request image resource GC + Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect(); } } @@ -753,6 +812,29 @@ void Model::SetMotionData(Scene3D::MotionData motionData) } } +void Model::CastShadow(bool castShadow) +{ + mIsShadowCasting = castShadow; + UpdateCastShadowRecursively(mModelRoot, mIsShadowCasting); +} + +bool Model::IsShadowCasting() const +{ + return mIsShadowCasting; +} + +void Model::ReceiveShadow(bool receiveShadow) +{ + mIsShadowReceiving = receiveShadow; + UpdateReceiveShadowRecursively(mModelRoot, mIsShadowReceiving); +} + +bool Model::IsShadowReceiving() const +{ + return mIsShadowReceiving; +} + + /////////////////////////////////////////////////////////// // // Private methods @@ -762,6 +844,9 @@ void Model::OnInitialize() { // Make ParentOrigin as Center. Self().SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + + mDefaultDiffuseTexture = ImageResourceLoader::GetEmptyTextureWhiteRGB(); + mDefaultSpecularTexture = ImageResourceLoader::GetEmptyTextureWhiteRGB(); } void Model::OnSceneConnection(int depth) @@ -922,6 +1007,46 @@ void Model::FitModelPosition() mModelRoot.SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3::ONE - mModelPivot); } +void Model::UpdateCastShadowRecursively(Scene3D::ModelNode node, bool castShadow) +{ + if(!node) + { + return; + } + + GetImplementation(node).CastShadow(castShadow); + uint32_t childrenCount = node.GetChildCount(); + for(uint32_t i = 0; i < childrenCount; ++i) + { + Scene3D::ModelNode childNode = Scene3D::ModelNode::DownCast(node.GetChildAt(i)); + if(!childNode) + { + continue; + } + UpdateCastShadowRecursively(childNode, castShadow); + } +} + +void Model::UpdateReceiveShadowRecursively(Scene3D::ModelNode node, bool receiveShadow) +{ + if(!node) + { + return; + } + + GetImplementation(node).ReceiveShadow(receiveShadow); + uint32_t childrenCount = node.GetChildCount(); + for(uint32_t i = 0; i < childrenCount; ++i) + { + Scene3D::ModelNode childNode = Scene3D::ModelNode::DownCast(node.GetChildAt(i)); + if(!childNode) + { + continue; + } + UpdateReceiveShadowRecursively(childNode, receiveShadow); + } +} + void Model::UpdateImageBasedLightTextureRecursively(Scene3D::ModelNode node, Dali::Texture diffuseTexture, Dali::Texture specularTexture, float iblScaleFactor, uint32_t specularMipmapLevels) { if(!node) @@ -1068,6 +1193,8 @@ void Model::NotifyImageBasedLightScaleFactor(float scaleFactor) void Model::OnModelLoadComplete() { + IntrusivePtr self = this; // Keep reference until this API finished + if(!mModelLoadTask->HasSucceeded()) { ResetResourceTasks(); @@ -1092,8 +1219,14 @@ void Model::OnModelLoadComplete() ResetCameraParameters(); if(!resources.mEnvironmentMaps.empty()) { - mDefaultDiffuseTexture = resources.mEnvironmentMaps.front().second.mDiffuse; - mDefaultSpecularTexture = resources.mEnvironmentMaps.front().second.mSpecular; + if(resources.mEnvironmentMaps.front().second.mDiffuse) + { + mDefaultDiffuseTexture = resources.mEnvironmentMaps.front().second.mDiffuse; + } + if(resources.mEnvironmentMaps.front().second.mSpecular) + { + mDefaultSpecularTexture = resources.mEnvironmentMaps.front().second.mSpecular; + } } if(mShadowMapTexture) @@ -1105,8 +1238,8 @@ void Model::OnModelLoadComplete() Self().SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3(mModelPivot.x, 1.0f - mModelPivot.y, mModelPivot.z)); mModelResourceReady = true; - NotifyResourceReady(); ResetResourceTask(mModelLoadTask); + NotifyResourceReady(); } void Model::OnIblDiffuseLoadComplete() @@ -1154,16 +1287,6 @@ void Model::ResetResourceTasks() ResetResourceTask(mIblSpecularLoadTask); } -void Model::ResetResourceTask(IntrusivePtr asyncTask) -{ - if(!asyncTask) - { - return; - } - Dali::AsyncTaskManager::Get().RemoveTask(asyncTask); - asyncTask.Reset(); -} - void Model::NotifyResourceReady() { if(!IsResourceReady())