X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=dali-scene3d%2Fpublic-api%2Floader%2Fscene-definition.cpp;h=b1617de5fc6d8af540ebb212cfdd9062cd897520;hb=a1165ab956b5f3493266ba4b7cad4625e50effed;hp=8cc538545126bdbeb3e2557de98d130005f4757b;hpb=5feee171a62b20f7d7b8cd1bcfdf5abb79bdd524;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-scene3d/public-api/loader/scene-definition.cpp b/dali-scene3d/public-api/loader/scene-definition.cpp index 8cc5385..b1617de 100644 --- a/dali-scene3d/public-api/loader/scene-definition.cpp +++ b/dali-scene3d/public-api/loader/scene-definition.cpp @@ -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& 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& 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(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& 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> rootsJoints; - std::vector path; - path.reserve(16); - for(auto& s : skeletons) - { - std::map 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 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(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>> skinningShaderUsers;