[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-scene3d / utc-Dali-MotionData.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 #include <dali-toolkit-test-suite-utils.h>
19 #include <dali-toolkit/dali-toolkit.h>
20 #include <stdlib.h>
21 #include <fstream>
22 #include <iostream>
23
24 #include <toolkit-event-thread-callback.h>
25
26 #include <dali-scene3d/public-api/model-motion/motion-data.h>
27 #include <dali-scene3d/public-api/model-motion/motion-value.h>
28
29 #include <dali-scene3d/public-api/model-motion/motion-index/blend-shape-index.h>
30 #include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
31 #include <dali-scene3d/public-api/model-motion/motion-index/motion-transform-index.h>
32
33 using namespace Dali;
34 using namespace Dali::Toolkit;
35 using namespace Dali::Scene3D;
36
37 void model_motion_motion_data_startup(void)
38 {
39   test_return_value = TET_UNDEF;
40 }
41
42 void model_motion_motion_data_cleanup(void)
43 {
44   test_return_value = TET_PASS;
45 }
46
47 namespace
48 {
49 const char* TEST_BVH_FILE_NAME    = TEST_RESOURCE_DIR "/test.bvh";
50 const char* TEST_FACIAL_FILE_NAME = TEST_RESOURCE_DIR "/facial-blendshape-animation.json";
51
52 std::string ReadBufferFromFile(const std::string& url)
53 {
54   std::string  rawString;
55   std::fstream fileStream;
56
57   fileStream.open(url, std::ios::in | std::ios::binary);
58   if(!fileStream.is_open())
59   {
60     DALI_LOG_WARNING("stream open failed for: \"%s\", in mode: \"%d\".\n", url.c_str(), static_cast<int>(std::ios::in | std::ios::binary));
61   }
62
63   // get length of file:
64   fileStream.seekg(0, std::ios::end);
65   auto length = fileStream.tellg();
66   fileStream.seekg(0, std::ios::beg);
67
68   rawString.resize(length);
69   fileStream.read(rawString.data(), length);
70
71   fileStream.close();
72
73   return rawString;
74 }
75
76 // For LoadCompleted
77 static bool gLoadCompleted = false;
78 void        OnLoadCompleted(MotionData data)
79 {
80   gLoadCompleted = true;
81 }
82 } // namespace
83
84 // Positive test case for a method
85 int UtcDaliMotionDataNew(void)
86 {
87   ToolkitTestApplication application;
88   tet_infoline(" UtcDaliMotionDataNew");
89
90   float      expectDuration = 0.0f;
91   MotionData motionData     = MotionData::New();
92   DALI_TEST_CHECK(motionData);
93   DALI_TEST_EQUALS(motionData.GetDuration(), expectDuration, TEST_LOCATION);
94
95   expectDuration = 10.0f;
96   motionData     = MotionData::New(expectDuration);
97   DALI_TEST_CHECK(motionData);
98   DALI_TEST_EQUALS(motionData.GetDuration(), expectDuration, TEST_LOCATION);
99   END_TEST;
100 }
101
102 int UtcDaliMotionDataDownCast(void)
103 {
104   ToolkitTestApplication application;
105   tet_infoline(" UtcDaliMotionDataDownCast");
106
107   MotionData motionData = MotionData::New();
108   BaseHandle handle(motionData);
109
110   MotionData motionData2 = MotionData::DownCast(handle);
111   DALI_TEST_CHECK(motionData);
112   DALI_TEST_CHECK(motionData2);
113   DALI_TEST_CHECK(motionData2 == motionData);
114   END_TEST;
115 }
116
117 int UtcDaliMotionDataTypeRegistry(void)
118 {
119   ToolkitTestApplication application;
120
121   TypeRegistry typeRegistry = TypeRegistry::Get();
122   DALI_TEST_CHECK(typeRegistry);
123
124   TypeInfo typeInfo = typeRegistry.GetTypeInfo("MotionData");
125   DALI_TEST_CHECK(typeInfo);
126
127   BaseHandle handle = typeInfo.CreateInstance();
128   DALI_TEST_CHECK(handle);
129
130   MotionData motionData = MotionData::DownCast(handle);
131   DALI_TEST_CHECK(motionData);
132
133   END_TEST;
134 }
135
136 int UtcDaliMotionDataCopyAndAssignment(void)
137 {
138   ToolkitTestApplication application;
139
140   MotionData motionData = MotionData::New();
141   DALI_TEST_CHECK(motionData);
142
143   MotionData copy(motionData);
144   DALI_TEST_CHECK(motionData == copy);
145
146   MotionData assign;
147   DALI_TEST_CHECK(!assign);
148
149   assign = copy;
150   DALI_TEST_CHECK(assign == motionData);
151
152   END_TEST;
153 }
154
155 int UtcDaliMotionDataMoveConstructor(void)
156 {
157   ToolkitTestApplication application;
158
159   MotionData motionData = MotionData::New();
160   DALI_TEST_EQUALS(1, motionData.GetBaseObject().ReferenceCount(), TEST_LOCATION);
161
162   MotionData moved = std::move(motionData);
163   DALI_TEST_CHECK(moved);
164   DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
165   DALI_TEST_CHECK(!motionData);
166
167   END_TEST;
168 }
169
170 int UtcDaliMotionDataMoveAssignment(void)
171 {
172   ToolkitTestApplication application;
173
174   MotionData motionData = MotionData::New();
175   DALI_TEST_EQUALS(1, motionData.GetBaseObject().ReferenceCount(), TEST_LOCATION);
176
177   MotionData moved;
178   moved = std::move(motionData);
179   DALI_TEST_CHECK(moved);
180   DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
181
182   END_TEST;
183 }
184
185 // Method test
186
187 int UtcDaliMotionDataAddMotion(void)
188 {
189   ToolkitTestApplication application;
190
191   MotionData motionData = MotionData::New(3.0f);
192
193   const uint32_t countMax = 4;
194   MotionIndex    index[countMax];
195   MotionValue    value[countMax];
196   for(uint32_t i = 0u; i < countMax; ++i)
197   {
198     // Generate index
199     if(i & 1)
200     {
201       index[i] = BlendShapeIndex::New("node", 0);
202     }
203     else
204     {
205       index[i] = MotionTransformIndex::New("node", MotionTransformIndex::TransformType::POSITION_X);
206     }
207
208     // Generate value
209     if(i & 2)
210     {
211       value[i] = MotionValue::New(3.0f);
212     }
213     else
214     {
215       KeyFrames keyFrames = KeyFrames::New();
216       keyFrames.Add(0.0f, 9.0f);
217       keyFrames.Add(1.0f, 5.0f);
218       value[i] = MotionValue::New(keyFrames);
219     }
220
221     DALI_TEST_CHECK(index[i]);
222     DALI_TEST_CHECK(value[i]);
223     motionData.Add(index[i], value[i]);
224
225     DALI_TEST_EQUALS(i + 1, motionData.GetMotionCount(), TEST_LOCATION);
226   }
227
228   for(uint32_t i = 0u; i < countMax; ++i)
229   {
230     DALI_TEST_EQUALS(index[i], motionData.GetIndex(i), TEST_LOCATION);
231     DALI_TEST_EQUALS(value[i], motionData.GetValue(i), TEST_LOCATION);
232   }
233
234   DALI_TEST_CHECK(!motionData.GetIndex(countMax));
235   DALI_TEST_CHECK(!motionData.GetValue(countMax));
236
237   motionData.Clear();
238
239   DALI_TEST_EQUALS(0u, motionData.GetMotionCount(), TEST_LOCATION);
240   DALI_TEST_CHECK(!motionData.GetIndex(0u));
241   DALI_TEST_CHECK(!motionData.GetValue(0u));
242
243   END_TEST;
244 }
245
246 int UtcDaliMotionDataSetGetDuration(void)
247 {
248   ToolkitTestApplication application;
249
250   float      expectDuration = 3.0f;
251   MotionData motionData     = MotionData::New(expectDuration);
252   DALI_TEST_EQUALS(motionData.GetDuration(), expectDuration, TEST_LOCATION);
253
254   expectDuration = 7.0f;
255   motionData.SetDuration(expectDuration);
256   DALI_TEST_EQUALS(motionData.GetDuration(), expectDuration, TEST_LOCATION);
257
258   expectDuration = 1.0f;
259   motionData.SetDuration(expectDuration);
260   DALI_TEST_EQUALS(motionData.GetDuration(), expectDuration, TEST_LOCATION);
261
262   END_TEST;
263 }
264
265 int UtcDaliMotionDataLoadBvhAndFacialAsync(void)
266 {
267   ToolkitTestApplication application;
268
269   for(uint32_t tc = 0; tc < 4; ++tc)
270   {
271     MotionData motionData = MotionData::New();
272     gLoadCompleted        = false;
273     motionData.LoadCompletedSignal().Connect(&OnLoadCompleted);
274
275     switch(tc)
276     {
277       case 0:
278       default:
279       {
280         motionData.LoadBvh(TEST_BVH_FILE_NAME);
281         break;
282       }
283       case 1:
284       {
285         motionData.LoadFacialAnimation(TEST_FACIAL_FILE_NAME);
286         break;
287       }
288       case 2:
289       {
290         std::string rawString = ReadBufferFromFile(TEST_BVH_FILE_NAME);
291         motionData.LoadBvhFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()));
292         break;
293       }
294       case 3:
295       {
296         std::string rawString = ReadBufferFromFile(TEST_FACIAL_FILE_NAME);
297         motionData.LoadFacialAnimationFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()));
298         break;
299       }
300     }
301
302     DALI_TEST_EQUALS(gLoadCompleted, false, TEST_LOCATION);
303
304     application.SendNotification();
305     application.Render();
306
307     DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
308     application.SendNotification();
309     application.Render();
310
311     // Check LoadCompletedSignal emitted.
312     DALI_TEST_EQUALS(gLoadCompleted, true, TEST_LOCATION);
313
314     // Check MotionData load successfully.
315     DALI_TEST_GREATER(motionData.GetMotionCount(), 0u, TEST_LOCATION);
316   }
317
318   END_TEST;
319 }
320
321 int UtcDaliMotionDataLoadBvhAndFacialSync(void)
322 {
323   ToolkitTestApplication application;
324
325   for(uint32_t tc = 0; tc < 4; ++tc)
326   {
327     MotionData motionData = MotionData::New();
328     gLoadCompleted        = false;
329     motionData.LoadCompletedSignal().Connect(&OnLoadCompleted);
330
331     switch(tc)
332     {
333       case 0:
334       default:
335       {
336         motionData.LoadBvh(TEST_BVH_FILE_NAME, Vector3::ONE, true);
337         break;
338       }
339       case 1:
340       {
341         motionData.LoadFacialAnimation(TEST_FACIAL_FILE_NAME, true);
342         break;
343       }
344       case 2:
345       {
346         std::string rawString = ReadBufferFromFile(TEST_BVH_FILE_NAME);
347         motionData.LoadBvhFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()), Vector3::ONE, true);
348         break;
349       }
350       case 3:
351       {
352         std::string rawString = ReadBufferFromFile(TEST_FACIAL_FILE_NAME);
353         motionData.LoadFacialAnimationFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()), true);
354         break;
355       }
356     }
357
358     // Check LoadCompletedSignal emitted.
359     DALI_TEST_EQUALS(gLoadCompleted, true, TEST_LOCATION);
360
361     // Check MotionData load successfully.
362     DALI_TEST_GREATER(motionData.GetMotionCount(), 0u, TEST_LOCATION);
363   }
364
365   END_TEST;
366 }
367
368 int UtcDaliMotionDataLoadAsyncMultiple(void)
369 {
370   ToolkitTestApplication application;
371
372   MotionData motionData = MotionData::New();
373   gLoadCompleted        = false;
374   motionData.LoadCompletedSignal().Connect(&OnLoadCompleted);
375
376   auto tryCount = 10u;
377   for(auto i = 0u; i < tryCount; ++i)
378   {
379     motionData.LoadBvh(TEST_BVH_FILE_NAME);
380   }
381
382   DALI_TEST_EQUALS(gLoadCompleted, false, TEST_LOCATION);
383
384   application.SendNotification();
385   application.Render();
386
387   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
388   application.SendNotification();
389   application.Render();
390
391   DALI_TEST_EQUALS(gLoadCompleted, true, TEST_LOCATION);
392
393   // Check MotionData load successfully.
394   DALI_TEST_GREATER(motionData.GetMotionCount(), 0u, TEST_LOCATION);
395
396   gLoadCompleted = false;
397
398   // Check if completed request comes only 1 time.
399   Test::WaitForEventThreadTrigger(1, 1);
400   application.SendNotification();
401   application.Render();
402
403   DALI_TEST_EQUALS(gLoadCompleted, false, TEST_LOCATION);
404
405   END_TEST;
406 }
407
408 int UtcDaliMotionDataLoadBvhUseRootTranslationOnly(void)
409 {
410   ToolkitTestApplication application;
411
412   MotionData motionDataAllTranslation = MotionData::New();
413   motionDataAllTranslation.LoadBvh(TEST_BVH_FILE_NAME, false, Vector3::ONE, true);
414
415   DALI_TEST_EQUALS(motionDataAllTranslation.GetMotionCount(), 4, TEST_LOCATION);  
416
417   MotionData motionDataOnlyRootTranslation = MotionData::New();
418   motionDataOnlyRootTranslation.LoadBvh(TEST_BVH_FILE_NAME, true, Vector3::ONE, true);
419
420   DALI_TEST_EQUALS(motionDataOnlyRootTranslation.GetMotionCount(), 3, TEST_LOCATION);  
421
422   END_TEST;
423 }
424
425 int UtcDaliMotionDataLoadBvhFromBufferUseRootTranslationOnly(void)
426 {
427   ToolkitTestApplication application;
428
429   std::string rawString = ReadBufferFromFile(TEST_BVH_FILE_NAME);
430
431   MotionData motionDataAllTranslation = MotionData::New();
432   motionDataAllTranslation.LoadBvhFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()), false, Vector3::ONE, true);
433
434   DALI_TEST_EQUALS(motionDataAllTranslation.GetMotionCount(), 4, TEST_LOCATION);  
435
436   MotionData motionDataOnlyRootTranslation = MotionData::New();
437   motionDataOnlyRootTranslation.LoadBvhFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()), true, Vector3::ONE, true);
438
439   DALI_TEST_EQUALS(motionDataOnlyRootTranslation.GetMotionCount(), 3, TEST_LOCATION);  
440
441   END_TEST;
442 }