[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / model-motion / motion-data-impl.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-scene3d/internal/model-motion/motion-data-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/adaptor-framework/adaptor.h>
23 #include <dali/public-api/adaptor-framework/async-task-manager.h>
24 #include <dali/public-api/object/type-registry-helper.h>
25 #include <dali/public-api/object/type-registry.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-scene3d/public-api/model-motion/motion-index/motion-property-index.h>
29
30 namespace Dali
31 {
32 namespace Scene3D
33 {
34 namespace Internal
35 {
36 namespace
37 {
38 /**
39  * Creates control through type registry
40  */
41 BaseHandle Create()
42 {
43   return Scene3D::MotionData::New();
44 }
45
46 // Setup properties, signals and actions using the type-registry.
47 DALI_TYPE_REGISTRATION_BEGIN(Scene3D::MotionData, Dali::BaseHandle, Create);
48 DALI_TYPE_REGISTRATION_END()
49
50 } // unnamed namespace
51
52 MotionDataPtr MotionData::New()
53 {
54   MotionDataPtr motionData = new MotionData();
55
56   motionData->Initialize();
57
58   return motionData;
59 }
60
61 MotionData::MotionData()
62 {
63 }
64
65 MotionData::~MotionData()
66 {
67   if(Dali::Adaptor::IsAvailable())
68   {
69     CancelMotionDataLoad();
70   }
71 }
72
73 void MotionData::Initialize()
74 {
75 }
76
77 uint32_t MotionData::GetMotionCount() const
78 {
79   return static_cast<uint32_t>(mMotions.size());
80 }
81
82 Scene3D::MotionIndex MotionData::GetIndex(uint32_t index) const
83 {
84   if(index < mMotions.size())
85   {
86     return mMotions[index].first;
87   }
88   return Scene3D::MotionIndex();
89 }
90
91 Scene3D::MotionValue MotionData::GetValue(uint32_t index) const
92 {
93   if(index < mMotions.size())
94   {
95     return mMotions[index].second;
96   }
97   return Scene3D::MotionValue();
98 }
99
100 void MotionData::Add(Scene3D::MotionIndex index, Scene3D::MotionValue value)
101 {
102   mMotions.emplace_back(index, value);
103 }
104
105 void MotionData::Clear()
106 {
107   mMotions.clear();
108 }
109
110 void MotionData::SetDuration(float durationSeconds)
111 {
112   mDurationSeconds = durationSeconds;
113 }
114
115 float MotionData::GetDuration() const
116 {
117   return mDurationSeconds;
118 }
119
120 void MotionData::LoadBvh(const std::string& path, bool useRootTranslationOnly, const Vector3& scale, bool synchronousLoad)
121 {
122   CancelMotionDataLoad();
123   mMotionDataLoadTask = new MotionDataLoadTask(path, useRootTranslationOnly, scale, MakeCallback(this, &MotionData::OnLoadCompleted));
124   RequestMotionDataLoad(synchronousLoad);
125 }
126
127 void MotionData::LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, bool useRootTranslationOnly, const Vector3& scale, bool synchronousLoad)
128 {
129   CancelMotionDataLoad();
130   mMotionDataLoadTask = new MotionDataLoadTask(rawBuffer, rawBufferLength, useRootTranslationOnly, scale, MakeCallback(this, &MotionData::OnLoadCompleted));
131   RequestMotionDataLoad(synchronousLoad);
132 }
133
134 void MotionData::LoadFacialAnimation(const std::string& url, bool synchronousLoad)
135 {
136   CancelMotionDataLoad();
137   mMotionDataLoadTask = new MotionDataLoadTask(url, MakeCallback(this, &MotionData::OnLoadCompleted));
138   RequestMotionDataLoad(synchronousLoad);
139 }
140
141 void MotionData::LoadFacialAnimationFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, bool synchronousLoad)
142 {
143   CancelMotionDataLoad();
144   mMotionDataLoadTask = new MotionDataLoadTask(rawBuffer, rawBufferLength, MakeCallback(this, &MotionData::OnLoadCompleted));
145   RequestMotionDataLoad(synchronousLoad);
146 }
147
148 // Private method
149 void MotionData::RequestMotionDataLoad(bool synchronousLoad)
150 {
151   if(mMotionDataLoadTask)
152   {
153     if(synchronousLoad)
154     {
155       mMotionDataLoadTask->Process();
156       OnLoadCompleted(mMotionDataLoadTask);
157     }
158     else
159     {
160       Dali::AsyncTaskManager::Get().AddTask(mMotionDataLoadTask);
161     }
162   }
163 }
164
165 void MotionData::CancelMotionDataLoad()
166 {
167   if(mMotionDataLoadTask)
168   {
169     Dali::AsyncTaskManager::Get().RemoveTask(mMotionDataLoadTask);
170     mMotionDataLoadTask.Reset();
171   }
172 }
173
174 // Called from MotionDataLoadTask
175 void MotionData::OnLoadCompleted(MotionDataLoadTaskPtr task)
176 {
177   if(mMotionDataLoadTask == task)
178   {
179     const Scene3D::Loader::AnimationDefinition& animationDefinition = mMotionDataLoadTask->GetAnimationDefinition();
180
181     mDurationSeconds = animationDefinition.GetDuration();
182
183     auto animatedPropertyCount = animationDefinition.GetPropertyCount();
184
185     mMotions.clear();
186     mMotions.reserve(animatedPropertyCount);
187
188     for(uint32_t i = 0u; i < animatedPropertyCount; ++i)
189     {
190       const auto& animatedProperty = animationDefinition.GetPropertyAt(i);
191
192       // TODO : Currently, we only support KeyFrames without alpha function and time period now.
193       if(animatedProperty.mKeyFrames)
194       {
195         Add(Scene3D::MotionPropertyIndex::New(animatedProperty.mNodeName, animatedProperty.mPropertyName), Scene3D::MotionValue::New(animatedProperty.mKeyFrames));
196       }
197     }
198
199     // Reset task before emit load competed signal.
200     mMotionDataLoadTask.Reset();
201     {
202       Scene3D::MotionData handle(this); ///< Keep handle for lifecycle.
203       LoadCompletedSignal().Emit(handle);
204     }
205   }
206 }
207
208 } // namespace Internal
209
210 } // namespace Scene3D
211
212 } // namespace Dali