X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-scene3d%2Finternal%2Fcontrols%2Fmodel%2Fmodel-impl.cpp;h=31e75e555bd286dd9b2c3d097f4b4da6bb150ba8;hb=c70520ff81c009acafc2a2cfd1ac38adb64ffcae;hp=86893a7a13c3992c8074677d111812d7222704e8;hpb=473dccdfb5ce5140c70aded7373ef21ba19a2665;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 86893a7..31e75e5 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) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -23,7 +23,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -33,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -69,11 +70,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() @@ -104,7 +100,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; } @@ -120,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); @@ -187,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) @@ -250,18 +251,79 @@ 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(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 Model resource is already ready, then set resource ready. - // If Model resource is still not ready, wait for model resource ready. - if(IsResourceReady()) + // If one or both of diffuse url and specular url are empty, + // we don't need to request to load texture. + if(needIblReset) { - SetResourceReady(false); + ResetResourceTask(mIblDiffuseLoadTask); + ResetResourceTask(mIblSpecularLoadTask); + + mIblDiffuseDirty = false; + mIblSpecularDirty = false; + mIblDiffuseResourceReady = true; + mIblSpecularResourceReady = true; + + mDiffuseTexture.Reset(); + mSpecularTexture.Reset(); + UpdateImageBasedLightTexture(); + } + else + { + if(isOnScene && mIblDiffuseDirty) + { + ResetResourceTask(mIblDiffuseLoadTask); + mIblDiffuseLoadTask = new EnvironmentMapLoadTask(mDiffuseIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &Model::OnIblDiffuseLoadComplete)); + Dali::AsyncTaskManager::Get().AddTask(mIblDiffuseLoadTask); + mIblDiffuseDirty = false; + } + + if(isOnScene && mIblSpecularDirty) + { + ResetResourceTask(mIblSpecularLoadTask); + mIblSpecularLoadTask = new EnvironmentMapLoadTask(mSpecularIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, 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. + NotifyResourceReady(); } void Model::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor) @@ -335,9 +397,16 @@ void Model::OnInitialize() void Model::OnSceneConnection(int depth) { - if(!mModelRoot) + if(!mModelLoadTask && !mModelRoot) { - LoadModel(); + 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()) + { + SetImageBasedLightSource(mDiffuseIblUrl, mSpecularIblUrl, mIblScaleFactor); } Actor parent = Self().GetParent(); @@ -371,7 +440,8 @@ Vector3 Model::GetNaturalSize() { if(!mModelRoot) { - LoadModel(); + DALI_LOG_ERROR("Model is still not loaded.\n"); + return Vector3::ZERO; } return mNaturalSize; @@ -399,270 +469,304 @@ 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()) + "/"; + return; } - 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; - }; - - Dali::Scene3D::Loader::ResourceBundle resources; - Dali::Scene3D::Loader::SceneDefinition scene; - std::vector animGroups; - std::vector cameraParameters; - std::vector lights; - - std::vector animations; - animations.clear(); - Dali::Scene3D::Loader::LoadResult output{resources, scene, animations, animGroups, cameraParameters, lights}; - - if(extension == DLI_EXTENSION) + float scale = 1.0f; + Vector3 size = Self().GetProperty(Dali::Actor::Property::SIZE); + if(size.x > 0.0f && size.y > 0.0f) { - 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)) - { - Dali::Scene3D::Loader::ExceptionFlinger(ASSERT_LOCATION) << "Failed to load scene from '" << mModelUrl << "': " << loader.GetParseError(); - } + scale = MAXFLOAT; + scale = std::min(size.x / mNaturalSize.x, scale); + scale = std::min(size.y / mNaturalSize.y, scale); } - else if(extension == GLTF_EXTENSION) - { - Dali::Scene3D::Loader::ShaderDefinitionFactory sdf; - sdf.SetResources(resources); - Dali::Scene3D::Loader::LoadGltfScene(mModelUrl, sdf, output); + // 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); +} - resources.mEnvironmentMaps.push_back({}); +void Model::FitModelPosition() +{ + if(!mModelRoot) + { + return; } - else + // 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) +{ + uint32_t rendererCount = actor.GetRendererCount(); + if(rendererCount) { - DALI_LOG_ERROR("Unsupported model type.\n"); + mRenderableActors.push_back(actor); } - 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; + uint32_t childrenCount = actor.GetChildCount(); + for(uint32_t i = 0; i < childrenCount; ++i) + { + CollectRenderableActor(actor.GetChildAt(i)); + } +} - mModelRoot = Actor::New(); +void Model::UpdateImageBasedLightTexture() +{ + Dali::Texture currentDiffuseTexture = (mDiffuseTexture && mSpecularTexture) ? mDiffuseTexture : mSceneDiffuseTexture; + Dali::Texture currentSpecularTexture = (mDiffuseTexture && mSpecularTexture) ? mSpecularTexture : mSceneSpecularTexture; + float currentIblScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor; - BoundingVolume AABB; - for(auto iRoot : scene.GetRoots()) + if(!currentDiffuseTexture || !currentSpecularTexture) { - auto resourceRefs = resources.CreateRefCounter(); - scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); - - resources.LoadResources(resourceRefs, pathProvider); + currentDiffuseTexture = mDefaultDiffuseTexture; + currentSpecularTexture = mDefaultSpecularTexture; + currentIblScaleFactor = Dali::Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity(); + } - // 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) + for(auto&& actor : mRenderableActors) + { + Actor renderableActor = actor.GetHandle(); + if(!renderableActor) { - env.first.mYDirection = Y_DIRECTION; + continue; } - if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) + uint32_t rendererCount = renderableActor.GetRendererCount(); + for(uint32_t i = 0; i < rendererCount; ++i) { - 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); + Dali::Renderer renderer = renderableActor.GetRendererAt(i); + if(!renderer) + { + 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); + } } - - AddModelTreeToAABB(AABB, scene, choices, iRoot, nodeParams, Matrix::IDENTITY); + renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIblScaleFactor); } +} - if(!resources.mEnvironmentMaps.empty()) +void Model::UpdateImageBasedLightScaleFactor() +{ + if((!mDiffuseTexture || !mSpecularTexture) && + (!mSceneDiffuseTexture || !mSceneSpecularTexture)) { - mDefaultDiffuseTexture = resources.mEnvironmentMaps.front().second.mDiffuse; - mDefaultSpecularTexture = resources.mEnvironmentMaps.front().second.mSpecular; + return; } - if(!animations.empty()) + float currentIblScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor; + for(auto&& actor : mRenderableActors) { - auto getActor = [&](const std::string& name) { - return mModelRoot.FindChildByName(name); - }; - - mAnimations.clear(); - for(auto&& animation : animations) + Actor renderableActor = actor.GetHandle(); + if(renderableActor) { - Dali::Animation anim = animation.ReAnimate(getActor); + renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIblScaleFactor); + } + } +} - mAnimations.push_back({animation.mName, anim}); +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(); } } +} + +void Model::NotifyImageBasedLightScaleFactor(float scaleFactor) +{ + mSceneIblScaleFactor = scaleFactor; + if(mSceneDiffuseTexture && mSceneSpecularTexture) + { + UpdateImageBasedLightScaleFactor(); + } +} + +void Model::OnModelLoadComplete() +{ + if(!mModelLoadTask->HasSucceeded()) + { + ResetResourceTasks(); + return; + } + CreateModel(); 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(controlSize.x == 0.0f || controlSize.y == 0.0f) + auto* resources = &(mModelLoadTask->mResources); + auto* scene = &(mModelLoadTask->mScene); + CreateAnimations(*scene); + if(!resources->mEnvironmentMaps.empty()) { - Self().SetProperty(Dali::Actor::Property::SIZE, mNaturalSize); + mDefaultDiffuseTexture = resources->mEnvironmentMaps.front().second.mDiffuse; + mDefaultSpecularTexture = resources->mEnvironmentMaps.front().second.mSpecular; } - FitModelPosition(); - ScaleModel(); + UpdateImageBasedLightTexture(); + UpdateImageBasedLightScaleFactor(); 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; - - Control::SetResourceReady(false); + NotifyResourceReady(); + ResetResourceTask(mModelLoadTask); } -void Model::ScaleModel() +void Model::OnIblDiffuseLoadComplete() { - if(mModelRoot) + mDiffuseTexture = mIblDiffuseLoadTask->GetLoadedTexture(); + ResetResourceTask(mIblDiffuseLoadTask); + mIblDiffuseResourceReady = true; + if(mIblDiffuseResourceReady && mIblSpecularResourceReady) { - 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); + OnIblLoadComplete(); } } -void Model::FitModelPosition() +void Model::OnIblSpecularLoadComplete() { - if(mModelRoot) + mSpecularTexture = mIblSpecularLoadTask->GetLoadedTexture(); + ResetResourceTask(mIblSpecularLoadTask); + mIblSpecularResourceReady = 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(); } } -void Model::CollectRenderableActor(Actor actor) +void Model::OnIblLoadComplete() { - uint32_t rendererCount = actor.GetRendererCount(); - if(rendererCount) - { - mRenderableActors.push_back(actor); - } - - uint32_t childrenCount = actor.GetChildCount(); - for(uint32_t i = 0; i < childrenCount; ++i) - { - CollectRenderableActor(actor.GetChildAt(i)); - } + UpdateImageBasedLightTexture(); + NotifyResourceReady(); } -void Model::UpdateImageBasedLightTexture() +void Model::ResetResourceTasks() { - Dali::Texture currentDiffuseTexture = (mDiffuseTexture) ? mDiffuseTexture : mSceneDiffuseTexture; - Dali::Texture currentSpecularTexture = (mSpecularTexture) ? mSpecularTexture : mSceneSpecularTexture; - float currentIBLScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor; - if(!currentDiffuseTexture || !currentSpecularTexture) + if(!Dali::Adaptor::IsAvailable()) { - currentDiffuseTexture = mDefaultDiffuseTexture; - currentSpecularTexture = mDefaultSpecularTexture; - currentIBLScaleFactor = Dali::Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity(); + return; } + ResetResourceTask(mModelLoadTask); + ResetResourceTask(mIblDiffuseLoadTask); + ResetResourceTask(mIblSpecularLoadTask); +} - for(auto&& actor : mRenderableActors) +void Model::ResetResourceTask(IntrusivePtr asyncTask) +{ + if(!asyncTask) { - 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); - } + return; } + Dali::AsyncTaskManager::Get().RemoveTask(asyncTask); + asyncTask.Reset(); } -void Model::UpdateImageBasedLightScaleFactor() +void Model::NotifyResourceReady() { - if((!mDiffuseTexture || !mSpecularTexture) && - (!mSceneDiffuseTexture || !mSceneSpecularTexture)) + if(!IsResourceReady()) { return; } + Control::SetResourceReady(false); +} - float currentIBLScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor; - for(auto&& actor : mRenderableActors) +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()) { - Actor renderableActor = actor.GetHandle(); - if(renderableActor) + resources->GenerateResources(mModelLoadTask->mResourceRefCounts[rootCount]); + + if(auto actor = scene->CreateNodes(iRoot, mModelLoadTask->mResourceChoices, nodeParams)) { - renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIBLScaleFactor); + 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++; } -} -void Model::NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor) -{ - if(mSceneDiffuseTexture != diffuseTexture || mSceneSpecularTexture != specularTexture) + 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)) { - mSceneDiffuseTexture = diffuseTexture; - mSceneSpecularTexture = specularTexture; - mSceneIblScaleFactor = scaleFactor; - UpdateImageBasedLightTexture(); + Self().SetProperty(Dali::Actor::Property::SIZE, mNaturalSize); } + FitModelPosition(); + ScaleModel(); } -void Model::NotifyImageBasedLightScaleFactor(float scaleFactor) +void Model::CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene) { - mSceneIblScaleFactor = scaleFactor; - if(mSceneDiffuseTexture && mSceneSpecularTexture) + if(!mModelLoadTask->mAnimations.empty()) { - UpdateImageBasedLightScaleFactor(); + auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property) + { + 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::Animation anim = animation.ReAnimate(getActor); + mAnimations.push_back({animation.mName, anim}); + } } }