#include <iostream>
#include <dali-scene3d/public-api/model-components/model-node.h>
+#include "mesh-builder.h"
using namespace Dali;
using namespace Dali::Toolkit;
test_return_value = TET_PASS;
}
-namespace
-{
-} // namespace
-
// Negative test case for a method
int UtcDaliModelNodeUninitialized(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;
+}
${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
)
+++ /dev/null
-/*
- * 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 <dali-scene3d/internal/model-components/model-node-data-impl.h>
-
-// EXTERNAL INCLUDES
-#include <dali/integration-api/debug.h>
-#include <dali/public-api/object/type-registry-helper.h>
-#include <dali/public-api/object/type-registry.h>
-
-// INTERNAL INCLUDES
-#include <dali-scene3d/internal/model-components/model-primitive-impl.h>
-#include <dali-scene3d/public-api/model-components/model-node.h>
-
-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<Matrix>(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
+++ /dev/null
-#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 <dali/public-api/animation/constraints.h>
-#include <dali/public-api/common/dali-vector.h>
-#include <dali/public-api/object/type-registry.h>
-
-// INTERNAL INCLUDES
-#include <dali-scene3d/internal/model-components/model-node-impl.h>
-#include <dali-scene3d/internal/model-components/model-primitive-modify-observer.h>
-#include <dali-scene3d/public-api/loader/skinning-details.h>
-
-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<Scene3D::ModelPrimitive>;
- using BoneDataContainer = std::vector<Dali::Scene3D::Loader::Skinning::BoneData>;
-
- /**
- * @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<uint32_t>(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
// EXTERNAL INCLUDES
#include <dali/integration-api/debug.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry.h>
// INTERNAL INCLUDES
-#include <dali-scene3d/internal/model-components/model-node-data-impl.h>
+#include <dali-scene3d/internal/model-components/model-primitive-impl.h>
namespace Dali
{
{
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
}
ModelNode::ModelNode()
-: CustomActorImpl(ActorFlags::DISABLE_SIZE_NEGOTIATION),
- mImpl(new Impl(*this))
+: CustomActorImpl(ActorFlags::DISABLE_SIZE_NEGOTIATION)
{
}
void ModelNode::OnSceneConnection(int depth)
{
- mImpl->OnSceneConnection(depth);
}
void ModelNode::OnSceneDisconnection()
{
- mImpl->OnSceneDisconnection();
}
void ModelNode::OnChildAdd(Actor& child)
ModelNode& GetImplementation(Dali::Scene3D::ModelNode& handle)
{
CustomActorImpl& customInterface = handle.GetImplementation();
- ModelNode& impl = dynamic_cast<Internal::ModelNode&>(customInterface);
+ ModelNode& impl = dynamic_cast<Internal::ModelNode&>(customInterface);
return impl;
}
uint32_t ModelNode::GetModelPrimitiveCount() const
{
- return mImpl->GetModelPrimitiveCount();
+ return static_cast<uint32_t>(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)
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<Matrix>(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
#include <memory> // for std::unique_ptr
// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-components/model-primitive-modify-observer.h>
#include <dali-scene3d/public-api/loader/mesh-definition.h>
+#include <dali-scene3d/public-api/loader/skinning-details.h>
#include <dali-scene3d/public-api/model-components/model-node.h>
#include <dali-scene3d/public-api/model-components/model-primitive.h>
*
* @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<Scene3D::ModelPrimitive>;
+ using BoneDataContainer = std::vector<Dali::Scene3D::Loader::Skinning::BoneData>;
+
// Creation & Destruction
/**
* @brief Creates a new ModelNodeImpl instance that does not require touch by default.
*/
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
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<Impl> mImpl;
+ ModelPrimitiveContainer mModelPrimitiveContainer; ///< List of model primitives
+ BoneDataContainer mBoneDataContainer;
+ Dali::Texture mSpecularTexture;
+ Dali::Texture mDiffuseTexture;
+ float mIblScaleFactor{1.0f};
+ uint32_t mSpecularMipmapLevels{1u};
/// @endcond
};