Merge branch 'devel/master' into tizen accepted/tizen/unified/20230428.155101
authorjoogab.yun <joogab.yun@samsung.com>
Wed, 26 Apr 2023 05:38:43 +0000 (14:38 +0900)
committerjoogab.yun <joogab.yun@samsung.com>
Wed, 26 Apr 2023 05:38:43 +0000 (14:38 +0900)
Change-Id: I5e52e498d72a8d7eb3362cada5044dd17aaa1693

22 files changed:
automated-tests/resources/dli_pbr.vsh
automated-tests/src/dali-scene3d-internal/utc-Dali-DliLoaderImpl.cpp
automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp
automated-tests/src/dali-scene3d/utc-Dali-ModelNode.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-gl-abstraction.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-graphics-controller.cpp
dali-scene3d/internal/controls/model/model-impl.cpp
dali-scene3d/internal/file.list
dali-scene3d/internal/graphics/shaders/default-physically-based-shader.vert
dali-scene3d/internal/model-components/model-node-data-impl.cpp [deleted file]
dali-scene3d/internal/model-components/model-node-data-impl.h [deleted file]
dali-scene3d/internal/model-components/model-node-impl.cpp
dali-scene3d/internal/model-components/model-node-impl.h
dali-scene3d/public-api/loader/mesh-definition.cpp
dali-scene3d/public-api/loader/scene-definition.cpp
dali-scene3d/public-api/loader/scene-definition.h
dali-scene3d/public-api/loader/skinning-details.cpp
dali-scene3d/public-api/loader/skinning-details.h
dali-toolkit/internal/focus-manager/keyinput-focus-manager-impl.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index d1be304..fa6b480 100644 (file)
@@ -128,9 +128,13 @@ void main()
   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
index e23616e..acfa4ea 100644 (file)
@@ -231,7 +231,6 @@ int UtcDaliDliLoaderLoadSceneExercise(void)
     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));
@@ -350,7 +349,6 @@ int UtcDaliDliLoaderLoadSceneMorph(void)
     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));
@@ -415,7 +413,6 @@ int UtcDaliDliLoaderLoadSceneArc(void)
     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));
@@ -696,7 +693,6 @@ int UtcDaliDliLoaderLoadCoverageTest(void)
     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));
index a40ccac..1f274d0 100644 (file)
@@ -616,7 +616,6 @@ int UtcDaliGltfLoaderMRendererTest(void)
     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);
@@ -672,7 +671,6 @@ int UtcDaliGltfLoaderAnimationLoadingTest(void)
     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);
@@ -726,7 +724,6 @@ int UtcDaliGltfLoaderImageFromBufferView(void)
     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);
@@ -776,7 +773,6 @@ int UtcDaliGltfLoaderUint8Indices(void)
     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);
index e124bc6..3aaecc6 100644 (file)
@@ -21,6 +21,7 @@
 #include <iostream>
 
 #include <dali-scene3d/public-api/model-components/model-node.h>
+#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;
+}
index 7d0c661..56b3b5e 100644 (file)
@@ -268,8 +268,20 @@ void Impl::DummyControl::OnChildRemove(Actor& child) { childRemoveCalled = true;
 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 )
 {
index 7ba7834..834ae6f 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -1893,10 +1893,26 @@ public:
 
   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
@@ -1981,6 +1997,12 @@ public:
 
   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
index 319ec67..3cc464c 100644 (file)
@@ -712,9 +712,19 @@ void TestGraphicsController::ProcessCommandBuffer(TestGraphicsCommandBuffer& com
       {
         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;
       }
@@ -722,10 +732,21 @@ void TestGraphicsController::ProcessCommandBuffer(TestGraphicsCommandBuffer& com
       {
         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;
       }
@@ -983,12 +1004,22 @@ void TestGraphicsController::BindPipeline(TestGraphicsPipeline* pipeline)
     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
index 2f29b25..be1b792 100644 (file)
@@ -842,7 +842,6 @@ void Model::CreateModel()
   {
     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));
 
index 4921731..3706b72 100644 (file)
@@ -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
 )
index 4161b3a..5b48af0 100644 (file)
@@ -45,14 +45,14 @@ uniform mat4 uProjection;
 
 #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()
@@ -64,27 +64,30 @@ 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 );
@@ -140,9 +143,13 @@ void main()
   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);
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 (file)
index 308dad9..0000000
+++ /dev/null
@@ -1,263 +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 <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
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 (file)
index b19a82f..0000000
+++ /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 <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
index 60dca00..257cbd0 100644 (file)
 
 // 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
 {
@@ -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<Internal::ModelNode&>(customInterface);
+  ModelNode&       impl            = dynamic_cast<Internal::ModelNode&>(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<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)
@@ -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<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
index d216bb5..e3c718c 100644 (file)
@@ -24,7 +24,9 @@
 #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>
 
@@ -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<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.
@@ -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<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
 };
 
index a485e97..948cb89 100644 (file)
@@ -382,7 +382,7 @@ void CalculateTextureSize(uint32_t totalTextureSize, uint32_t& textureWidth, uin
 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)
   {
@@ -406,7 +406,7 @@ void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, const std::vector<MeshDe
           Vector3& delta = geometryBufferV3[geometryBufferIndex++];
           delta          = deltasBuffer[index];
 
-          maxDistance = std::max(maxDistance, delta.LengthSquared());
+          maxDistanceSquared = std::max(maxDistanceSquared, delta.LengthSquared());
         }
       }
     }
@@ -475,6 +475,14 @@ void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, const std::vector<MeshDe
   }
 
   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.
@@ -482,8 +490,6 @@ void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, const std::vector<MeshDe
     // 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++];
@@ -491,9 +497,6 @@ void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, const std::vector<MeshDe
         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())
index 8cc5385..b1617de 100644 (file)
@@ -207,62 +207,6 @@ private:
   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.
@@ -813,167 +757,6 @@ void SceneDefinition::ApplyConstraints(Actor&                           root,
   }
 }
 
-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;
index 06d24db..312b9e6 100644 (file)
@@ -199,18 +199,6 @@ public: // METHODS
                         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.
    */
index fc18d40..0e5e499 100644 (file)
@@ -28,5 +28,4 @@ namespace Dali::Scene3D::Loader
 const unsigned int Skinning::MAX_JOINTS = 64;
 
 const char* Skinning::BONE_UNIFORM_NAME = "uBone";
-const char* Skinning::JOINT_MATRIX      = "jointMatrix";
 } // namespace Dali::Scene3D::Loader
index ca0bdc2..59f778a 100644 (file)
@@ -50,7 +50,6 @@ public:
    * @brief Name of bone matrix uniform (array).
    */
   static const char* BONE_UNIFORM_NAME;
-  static const char* JOINT_MATRIX;
 
   Skinning() = delete;
 };
index ebdb214..88da9b7 100644 (file)
@@ -84,15 +84,16 @@ void KeyInputFocusManager::SetFocus(Toolkit::Control control)
   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();
 
@@ -109,10 +110,10 @@ void KeyInputFocusManager::RemoveFocus(Toolkit::Control control)
   {
     control.OffSceneSignal().Disconnect(mSlotDelegate, &KeyInputFocusManager::OnFocusControlSceneDisconnection);
 
+    mCurrentFocusControl.Reset();
+
     // Notify the control that it has lost key input focus
     GetImplementation(control).OnKeyInputFocusLost();
-
-    mCurrentFocusControl.Reset();
   }
 }
 
index 83149ec..54e78c2 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 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
index 711fa40..6236555 100644 (file)
@@ -1,6 +1,6 @@
 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