From: seungho baek Date: Mon, 12 Dec 2022 05:26:05 +0000 (+0900) Subject: Allow duplicated name and use Actor ID as a unique key to define animation. X-Git-Tag: dali_2.2.7~16^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F92%2F285392%2F11;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git Allow duplicated name and use Actor ID as a unique key to define animation. - We don't need to make crash when multiple nodes had same name. - DALi actor also allows duplicated name. - Because name is not an unique key, make AnimationDefinition use Actor ID as a key.(for glTF) - glTF don't use name as a key. Change-Id: Ibcb3e21640cf2a8124bb450b73159eeaf1cdf4f3 Signed-off-by: seungho baek --- diff --git a/automated-tests/resources/AnimatedCube.gltf b/automated-tests/resources/AnimatedCube.gltf index 455120d..7787c04 100644 --- a/automated-tests/resources/AnimatedCube.gltf +++ b/automated-tests/resources/AnimatedCube.gltf @@ -322,7 +322,7 @@ }, { "mesh" : 1, - "name" : "AnimatedCube2" + "name" : "AnimatedCube" }, { diff --git a/automated-tests/resources/BoxAnimated.gltf b/automated-tests/resources/BoxAnimated.gltf index afa7afb..82e9702 100644 --- a/automated-tests/resources/BoxAnimated.gltf +++ b/automated-tests/resources/BoxAnimated.gltf @@ -14,6 +14,7 @@ ], "nodes": [ { + "name" : "node0", "children": [ 1 ], @@ -25,11 +26,13 @@ ] }, { + "name" : "node1", "children": [ 2 ] }, { + "name" : "node2", "mesh": 0, "rotation": [ -0.0, @@ -39,6 +42,7 @@ ] }, { + "name" : "node3", "mesh": 1 } ], diff --git a/automated-tests/src/dali-scene3d/utc-Dali-AnimatedProperty.cpp b/automated-tests/src/dali-scene3d/utc-Dali-AnimatedProperty.cpp index 0a59e26..6c4502f 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-AnimatedProperty.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-AnimatedProperty.cpp @@ -31,6 +31,7 @@ int UtcDaliAnimatedPropertyGetPropertyType(void) actor.SetProperty(Actor::Property::NAME, "ChristopherPlummer"); AnimatedProperty animProp { + INVALID_INDEX, "ChristopherPlummer", "position", KeyFrames(), diff --git a/automated-tests/src/dali-scene3d/utc-Dali-AnimationDefinition.cpp b/automated-tests/src/dali-scene3d/utc-Dali-AnimationDefinition.cpp index 5cde1b9..99b0aaf 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-AnimationDefinition.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-AnimationDefinition.cpp @@ -44,8 +44,8 @@ int UtcDaliAnimationDefinitionReAnimate(void) auto actor = Actor::New(); actor.SetProperty(Actor::Property::NAME, "ChristopherPlummer"); - auto getActor = [&actor](const std::string& name) { - return actor.FindChildByName(name); + auto getActor = [&actor](const Dali::Scene3D::Loader::AnimatedProperty& property) { + return actor.FindChildByName(property.mNodeName); }; for (bool b: { false, true }) @@ -57,6 +57,7 @@ int UtcDaliAnimationDefinitionReAnimate(void) animDef.mEndAction = Animation::BAKE_FINAL; animDef.mSpeedFactor = .7f; animDef.mProperties.push_back(AnimatedProperty{ + INVALID_INDEX, "ChristopherPlummer", "position", KeyFrames(), @@ -84,8 +85,8 @@ int UtcDaliAnimationDefinitionReAnimateKeyFrames(void) auto actor = Actor::New(); actor.SetProperty(Actor::Property::NAME, "ChristopherPlummer"); - auto getActor = [&actor](const std::string& name) { - return actor.FindChildByName(name); + auto getActor = [&actor](const Dali::Scene3D::Loader::AnimatedProperty& property) { + return actor.FindChildByName(property.mNodeName); }; KeyFrames kf = KeyFrames::New(); @@ -99,6 +100,7 @@ int UtcDaliAnimationDefinitionReAnimateKeyFrames(void) animDef.mEndAction = Animation::BAKE_FINAL; animDef.mSpeedFactor = .7f; animDef.mProperties.push_back(AnimatedProperty{ + INVALID_INDEX, "ChristopherPlummer", "position", kf, diff --git a/automated-tests/src/dali-scene3d/utc-Dali-BvhLoader.cpp b/automated-tests/src/dali-scene3d/utc-Dali-BvhLoader.cpp index 91fdb19..db5f525 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-BvhLoader.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-BvhLoader.cpp @@ -57,8 +57,8 @@ int UtcDaliLoadBvh(void) first.SetProperty(Actor::Property::NAME, "first"); root.Add(first); - auto getActor = [&root](const std::string& name) { - return root.FindChildByName(name); + auto getActor = [&root](const Dali::Scene3D::Loader::AnimatedProperty& property) { + return root.FindChildByName(property.mNodeName); }; Animation animation = animDef.ReAnimate(getActor); diff --git a/automated-tests/src/dali-scene3d/utc-Dali-DliLoader.cpp b/automated-tests/src/dali-scene3d/utc-Dali-DliLoader.cpp index c663327..9d67ab4 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-DliLoader.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-DliLoader.cpp @@ -169,7 +169,6 @@ int UtcDaliDliLoaderLoadSceneAssertions(void) {"node-renderable-mesh-invalid-type", "Invalid Mesh index type"}, {"node-renderable-mesh-out-of-bounds", "out of bounds"}, {"node-child-invalid-type", "invalid index type"}, - {"node-name-already-used", "name already used"}, // from ParseAnimations() {"animation-failed-to-open", "Failed to open animation data"}}; for(auto& i : pathExceptionPairs) diff --git a/automated-tests/src/dali-scene3d/utc-Dali-FacialAnimation.cpp b/automated-tests/src/dali-scene3d/utc-Dali-FacialAnimation.cpp index 22692e0..2e97dc9 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-FacialAnimation.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-FacialAnimation.cpp @@ -77,8 +77,8 @@ int UtcDaliLoadFacialAnimation(void) actor.RegisterProperty(weightName, 0.0f); } - auto getActor = [&actor](const std::string& name) { - return actor.FindChildByName(name); + auto getActor = [&actor](const Dali::Scene3D::Loader::AnimatedProperty& property) { + return actor.FindChildByName(property.mNodeName); }; auto anim = animDef.ReAnimate(getActor); diff --git a/automated-tests/src/dali-scene3d/utc-Dali-Gltf2Loader.cpp b/automated-tests/src/dali-scene3d/utc-Dali-Gltf2Loader.cpp index eb19c4d..f7f20cd 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-Gltf2Loader.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-Gltf2Loader.cpp @@ -546,3 +546,59 @@ int UtcDaliGltfLoaderMRendererTest(void) END_TEST; } + + +int UtcDaliGltfLoaderAnimationLoadingTest(void) +{ + Context ctx; + + ShaderDefinitionFactory sdf; + sdf.SetResources(ctx.resources); + auto& resources = ctx.resources; + + LoadGltfScene(TEST_RESOURCE_DIR "/BoxAnimated.gltf", sdf, ctx.loadResult); + + auto& scene = ctx.scene; + auto& roots = scene.GetRoots(); + DALI_TEST_EQUAL(roots.size(), 1u); + + ViewProjection viewProjection; + Transforms xforms{ + MatrixStack{}, + viewProjection}; + NodeDefinition::CreateParams nodeParams{ + resources, + xforms, + }; + + Customization::Choices choices; + + TestApplication app; + + Actor root = Actor::New(); + SetActorCentered(root); + for(auto iRoot : roots) + { + auto resourceRefs = resources.CreateRefCounter(); + scene.CountResourceRefs(iRoot, choices, resourceRefs); + resources.CountEnvironmentReferences(resourceRefs); + resources.LoadResources(resourceRefs, 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); + } + } + + DALI_TEST_EQUAL(ctx.loadResult.mAnimationDefinitions.size(), 1u); + DALI_TEST_EQUAL(ctx.loadResult.mAnimationDefinitions[0].mProperties.size(), 2u); + + uint32_t id = ctx.loadResult.mScene.GetNode(ctx.loadResult.mAnimationDefinitions[0].mProperties[0].mNodeIndex)->mNodeId; + DALI_TEST_EQUAL(id, root.FindChildByName("node2").GetProperty(Dali::Actor::Property::ID)); + uint32_t id2 = ctx.loadResult.mScene.GetNode(ctx.loadResult.mAnimationDefinitions[0].mProperties[1].mNodeIndex)->mNodeId; + DALI_TEST_EQUAL(id2, root.FindChildByName("node0").GetProperty(Dali::Actor::Property::ID)); + + END_TEST; +} diff --git a/automated-tests/src/dali-scene3d/utc-Dali-NodeDefinition.cpp b/automated-tests/src/dali-scene3d/utc-Dali-NodeDefinition.cpp index 415e2e1..2b7c319 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-NodeDefinition.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-NodeDefinition.cpp @@ -101,6 +101,7 @@ int UtcDaliNodeDefinitionProperties(void) TestApplication testApp; NodeDefinition nodeDef{ "testRootNode", + INVALID_INDEX, Vector3{-100.f, 100.f, -500.f}, Quaternion{Radian(Degree(45.f)), Vector3::ZAXIS}, Vector3{2.f, 4.f, 8.f}, diff --git a/automated-tests/src/dali-scene3d/utc-Dali-SceneDefinition.cpp b/automated-tests/src/dali-scene3d/utc-Dali-SceneDefinition.cpp index dc2fc92..e7126eb 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-SceneDefinition.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-SceneDefinition.cpp @@ -42,10 +42,9 @@ int UtcDaliSceneDefinitionAddNode(void) auto node2 = new NodeDefinition(); node2->mName = node->mName; result = sceneDef.AddNode(std::unique_ptr{ node2 }); - DALI_TEST_EQUAL(result, static_cast(nullptr)); // failed - DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 1u); // still - DALI_TEST_EQUAL(sceneDef.GetNode(0), node); // still - DALI_TEST_EQUAL(sceneDef.FindNode(node->mName), node); // still + DALI_TEST_EQUAL(result, node2); + DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 2u); + DALI_TEST_EQUAL(sceneDef.GetNode(1), node2); auto child = new NodeDefinition(); child->mName = "Second"; @@ -55,11 +54,11 @@ int UtcDaliSceneDefinitionAddNode(void) result = sceneDef.AddNode(std::unique_ptr{ child }); DALI_TEST_EQUAL(result, child); - DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 2u); - DALI_TEST_EQUAL(sceneDef.GetNode(1), child); + DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 3u); + DALI_TEST_EQUAL(sceneDef.GetNode(2), child); DALI_TEST_EQUAL(sceneDef.FindNode(child->mName), child); - DALI_TEST_EQUAL(node->mChildren[0], 1u); // these are hooked up by AddNode, base on parent idx. + DALI_TEST_EQUAL(node->mChildren[0], 2u); // these are hooked up by AddNode, base on parent idx. END_TEST; } diff --git a/dali-scene3d/internal/controls/model/model-impl.cpp b/dali-scene3d/internal/controls/model/model-impl.cpp index 73f1248..8b95f82 100644 --- a/dali-scene3d/internal/controls/model/model-impl.cpp +++ b/dali-scene3d/internal/controls/model/model-impl.cpp @@ -507,8 +507,8 @@ void Model::LoadModel() if(!animations.empty()) { - auto getActor = [&](const std::string& name) { - return mModelRoot.FindChildByName(name); + auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property) { + return mModelRoot.FindChildById(scene.GetNode(property.mNodeIndex)->mNodeId); }; mAnimations.clear(); diff --git a/dali-scene3d/public-api/loader/animated-property.cpp b/dali-scene3d/public-api/loader/animated-property.cpp index 5f15815..83ae2df 100644 --- a/dali-scene3d/public-api/loader/animated-property.cpp +++ b/dali-scene3d/public-api/loader/animated-property.cpp @@ -24,7 +24,7 @@ namespace Loader { void AnimatedProperty::Animate(Animation& anim, GetActor getActor) { - if(Actor actor = getActor(mNodeName)) + if(Actor actor = getActor(*this)) { Property prop = GetProperty(actor); if(mKeyFrames) diff --git a/dali-scene3d/public-api/loader/animated-property.h b/dali-scene3d/public-api/loader/animated-property.h index 6433d5c..87fe87a 100644 --- a/dali-scene3d/public-api/loader/animated-property.h +++ b/dali-scene3d/public-api/loader/animated-property.h @@ -19,6 +19,8 @@ // INTERNAL INCLUDES #include "dali-scene3d/public-api/api.h" +#include "dali-scene3d/public-api/loader/index.h" + // EXTERNAL INCLUDES #include @@ -44,10 +46,10 @@ struct DALI_SCENE3D_API AnimatedProperty { public: // METHODS /** - * @brief Function to obtain an Actor based on its name. Its processing will + * @brief Function to obtain an Actor based on its property. Its processing will * ignore empty handles returned by it. */ - using GetActor = std::function; + using GetActor = std::function; /** * @return The Property object (of the given @a actor) whose value is being animated. @@ -82,6 +84,7 @@ public: // DATA bool mIsRelative; }; + Index mNodeIndex = INVALID_INDEX; std::string mNodeName; std::string mPropertyName; diff --git a/dali-scene3d/public-api/loader/gltf2-loader.cpp b/dali-scene3d/public-api/loader/gltf2-loader.cpp index 75d7ad0..dc0eb8a 100644 --- a/dali-scene3d/public-api/loader/gltf2-loader.cpp +++ b/dali-scene3d/public-api/loader/gltf2-loader.cpp @@ -951,7 +951,7 @@ float LoadKeyFrames(const std::string& path, const gt::Animation::Channel& chann return duration; } -float LoadBlendShapeKeyFrames(const std::string& path, const gt::Animation::Channel& channel, const std::string& nodeName, uint32_t& propertyIndex, std::vector& properties) +float LoadBlendShapeKeyFrames(const std::string& path, const gt::Animation::Channel& channel, Index nodeIndex, uint32_t& propertyIndex, std::vector& properties) { const gltf2::Accessor& input = *channel.mSampler->mInput; const gltf2::Accessor& output = *channel.mSampler->mOutput; @@ -969,7 +969,7 @@ float LoadBlendShapeKeyFrames(const std::string& path, const gt::Animation::Chan { AnimatedProperty& animatedProperty = properties[propertyIndex++]; - animatedProperty.mNodeName = nodeName; + animatedProperty.mNodeIndex = nodeIndex; snprintf(pWeightName, remainingSize, "%d]", weightIndex); animatedProperty.mPropertyName = std::string(weightNameBuffer); @@ -1001,27 +1001,23 @@ void ConvertAnimations(const gt::Document& doc, ConversionContext& context) } uint32_t numberOfProperties = 0u; - - for(const auto& channel : animation.mChannels) - { - numberOfProperties += channel.mSampler->mOutput->mCount; - } - animationDef.mProperties.resize(numberOfProperties); - - Index propertyIndex = 0u; for(const auto& channel : animation.mChannels) { - std::string nodeName; - if(!channel.mTarget.mNode->mName.empty()) + if(channel.mTarget.mPath == gt::Animation::Channel::Target::WEIGHTS) { - nodeName = channel.mTarget.mNode->mName; + numberOfProperties += channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount; } else { - Index index = context.mNodeIndices.GetRuntimeId(channel.mTarget.mNode.GetIndex()); - nodeName = context.mOutput.mScene.GetNode(index)->mName; + numberOfProperties++; } + } + animationDef.mProperties.resize(numberOfProperties); + Index propertyIndex = 0u; + for(const auto& channel : animation.mChannels) + { + Index nodeIndex = context.mNodeIndices.GetRuntimeId(channel.mTarget.mNode.GetIndex()); float duration = 0.f; switch(channel.mTarget.mPath) @@ -1030,7 +1026,7 @@ void ConvertAnimations(const gt::Document& doc, ConversionContext& context) { AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; - animatedProperty.mNodeName = nodeName; + animatedProperty.mNodeIndex = nodeIndex; animatedProperty.mPropertyName = POSITION_PROPERTY; animatedProperty.mKeyFrames = KeyFrames::New(); @@ -1043,7 +1039,7 @@ void ConvertAnimations(const gt::Document& doc, ConversionContext& context) { AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; - animatedProperty.mNodeName = nodeName; + animatedProperty.mNodeIndex = nodeIndex; animatedProperty.mPropertyName = ORIENTATION_PROPERTY; animatedProperty.mKeyFrames = KeyFrames::New(); @@ -1056,7 +1052,7 @@ void ConvertAnimations(const gt::Document& doc, ConversionContext& context) { AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; - animatedProperty.mNodeName = nodeName; + animatedProperty.mNodeIndex = nodeIndex; animatedProperty.mPropertyName = SCALE_PROPERTY; animatedProperty.mKeyFrames = KeyFrames::New(); @@ -1067,7 +1063,7 @@ void ConvertAnimations(const gt::Document& doc, ConversionContext& context) } case gt::Animation::Channel::Target::WEIGHTS: { - duration = LoadBlendShapeKeyFrames(context.mPath, channel, nodeName, propertyIndex, animationDef.mProperties); + duration = LoadBlendShapeKeyFrames(context.mPath, channel, nodeIndex, propertyIndex, animationDef.mProperties); break; } diff --git a/dali-scene3d/public-api/loader/node-definition.cpp b/dali-scene3d/public-api/loader/node-definition.cpp index bbed301..cd32bc7 100644 --- a/dali-scene3d/public-api/loader/node-definition.cpp +++ b/dali-scene3d/public-api/loader/node-definition.cpp @@ -63,9 +63,11 @@ void NodeDefinition::Renderable::OnCreate(const NodeDefinition& node, CreatePara const std::string NodeDefinition::ORIGINAL_MATRIX_PROPERTY_NAME = "originalMatrix"; -Actor NodeDefinition::CreateActor(CreateParams& params) const +Actor NodeDefinition::CreateActor(CreateParams& params) { Actor actor = Actor::New(); + mNodeId = actor.GetProperty(Dali::Actor::Property::ID); + SetActorCentered(actor); actor.SetProperty(Actor::Property::NAME, mName); diff --git a/dali-scene3d/public-api/loader/node-definition.h b/dali-scene3d/public-api/loader/node-definition.h index fde74e2..d713ed5 100644 --- a/dali-scene3d/public-api/loader/node-definition.h +++ b/dali-scene3d/public-api/loader/node-definition.h @@ -218,7 +218,7 @@ public: // METHODS * @brief Creates a DALi Actor from this definition only. * @note Not recursive. */ - Actor CreateActor(CreateParams& params) const; + Actor CreateActor(CreateParams& params); /** * @brief Gets local space matrix of this node @@ -253,6 +253,7 @@ public: // DATA static const std::string ORIGINAL_MATRIX_PROPERTY_NAME; std::string mName; + uint32_t mNodeId = INVALID_INDEX; Vector3 mPosition = Vector3::ZERO; Quaternion mOrientation = Quaternion::IDENTITY; diff --git a/dali-scene3d/public-api/loader/scene-definition.cpp b/dali-scene3d/public-api/loader/scene-definition.cpp index a117e1e..b6a2743 100644 --- a/dali-scene3d/public-api/loader/scene-definition.cpp +++ b/dali-scene3d/public-api/loader/scene-definition.cpp @@ -164,7 +164,7 @@ void AddJointDebugVisual(Actor aJoint) } #endif //DEBUG_JOINTS -class ActorCreatorVisitor : public NodeDefinition::IConstVisitor +class ActorCreatorVisitor : public NodeDefinition::IVisitor { public: ActorCreatorVisitor(NodeDefinition::CreateParams& params) @@ -172,7 +172,7 @@ public: { } - void Start(const NodeDefinition& n) + void Start(NodeDefinition& n) { mCreationContext.mXforms.modelStack.Push(n.GetLocalSpace()); @@ -188,7 +188,7 @@ public: mActorStack.push_back(a); } - void Finish(const NodeDefinition& n) + void Finish(NodeDefinition& n) { mActorStack.pop_back(); mCreationContext.mXforms.modelStack.Pop(); @@ -469,7 +469,7 @@ void SceneDefinition::CountResourceRefs(Index iNode, const Customization::Choice Visit(iNode, choices, refCounterVisitor); } -Actor SceneDefinition::CreateNodes(Index iNode, const Customization::Choices& choices, NodeDefinition::CreateParams& params) const +Actor SceneDefinition::CreateNodes(Index iNode, const Customization::Choices& choices, NodeDefinition::CreateParams& params) { ActorCreatorVisitor actorCreatorVisitor(params); @@ -526,11 +526,6 @@ void SceneDefinition::GetCustomizationOptions(const Customization::Choices& choi NodeDefinition* SceneDefinition::AddNode(std::unique_ptr&& nodeDef) { - if(!nodeDef->mName.empty() && FindNode(nodeDef->mName)) - { - return nullptr; - } - // add next index (to which we're about to push) as a child to the designated parent, if any. if(nodeDef->mParentIdx != INVALID_INDEX) { diff --git a/dali-scene3d/public-api/loader/scene-definition.h b/dali-scene3d/public-api/loader/scene-definition.h index 0f40f5b..ecb5cff 100644 --- a/dali-scene3d/public-api/loader/scene-definition.h +++ b/dali-scene3d/public-api/loader/scene-definition.h @@ -113,7 +113,7 @@ public: // METHODS * from node definitions. * @return Handle to the root actor. */ - Actor CreateNodes(Index iNode, const Customization::Choices& choices, NodeDefinition::CreateParams& params) const; + Actor CreateNodes(Index iNode, const Customization::Choices& choices, NodeDefinition::CreateParams& params); /* * @brief Creates / update a registry of mappings from customization tags to