position = bone * position;\r
normal = (bone * vec4(normal, 0.0)).xyz;\r
tangent = (bone * vec4(tangent, 0.0)).xyz;\r
-#endif\r
\r
+ normal = normalize(normal);\r
+ tangent = normalize(tangent);\r
+ vec4 vPosition = position;\r
+#else\r
vec4 vPosition = uModelMatrix * position;\r
+#endif\r
\r
vNormal = normalize(uNormalMatrix * normal);\r
\r
resources.LoadResources(ctx.pathProvider);
if(auto actor = scene.CreateNodes(iRoot, choices, 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));
resources.LoadResources(ctx.pathProvider);
if(auto actor = scene.CreateNodes(iRoot, choices, 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));
resources.LoadResources(ctx.pathProvider);
if(auto actor = scene.CreateNodes(iRoot, choices, 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));
resources.LoadResources(ctx.pathProvider);
if(auto actor = scene.CreateNodes(iRoot, choices, 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));
ctx.resources.LoadResources(ctx.pathProvider);
if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
{
- scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
root.Add(actor);
resources.LoadResources(ctx.pathProvider);
if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
{
- scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
root.Add(actor);
resources.LoadResources(ctx.pathProvider);
if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
{
- scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
root.Add(actor);
resources.LoadResources(ctx.pathProvider);
if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
{
- scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
root.Add(actor);
#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;
+}
void Impl::DummyControl::OnSizeSet(const Vector3& targetSize) { Control::OnSizeSet( targetSize ); sizeSetCalled = true; }
void Impl::DummyControl::OnSizeAnimation(Animation& animation, const Vector3& targetSize) { Control::OnSizeAnimation( animation, targetSize ); sizeAnimationCalled = true; }
bool Impl::DummyControl::OnKeyEvent(const KeyEvent& event) { keyEventCalled = true; return false;}
-void Impl::DummyControl::OnKeyInputFocusGained() { keyInputFocusGained = true; }
-void Impl::DummyControl::OnKeyInputFocusLost() { keyInputFocusLost = true; }
+void Impl::DummyControl::OnKeyInputFocusGained()
+{
+ if(this->HasKeyInputFocus())
+ {
+ keyInputFocusGained = true;
+ }
+}
+void Impl::DummyControl::OnKeyInputFocusLost()
+{
+ if(!this->HasKeyInputFocus())
+ {
+ keyInputFocusLost = true;
+ }
+}
void Impl::DummyControl::SetLayout( Property::Index visualIndex, Property::Map& map )
{
#define TEST_GL_ABSTRACTION_H
/*
- * 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.
inline void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) override
{
+ std::stringstream out;
+ out << mode << ", " << first << ", " << count << ", " << instanceCount;
+ TraceCallStack::NamedParams namedParams;
+ namedParams["mode"] << std::hex << mode;
+ namedParams["first"] << first;
+ namedParams["count"] << count;
+ namedParams["instanceCount"] << instanceCount;
+ mDrawTrace.PushCall("DrawArraysInstanced", out.str(), namedParams);
}
inline void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) override
{
+ std::stringstream out;
+ out << mode << ", " << count << ", " << type << ", " << instanceCount;
+ TraceCallStack::NamedParams namedParams;
+ namedParams["mode"] << std::hex << mode;
+ namedParams["count"] << count;
+ namedParams["type"] << std::hex << type;
+ namedParams["indexCount"] << instanceCount;
+ mDrawTrace.PushCall("DrawElementsInstanced", out.str(), namedParams);
}
inline GLsync FenceSync(GLenum condition, GLbitfield flags) override
inline void VertexAttribDivisor(GLuint index, GLuint divisor) override
{
+ std::stringstream out;
+ out << index << ", " << divisor;
+ TraceCallStack::NamedParams namedParams;
+ namedParams["index"] << index;
+ namedParams["divisor"] << divisor;
+ mBufferTrace.PushCall("VertexAttribDivisor", out.str(), namedParams);
}
inline void BindTransformFeedback(GLenum target, GLuint id) override
{
if(currentPipeline)
{
- mGl.DrawArrays(GetTopology(currentPipeline->inputAssemblyState.topology),
- 0,
- cmd.data.draw.draw.vertexCount);
+ if(cmd.data.draw.draw.instanceCount == 0)
+ {
+ mGl.DrawArrays(GetTopology(currentPipeline->inputAssemblyState.topology),
+ 0,
+ cmd.data.draw.draw.vertexCount);
+ }
+ else
+ {
+ mGl.DrawArraysInstanced(GetTopology(currentPipeline->inputAssemblyState.topology),
+ 0,
+ cmd.data.draw.draw.vertexCount,
+ cmd.data.draw.draw.instanceCount);
+ }
}
break;
}
{
if(currentPipeline)
{
- mGl.DrawElements(GetTopology(currentPipeline->inputAssemblyState.topology),
- static_cast<GLsizei>(cmd.data.draw.drawIndexed.indexCount),
- GL_UNSIGNED_SHORT,
- reinterpret_cast<void*>(cmd.data.draw.drawIndexed.firstIndex));
+ if(cmd.data.draw.draw.instanceCount == 0)
+ {
+ mGl.DrawElements(GetTopology(currentPipeline->inputAssemblyState.topology),
+ static_cast<GLsizei>(cmd.data.draw.drawIndexed.indexCount),
+ GL_UNSIGNED_SHORT,
+ reinterpret_cast<void*>(cmd.data.draw.drawIndexed.firstIndex));
+ }
+ else
+ {
+ mGl.DrawElementsInstanced(GetTopology(currentPipeline->inputAssemblyState.topology),
+ static_cast<GLsizei>(cmd.data.draw.drawIndexed.indexCount),
+ GL_UNSIGNED_SHORT,
+ reinterpret_cast<void*>(cmd.data.draw.drawIndexed.firstIndex),
+ cmd.data.draw.drawIndexed.instanceCount);
+ }
}
break;
}
uint32_t attributeOffset = attribute.offset;
GLsizei stride = vi.bufferBindings[attribute.binding].stride;
+ auto rate = vi.bufferBindings[attribute.binding].inputRate;
+
mGl.VertexAttribPointer(attribute.location,
GetNumComponents(attribute.format),
GetGlType(attribute.format),
GL_FALSE, // Not normalized
stride,
reinterpret_cast<void*>(attributeOffset));
+ if(rate == Graphics::VertexInputRate::PER_VERTEX)
+ {
+ mGl.VertexAttribDivisor(attribute.location, 0);
+ }
+ else if(rate == Graphics::VertexInputRate::PER_INSTANCE)
+ {
+ mGl.VertexAttribDivisor(attribute.location, 1);
+ }
}
// Cull face setup
{
if(auto actor = scene.CreateNodes(iRoot, resourceChoices, nodeParams))
{
- scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests));
${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
)
#ifdef MORPH
#define MAX_BLEND_SHAPE_NUMBER 128
-uniform float uNumberOfBlendShapes; ///< Total number of blend shapes loaded.
+uniform float uNumberOfBlendShapes; ///< Total number of blend shapes loaded.
uniform highp float uBlendShapeWeight[MAX_BLEND_SHAPE_NUMBER]; ///< The weight of each blend shape.
#ifdef MORPH_VERSION_2_0
-uniform float uBlendShapeUnnormalizeFactor; ///< Factor used to unnormalize the geometry of the blend shape.
+uniform highp float uBlendShapeUnnormalizeFactor; ///< Factor used to unnormalize the geometry of the blend shape.
#else
-uniform float uBlendShapeUnnormalizeFactor[MAX_BLEND_SHAPE_NUMBER]; ///< Factor used to unnormalize the geometry of the blend shape.
+uniform highp float uBlendShapeUnnormalizeFactor[MAX_BLEND_SHAPE_NUMBER]; ///< Factor used to unnormalize the geometry of the blend shape.
#endif
-uniform float uBlendShapeComponentSize; ///< The size in the texture of either the vertices, normals or tangents. Used to calculate the offset to address them.
+uniform highp float uBlendShapeComponentSize; ///< The size in the texture of either the vertices, normals or tangents. Used to calculate the offset to address them.
#endif
void main()
#ifdef MORPH
int width = textureSize( sBlendShapeGeometry, 0 ).x;
- int blendShapeBufferOffset = 0;
- int blendShapeComponentSize = int(uBlendShapeComponentSize);
+ highp int blendShapeBufferOffset = 0;
+ highp int blendShapeComponentSize = int(uBlendShapeComponentSize);
int numberOfBlendShapes = int(uNumberOfBlendShapes);
for( int index = 0; index < numberOfBlendShapes; ++index )
{
highp vec3 diff = vec3(0.0);
+ highp int vertexId = 0;
+ highp int x = 0;
+ highp int y = 0;
#ifdef MORPH_POSITION
// Calculate the index to retrieve the geometry from the texture.
- int vertexId = gl_VertexID + blendShapeBufferOffset;
- int x = vertexId % width;
- int y = vertexId / width;
+ vertexId = gl_VertexID + blendShapeBufferOffset;
+ x = vertexId % width;
+ y = vertexId / width;
// Retrieves the blend shape geometry from the texture, unnormalizes it and multiply by the weight.
if( 0.0 != uBlendShapeWeight[index] )
{
#ifdef MORPH_VERSION_2_0
- float unnormalizeFactor = uBlendShapeUnnormalizeFactor;
+ highp float unnormalizeFactor = uBlendShapeUnnormalizeFactor;
#else
- float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index];
+ highp float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index];
#endif
diff = uBlendShapeWeight[index] * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );
position = bone * position;
normal = (bone * vec4(normal, 0.0)).xyz;
tangent = (bone * vec4(tangent, 0.0)).xyz;
-#endif
+ normal = normalize(normal);
+ tangent = normalize(tangent);
+ highp vec4 positionW = position;
+#else
highp vec4 positionW = uModelMatrix * position;
+#endif
highp vec4 positionV = uViewMatrix * positionW;
vPositionToCamera = transpose(mat3(uViewMatrix)) * -vec3(positionV.xyz / positionV.w);
+++ /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();
- auto propJointMatrix = joint.GetPropertyIndex(Dali::Scene3D::Loader::Skinning::JOINT_MATRIX);
- boneData.constraint.AddSource(Source{joint, propJointMatrix});
- boneData.constraint.Apply();
- }
- 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
};
void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, const std::vector<MeshDefinition::BlendShape>& blendShapes, uint32_t numberOfVertices, float& blendShapeUnnormalizeFactor, BufferDefinition::Vector& buffers)
{
uint32_t geometryBufferIndex = 0u;
- float maxDistance = 0.f;
+ float maxDistanceSquared = 0.f;
Vector3* geometryBufferV3 = reinterpret_cast<Vector3*>(geometryBuffer);
for(const auto& blendShape : blendShapes)
{
Vector3& delta = geometryBufferV3[geometryBufferIndex++];
delta = deltasBuffer[index];
- maxDistance = std::max(maxDistance, delta.LengthSquared());
+ maxDistanceSquared = std::max(maxDistanceSquared, delta.LengthSquared());
}
}
}
}
geometryBufferIndex = 0u;
+
+ const float maxDistance = sqrtf(maxDistanceSquared);
+
+ const float normalizeFactor = (maxDistanceSquared < Math::MACHINE_EPSILON_1000) ? 1.f : (0.5f / maxDistance);
+
+ // Calculate and store the unnormalize factor.
+ blendShapeUnnormalizeFactor = maxDistance * 2.0f;
+
for(const auto& blendShape : blendShapes)
{
// Normalize all the deltas and translate to a possitive value.
// whose values that are less than zero are clamped.
if(blendShape.deltas.IsDefined())
{
- const float normalizeFactor = (fabsf(maxDistance) < Math::MACHINE_EPSILON_1000) ? 1.f : (0.5f / sqrtf(maxDistance));
-
for(uint32_t index = 0u; index < numberOfVertices; ++index)
{
Vector3& delta = geometryBufferV3[geometryBufferIndex++];
delta.y = Clamp(((delta.y * normalizeFactor) + 0.5f), 0.f, 1.f);
delta.z = Clamp(((delta.z * normalizeFactor) + 0.5f), 0.f, 1.f);
}
-
- // Calculate and store the unnormalize factor.
- blendShapeUnnormalizeFactor = 1.f / normalizeFactor;
}
if(blendShape.normals.IsDefined())
ModelNode mRoot;
};
-bool IsAncestor(const SceneDefinition& scene, Index ancestor, Index node, Index rootHint = INVALID_INDEX)
-{
- bool isAncestor = false;
- while(node != rootHint && !isAncestor)
- {
- node = scene.GetNode(node)->mParentIdx;
- isAncestor = ancestor == node;
- }
- return isAncestor;
-}
-
-void InsertUniqueSorted(std::vector<Index>& data, Index value)
-{
- auto iInsert = std::lower_bound(data.begin(), data.end(), value);
- if(iInsert == data.end() || *iInsert != value)
- {
- data.insert(iInsert, value);
- }
-}
-
-void RemoveFromSorted(std::vector<Index>& data, Index value)
-{
- auto iRemove = std::lower_bound(data.begin(), data.end(), value);
- if(iRemove != data.end() && *iRemove == value)
- {
- data.erase(iRemove);
- }
-}
-
-Property::Index ConfigureJointMatrix(Actor actor, Actor ancestor, Property::Index propJointMatrix)
-{
- Actor parent = actor.GetParent();
- if(parent != ancestor)
- {
- propJointMatrix = ConfigureJointMatrix(parent, ancestor, propJointMatrix);
- }
-
- auto myPropJointMatrix = actor.GetPropertyIndex(Skinning::JOINT_MATRIX);
- if(myPropJointMatrix == Property::INVALID_INDEX)
- {
- myPropJointMatrix = actor.RegisterProperty(Skinning::JOINT_MATRIX, Matrix{false});
- Constraint constraint = Constraint::New<Matrix>(actor, propJointMatrix, [](Matrix& output, const PropertyInputContainer& inputs) {
- Matrix jointMatrix{false};
- jointMatrix.SetTransformComponents(Vector3::ONE, inputs[0]->GetQuaternion(), inputs[1]->GetVector3());
-
- Matrix::Multiply(output, jointMatrix, inputs[2]->GetMatrix());
- });
- constraint.AddSource(Source{actor, Actor::Property::ORIENTATION});
- constraint.AddSource(Source{actor, Actor::Property::POSITION});
- constraint.AddSource(Source{parent, propJointMatrix});
- constraint.Apply();
- }
-
- return myPropJointMatrix;
-}
-
void SortAndDeduplicateSkinningRequests(std::vector<SkinningShaderConfigurationRequest>& requests)
{
// Sort requests by shaders.
}
}
-void SceneDefinition::ConfigureSkeletonJoints(uint32_t iRoot, const SkeletonDefinition::Vector& skeletons, Actor root) const
-{
- // 1, For each skeleton, for each joint, walk upwards until we reach mNodes[iRoot]. If we do, record +1
- // to the refcount of each node we have visited, in our temporary registry. Those with refcount 1
- // are the leaves, while the most descendant node with the highest refcount is the root of the skeleton.
- std::map<Index, std::vector<Index>> rootsJoints;
- std::vector<Index> path;
- path.reserve(16);
- for(auto& s : skeletons)
- {
- std::map<uint32_t, uint32_t> jointRefs;
- for(auto& j : s.mJoints)
- {
- auto nodeIdx = j.mNodeIdx;
- do // Traverse upwards and record each node we have visited until we reach the scene root.
- {
- path.push_back(nodeIdx);
- if(nodeIdx == iRoot)
- {
- break;
- }
- auto node = GetNode(nodeIdx);
- nodeIdx = node->mParentIdx;
- } while(nodeIdx != INVALID_INDEX);
-
- if(nodeIdx == iRoot) // If the joint is in the correct scene, increment the reference count for all visited nodes.
- {
- for(auto i : path)
- {
- ++jointRefs[i];
- }
- }
-
- path.clear();
- }
-
- // Only record the skeleton if we have encountered the root of the current scene.
- if(jointRefs.empty())
- {
- continue;
- }
-
- Index root = s.mRootNodeIdx;
- uint32_t maxRef = 0;
- auto iFind = jointRefs.find(root);
- if(iFind != jointRefs.end())
- {
- maxRef = iFind->second;
- }
-
- std::vector<Index> joints;
- for(auto& j : jointRefs) // NOTE: jointRefs are sorted, so joints will also be.
- {
- // The most descendant node with the highest ref count is the root of the skeleton.
- if(j.second > maxRef || (j.second == maxRef && IsAncestor(*this, root, j.first, iRoot)))
- {
- maxRef = j.second;
-
- RemoveFromSorted(joints, root);
- root = j.first;
- }
- else if(j.second == 1) // This one's a leaf.
- {
- InsertUniqueSorted(joints, j.first);
- }
- }
-
- // Merge skeletons that share the same root.
- auto& finalJoints = rootsJoints[root];
- for(auto j : joints)
- {
- if(std::find_if(finalJoints.begin(), finalJoints.end(), [this, j, root](Index jj) {
- return IsAncestor(*this, j, jj, root);
- }) != finalJoints.end())
- {
- continue; // if the joint is found to be an ancestor of another joint already registered, move on.
- }
-
- auto i = j;
- while(i != root) // See if the current joint is a better leaf, i.e. descended from another leaf - which we'll then remove.
- {
- auto node = GetNode(i);
- i = node->mParentIdx;
-
- RemoveFromSorted(finalJoints, i);
- }
-
- InsertUniqueSorted(finalJoints, j);
- }
- }
-
- // 2, Merge records where one root joint is descendant of another. Handle leaf node changes - remove previous
- // leaf nodes that now have descendants, and add new ones.
- auto iRoots = rootsJoints.begin();
- auto iRootsEnd = rootsJoints.end();
- while(iRoots != iRootsEnd)
- {
- auto i = iRoots->first;
- bool merged = false;
- while(i != iRoot) // Starting with the root joint of the skeleton, traverse upwards.
- {
- auto node = GetNode(i);
- i = node->mParentIdx;
-
- auto iFind = rootsJoints.find(i);
- if(iFind != rootsJoints.end()) // Check if we've reached the root of another skeleton.
- {
- // Now find out which leaf of iFind is an ancestor, if any.
- auto iFindLeaf = std::find_if(iFind->second.begin(), iFind->second.end(), [this, iRoots, iFind](Index j) {
- return IsAncestor(*this, j, iRoots->first, iFind->first);
- });
- if(iFindLeaf != iFind->second.end())
- {
- iFind->second.erase(iFindLeaf); // Will no longer be a leaf -- remove it.
- }
-
- // Merge iRoots with iFind
- auto& targetJoints = iFind->second;
- if(iRoots->second.empty()) // The root is a leaf.
- {
- InsertUniqueSorted(targetJoints, iRoots->first);
- }
- else
- for(auto j : iRoots->second)
- {
- InsertUniqueSorted(targetJoints, j);
- }
-
- merged = true;
- break; // Traverse no more
- }
- }
-
- iRoots = merged ? rootsJoints.erase(iRoots) : std::next(iRoots);
- }
-
- // 3, For each root, register joint matrices and constraints
- for(const auto& r : rootsJoints)
- {
- auto node = GetNode(r.first);
- auto rootJoint = root.FindChildByName(node->mName);
- DALI_ASSERT_ALWAYS(!!rootJoint);
-
- DALI_ASSERT_DEBUG(rootJoint.GetPropertyIndex(Skinning::JOINT_MATRIX) == Property::INVALID_INDEX);
- auto propJointMatrix = rootJoint.RegisterProperty(Skinning::JOINT_MATRIX, Matrix{false});
- Constraint constraint = Constraint::New<Matrix>(rootJoint, propJointMatrix, [](Matrix& output, const PropertyInputContainer& inputs) {
- output.SetTransformComponents(Vector3::ONE, inputs[0]->GetQuaternion(), inputs[1]->GetVector3());
- });
- constraint.AddSource(Source(rootJoint, Actor::Property::ORIENTATION));
- constraint.AddSource(Source(rootJoint, Actor::Property::POSITION));
- constraint.Apply();
-
- for(const auto j : r.second)
- {
- node = GetNode(j);
- auto joint = rootJoint.FindChildByName(node->mName);
- ConfigureJointMatrix(joint, rootJoint, propJointMatrix);
- }
- }
-}
-
void SceneDefinition::EnsureUniqueSkinningShaderInstances(ResourceBundle& resources) const
{
std::map<Index, std::map<Index, std::vector<Index*>>> skinningShaderUsers;
StringCallback onError = DefaultErrorCallback) const;
/*
- * @brief Sets up joint matrix properties and constraints on actors that are involved in skeletal
- * animation (i.e. those that are between (inclusive) the lower and upper bounds of any skeleton),
- * to ensure the correct update of meshes skinned to these skeletons.
- * @param iRoot The index of the scene root node. Skeletons that aren't descendants of this node
- * will be ignored.
- * @param skeletons The list of skeletons that require setting up.
- * @param rootActor The Actor corresponding to the root node, which will be used to locate
- * other actors.
- */
- void ConfigureSkeletonJoints(uint32_t iRoot, const SkeletonDefinition::Vector& skeletons, Actor rootActor) const;
-
- /*
* @brief Ensures that there is no overlap between shaders used by nodes that have
* meshes skinned to different skeletons.
*/
const unsigned int Skinning::MAX_JOINTS = 64;
const char* Skinning::BONE_UNIFORM_NAME = "uBone";
-const char* Skinning::JOINT_MATRIX = "jointMatrix";
} // namespace Dali::Scene3D::Loader
* @brief Name of bone matrix uniform (array).
*/
static const char* BONE_UNIFORM_NAME;
- static const char* JOINT_MATRIX;
Skinning() = delete;
};
control.OffSceneSignal().Connect(mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection);
Dali::Toolkit::Control previousFocusControl = GetCurrentFocusControl();
+
+ // Set control to currentFocusControl
+ mCurrentFocusControl = control;
+
if(previousFocusControl)
{
// Notify the control that it has lost key input focus
GetImplementation(previousFocusControl).OnKeyInputFocusLost();
}
- // Set control to currentFocusControl
- mCurrentFocusControl = control;
-
// Tell the new actor that it has gained focus.
GetImplementation(control).OnKeyInputFocusGained();
{
control.OffSceneSignal().Disconnect(mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection);
+ mCurrentFocusControl.Reset();
+
// Notify the control that it has lost key input focus
GetImplementation(control).OnKeyInputFocusLost();
-
- mCurrentFocusControl.Reset();
}
}
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 22;
+const unsigned int TOOLKIT_MICRO_VERSION = 23;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.2.22
+Version: 2.2.23
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT