Apply fittingMode lazy when resource is not ready
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-physics2d / utc-Dali-PhysicsAdaptor.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 #include <stdlib.h>
18 #include <iostream>
19 #include <typeinfo>
20
21 // Need to override adaptor classes for toolkit test harness, so include
22 // test harness headers before dali headers.
23 #include <dali-physics/dali-physics.h>
24 #include <dali-toolkit-test-suite-utils.h>
25 #include <toolkit-event-thread-callback.h>
26
27 #include <dali-toolkit/devel-api/controls/alignment/alignment.h>
28 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
29 #include <dali/devel-api/adaptor-framework/window-devel.h>
30 #include <dali/devel-api/events/hit-test-algorithm.h>
31
32 #include <chipmunk/chipmunk.h>
33
34 using namespace Dali;
35 using namespace Dali::Toolkit::Physics;
36
37 void utc_dali_physics2d_startup(void)
38 {
39   test_return_value = TET_UNDEF;
40 }
41
42 void utc_dali_physics2d_cleanup(void)
43 {
44   test_return_value = TET_PASS;
45 }
46
47 cpBody* CreateBody(cpSpace* space)
48 {
49   const float BALL_MASS       = 10.0f;
50   const float BALL_RADIUS     = 26.0f;
51   const float BALL_ELASTICITY = 0.5f;
52   const float BALL_FRICTION   = 0.5f;
53
54   cpBody* body = cpSpaceAddBody(space, cpBodyNew(BALL_MASS, cpMomentForCircle(BALL_MASS, 0.0f, BALL_RADIUS, cpvzero)));
55
56   cpShape* shape = cpSpaceAddShape(space, cpCircleShapeNew(body, BALL_RADIUS, cpvzero));
57   cpShapeSetElasticity(shape, BALL_ELASTICITY);
58   cpShapeSetFriction(shape, BALL_FRICTION);
59
60   return body;
61 }
62
63 int UtcDaliPhysics2DCreateAdaptorP1(void)
64 {
65   ToolkitTestApplication application;
66
67   Matrix     transform(true);
68   Uint16Pair size(640, 480);
69
70   PhysicsAdaptor handle = PhysicsAdaptor::New(transform, size);
71   DALI_TEST_CHECK(handle);
72
73   END_TEST;
74 }
75
76 int UtcDaliPhysics2DCreateAdaptorN1(void)
77 {
78   ToolkitTestApplication application;
79
80   PhysicsAdaptor handle;
81   DALI_TEST_CHECK(!handle);
82
83   END_TEST;
84 }
85
86 int UtcDaliPhysics2DDowncastP1(void)
87 {
88   ToolkitTestApplication application;
89
90   Matrix     transform(true);
91   Uint16Pair size(640, 480);
92
93   BaseHandle handle = PhysicsAdaptor::New(transform, size);
94
95   auto adaptor = PhysicsAdaptor::DownCast(handle);
96   DALI_TEST_CHECK(adaptor);
97   //Following only works if type is registered
98   //DALI_TEST_EQUALS("PhysicsAdaptor", adaptor.GetTypeName(), TEST_LOCATION);
99   END_TEST;
100 }
101
102 int UtcDaliPhysics2DDowncastN1(void)
103 {
104   BaseHandle handle;
105   auto       adaptor = PhysicsAdaptor::DownCast(handle);
106   DALI_TEST_CHECK(!adaptor);
107
108   DALI_TEST_CHECK(typeid(PhysicsAdaptor) == typeid(decltype(adaptor)));
109   END_TEST;
110 }
111
112 int UtcDaliPhysics2DAdaptorMoveConstructor(void)
113 {
114   ToolkitTestApplication application;
115   tet_infoline("Testing the move constructor");
116
117   Matrix         transform(true);
118   Uint16Pair     size(640, 480);
119   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
120   DALI_TEST_CHECK(adaptor);
121
122   PhysicsAdaptor moved = std::move(adaptor);
123   DALI_TEST_CHECK(moved);
124   DALI_TEST_CHECK(!adaptor);
125   DALI_TEST_CHECK(moved != adaptor);
126
127   END_TEST;
128 }
129
130 int UtcDaliPhysics2DAdaptorCopyConstructor(void)
131 {
132   ToolkitTestApplication application;
133   tet_infoline("Testing the move constructor");
134
135   Matrix         transform(true);
136   Uint16Pair     size(640, 480);
137   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
138
139   DALI_TEST_CHECK(adaptor);
140
141   PhysicsAdaptor altAdaptor = adaptor;
142   DALI_TEST_CHECK(altAdaptor);
143   DALI_TEST_CHECK(adaptor);
144   DALI_TEST_CHECK(altAdaptor == adaptor); // should point at same object
145
146   END_TEST;
147 }
148
149 int UtcDaliPhysics2DAdaptorCopyAssign(void)
150 {
151   ToolkitTestApplication application;
152   tet_infoline("Testing the copy assign");
153
154   Matrix         transform(true);
155   Uint16Pair     size(640, 480);
156   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
157   DALI_TEST_CHECK(adaptor);
158
159   PhysicsAdaptor altAdaptor = adaptor;
160   DALI_TEST_CHECK(altAdaptor);
161   DALI_TEST_CHECK(adaptor);
162   DALI_TEST_CHECK(altAdaptor == adaptor); // should point at same object
163
164   END_TEST;
165 }
166
167 int UtcDaliPhysics2DAdaptorMoveAssignment(void)
168 {
169   ToolkitTestApplication application;
170   tet_infoline("Testing the move constructor");
171
172   Matrix         transform(true);
173   Uint16Pair     size(640, 480);
174   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
175   DALI_TEST_CHECK(adaptor);
176
177   PhysicsAdaptor moved;
178   moved = std::move(adaptor);
179   DALI_TEST_CHECK(moved);
180   DALI_TEST_CHECK(!adaptor);
181
182   END_TEST;
183 }
184
185 int UtcDaliPhysics2DSetTimestep(void)
186 {
187   ToolkitTestApplication application;
188
189   Matrix     transform(true);
190   Uint16Pair size(640, 480);
191
192   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
193   adaptor.SetTimestep(1.0f / 60.0f);
194
195   DALI_TEST_EQUALS(adaptor.GetTimestep(), 1.0f / 60.0f, 0.0001f, TEST_LOCATION);
196
197   END_TEST;
198 }
199
200 int UtcDaliPhysics2DGetTimestep(void)
201 {
202   ToolkitTestApplication application;
203
204   Matrix     transform(true);
205   Uint16Pair size(640, 480);
206
207   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
208   adaptor.SetTimestep(1.0f / 60.0f);
209   float timestep = adaptor.GetTimestep();
210   float expected = 1.0f / 60.0f;
211   DALI_TEST_EQUALS(timestep, expected, 0.0001f, TEST_LOCATION);
212
213   adaptor.SetTimestep(1.0f / 120.0f);
214   timestep = adaptor.GetTimestep();
215   expected = 1.0f / 120.0f;
216   DALI_TEST_EQUALS(timestep, expected, 0.0001f, TEST_LOCATION);
217
218   END_TEST;
219 }
220
221 int UtcDaliPhysics2DGetPhysicsAccessorP1(void)
222 {
223   ToolkitTestApplication application;
224
225   Matrix     transform(true);
226   Uint16Pair size(640, 480);
227
228   PhysicsAdaptor                           adaptor  = PhysicsAdaptor::New(transform, size);
229   PhysicsAdaptor::ScopedPhysicsAccessorPtr accessor = adaptor.GetPhysicsAccessor();
230   DALI_TEST_CHECK(accessor.get() != nullptr);
231
232   Dali::Any world = accessor->GetNative();
233   DALI_TEST_CHECK(!world.Empty());
234
235   END_TEST;
236 }
237
238 int UtcDaliPhysics2DGetPhysicsAccessorN1(void)
239 {
240   ToolkitTestApplication application;
241
242   PhysicsAdaptor handle;
243   DALI_TEST_CHECK(!handle);
244
245   try
246   {
247     auto ptr = handle.GetPhysicsAccessor();
248     DALI_TEST_CHECK(ptr == nullptr);
249
250     tet_result(TET_FAIL);
251   }
252   catch(DaliException& e)
253   {
254     DALI_TEST_ASSERT(e, "Physics adaptor handle is empty", TEST_LOCATION);
255   }
256
257   END_TEST;
258 }
259
260 int UtcDaliPhysics2DAdaptorGetRootActor(void)
261 {
262   tet_infoline("Test that the root actor can be retrieved");
263
264   ToolkitTestApplication application;
265   Matrix                 transform(false);
266   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
267   Uint16Pair     size(640, 480);
268   auto           scene     = application.GetScene();
269   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
270   Actor          rootActor = adaptor.GetRootActor();
271   scene.Add(rootActor);
272
273   DALI_TEST_CHECK(rootActor);
274   DALI_TEST_EQUALS(rootActor.GetProperty<Vector2>(Actor::Property::SIZE), Vector2(640.0f, 480.0f), 0.001f, TEST_LOCATION);
275
276   END_TEST;
277 }
278
279 int UtcDaliPhysics2DAdaptorCreateDebugLayer(void)
280 {
281   ToolkitTestApplication application;
282   Matrix                 transform(true);
283   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
284   Uint16Pair size(640, 480);
285   auto       scene = application.GetScene();
286
287   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
288   Actor          rootActor = adaptor.GetRootActor();
289   scene.Add(rootActor);
290   Window window = DevelWindow::Get(rootActor);
291
292   Layer layer = adaptor.CreateDebugLayer(window);
293   DALI_TEST_CHECK(!layer);
294
295   END_TEST;
296 }
297
298 int UtcDaliPhysics2DAdaptorTranslateToPhysicsSpace1(void)
299 {
300   ToolkitTestApplication application;
301   Matrix                 transform(false);
302   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
303   Uint16Pair     size(640, 480);
304   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
305
306   Vector3 a(30, 20, 10);
307   Vector3 expected(60, 40, 10);
308   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(a), expected, 0.0001f, TEST_LOCATION);
309
310   END_TEST;
311 }
312
313 int UtcDaliPhysics2DAdaptorTranslateToPhysicsSpace2(void)
314 {
315   ToolkitTestApplication application;
316   Matrix                 transform(false);
317   tet_infoline("Test that using an alternative scale doesn't change rotation");
318   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
319   Uint16Pair     size(640, 480);
320   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
321
322   // Rotation shouldn't change under this scale
323   Quaternion q(Degree(30.0f), Vector3::XAXIS);
324   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), q, 0.0001f, TEST_LOCATION);
325
326   END_TEST;
327 }
328
329 int UtcDaliPhysics2DAdaptorTranslateToPhysicsSpace3(void)
330 {
331   ToolkitTestApplication application;
332   Matrix                 transform(false);
333   tet_infoline("Test that using an inverted Y scale does nothing to rotation");
334
335   transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
336   Uint16Pair     size(640, 480);
337   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
338
339   Quaternion q(Degree(30.0f), Vector3::ZAXIS);
340   Quaternion qp(Degree(30.0f), Vector3::ZAXIS);
341
342   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), qp, 0.0001f, TEST_LOCATION);
343
344   END_TEST;
345 }
346
347 int UtcDaliPhysics2DAdaptorTranslateToPhysicsSpace4(void)
348 {
349   ToolkitTestApplication application;
350   Matrix                 transform(false);
351   tet_infoline("Test that using an inverted Y scale does nothing to rotation");
352
353   transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
354   Uint16Pair     size(640, 480);
355   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
356
357   Quaternion q(Degree(30.0f), Vector3::XAXIS);
358   Quaternion qp(Degree(30.0f), Vector3::XAXIS);
359
360   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), qp, 0.0001f, TEST_LOCATION);
361
362   END_TEST;
363 }
364
365 int UtcDaliPhysics2DAdaptorTranslateToPhysicsSpace5(void)
366 {
367   ToolkitTestApplication application;
368   Matrix                 transform(false);
369   tet_infoline("Test that using an inverted Y scale does nothing to rotation");
370
371   transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
372   Uint16Pair     size(640, 480);
373   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
374
375   Quaternion q(Degree(30.0f), Vector3::YAXIS);
376   Quaternion qp(Degree(30.0f), Vector3::YAXIS);
377
378   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), qp, 0.0001f, TEST_LOCATION);
379
380   END_TEST;
381 }
382
383 int UtcDaliPhysics2DAdaptorTranslateFromPhysicsSpace1(void)
384 {
385   ToolkitTestApplication application;
386   Matrix                 transform(false);
387   tet_infoline("Test that using a double scale halves position");
388
389   transform.SetIdentityAndScale(Vector3(2.0f, -2.0f, 1.0f));
390   Uint16Pair     size(640, 480);
391   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
392
393   Vector3 position(20.0f, 20.0f, 0.0f);
394   Vector3 expected(10.0f, -10.0f, 0.0f);
395
396   DALI_TEST_EQUALS(adaptor.TranslateFromPhysicsSpace(position), expected, 0.0001f, TEST_LOCATION);
397
398   END_TEST;
399 }
400
401 int UtcDaliPhysics2DAdaptorConvertVectorToPhysicsSpace01(void)
402 {
403   ToolkitTestApplication application;
404   Matrix                 transform(false);
405   tet_infoline("Test that using a translation does not translate vector");
406
407   transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
408   transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
409   Uint16Pair     size(640, 480);
410   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
411   Vector3        vector(20.0f, 20.0f, 0.0f);
412   DALI_TEST_EQUALS(adaptor.ConvertVectorToPhysicsSpace(vector), vector, 0.0001f, TEST_LOCATION);
413
414   END_TEST;
415 }
416
417 int UtcDaliPhysics2DAdaptorConvertVectorToPhysicsSpace02(void)
418 {
419   ToolkitTestApplication application;
420   Matrix                 transform(false);
421   tet_infoline("Test that using a translation with inverse Y does not translate vector");
422
423   transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
424   transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
425   Uint16Pair     size(640, 480);
426   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
427   Vector3        vector(20.0f, 20.0f, 0.0f);
428   Vector3        expected(20.0f, -20.0f, 0.0f);
429   DALI_TEST_EQUALS(adaptor.ConvertVectorToPhysicsSpace(vector), expected, 0.0001f, TEST_LOCATION);
430
431   END_TEST;
432 }
433
434 int UtcDaliPhysics2DAdaptorConvertVectorFromPhysicsSpace01(void)
435 {
436   ToolkitTestApplication application;
437   Matrix                 transform(false);
438   tet_infoline("Test that using a translation does not translate vector");
439
440   transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
441   transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
442   Uint16Pair     size(640, 480);
443   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
444   Vector3        vector(20.0f, 20.0f, 0.0f);
445   DALI_TEST_EQUALS(adaptor.ConvertVectorFromPhysicsSpace(vector), vector, 0.0001f, TEST_LOCATION);
446
447   END_TEST;
448 }
449
450 int UtcDaliPhysics2DAdaptorConvertVectorFromPhysicsSpace02(void)
451 {
452   ToolkitTestApplication application;
453   Matrix                 transform(false);
454   tet_infoline("Test that using a translation with inverse Y does not translate vector");
455
456   transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
457   transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
458   Uint16Pair     size(640, 480);
459   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
460   Vector3        vector(20.0f, 20.0f, 0.0f);
461   Vector3        expected(20.0f, -20.0f, 0.0f);
462   DALI_TEST_EQUALS(adaptor.ConvertVectorFromPhysicsSpace(vector), expected, 0.0001f, TEST_LOCATION);
463
464   END_TEST;
465 }
466
467 int UtcDaliPhysics2DAdaptorSetTransformAndSize(void)
468 {
469   ToolkitTestApplication application;
470   Matrix                 transform(false);
471   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
472   Uint16Pair     size(640, 480);
473   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
474
475   Vector3 a(30, 20, 10);
476   Vector3 expected(60, 40, 10);
477   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(a), expected, 0.0001f, TEST_LOCATION);
478
479   transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
480   transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
481   adaptor.SetTransformAndSize(transform, size);
482
483   Vector3 expect2(30, 80, 10);
484   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(a), expect2, 0.0001f, TEST_LOCATION);
485
486   END_TEST;
487 }
488
489 int UtcDaliPhysics2DAdaptorSetIntegrationState(void)
490 {
491   tet_infoline("Test that changing the integration state is reflected");
492
493   ToolkitTestApplication application;
494   Matrix                 transform(false);
495   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
496   Uint16Pair     size(640, 480);
497   auto           scene     = application.GetScene();
498   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
499   Actor          rootActor = adaptor.GetRootActor();
500   scene.Add(rootActor);
501
502   DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::ON);
503
504   adaptor.SetIntegrationState(PhysicsAdaptor::IntegrationState::OFF);
505   DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::OFF);
506
507   END_TEST;
508 }
509
510 int UtcDaliPhysics2DAdaptorGetIntegrationState(void)
511 {
512   tet_infoline("Test that changing the integration state is reflected");
513
514   ToolkitTestApplication application;
515   Matrix                 transform(false);
516   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
517   Uint16Pair     size(640, 480);
518   auto           scene     = application.GetScene();
519   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
520   Actor          rootActor = adaptor.GetRootActor();
521   scene.Add(rootActor);
522
523   adaptor.SetIntegrationState(PhysicsAdaptor::IntegrationState::OFF);
524   DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::OFF);
525
526   adaptor.SetIntegrationState(PhysicsAdaptor::IntegrationState::ON);
527   DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::ON);
528
529   // Can't test actual integration step runs without adding actors - see utc-Dali-PhysicsActor.cpp.
530   END_TEST;
531 }
532
533 int UtcDaliPhysics2DAdaptorSetDebugState(void)
534 {
535   tet_infoline("Test that changing the debug state is reflected");
536
537   ToolkitTestApplication application;
538   Matrix                 transform(false);
539   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
540   Uint16Pair     size(640, 480);
541   auto           scene     = application.GetScene();
542   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
543   Actor          rootActor = adaptor.GetRootActor();
544   scene.Add(rootActor);
545
546   DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::OFF);
547
548   adaptor.SetDebugState(PhysicsAdaptor::DebugState::ON);
549   DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::ON);
550
551   adaptor.SetDebugState(PhysicsAdaptor::DebugState::OFF);
552   DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::OFF);
553
554   END_TEST;
555 }
556
557 int UtcDaliPhysics2DAdaptorGetDebugState(void)
558 {
559   tet_infoline("Test that changing the debug state is reflected");
560
561   ToolkitTestApplication application;
562   Matrix                 transform(false);
563   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
564   Uint16Pair     size(640, 480);
565   auto           scene     = application.GetScene();
566   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
567   Actor          rootActor = adaptor.GetRootActor();
568   scene.Add(rootActor);
569
570   adaptor.SetDebugState(PhysicsAdaptor::DebugState::OFF);
571   DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::OFF);
572
573   adaptor.SetDebugState(PhysicsAdaptor::DebugState::ON);
574   DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::ON);
575
576   // Can't test actual debug step runs without adding actors - see utc-Dali-PhysicsActor.cpp.
577   END_TEST;
578 }
579
580 int UtcDaliPhysics2DAdaptorAddActorBody(void)
581 {
582   tet_infoline("Test that an actor/body pair can be added");
583
584   ToolkitTestApplication application;
585   Matrix                 transform(false);
586   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
587   Uint16Pair     size(640, 480);
588   auto           scene     = application.GetScene();
589   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
590   Actor          rootActor = adaptor.GetRootActor();
591   scene.Add(rootActor);
592
593   auto accessor = adaptor.GetPhysicsAccessor();
594   auto space    = accessor->GetNative().Get<cpSpace*>();
595
596   cpBody*     body         = CreateBody(space);
597   Dali::Actor ballActor    = Toolkit::ImageView::New("gallery-small-1.jpg");
598   auto        physicsActor = adaptor.AddActorBody(ballActor, body);
599
600   DALI_TEST_CHECK(physicsActor);
601   int id = ballActor[Actor::Property::ID];
602
603   DALI_TEST_EQUALS(physicsActor.GetId(), id, TEST_LOCATION);
604   DALI_TEST_EQUALS(physicsActor.GetBody().Get<cpBody*>(), body, TEST_LOCATION);
605
606   END_TEST;
607 }
608
609 void removeShape(cpBody* body, cpShape* shape, void* data)
610 {
611   cpSpace* space = static_cast<cpSpace*>(data);
612   cpSpaceRemoveShape(space, shape);
613   cpShapeSetBody(shape, nullptr);
614   cpShapeFree(shape);
615 }
616
617 int UtcDaliPhysics2DAdaptorRemoveActorBodyP01(void)
618 {
619   tet_infoline("Test that an actor/body pair can be removed");
620
621   ToolkitTestApplication application;
622   Matrix                 transform(false);
623   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
624   Uint16Pair     size(640, 480);
625   auto           scene     = application.GetScene();
626   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
627   Actor          rootActor = adaptor.GetRootActor();
628   scene.Add(rootActor);
629
630   cpBody* body;
631   {
632     auto accessor = adaptor.GetPhysicsAccessor();
633     auto space    = accessor->GetNative().Get<cpSpace*>();
634
635     body = CreateBody(space);
636   }
637   Dali::Actor ballActor    = Toolkit::ImageView::New("gallery-small-1.jpg");
638   auto        physicsActor = adaptor.AddActorBody(ballActor, body);
639
640   application.SendNotification();
641   application.Render();
642   application.SendNotification();
643   application.Render();
644
645   adaptor.RemoveActorBody(physicsActor);
646   DALI_TEST_CHECK(!ballActor.GetParent());
647
648   {
649     auto accessor = adaptor.GetPhysicsAccessor();
650     auto space    = accessor->GetNative().Get<cpSpace*>();
651
652     try
653     {
654       cpBodyEachShape(body, removeShape, space);
655       cpSpaceRemoveBody(space, body);
656       tet_result(TET_PASS);
657     }
658     catch(std::exception& e)
659     {
660       tet_result(TET_FAIL);
661     }
662   }
663
664   END_TEST;
665 }
666
667 int UtcDaliPhysics2DAdaptorRemoveActorBodyN01(void)
668 {
669   ToolkitTestApplication application;
670   Matrix                 transform(false);
671   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
672   Uint16Pair     size(640, 480);
673   auto           scene     = application.GetScene();
674   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
675   Actor          rootActor = adaptor.GetRootActor();
676   scene.Add(rootActor);
677
678   tet_infoline("Test that removing a physics actor that hasn't been created with AddActorBody does nothing");
679   Dali::Actor  actor        = Dali::Actor::New();
680   cpBody*      body         = cpBodyNew(1.0f, 1.0f);
681   PhysicsActor physicsActor = PhysicsActor::New(actor, body, adaptor);
682   ;
683   try
684   {
685     adaptor.RemoveActorBody(physicsActor);
686     tet_result(TET_PASS);
687   }
688   catch(std::exception& e)
689   {
690     // Should fail silently, without exception!
691     tet_result(TET_FAIL);
692   }
693
694   END_TEST;
695 }
696
697 int UtcDaliPhysics2DAdaptorRemoveActorBodyN02(void)
698 {
699   tet_infoline("Test that an empty actor/body pair doesn't break adaptor");
700
701   ToolkitTestApplication application;
702   Matrix                 transform(false);
703   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
704   Uint16Pair     size(640, 480);
705   auto           scene     = application.GetScene();
706   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
707   Actor          rootActor = adaptor.GetRootActor();
708   scene.Add(rootActor);
709
710   PhysicsActor physicsActor;
711   try
712   {
713     adaptor.RemoveActorBody(physicsActor);
714     tet_result(TET_FAIL);
715   }
716   catch(DaliException& e)
717   {
718     DALI_TEST_ASSERT(e, "Physics actor handle is empty", TEST_LOCATION);
719   }
720
721   END_TEST;
722 }
723
724 int UtcDaliPhysics2DAdaptorGetPhysicsActor(void)
725 {
726   tet_infoline("Test that an actor/body pair can be retrieved");
727
728   ToolkitTestApplication application;
729   Matrix                 transform(false);
730   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
731   Uint16Pair     size(640, 480);
732   auto           scene     = application.GetScene();
733   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
734   Actor          rootActor = adaptor.GetRootActor();
735   scene.Add(rootActor);
736
737   auto accessor = adaptor.GetPhysicsAccessor();
738   auto space    = accessor->GetNative().Get<cpSpace*>();
739
740   cpBody*     body         = CreateBody(space);
741   Dali::Actor ballActor    = Toolkit::ImageView::New("gallery-small-1.jpg");
742   auto        physicsActor = adaptor.AddActorBody(ballActor, body);
743
744   DALI_TEST_CHECK(physicsActor);
745
746   PhysicsActor testActor = adaptor.GetPhysicsActor(body);
747   DALI_TEST_CHECK(testActor);
748   DALI_TEST_CHECK(physicsActor == testActor);
749
750   END_TEST;
751 }
752
753 int UtcDaliPhysics2DAdaptorBuildPickingRay(void)
754 {
755   tet_infoline("Test that picking ray converts screen coords");
756
757   ToolkitTestApplication application;
758   Matrix                 transform(false);
759   transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
760   Uint16Pair     size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
761   const Vector2  center(TestApplication::DEFAULT_SURFACE_WIDTH * 0.5f, TestApplication::DEFAULT_SURFACE_HEIGHT * 0.5f);
762   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
763   Actor          rootActor = adaptor.GetRootActor();
764   auto           scene     = application.GetScene();
765   scene.Add(rootActor);
766
767   Vector3 from, to;
768   adaptor.BuildPickingRay(Vector3(center), Vector3(center), from, to); // Hit test centre of screen
769   Vector3 physCenter = adaptor.TranslateToPhysicsSpace(Vector3(center));
770   DALI_TEST_EQUALS(from, physCenter, 0.001f, TEST_LOCATION);
771
772   END_TEST;
773 }
774
775 int UtcDaliPhysics2DAdaptorProjectPoint(void)
776 {
777   tet_infoline("Test that a point is projected into physics space");
778
779   ToolkitTestApplication application;
780   Matrix                 transform(false);
781   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
782   Uint16Pair     size(640, 480);
783   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
784
785   Vector3 projectedPoint = adaptor.ProjectPoint(Vector3(), -Vector3::ZAXIS, 200);
786
787   DALI_TEST_EQUALS(projectedPoint, Vector3(0.0f, 0.0f, 0.0f), 0.001f, TEST_LOCATION);
788
789   END_TEST;
790 }
791
792 int UtcDaliPhysics2DAdaptorQueue(void)
793 {
794   tet_infoline("Test that Queue and CreateSyncPoint both work");
795
796   ToolkitTestApplication application;
797   Matrix                 transform(false);
798   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
799   Uint16Pair     size(640, 480);
800   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
801   Actor          rootActor = adaptor.GetRootActor();
802   auto           scene     = application.GetScene();
803   scene.Add(rootActor);
804
805   cpBody* body{nullptr};
806   {
807     auto accessor            = adaptor.GetPhysicsAccessor();
808     auto space               = accessor->GetNative().Get<cpSpace*>();
809     body                     = CreateBody(space);
810     Dali::Actor ballActor    = Toolkit::ImageView::New("gallery-small-1.jpg");
811     auto        physicsActor = adaptor.AddActorBody(ballActor, body);
812   }
813
814   tet_infoline("Test that Queue works without accessor");
815   adaptor.Queue([body]() {
816     cpBodySetPosition(body, cpv(100.0f, 20.0f));
817   });
818   adaptor.CreateSyncPoint();
819
820   application.SendNotification();
821   application.Render();
822   // Should trigger an Update
823
824   {
825     auto   accessor = adaptor.GetPhysicsAccessor();
826     cpVect origin   = cpBodyGetPosition(body);
827
828     DALI_TEST_EQUALS(origin.x, cpFloat(100.0f), 0.001f, TEST_LOCATION);
829     DALI_TEST_EQUALS(origin.y, cpFloat(20.0f), 0.001f, TEST_LOCATION);
830   }
831
832   END_TEST;
833 }
834
835 int UtcDaliPhysics2DAdaptorCreateSyncPoint(void)
836 {
837   tet_infoline("Test that a delayed CreateSyncPoint delays update");
838
839   ToolkitTestApplication application;
840   Matrix                 transform(false);
841   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
842   Uint16Pair     size(640, 480);
843   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
844   Actor          rootActor = adaptor.GetRootActor();
845   auto           scene     = application.GetScene();
846   scene.Add(rootActor);
847
848   cpBody* body{nullptr};
849   {
850     auto accessor            = adaptor.GetPhysicsAccessor();
851     auto space               = accessor->GetNative().Get<cpSpace*>();
852     body                     = CreateBody(space);
853     Dali::Actor ballActor    = Toolkit::ImageView::New("gallery-small-1.jpg");
854     auto        physicsActor = adaptor.AddActorBody(ballActor, body);
855
856     tet_infoline("Test that Queue works with accessor");
857     adaptor.Queue([body]() {
858       cpBodySetPosition(body, cpv(100.0f, 20.0f));
859     });
860   }
861
862   // Should trigger an Update without processing queue
863   application.SendNotification();
864   application.Render();
865
866   {
867     auto accessor = adaptor.GetPhysicsAccessor();
868
869     cpVect origin = cpBodyGetPosition(body);
870     DALI_TEST_EQUALS(origin.x, cpFloat(0.0f), 0.01f, TEST_LOCATION);
871     DALI_TEST_EQUALS(origin.y, cpFloat(0.0f), 0.01f, TEST_LOCATION);
872   }
873
874   // Should now execute queue
875   adaptor.CreateSyncPoint();
876   application.SendNotification();
877   application.Render();
878
879   {
880     auto accessor = adaptor.GetPhysicsAccessor();
881
882     cpVect origin = cpBodyGetPosition(body);
883     DALI_TEST_EQUALS(origin.x, cpFloat(100.0f), 0.01f, TEST_LOCATION);
884     DALI_TEST_EQUALS(origin.y, cpFloat(20.0f), 0.01f, TEST_LOCATION);
885   }
886
887   END_TEST;
888 }
889
890 int UtcDaliPhysics2DAdaptorHitTestP(void)
891 {
892   tet_infoline("Test that hit testing finds a body");
893
894   ToolkitTestApplication application;
895   Matrix                 transform(false);
896   transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
897   Uint16Pair     size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
898   const Vector2  center(TestApplication::DEFAULT_SURFACE_WIDTH * 0.5f, TestApplication::DEFAULT_SURFACE_HEIGHT * 0.5f);
899   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
900   Actor          rootActor = adaptor.GetRootActor();
901   auto           scene     = application.GetScene();
902   scene.Add(rootActor);
903
904   {
905     auto        accessor  = adaptor.GetPhysicsAccessor(); // Prevent integration
906     auto        space     = accessor->GetNative().Get<cpSpace*>();
907     Dali::Actor ballActor = Toolkit::ImageView::New(TEST_RESOURCE_DIR "/gallery-small-1.jpg");
908     cpBody*     body      = CreateBody(space);
909     cpBodySetPosition(body, cpv(center.x, center.y));
910
911     ballActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
912     ballActor[Actor::Property::ANCHOR_POINT]  = AnchorPoint::CENTER;
913
914     auto physicsActor = adaptor.AddActorBody(ballActor, body);
915   }
916   Test::WaitForEventThreadTrigger(1);
917
918   // Should trigger an Update without processing queue
919   application.SendNotification();
920   application.Render();
921
922   Vector3 from, to;
923   adaptor.BuildPickingRay(Vector3(center), Vector3(center), from, to); // Hit test centre of screen
924
925   {
926     auto    accessor = adaptor.GetPhysicsAccessor();
927     Vector3 localPivot;
928     float   distanceFromCamera;
929     auto    body = accessor->HitTest(from, from, localPivot, distanceFromCamera);
930
931     DALI_TEST_CHECK(!body.Empty());
932   }
933
934   END_TEST;
935 }