X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-scene3d%2Finternal%2Fcontrols%2Fmodel%2Fmodel-impl.cpp;h=acaccbfa74ba65b0644ecc74e8557dfc76d7fb05;hb=2116ad7b1ce51093a891ca6b3e83419b0b5b79dd;hp=73823d51bcd702c9c084a28e7c64af7419e3fa59;hpb=0d1a321056df3120e1896035e4a4f9617cc8a1a5;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-scene3d/internal/controls/model/model-impl.cpp b/dali-scene3d/internal/controls/model/model-impl.cpp index 73823d5..acaccbf 100644 --- a/dali-scene3d/internal/controls/model/model-impl.cpp +++ b/dali-scene3d/internal/controls/model/model-impl.cpp @@ -43,6 +43,7 @@ #include #include #include +#include using namespace Dali; @@ -118,8 +119,7 @@ void ConfigureBlendShapeShaders( Dali::Scene3D::Loader::ResourceBundle& resources, const Dali::Scene3D::Loader::SceneDefinition& scene, Actor root, std::vector&& requests) { std::vector errors; - auto onError = [&errors](const std::string& msg) - { errors.push_back(msg); }; + auto onError = [&errors](const std::string& msg) { errors.push_back(msg); }; if(!scene.ConfigureBlendshapeShaders(resources, root, std::move(requests), onError)) { Dali::Scene3D::Loader::ExceptionFlinger flinger(ASSERT_LOCATION); @@ -178,7 +178,6 @@ void AddLightRecursively(Scene3D::ModelNode node, Scene3D::Light light, uint32_t { return; } - GetImplementation(node).AddLight(light, lightIndex); uint32_t childrenCount = node.GetChildCount(); @@ -212,6 +211,27 @@ void RemoveLightRecursively(Scene3D::ModelNode node, uint32_t lightIndex) } } +void UpdateBlendShapeNodeMapRecursively(Model::BlendShapeModelNodeMap& resultMap, const Scene3D::ModelNode& node) +{ + if(!node) + { + return; + } + const auto childCount = node.GetChildCount(); + for(auto i = 0u; i < childCount; ++i) + { + UpdateBlendShapeNodeMapRecursively(resultMap, Scene3D::ModelNode::DownCast(node.GetChildAt(i))); + } + + std::vector blendShapeNames; + node.RetrieveBlendShapeNames(blendShapeNames); + for(const auto& iter : blendShapeNames) + { + // Append or create new list. + resultMap[iter].push_back(node); + } +} + } // anonymous namespace Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUrl) @@ -516,6 +536,229 @@ Scene3D::ModelNode Model::FindChildModelNodeByName(std::string_view nodeName) return Scene3D::ModelNode::DownCast(childActor); } +void Model::RetrieveBlendShapeNames(std::vector& blendShapeNames) const +{ + blendShapeNames.reserve(blendShapeNames.size() + mBlendShapeModelNodeMap.size()); + for(const auto& iter : mBlendShapeModelNodeMap) + { + blendShapeNames.push_back(iter.first); + } +} + +void Model::RetrieveModelNodesByBlendShapeName(std::string_view blendShapeName, std::vector& modelNodes) const +{ + auto iter = mBlendShapeModelNodeMap.find(std::string(blendShapeName)); + if(iter != mBlendShapeModelNodeMap.end()) + { + const auto& modelNodeList = iter->second; + modelNodes.reserve(modelNodes.size() + modelNodeList.size()); + for(const auto& nodeIter : modelNodeList) + { + modelNodes.push_back(nodeIter); + } + } +} + +Dali::Animation Model::GenerateMotionDataAnimation(Scene3D::MotionData motionData) +{ + Dali::Animation animation; + + // TODO : Collect duplicated codes. + + if(motionData) + { + const uint32_t motionCount = motionData.GetMotionCount(); + for(uint32_t i = 0u; i < motionCount; ++i) + { + auto motionIndex = motionData.GetIndex(i); + auto motionValue = motionData.GetValue(i); + if(motionIndex && motionValue) + { + if(motionIndex.GetModelNodeId() != Property::INVALID_KEY) + { + Scene3D::ModelNode modelNode; + if(motionIndex.GetModelNodeId().type == Property::Key::Type::STRING) + { + modelNode = FindChildModelNodeByName(motionIndex.GetModelNodeId().stringKey); + } + else if(motionIndex.GetModelNodeId().type == Property::Key::Type::INDEX) + { + // TODO : Not implement yet. + } + + if(modelNode) + { + KeyFrames keyFrames = motionValue.GetKeyFrames(); + + if(keyFrames) + { + // Try to use index first. If failed, try to use name + Property::Index animatedPropertyIndex = motionIndex.GetPropertyIndex(modelNode); + if(animatedPropertyIndex != Property::INVALID_INDEX) + { + if(DALI_UNLIKELY(!animation)) + { + animation = Animation::New(motionData.GetDuration()); + } + animation.AnimateBetween(Dali::Property(modelNode, animatedPropertyIndex), keyFrames); + } + else + { + std::string animatedPropertyName = motionIndex.GetPropertyName(modelNode); + Dali::Property property(modelNode, animatedPropertyName); + if(property.propertyIndex != Property::INVALID_INDEX) + { + if(DALI_UNLIKELY(!animation)) + { + animation = Animation::New(motionData.GetDuration()); + } + animation.AnimateBetween(property, keyFrames); + } + } + } + } + } + else + { + Scene3D::BlendShapeIndex blendShapeIndex = Scene3D::BlendShapeIndex::DownCast(motionIndex); + if(blendShapeIndex && blendShapeIndex.GetBlendShapeId().type == Property::Key::Type::STRING) + { + // Special case : For BlendShapeIndex that doesn't have ModelNodeId and has string BlendShapeId, + // we need to animate all kind of blendshapes + + KeyFrames keyFrames = motionValue.GetKeyFrames(); + + if(keyFrames) + { + std::vector modelNodes; + RetrieveModelNodesByBlendShapeName(blendShapeIndex.GetBlendShapeId().stringKey, modelNodes); + + for(auto& modelNode : modelNodes) + { + // Try to use index first. If failed, try to use name + Property::Index animatedPropertyIndex = motionIndex.GetPropertyIndex(modelNode); + if(animatedPropertyIndex != Property::INVALID_INDEX) + { + if(DALI_UNLIKELY(!animation)) + { + animation = Animation::New(motionData.GetDuration()); + } + animation.AnimateBetween(Dali::Property(modelNode, animatedPropertyIndex), keyFrames); + } + else + { + std::string animatedPropertyName = motionIndex.GetPropertyName(modelNode); + Dali::Property property(modelNode, animatedPropertyName); + + if(property.propertyIndex != Property::INVALID_INDEX) + { + if(DALI_UNLIKELY(!animation)) + { + animation = Animation::New(motionData.GetDuration()); + } + animation.AnimateBetween(property, keyFrames); + } + } + } + } + } + } + } + } + } + + return animation; +} + +void Model::SetMotionData(Scene3D::MotionData motionData) +{ + // TODO : Collect duplicated codes. + if(motionData) + { + const uint32_t motionCount = motionData.GetMotionCount(); + for(uint32_t i = 0u; i < motionCount; ++i) + { + auto motionIndex = motionData.GetIndex(i); + auto motionValue = motionData.GetValue(i); + if(motionIndex && motionValue) + { + if(motionIndex.GetModelNodeId() != Property::INVALID_KEY) + { + Scene3D::ModelNode modelNode; + if(motionIndex.GetModelNodeId().type == Property::Key::Type::STRING) + { + modelNode = FindChildModelNodeByName(motionIndex.GetModelNodeId().stringKey); + } + else if(motionIndex.GetModelNodeId().type == Property::Key::Type::INDEX) + { + // TODO : Not implement yet. + } + + if(modelNode) + { + Property::Value value = motionValue.GetPropertyValue(); + + if(value.GetType() != Property::Type::NONE) + { + // Try to use index first. If failed, try to use name + Property::Index propertyIndex = motionIndex.GetPropertyIndex(modelNode); + if(propertyIndex != Property::INVALID_INDEX) + { + modelNode.SetProperty(propertyIndex, value); + } + else + { + std::string propertyName = motionIndex.GetPropertyName(modelNode); + Dali::Property property(modelNode, propertyName); + if(property.propertyIndex != Property::INVALID_INDEX) + { + modelNode.SetProperty(property.propertyIndex, value); + } + } + } + } + } + else + { + Scene3D::BlendShapeIndex blendShapeIndex = Scene3D::BlendShapeIndex::DownCast(motionIndex); + if(blendShapeIndex && blendShapeIndex.GetBlendShapeId().type == Property::Key::Type::STRING) + { + // Special case : For BlendShapeIndex that doesn't have ModelNodeId and has string BlendShapeId, + // we need to animate all kind of blendshapes + + Property::Value value = motionValue.GetPropertyValue(); + + if(value.GetType() != Property::Type::NONE) + { + std::vector modelNodes; + RetrieveModelNodesByBlendShapeName(blendShapeIndex.GetBlendShapeId().stringKey, modelNodes); + + for(auto& modelNode : modelNodes) + { + // Try to use index first. If failed, try to use name + Property::Index propertyIndex = motionIndex.GetPropertyIndex(modelNode); + if(propertyIndex != Property::INVALID_INDEX) + { + modelNode.SetProperty(propertyIndex, value); + } + else + { + std::string propertyName = motionIndex.GetPropertyName(modelNode); + Dali::Property property(modelNode, propertyName); + if(property.propertyIndex != Property::INVALID_INDEX) + { + modelNode.SetProperty(property.propertyIndex, value); + } + } + } + } + } + } + } + } + } +} + /////////////////////////////////////////////////////////// // // Private methods @@ -941,19 +1184,21 @@ void Model::CreateModel() resources.GenerateResources(); for(auto iRoot : scene.GetRoots()) { - if(auto actor = scene.CreateNodes(iRoot, resourceChoices, nodeParams)) + if(auto modelNode = scene.CreateNodes(iRoot, resourceChoices, nodeParams)) { - scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables)); - ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests)); + scene.ConfigureSkinningShaders(resources, modelNode, std::move(nodeParams.mSkinnables)); + ConfigureBlendShapeShaders(resources, scene, modelNode, std::move(nodeParams.mBlendshapeRequests)); - scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables)); + scene.ApplyConstraints(modelNode, std::move(nodeParams.mConstrainables)); - mModelRoot.Add(actor); + mModelRoot.Add(modelNode); } AddModelTreeToAABB(AABB, scene, resourceChoices, iRoot, nodeParams, Matrix::IDENTITY); } + UpdateBlendShapeNodeMap(); + mNaturalSize = AABB.CalculateSize(); mModelPivot = AABB.CalculatePivot(); mModelRoot.SetProperty(Dali::Actor::Property::SIZE, mNaturalSize); @@ -971,8 +1216,7 @@ void Model::CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene) mAnimations.clear(); if(!mModelLoadTask->GetAnimations().empty()) { - auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property) - { + auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property) { if(property.mNodeIndex == Scene3D::Loader::INVALID_INDEX) { return mModelRoot.FindChildByName(property.mNodeName); @@ -1003,6 +1247,14 @@ void Model::ResetCameraParameters() } } +void Model::UpdateBlendShapeNodeMap() +{ + // Remove privous node map + mBlendShapeModelNodeMap.clear(); + + UpdateBlendShapeNodeMapRecursively(mBlendShapeModelNodeMap, mModelRoot); +} + } // namespace Internal } // namespace Scene3D } // namespace Dali