Merge "Refactoring of path constraints + LinearConstrainer" into tizen
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Constrainer.cpp
1 /*
2  * Copyright (c) 2014 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 <iostream>
19
20 #include <stdlib.h>
21 #include <dali/public-api/dali-core.h>
22 #include <dali-test-suite-utils.h>
23
24 using namespace Dali;
25 using namespace Dali::Internal;
26
27 namespace
28 {
29
30 static void SetupPath( Dali::Path& path)
31 {
32   path.AddPoint(Vector3( 30.0,  80.0, 0.0));
33   path.AddPoint(Vector3( 70.0, 120.0, 0.0));
34   path.AddPoint(Vector3(100.0, 100.0, 0.0));
35
36   //Control points for first segment
37   path.AddControlPoint( Vector3( 39.0,  90.0, 0.0) );
38   path.AddControlPoint(Vector3( 56.0, 119.0, 0.0) );
39
40   //Control points for second segment
41   path.AddControlPoint(Vector3( 78.0, 120.0, 0.0) );
42   path.AddControlPoint(Vector3( 93.0, 104.0, 0.0) );
43 }
44
45 static void SetupPathConstrainer( Dali::PathConstrainer& PathConstrainer)
46 {
47   PathConstrainer.SetProperty( Dali::PathConstrainer::Property::FORWARD, Vector3(1.0f,0.0f,0.0f) );
48
49   Dali::Property::Array points;
50   points.resize(3);
51   points[0] = Vector3( 30.0,  80.0, 0.0);
52   points[1] = Vector3( 70.0, 120.0, 0.0);
53   points[2] = Vector3(100.0, 100.0, 0.0);
54   PathConstrainer.SetProperty( Dali::PathConstrainer::Property::POINTS, points );
55
56   points.resize(4);
57   points[0] = Vector3( 39.0,  90.0, 0.0);
58   points[1] = Vector3( 56.0, 119.0, 0.0);
59   points[2] = Vector3( 78.0, 120.0, 0.0);
60   points[3] = Vector3( 93.0, 104.0, 0.0);
61   PathConstrainer.SetProperty( Dali::PathConstrainer::Property::CONTROL_POINTS, points );
62 }
63
64 static void SetupLinearConstrainerUniformProgress( Dali::LinearConstrainer& linearConstrainer)
65 {
66   Dali::Property::Array points;
67   points.resize(3);
68   points[0] = 0.0f;
69   points[1] = 1.0f;
70   points[2] = 0.0f;
71   linearConstrainer.SetProperty( Dali::LinearConstrainer::Property::VALUE, points );
72 }
73
74 static void SetupLinearConstrainerNonUniformProgress( Dali::LinearConstrainer& linearConstrainer)
75 {
76   Dali::Property::Array points;
77   points.resize(3);
78   points[0] = 0.0f;
79   points[1] = 1.0f;
80   points[2] = 0.0f;
81   linearConstrainer.SetProperty( Dali::LinearConstrainer::Property::VALUE, points );
82
83   points[0] = 0.0f;
84   points[1] = 0.25f;
85   points[2] = 1.0f;
86   linearConstrainer.SetProperty( Dali::LinearConstrainer::Property::PROGRESS, points );
87 }
88
89 } // anonymous namespace
90
91 //PathConstrainer test cases
92 int UtcPathConstrainerApply(void)
93 {
94   TestApplication application;
95
96   Dali::Actor actor = Dali::Actor::New();
97
98   // Register a float property
99   Property::Index index = actor.RegisterProperty( "t", 0.0f );
100
101   Dali::Stage::GetCurrent().Add(actor);
102
103   //Create a Path
104   Dali::Path path = Dali::Path::New();
105   SetupPath(path);
106
107   //Create a PathConstrainer
108   Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
109   SetupPathConstrainer( pathConstrainer );
110
111   //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
112   Vector2 range( 0.0f, 1.0f );
113   pathConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION), Property(actor,index), range );
114
115   //Create an animation to animate the custom property
116   float durationSeconds(1.0f);
117   Dali::Animation animation = Dali::Animation::New(durationSeconds);
118   animation.AnimateTo(Dali::Property(actor,index),1.0f);
119   animation.Play();
120
121   application.SendNotification();
122   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* 20% progress */);
123
124   Vector3 position, tangent;
125   path.Sample(0.2f, position, tangent );
126   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
127
128   application.SendNotification();
129   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* 40% progress */);
130   path.Sample(0.4f, position, tangent );
131   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
132
133   application.SendNotification();
134   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* 60% progress */);
135   path.Sample(0.6f, position, tangent );
136   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
137
138   application.SendNotification();
139   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* 80% progress */);
140   path.Sample(0.8f, position, tangent );
141   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
142
143   application.SendNotification();
144   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* 100% progress */);
145   path.Sample(1.0f, position, tangent );
146   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
147
148   application.SendNotification();
149   application.Render(static_cast<unsigned int>(durationSeconds*200.0f)/* beyond the animation duration*/);
150   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
151
152   END_TEST;
153 }
154
155 int UtcPathConstrainerApplyRange(void)
156 {
157   TestApplication application;
158
159   Dali::Actor actor = Dali::Actor::New();
160
161   // Register a float property
162   Property::Index index = actor.RegisterProperty( "t", 0.0f );
163   Dali::Stage::GetCurrent().Add(actor);
164
165   //Create a Path
166   Dali::Path path = Dali::Path::New();
167   SetupPath(path);
168
169   //Create a PathConstrainer
170   Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
171   SetupPathConstrainer( pathConstrainer );
172
173   //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
174   Vector2 range( 100.0f, 300.0f );
175   pathConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION), Property(actor,index), range );
176
177
178   //Create an animation to animate the custom property
179   float durationSeconds(1.0f);
180   Dali::Animation animation = Dali::Animation::New(durationSeconds);
181   animation.AnimateTo(Dali::Property(actor,index),400.0f);
182   animation.Play();
183
184   application.SendNotification();
185   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
186
187
188   Vector3 position, tangent;
189   float tValue;
190   actor.GetProperty(index).Get(tValue);
191   float currentCursor =  ( tValue - range.x ) / (range.y-range.x);
192   path.Sample(currentCursor, position, tangent );
193   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
194
195   application.SendNotification();
196   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
197   actor.GetProperty(index).Get(tValue);
198   currentCursor =  ( tValue - range.x ) / (range.y-range.x);
199   path.Sample(currentCursor, position, tangent );
200   path.Sample(0.5, position, tangent );
201   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
202
203   application.SendNotification();
204   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
205   actor.GetProperty(index).Get(tValue);
206   currentCursor =  ( tValue - range.x ) / (range.y-range.x);
207   path.Sample(currentCursor, position, tangent );
208   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
209
210   application.SendNotification();
211   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
212   actor.GetProperty(index).Get(tValue);
213   currentCursor =  ( tValue - range.x ) / (range.y-range.x);
214   path.Sample(currentCursor, position, tangent );
215   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
216
217   application.SendNotification();
218   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
219   actor.GetProperty(index).Get(tValue);
220   currentCursor =  ( tValue - range.x ) / (range.y-range.x);
221   path.Sample(currentCursor, position, tangent );
222   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
223
224   END_TEST;
225 }
226
227 int UtcPathConstrainerDestroy(void)
228 {
229   TestApplication application;
230
231   Dali::Actor actor = Dali::Actor::New();
232
233   // Register a float property
234   Property::Index index = actor.RegisterProperty( "t", 0.0f );
235   Dali::Stage::GetCurrent().Add(actor);
236
237   {
238     //Create a Path
239     Dali::Path path = Dali::Path::New();
240     SetupPath(path);
241
242     //Create a PathConstrainer
243     Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
244     SetupPathConstrainer( pathConstrainer );
245
246     //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
247     Vector2 range( 0.0f, 1.0f );
248     pathConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION), Property(actor,index), range );
249
250     //Test that the constraint is correctly applied
251     actor.SetProperty(index,0.5f);
252     application.SendNotification();
253     application.Render(static_cast<unsigned int>(1.0f));
254
255     Vector3 position, tangent;
256     path.Sample(0.5f, position, tangent );
257     DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
258
259   }
260
261   //PathConstrainer has been destroyed. Constraint in the actor should have been removed
262   actor.SetProperty(index,0.75f);
263   application.SendNotification();
264   application.Render(static_cast<unsigned int>(1.0f));
265
266   DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION );
267
268   END_TEST;
269 }
270
271 int UtcPathConstrainerRemove(void)
272 {
273   TestApplication application;
274
275   Dali::Actor actor = Dali::Actor::New();
276
277   // Register a float property
278   Property::Index index = actor.RegisterProperty( "t", 0.0f );
279   Dali::Stage::GetCurrent().Add(actor);
280
281   //Create a Path
282   Dali::Path path = Dali::Path::New();
283   SetupPath(path);
284
285   //Create a PathConstrainer
286   Dali::PathConstrainer pathConstrainer = Dali::PathConstrainer::New();
287   SetupPathConstrainer( pathConstrainer );
288
289   //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
290   Vector2 range( 0.0f, 1.0f );
291   pathConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION), Property(actor,index), range );
292
293   //Test that the constraint is correctly applied
294   actor.SetProperty(index,0.5f);
295   application.SendNotification();
296   application.Render(static_cast<unsigned int>(1.0f));
297
298   Vector3 position, tangent;
299   path.Sample(0.5f, position, tangent );
300   DALI_TEST_EQUALS( actor.GetCurrentPosition(), position, TEST_LOCATION );
301
302   //Remove constraint
303   pathConstrainer.Remove( actor );
304   actor.SetProperty(index,0.75f);
305   application.SendNotification();
306   application.Render(static_cast<unsigned int>(1.0f));
307
308   DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3::ZERO, TEST_LOCATION );
309
310   END_TEST;
311 }
312
313 //LinearConstrainer test cases
314 int UtcLinearConstrainerApply(void)
315 {
316   TestApplication application;
317
318   Dali::Actor actor = Dali::Actor::New();
319
320   // Register a float property
321   Property::Index index = actor.RegisterProperty( "t", 0.0f );
322
323   Dali::Stage::GetCurrent().Add(actor);
324
325
326   //Create a LinearConstrainer without specifying progress for values
327   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
328   SetupLinearConstrainerUniformProgress( linearConstrainer );
329
330   //Apply the linear constraint to the actor's position. The source property for the constraint will be the custom property "t"
331   Vector2 range( 0.0f, 1.0f );
332   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
333
334   //Create an animation to animate the custom property
335   float durationSeconds(1.0f);
336   Dali::Animation animation = Dali::Animation::New(durationSeconds);
337   animation.AnimateTo(Dali::Property(actor,index),1.0f);
338   animation.Play();
339
340   application.SendNotification();
341   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
342
343   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
344
345   application.SendNotification();
346   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
347   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
348
349   application.SendNotification();
350   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
351   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
352
353   application.SendNotification();
354   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
355   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
356
357   application.SendNotification();
358   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
359   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
360
361   //Setup a LinearConstrainer specifying the progress for each value
362   linearConstrainer.Remove(actor);
363   SetupLinearConstrainerNonUniformProgress( linearConstrainer );
364   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
365
366   actor.SetProperty(index,0.0f);
367   animation.Play();
368   application.SendNotification();
369   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
370
371   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
372
373   application.SendNotification();
374   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
375   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 2.0f/3.0f, Math::MACHINE_EPSILON_1, TEST_LOCATION );
376
377   application.SendNotification();
378   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
379   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f/3.0f, Math::MACHINE_EPSILON_1, TEST_LOCATION );
380
381   application.SendNotification();
382   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
383   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
384
385   application.SendNotification();
386   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
387   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
388
389   END_TEST;
390 }
391
392 int UtcLinearConstrainerApplyRange(void)
393 {
394   TestApplication application;
395
396   Dali::Actor actor = Dali::Actor::New();
397
398   // Register a float property
399   Property::Index index = actor.RegisterProperty( "t", 100.0f );
400   Dali::Stage::GetCurrent().Add(actor);
401
402   //Create a LinearConstrainer
403   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
404   SetupLinearConstrainerUniformProgress( linearConstrainer );
405
406   //Apply the linear constraint to the actor's position. The source property for the constraint will be the custom property "t"
407   Vector2 range( 100.0f, 300.0f );
408   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
409
410
411   //Create an animation to animate the custom property
412   float durationSeconds(1.0f);
413   Dali::Animation animation = Dali::Animation::New(durationSeconds);
414   animation.AnimateTo(Dali::Property(actor,index),300.0f);
415   animation.Play();
416
417   application.SendNotification();
418   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 25% progress */);
419
420   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
421
422   application.SendNotification();
423   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 50% progress */);
424   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
425
426   application.SendNotification();
427   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 75% progress */);
428   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.5f, TEST_LOCATION );
429
430   application.SendNotification();
431   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* 100% progress */);
432   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
433
434   application.SendNotification();
435   application.Render(static_cast<unsigned int>(durationSeconds*250.0f)/* beyond the animation duration*/);
436   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
437
438   END_TEST;
439 }
440
441 int UtcLinearConstrainerDestroy(void)
442 {
443   TestApplication application;
444
445   Dali::Actor actor = Dali::Actor::New();
446
447   // Register a float property
448   Property::Index index = actor.RegisterProperty( "t", 0.0f );
449   Dali::Stage::GetCurrent().Add(actor);
450
451   {
452     //Create a LinearConstrainer
453     Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
454     SetupLinearConstrainerUniformProgress( linearConstrainer );
455
456     //Apply the linear constraint to the actor's position. The source property for the constraint will be the custom property "t"
457     Vector2 range( 0.0f, 1.0f );
458     linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
459
460     //Test that the constraint is correctly applied
461     actor.SetProperty(index,0.5f);
462     application.SendNotification();
463     application.Render(static_cast<unsigned int>(1.0f));
464
465     DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
466
467   }
468
469   //LinearConstrainer has been destroyed. Constraint in the actor should have been removed
470   actor.SetProperty(index,0.75f);
471   application.SendNotification();
472   application.Render(static_cast<unsigned int>(1.0f));
473
474   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
475
476   END_TEST;
477 }
478
479 int UtcLinearConstrainerRemove(void)
480 {
481   TestApplication application;
482
483   Dali::Actor actor = Dali::Actor::New();
484
485   // Register a float property
486   Property::Index index = actor.RegisterProperty( "t", 0.0f );
487   Dali::Stage::GetCurrent().Add(actor);
488
489   //Create a LinearConstrainer
490   Dali::LinearConstrainer linearConstrainer = Dali::LinearConstrainer::New();
491   SetupLinearConstrainerUniformProgress( linearConstrainer );
492
493   //Apply the path constraint to the actor's position. The source property for the constraint will be the custom property "t"
494   Vector2 range( 0.0f, 1.0f );
495   linearConstrainer.Apply( Property(actor,Dali::Actor::Property::POSITION_X), Property(actor,index), range );
496
497   //Test that the constraint is correctly applied
498   actor.SetProperty(index,0.5f);
499   application.SendNotification();
500   application.Render(static_cast<unsigned int>(1.0f));
501
502   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 1.0f, TEST_LOCATION );
503
504   //Remove constraint
505   linearConstrainer.Remove( actor );
506   actor.SetProperty(index,0.75f);
507   application.SendNotification();
508   application.Render(static_cast<unsigned int>(1.0f));
509
510   DALI_TEST_EQUALS( actor.GetCurrentPosition().x, 0.0f, TEST_LOCATION );
511
512   END_TEST;
513 }