From 0b0405f88b95217119334c7dcf50099f8ea61146 Mon Sep 17 00:00:00 2001 From: seungho baek Date: Wed, 19 Apr 2023 18:20:00 +0900 Subject: [PATCH] Remove model-node-data-impl Change-Id: Iba64ae2ecbc67d42093affbc364693ff163551b6 Signed-off-by: seungho baek --- .../src/dali-scene3d/utc-Dali-ModelNode.cpp | 83 ++++++- dali-scene3d/internal/file.list | 1 - .../model-components/model-node-data-impl.cpp | 262 --------------------- .../model-components/model-node-data-impl.h | 162 ------------- .../internal/model-components/model-node-impl.cpp | 174 ++++++++++++-- .../internal/model-components/model-node-impl.h | 32 ++- 6 files changed, 264 insertions(+), 450 deletions(-) delete mode 100644 dali-scene3d/internal/model-components/model-node-data-impl.cpp delete mode 100644 dali-scene3d/internal/model-components/model-node-data-impl.h diff --git a/automated-tests/src/dali-scene3d/utc-Dali-ModelNode.cpp b/automated-tests/src/dali-scene3d/utc-Dali-ModelNode.cpp index e124bc6..3aaecc6 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-ModelNode.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-ModelNode.cpp @@ -21,6 +21,7 @@ #include #include +#include "mesh-builder.h" using namespace Dali; using namespace Dali::Toolkit; @@ -35,10 +36,6 @@ void model_components_model_node_cleanup(void) test_return_value = TET_PASS; } -namespace -{ -} // namespace - // Negative test case for a method int UtcDaliModelNodeUninitialized(void) { @@ -293,4 +290,80 @@ int UtcDaliModelNodeFindChildModelNodeByName(void) DALI_TEST_EQUALS(child2, modelNode2, TEST_LOCATION); END_TEST; -} \ No newline at end of file +} + +int UtcDaliModelNodeCustomNode1(void) +{ + tet_infoline(" UtcDaliModelNodeCustomNode1."); + + ToolkitTestApplication application; + + Scene3D::ModelNode modelNode = Scene3D::ModelNode::New(); + Scene3D::ModelPrimitive modelPrimitive = Scene3D::ModelPrimitive::New(); + Scene3D::Material material = Scene3D::Material::New(); + Geometry geometry = CreateQuadGeometry(); + + DALI_TEST_EQUALS(modelNode.GetRendererCount(), 0, TEST_LOCATION); + + modelNode.AddModelPrimitive(modelPrimitive); + + DALI_TEST_EQUALS(modelNode.GetRendererCount(), 0, TEST_LOCATION); + + modelPrimitive.SetGeometry(geometry); + + DALI_TEST_EQUALS(modelNode.GetRendererCount(), 0, TEST_LOCATION); + + modelPrimitive.SetMaterial(material); + + DALI_TEST_EQUALS(modelNode.GetRendererCount(), 1, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliModelNodeCustomNode2(void) +{ + tet_infoline(" UtcDaliModelNodeCustomNode2."); + + ToolkitTestApplication application; + + Scene3D::ModelNode modelNode = Scene3D::ModelNode::New(); + Scene3D::ModelPrimitive modelPrimitive = Scene3D::ModelPrimitive::New(); + Scene3D::Material material = Scene3D::Material::New(); + Geometry geometry = CreateQuadGeometry(); + modelPrimitive.SetGeometry(geometry); + modelPrimitive.SetMaterial(material); + + DALI_TEST_EQUALS(modelNode.GetRendererCount(), 0, TEST_LOCATION); + + modelNode.AddModelPrimitive(modelPrimitive); + + DALI_TEST_EQUALS(modelNode.GetRendererCount(), 1, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliModelNodeCustomNode3(void) +{ + tet_infoline(" UtcDaliModelNodeCustomNode3."); + + ToolkitTestApplication application; + + Scene3D::ModelNode modelNode = Scene3D::ModelNode::New(); + Scene3D::ModelPrimitive modelPrimitive = Scene3D::ModelPrimitive::New(); + Scene3D::Material material = Scene3D::Material::New(); + Geometry geometry = CreateQuadGeometry(); + modelPrimitive.SetGeometry(geometry); + modelPrimitive.SetMaterial(material); + + DALI_TEST_EQUALS(modelNode.GetRendererCount(), 0, TEST_LOCATION); + + modelNode.AddModelPrimitive(modelPrimitive); + + DALI_TEST_EQUALS(modelNode.GetRendererCount(), 1, TEST_LOCATION); + + modelNode.AddModelPrimitive(modelPrimitive); + + DALI_TEST_EQUALS(modelNode.GetRendererCount(), 1, TEST_LOCATION); + + END_TEST; +} diff --git a/dali-scene3d/internal/file.list b/dali-scene3d/internal/file.list index 4921731..3706b72 100644 --- a/dali-scene3d/internal/file.list +++ b/dali-scene3d/internal/file.list @@ -19,7 +19,6 @@ set(scene3d_src_files ${scene3d_src_files} ${scene3d_internal_dir}/loader/json-reader.cpp ${scene3d_internal_dir}/loader/json-util.cpp ${scene3d_internal_dir}/model-components/material-impl.cpp - ${scene3d_internal_dir}/model-components/model-node-data-impl.cpp ${scene3d_internal_dir}/model-components/model-node-impl.cpp ${scene3d_internal_dir}/model-components/model-primitive-impl.cpp ) diff --git a/dali-scene3d/internal/model-components/model-node-data-impl.cpp b/dali-scene3d/internal/model-components/model-node-data-impl.cpp deleted file mode 100644 index c1d3dbd..0000000 --- a/dali-scene3d/internal/model-components/model-node-data-impl.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// CLASS HEADER -#include - -// EXTERNAL INCLUDES -#include -#include -#include - -// INTERNAL INCLUDES -#include -#include - -namespace -{ -} // namespace - -namespace Dali -{ -namespace Scene3D -{ -namespace Internal -{ -namespace -{ -/** - * Creates control through type registry - */ -BaseHandle Create() -{ - return Scene3D::ModelNode::New(); -} - -// Setup properties, signals and actions using the type-registry. -DALI_TYPE_REGISTRATION_BEGIN(Scene3D::ModelNode, Dali::CustomActor, Create); -DALI_TYPE_REGISTRATION_END() -} // unnamed namespace - -ModelNode::Impl::Impl(ModelNode& modelNodeImpl) -: mModelNodeImpl(modelNodeImpl) -{ -} - -ModelNode::Impl::~Impl() -{ - for(auto&& primitive : mModelPrimitiveContainer) - { - GetImplementation(primitive).RemovePrimitiveObserver(this); - } - for(auto&& boneData : mBoneDataContainer) - { - boneData.primitive.Reset(); - if(boneData.constraint) - { - boneData.constraint.Remove(); - boneData.constraint.Reset(); - } - } -} - -void ModelNode::Impl::OnSceneConnection(int depth) -{ -} - -void ModelNode::Impl::OnSceneDisconnection() -{ -} - -void ModelNode::Impl::OnRendererCreated(Renderer renderer) -{ - mModelNodeImpl.Self().AddRenderer(renderer); -} - -// Public Method - -void ModelNode::Impl::AddModelPrimitive(Scene3D::ModelPrimitive modelPrimitive) -{ - for(auto&& primitive : mModelPrimitiveContainer) - { - if(primitive == modelPrimitive) - { - return; - } - } - - mModelPrimitiveContainer.push_back(modelPrimitive); - - Actor self = mModelNodeImpl.Self(); - - GetImplementation(modelPrimitive).AddPrimitiveObserver(this); - if(mDiffuseTexture && mSpecularTexture) - { - GetImplementation(modelPrimitive).SetImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor, mSpecularMipmapLevels); - } - - Dali::Renderer renderer = GetImplementation(modelPrimitive).GetRenderer(); - if(renderer) - { - uint32_t rendererCount = self.GetRendererCount(); - bool exist = false; - for(uint32_t i = 0; i < rendererCount; ++i) - { - if(renderer == self.GetRendererAt(i)) - { - exist = true; - break; - } - } - if(!exist) - { - self.AddRenderer(renderer); - } - } -} - -void ModelNode::Impl::RemoveModelPrimitive(Scene3D::ModelPrimitive modelPrimitive) -{ - uint32_t primitiveCount = GetModelPrimitiveCount(); - for(uint32_t i = 0; i < primitiveCount; ++i) - { - if(mModelPrimitiveContainer[i] != modelPrimitive) - { - continue; - } - RemoveModelPrimitive(i); - break; - } -} - -void ModelNode::Impl::RemoveModelPrimitive(uint32_t index) -{ - if(index >= mModelPrimitiveContainer.size()) - { - return; - } - - Actor self = mModelNodeImpl.Self(); - GetImplementation(mModelPrimitiveContainer[index]).RemovePrimitiveObserver(this); - - Dali::Renderer renderer = GetImplementation(mModelPrimitiveContainer[index]).GetRenderer(); - if(renderer) - { - self.RemoveRenderer(renderer); - } - - mModelPrimitiveContainer.erase(mModelPrimitiveContainer.begin() + index); -} - -Scene3D::ModelPrimitive ModelNode::Impl::GetModelPrimitive(uint32_t index) const -{ - if(index < mModelPrimitiveContainer.size()) - { - return mModelPrimitiveContainer[index]; - } - return Scene3D::ModelPrimitive(); -} - -void ModelNode::Impl::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float iblScaleFactor, uint32_t specularMipmapLevels) -{ - mDiffuseTexture = diffuseTexture; - mSpecularTexture = specularTexture; - mIblScaleFactor = iblScaleFactor; - mSpecularMipmapLevels = specularMipmapLevels; - for(auto&& primitive : mModelPrimitiveContainer) - { - GetImplementation(primitive).SetImageBasedLightTexture(diffuseTexture, specularTexture, iblScaleFactor, specularMipmapLevels); - } -} - -void ModelNode::Impl::SetImageBasedLightScaleFactor(float iblScaleFactor) -{ - mIblScaleFactor = iblScaleFactor; - for(auto&& primitive : mModelPrimitiveContainer) - { - GetImplementation(primitive).SetImageBasedLightScaleFactor(iblScaleFactor); - } -} - -void ModelNode::Impl::SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data, Scene3D::ModelPrimitive primitive) -{ - GetImplementation(primitive).SetBlendShapeData(data); -} - -void ModelNode::Impl::SetBoneMatrix(const Matrix& inverseMatrix, Scene3D::ModelPrimitive primitive, Scene3D::Loader::Index& boneIndex) -{ - Dali::Scene3D::Loader::Skinning::BoneData boneData; - boneData.primitive = primitive; - boneData.boneIndex = boneIndex; - char propertyNameBuffer[32]; - snprintf(propertyNameBuffer, sizeof(propertyNameBuffer), "%s[%d]", Dali::Scene3D::Loader::Skinning::BONE_UNIFORM_NAME, boneIndex); - boneData.propertyName = propertyNameBuffer; - boneData.inverseMatrix = inverseMatrix; - mBoneDataContainer.push_back(std::move(boneData)); - - UpdateBoneMatrix(primitive); -} - -void ModelNode::Impl::UpdateBoneMatrix(Scene3D::ModelPrimitive primitive) -{ - for(auto&& boneData : mBoneDataContainer) - { - if(boneData.primitive != primitive) - { - continue; - } - - Dali::Renderer renderer = GetImplementation(primitive).GetRenderer(); - if(!renderer) - { - continue; - } - - Dali::Shader shader = renderer.GetShader(); - if(!shader) - { - continue; - } - - if(boneData.constraint) - { - boneData.constraint.Remove(); - boneData.constraint.Reset(); - } - - if(shader.GetPropertyIndex(boneData.propertyName) == Property::INVALID_INDEX) - { - auto propBoneXform = shader.RegisterProperty(boneData.propertyName, Matrix{false}); - - Matrix inverseMatrix = boneData.inverseMatrix; - // Constrain bone matrix to joint transform. - boneData.constraint = Constraint::New(shader, propBoneXform, [inverseMatrix](Matrix& output, const PropertyInputContainer& inputs) - { Matrix::Multiply(output, inverseMatrix, inputs[0]->GetMatrix()); }); - - Actor joint = mModelNodeImpl.Self(); - boneData.constraint.AddSource(Source{joint, Actor::Property::WORLD_MATRIX}); - boneData.constraint.ApplyPost(); - } - break; - } -} - -} // namespace Internal - -} // namespace Scene3D - -} // namespace Dali diff --git a/dali-scene3d/internal/model-components/model-node-data-impl.h b/dali-scene3d/internal/model-components/model-node-data-impl.h deleted file mode 100644 index b19a82f..0000000 --- a/dali-scene3d/internal/model-components/model-node-data-impl.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef DALI_SCENE3D_MODEL_COMPONENTS_MODEL_NODE_DATA_IMPL_H -#define DALI_SCENE3D_MODEL_COMPONENTS_MODEL_NODE_DATA_IMPL_H - -/* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// EXTERNAL INCLUDES -#include -#include -#include - -// INTERNAL INCLUDES -#include -#include -#include - -namespace Dali -{ -namespace Scene3D -{ -namespace Internal -{ -/** - * @brief Holds the Implementation for the internal model node class - */ -class ModelNode::Impl : public ModelPrimitiveModifyObserver -{ -public: - using ModelPrimitiveContainer = std::vector; - using BoneDataContainer = std::vector; - - /** - * @brief Constructor. - * @param[in] modelNodeImpl The control which owns this implementation - */ - Impl(ModelNode& modelNodeImpl); - - /** - * @brief Destructor. - */ - ~Impl(); - -public: - /** - * @copydoc Dali::Scene3D::Internal::ModelNode::OnSceneConnection() - */ - void OnSceneConnection(int depth); - - /** - * @copydoc Dali::Scene3D::Internal::ModelNode::OnSceneConnection() - */ - void OnSceneDisconnection(); - -public: // Public Method - /** - * @copydoc Dali::Scene3D::ModelNode::GetModelPrimitiveCount() - */ - inline uint32_t GetModelPrimitiveCount() const - { - return static_cast(mModelPrimitiveContainer.size()); - } - - /** - * @copydoc Dali::Scene3D::ModelNode::AddModelPrimitive() - */ - void AddModelPrimitive(Scene3D::ModelPrimitive modelPrimitive); - - /** - * @copydoc Dali::Scene3D::ModelNode::RemoveModelPrimitive() - */ - void RemoveModelPrimitive(Scene3D::ModelPrimitive modelPrimitive); - - /** - * @copydoc Dali::Scene3D::ModelNode::RemoveModelPrimitive() - */ - void RemoveModelPrimitive(uint32_t index); - - /** - * @copydoc Dali::Scene3D::ModelNode::GetModelPrimitive() - */ - Scene3D::ModelPrimitive GetModelPrimitive(uint32_t index) const; - - /** - * @brief Sets the diffuse and specular image-based lighting textures for a ModelPrimitive. - * - * @param[in] diffuseTexture The diffuse texture. - * @param[in] specularTexture The specular texture. - * @param[in] iblScaleFactor The scale factor for the image-based lighting. - * @param[in] specularMipmapLevels The number of mipmap levels for the specular texture. - */ - void SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float iblScaleFactor, uint32_t specularMipmapLevels); - - /** - * @brief Sets the scale factor for image-based lighting. - * - * @param[in] iblScaleFactor The scale factor for image-based lighting. - */ - void SetImageBasedLightScaleFactor(float iblScaleFactor); - - /** - * @brief Sets the blend shape data for a ModelPrimitive. - * - * @param[in] data The blend shape data. - * @param[in] primitive The ModelPrimitive to set the blend shape data for. - */ - void SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data, Scene3D::ModelPrimitive primitive); - - /** - * @brief Sets the bone matrix for a ModelPrimitive and bone index. - * - * @param[in] inverseMatrix The inverse matrix of the bone. - * @param[in] primitive The ModelPrimitive to set the bone matrix for. - * @param[in] boneIndex The index of the bone to set the matrix for. - */ - void SetBoneMatrix(const Matrix& inverseMatrix, Scene3D::ModelPrimitive primitive, Scene3D::Loader::Index& boneIndex); - - /** - * @brief Called when a Renderer of ModelPrimitive is created. - * - * @param[in] renderer The Renderer that is created. - */ - void OnRendererCreated(Renderer renderer) override; - -private: - /** - * @brief Updates the bone matrix for a ModelPrimitive. - * - * @param[in] primitive The ModelPrimitive to set the bone matrix for. - */ - void UpdateBoneMatrix(Scene3D::ModelPrimitive primitive); - -private: - ModelNode& mModelNodeImpl; ///< Owner of this data - ModelPrimitiveContainer mModelPrimitiveContainer; ///< List of model primitives - BoneDataContainer mBoneDataContainer; - Dali::Texture mSpecularTexture; - Dali::Texture mDiffuseTexture; - float mIblScaleFactor{1.0f}; - uint32_t mSpecularMipmapLevels{1u}; -}; - -} // namespace Internal - -} // namespace Scene3D - -} // namespace Dali - -#endif // DALI_SCENE3D_MODEL_COMPONENTS_MODEL_NODE_DATA_IMPL_H diff --git a/dali-scene3d/internal/model-components/model-node-impl.cpp b/dali-scene3d/internal/model-components/model-node-impl.cpp index 60dca00..257cbd0 100644 --- a/dali-scene3d/internal/model-components/model-node-impl.cpp +++ b/dali-scene3d/internal/model-components/model-node-impl.cpp @@ -20,9 +20,11 @@ // EXTERNAL INCLUDES #include +#include +#include // INTERNAL INCLUDES -#include +#include namespace Dali { @@ -30,6 +32,21 @@ namespace Scene3D { namespace Internal { +namespace +{ +/** + * Creates control through type registry + */ +BaseHandle Create() +{ + return Scene3D::ModelNode::New(); +} + +// Setup properties, signals and actions using the type-registry. +DALI_TYPE_REGISTRATION_BEGIN(Scene3D::ModelNode, Dali::CustomActor, Create); +DALI_TYPE_REGISTRATION_END() +} // unnamed namespace + Dali::Scene3D::ModelNode ModelNode::New() { // Create the implementation, temporarily owned on stack @@ -46,8 +63,7 @@ Dali::Scene3D::ModelNode ModelNode::New() } ModelNode::ModelNode() -: CustomActorImpl(ActorFlags::DISABLE_SIZE_NEGOTIATION), - mImpl(new Impl(*this)) +: CustomActorImpl(ActorFlags::DISABLE_SIZE_NEGOTIATION) { } @@ -66,12 +82,10 @@ void ModelNode::OnInitialize() void ModelNode::OnSceneConnection(int depth) { - mImpl->OnSceneConnection(depth); } void ModelNode::OnSceneDisconnection() { - mImpl->OnSceneDisconnection(); } void ModelNode::OnChildAdd(Actor& child) @@ -139,7 +153,7 @@ void ModelNode::OnLayoutNegotiated(float size, Dimension::Type dimension) ModelNode& GetImplementation(Dali::Scene3D::ModelNode& handle) { CustomActorImpl& customInterface = handle.GetImplementation(); - ModelNode& impl = dynamic_cast(customInterface); + ModelNode& impl = dynamic_cast(customInterface); return impl; } @@ -155,27 +169,88 @@ const ModelNode& GetImplementation(const Dali::Scene3D::ModelNode& handle) uint32_t ModelNode::GetModelPrimitiveCount() const { - return mImpl->GetModelPrimitiveCount(); + return static_cast(mModelPrimitiveContainer.size()); } void ModelNode::AddModelPrimitive(Dali::Scene3D::ModelPrimitive modelPrimitive) { - mImpl->AddModelPrimitive(modelPrimitive); + for(auto&& primitive : mModelPrimitiveContainer) + { + if(primitive == modelPrimitive) + { + return; + } + } + + mModelPrimitiveContainer.push_back(modelPrimitive); + + Actor self = Self(); + GetImplementation(modelPrimitive).AddPrimitiveObserver(this); + if(mDiffuseTexture && mSpecularTexture) + { + GetImplementation(modelPrimitive).SetImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor, mSpecularMipmapLevels); + } + + Dali::Renderer renderer = GetImplementation(modelPrimitive).GetRenderer(); + if(renderer) + { + uint32_t rendererCount = self.GetRendererCount(); + bool exist = false; + for(uint32_t i = 0; i < rendererCount; ++i) + { + if(renderer == self.GetRendererAt(i)) + { + exist = true; + break; + } + } + if(!exist) + { + self.AddRenderer(renderer); + } + } } void ModelNode::RemoveModelPrimitive(Dali::Scene3D::ModelPrimitive modelPrimitive) { - mImpl->RemoveModelPrimitive(modelPrimitive); + uint32_t primitiveCount = GetModelPrimitiveCount(); + for(uint32_t i = 0; i < primitiveCount; ++i) + { + if(mModelPrimitiveContainer[i] != modelPrimitive) + { + continue; + } + RemoveModelPrimitive(i); + break; + } } void ModelNode::RemoveModelPrimitive(uint32_t index) { - mImpl->RemoveModelPrimitive(index); + if(index >= mModelPrimitiveContainer.size()) + { + return; + } + + Actor self = Self(); + GetImplementation(mModelPrimitiveContainer[index]).RemovePrimitiveObserver(this); + + Dali::Renderer renderer = GetImplementation(mModelPrimitiveContainer[index]).GetRenderer(); + if(renderer) + { + self.RemoveRenderer(renderer); + } + + mModelPrimitiveContainer.erase(mModelPrimitiveContainer.begin() + index); } Dali::Scene3D::ModelPrimitive ModelNode::GetModelPrimitive(uint32_t index) const { - return mImpl->GetModelPrimitive(index); + if(index < mModelPrimitiveContainer.size()) + { + return mModelPrimitiveContainer[index]; + } + return Scene3D::ModelPrimitive(); } Scene3D::ModelNode ModelNode::FindChildModelNodeByName(std::string_view nodeName) @@ -186,22 +261,91 @@ Scene3D::ModelNode ModelNode::FindChildModelNodeByName(std::string_view nodeName void ModelNode::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float iblScaleFactor, uint32_t specularMipmapLevels) { - mImpl->SetImageBasedLightTexture(diffuseTexture, specularTexture, iblScaleFactor, specularMipmapLevels); + mDiffuseTexture = diffuseTexture; + mSpecularTexture = specularTexture; + mIblScaleFactor = iblScaleFactor; + mSpecularMipmapLevels = specularMipmapLevels; + for(auto&& primitive : mModelPrimitiveContainer) + { + GetImplementation(primitive).SetImageBasedLightTexture(diffuseTexture, specularTexture, iblScaleFactor, specularMipmapLevels); + } } void ModelNode::SetImageBasedLightScaleFactor(float iblScaleFactor) { - mImpl->SetImageBasedLightScaleFactor(iblScaleFactor); + mIblScaleFactor = iblScaleFactor; + for(auto&& primitive : mModelPrimitiveContainer) + { + GetImplementation(primitive).SetImageBasedLightScaleFactor(iblScaleFactor); + } } void ModelNode::SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data, Scene3D::ModelPrimitive primitive) { - mImpl->SetBlendShapeData(data, primitive); + GetImplementation(primitive).SetBlendShapeData(data); } void ModelNode::SetBoneMatrix(const Matrix& inverseMatrix, Scene3D::ModelPrimitive primitive, Scene3D::Loader::Index& boneIndex) { - mImpl->SetBoneMatrix(inverseMatrix, primitive, boneIndex); + Dali::Scene3D::Loader::Skinning::BoneData boneData; + boneData.primitive = primitive; + boneData.boneIndex = boneIndex; + char propertyNameBuffer[32]; + snprintf(propertyNameBuffer, sizeof(propertyNameBuffer), "%s[%d]", Dali::Scene3D::Loader::Skinning::BONE_UNIFORM_NAME, boneIndex); + boneData.propertyName = propertyNameBuffer; + boneData.inverseMatrix = inverseMatrix; + mBoneDataContainer.push_back(std::move(boneData)); + + UpdateBoneMatrix(primitive); +} + +void ModelNode::OnRendererCreated(Renderer renderer) +{ + Self().AddRenderer(renderer); +} + +void ModelNode::UpdateBoneMatrix(Scene3D::ModelPrimitive primitive) +{ + for(auto&& boneData : mBoneDataContainer) + { + if(boneData.primitive != primitive) + { + continue; + } + + Dali::Renderer renderer = GetImplementation(primitive).GetRenderer(); + if(!renderer) + { + continue; + } + + Dali::Shader shader = renderer.GetShader(); + if(!shader) + { + continue; + } + + if(boneData.constraint) + { + boneData.constraint.Remove(); + boneData.constraint.Reset(); + } + + if(shader.GetPropertyIndex(boneData.propertyName) == Property::INVALID_INDEX) + { + auto propBoneXform = shader.RegisterProperty(boneData.propertyName, Matrix{false}); + + Matrix inverseMatrix = boneData.inverseMatrix; + // Constrain bone matrix to joint transform. + boneData.constraint = Constraint::New(shader, propBoneXform, [inverseMatrix](Matrix& output, const PropertyInputContainer& inputs) + { Matrix::Multiply(output, inverseMatrix, inputs[0]->GetMatrix()); }); + + Actor joint = Self(); + boneData.constraint.AddSource(Source{joint, Actor::Property::WORLD_MATRIX}); + boneData.constraint.ApplyPost(); + } + break; + } } } // namespace Internal diff --git a/dali-scene3d/internal/model-components/model-node-impl.h b/dali-scene3d/internal/model-components/model-node-impl.h index d216bb5..e3c718c 100644 --- a/dali-scene3d/internal/model-components/model-node-impl.h +++ b/dali-scene3d/internal/model-components/model-node-impl.h @@ -24,7 +24,9 @@ #include // for std::unique_ptr // INTERNAL INCLUDES +#include #include +#include #include #include @@ -44,9 +46,12 @@ namespace Internal * * @SINCE_2_2.99 */ -class DALI_SCENE3D_API ModelNode : public CustomActorImpl +class DALI_SCENE3D_API ModelNode : public CustomActorImpl, public ModelPrimitiveModifyObserver { public: + using ModelPrimitiveContainer = std::vector; + using BoneDataContainer = std::vector; + // Creation & Destruction /** * @brief Creates a new ModelNodeImpl instance that does not require touch by default. @@ -244,6 +249,21 @@ public: // Public Method */ void SetBoneMatrix(const Matrix& inverseMatrix, Scene3D::ModelPrimitive primitive, Scene3D::Loader::Index& boneIndex); + /** + * @brief Called when a Renderer of ModelPrimitive is created. + * + * @param[in] renderer The Renderer that is created. + */ + void OnRendererCreated(Renderer renderer) override; + +private: + /** + * @brief Updates the bone matrix for a ModelPrimitive. + * + * @param[in] primitive The ModelPrimitive to set the bone matrix for. + */ + void UpdateBoneMatrix(Scene3D::ModelPrimitive primitive); + private: /// @cond internal @@ -253,11 +273,13 @@ private: DALI_INTERNAL ModelNode& operator=(const ModelNode&) = delete; ///< Deleted copy assignment operator. DALI_INTERNAL ModelNode& operator=(ModelNode&&) = delete; ///< Deleted move assignment operator. -public: - class DALI_INTERNAL Impl; // Class declaration is public so we can internally add devel API's to the ModelNode's Impl - private: - const std::unique_ptr mImpl; + ModelPrimitiveContainer mModelPrimitiveContainer; ///< List of model primitives + BoneDataContainer mBoneDataContainer; + Dali::Texture mSpecularTexture; + Dali::Texture mDiffuseTexture; + float mIblScaleFactor{1.0f}; + uint32_t mSpecularMipmapLevels{1u}; /// @endcond }; -- 2.7.4