Fix transform issue of skinned mesh 33/291533/8
authorseungho baek <sbsh.baek@samsung.com>
Tue, 18 Apr 2023 05:47:24 +0000 (14:47 +0900)
committerseungho baek <sbsh.baek@samsung.com>
Wed, 19 Apr 2023 09:49:32 +0000 (18:49 +0900)
Change-Id: I5acd990e1e1ae586a0b6c66af3aefc99c991e206
Signed-off-by: seungho baek <sbsh.baek@samsung.com>
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
dali-scene3d/internal/controls/model/model-impl.cpp
dali-scene3d/internal/graphics/shaders/default-physically-based-shader.vert
dali-scene3d/internal/model-components/model-node-data-impl.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

index d1be30484e277c99a1d90b0d2bba574586e0f600..fa6b480b6ef9ea324b6e496808ab086f4d4188b3 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 e23616e41696792dbca6daffe716549503b47c72..acfa4ea84f0e02ef46d0e1d14cde1c9248b4d8a9 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 a40ccaca98df3b64f28fbb89e985e83adddeac1a..1f274d060587ac7b6169188e9c1b5cf51294eea3 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 2f29b255210b187779abee1bbc8b24f3f9ab4ec2..be1b7925d05c97a7c5d189d44762d02c66723a5a 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 4161b3a0289f0eee7e5bb81856559cfa55a9ac85..35323d3493d27941cfd87ab4b20e3a1fdf8c4f58 100644 (file)
@@ -140,9 +140,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);
index 308dad90d3448b37cf31e330c8da803d33a99ff5..c1d3dbd315b5e984f2839a7fd4c9604fa1d9caa1 100644 (file)
@@ -247,10 +247,9 @@ void ModelNode::Impl::UpdateBoneMatrix(Scene3D::ModelPrimitive primitive)
       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();
+      Actor joint = mModelNodeImpl.Self();
+      boneData.constraint.AddSource(Source{joint, Actor::Property::WORLD_MATRIX});
+      boneData.constraint.ApplyPost();
     }
     break;
   }
index 8cc538545126bdbeb3e2557de98d130005f4757b..b1617de5fc6d8af540ebb212cfdd9062cd897520 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 06d24dbb35163f98870a35df101aa1df1c13f931..312b9e601e1a57e5ead340f6175e6ec2c52f3be0 100644 (file)
@@ -198,18 +198,6 @@ public: // METHODS
                         std::vector<ConstraintRequest>&& constrainables,
                         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 fc18d40f3454ef75cea647218148830ef17cc6fe..0e5e499ac02e316b54a3444a633f6f6f970fc6d6 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 ca0bdc2514e69fe5ca38e3a07ed1e027d2c52494..59f778a1606217984d0661c496caab9f7a18862e 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;
 };