Bug fixes for 2d physics
[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   Quaternion expected(Degree(30.0f), Vector3::XAXIS);
325   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), expected, 0.0001f, TEST_LOCATION);
326
327   END_TEST;
328 }
329
330 int UtcDaliPhysics2DAdaptorTranslateToPhysicsSpace3(void)
331 {
332   ToolkitTestApplication application;
333   Matrix                 transform(false);
334   tet_infoline("Test that using an inverted Y scale inverts rotation");
335
336   transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
337   Uint16Pair     size(640, 480);
338   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
339
340   Quaternion q(Degree(30.0f), Vector3::ZAXIS);
341   Quaternion expected(Degree(-30.0f), Vector3::ZAXIS);
342
343   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), expected, 0.0001f, TEST_LOCATION);
344
345   END_TEST;
346 }
347
348 int UtcDaliPhysics2DAdaptorTranslateFromPhysicsSpace1(void)
349 {
350   ToolkitTestApplication application;
351   Matrix                 transform(false);
352   tet_infoline("Test that using a double scale halves position");
353
354   transform.SetIdentityAndScale(Vector3(2.0f, -2.0f, 1.0f));
355   Uint16Pair     size(640, 480);
356   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
357
358   Vector3 position(20.0f, 20.0f, 0.0f);
359   Vector3 expected(10.0f, -10.0f, 0.0f);
360
361   DALI_TEST_EQUALS(adaptor.TranslateFromPhysicsSpace(position), expected, 0.0001f, TEST_LOCATION);
362
363   END_TEST;
364 }
365
366 int UtcDaliPhysics2DAdaptorConvertVectorToPhysicsSpace01(void)
367 {
368   ToolkitTestApplication application;
369   Matrix                 transform(false);
370   tet_infoline("Test that using a translation does not translate vector");
371
372   transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
373   transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
374   Uint16Pair     size(640, 480);
375   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
376   Vector3        vector(20.0f, 20.0f, 0.0f);
377   DALI_TEST_EQUALS(adaptor.ConvertVectorToPhysicsSpace(vector), vector, 0.0001f, TEST_LOCATION);
378
379   END_TEST;
380 }
381
382 int UtcDaliPhysics2DAdaptorConvertVectorToPhysicsSpace02(void)
383 {
384   ToolkitTestApplication application;
385   Matrix                 transform(false);
386   tet_infoline("Test that using a translation with inverse Y does not translate vector");
387
388   transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
389   transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
390   Uint16Pair     size(640, 480);
391   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
392   Vector3        vector(20.0f, 20.0f, 0.0f);
393   Vector3        expected(20.0f, -20.0f, 0.0f);
394   DALI_TEST_EQUALS(adaptor.ConvertVectorToPhysicsSpace(vector), expected, 0.0001f, TEST_LOCATION);
395
396   END_TEST;
397 }
398
399 int UtcDaliPhysics2DAdaptorConvertVectorFromPhysicsSpace01(void)
400 {
401   ToolkitTestApplication application;
402   Matrix                 transform(false);
403   tet_infoline("Test that using a translation does not translate vector");
404
405   transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
406   transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
407   Uint16Pair     size(640, 480);
408   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
409   Vector3        vector(20.0f, 20.0f, 0.0f);
410   DALI_TEST_EQUALS(adaptor.ConvertVectorFromPhysicsSpace(vector), vector, 0.0001f, TEST_LOCATION);
411
412   END_TEST;
413 }
414
415 int UtcDaliPhysics2DAdaptorConvertVectorFromPhysicsSpace02(void)
416 {
417   ToolkitTestApplication application;
418   Matrix                 transform(false);
419   tet_infoline("Test that using a translation with inverse Y does not translate vector");
420
421   transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
422   transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
423   Uint16Pair     size(640, 480);
424   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
425   Vector3        vector(20.0f, 20.0f, 0.0f);
426   Vector3        expected(20.0f, -20.0f, 0.0f);
427   DALI_TEST_EQUALS(adaptor.ConvertVectorFromPhysicsSpace(vector), expected, 0.0001f, TEST_LOCATION);
428
429   END_TEST;
430 }
431
432 int UtcDaliPhysics2DAdaptorSetTransformAndSize(void)
433 {
434   ToolkitTestApplication application;
435   Matrix                 transform(false);
436   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
437   Uint16Pair     size(640, 480);
438   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
439
440   Vector3 a(30, 20, 10);
441   Vector3 expected(60, 40, 10);
442   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(a), expected, 0.0001f, TEST_LOCATION);
443
444   transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
445   transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
446   adaptor.SetTransformAndSize(transform, size);
447
448   Vector3 expect2(30, 80, 10);
449   DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(a), expect2, 0.0001f, TEST_LOCATION);
450
451   END_TEST;
452 }
453
454 int UtcDaliPhysics2DAdaptorSetIntegrationState(void)
455 {
456   tet_infoline("Test that changing the integration state is reflected");
457
458   ToolkitTestApplication application;
459   Matrix                 transform(false);
460   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
461   Uint16Pair     size(640, 480);
462   auto           scene     = application.GetScene();
463   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
464   Actor          rootActor = adaptor.GetRootActor();
465   scene.Add(rootActor);
466
467   DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::ON);
468
469   adaptor.SetIntegrationState(PhysicsAdaptor::IntegrationState::OFF);
470   DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::OFF);
471
472   END_TEST;
473 }
474
475 int UtcDaliPhysics2DAdaptorGetIntegrationState(void)
476 {
477   tet_infoline("Test that changing the integration state is reflected");
478
479   ToolkitTestApplication application;
480   Matrix                 transform(false);
481   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
482   Uint16Pair     size(640, 480);
483   auto           scene     = application.GetScene();
484   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
485   Actor          rootActor = adaptor.GetRootActor();
486   scene.Add(rootActor);
487
488   adaptor.SetIntegrationState(PhysicsAdaptor::IntegrationState::OFF);
489   DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::OFF);
490
491   adaptor.SetIntegrationState(PhysicsAdaptor::IntegrationState::ON);
492   DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::ON);
493
494   // Can't test actual integration step runs without adding actors - see utc-Dali-PhysicsActor.cpp.
495   END_TEST;
496 }
497
498 int UtcDaliPhysics2DAdaptorSetDebugState(void)
499 {
500   tet_infoline("Test that changing the debug state is reflected");
501
502   ToolkitTestApplication application;
503   Matrix                 transform(false);
504   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
505   Uint16Pair     size(640, 480);
506   auto           scene     = application.GetScene();
507   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
508   Actor          rootActor = adaptor.GetRootActor();
509   scene.Add(rootActor);
510
511   DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::OFF);
512
513   adaptor.SetDebugState(PhysicsAdaptor::DebugState::ON);
514   DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::ON);
515
516   adaptor.SetDebugState(PhysicsAdaptor::DebugState::OFF);
517   DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::OFF);
518
519   END_TEST;
520 }
521
522 int UtcDaliPhysics2DAdaptorGetDebugState(void)
523 {
524   tet_infoline("Test that changing the debug state is reflected");
525
526   ToolkitTestApplication application;
527   Matrix                 transform(false);
528   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
529   Uint16Pair     size(640, 480);
530   auto           scene     = application.GetScene();
531   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
532   Actor          rootActor = adaptor.GetRootActor();
533   scene.Add(rootActor);
534
535   adaptor.SetDebugState(PhysicsAdaptor::DebugState::OFF);
536   DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::OFF);
537
538   adaptor.SetDebugState(PhysicsAdaptor::DebugState::ON);
539   DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::ON);
540
541   // Can't test actual debug step runs without adding actors - see utc-Dali-PhysicsActor.cpp.
542   END_TEST;
543 }
544
545 int UtcDaliPhysics2DAdaptorAddActorBody(void)
546 {
547   tet_infoline("Test that an actor/body pair can be added");
548
549   ToolkitTestApplication application;
550   Matrix                 transform(false);
551   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
552   Uint16Pair     size(640, 480);
553   auto           scene     = application.GetScene();
554   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
555   Actor          rootActor = adaptor.GetRootActor();
556   scene.Add(rootActor);
557
558   auto accessor = adaptor.GetPhysicsAccessor();
559   auto space    = accessor->GetNative().Get<cpSpace*>();
560
561   cpBody*     body         = CreateBody(space);
562   Dali::Actor ballActor    = Toolkit::ImageView::New("gallery-small-1.jpg");
563   auto        physicsActor = adaptor.AddActorBody(ballActor, body);
564
565   DALI_TEST_CHECK(physicsActor);
566   int id = ballActor[Actor::Property::ID];
567
568   DALI_TEST_EQUALS(physicsActor.GetId(), id, TEST_LOCATION);
569   DALI_TEST_EQUALS(physicsActor.GetBody().Get<cpBody*>(), body, TEST_LOCATION);
570
571   END_TEST;
572 }
573
574 void removeShape(cpBody* body, cpShape* shape, void* data)
575 {
576   cpSpace* space = static_cast<cpSpace*>(data);
577   cpSpaceRemoveShape(space, shape);
578   cpShapeSetBody(shape, nullptr);
579   cpShapeFree(shape);
580 }
581
582 int UtcDaliPhysics2DAdaptorRemoveActorBodyP01(void)
583 {
584   tet_infoline("Test that an actor/body pair can be removed");
585
586   ToolkitTestApplication application;
587   Matrix                 transform(false);
588   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
589   Uint16Pair     size(640, 480);
590   auto           scene     = application.GetScene();
591   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
592   Actor          rootActor = adaptor.GetRootActor();
593   scene.Add(rootActor);
594
595   cpBody* body;
596   {
597     auto accessor = adaptor.GetPhysicsAccessor();
598     auto space    = accessor->GetNative().Get<cpSpace*>();
599
600     body = CreateBody(space);
601   }
602   Dali::Actor ballActor    = Toolkit::ImageView::New("gallery-small-1.jpg");
603   auto        physicsActor = adaptor.AddActorBody(ballActor, body);
604
605   application.SendNotification();
606   application.Render();
607   application.SendNotification();
608   application.Render();
609
610   adaptor.RemoveActorBody(physicsActor);
611   DALI_TEST_CHECK(!ballActor.GetParent());
612
613   {
614     auto accessor = adaptor.GetPhysicsAccessor();
615     auto space    = accessor->GetNative().Get<cpSpace*>();
616
617     try
618     {
619       cpBodyEachShape(body, removeShape, space);
620       cpSpaceRemoveBody(space, body);
621       tet_result(TET_PASS);
622     }
623     catch(std::exception& e)
624     {
625       tet_result(TET_FAIL);
626     }
627   }
628
629   END_TEST;
630 }
631
632 int UtcDaliPhysics2DAdaptorRemoveActorBodyN01(void)
633 {
634   ToolkitTestApplication application;
635   Matrix                 transform(false);
636   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
637   Uint16Pair     size(640, 480);
638   auto           scene     = application.GetScene();
639   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
640   Actor          rootActor = adaptor.GetRootActor();
641   scene.Add(rootActor);
642
643   tet_infoline("Test that removing a physics actor that hasn't been created with AddActorBody does nothing");
644   Dali::Actor  actor        = Dali::Actor::New();
645   cpBody*      body         = cpBodyNew(1.0f, 1.0f);
646   PhysicsActor physicsActor = PhysicsActor::New(actor, body, adaptor);
647   ;
648   try
649   {
650     adaptor.RemoveActorBody(physicsActor);
651     tet_result(TET_PASS);
652   }
653   catch(std::exception& e)
654   {
655     // Should fail silently, without exception!
656     tet_result(TET_FAIL);
657   }
658
659   END_TEST;
660 }
661
662 int UtcDaliPhysics2DAdaptorRemoveActorBodyN02(void)
663 {
664   tet_infoline("Test that an empty actor/body pair doesn't break adaptor");
665
666   ToolkitTestApplication application;
667   Matrix                 transform(false);
668   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
669   Uint16Pair     size(640, 480);
670   auto           scene     = application.GetScene();
671   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
672   Actor          rootActor = adaptor.GetRootActor();
673   scene.Add(rootActor);
674
675   PhysicsActor physicsActor;
676   try
677   {
678     adaptor.RemoveActorBody(physicsActor);
679     tet_result(TET_FAIL);
680   }
681   catch(DaliException& e)
682   {
683     DALI_TEST_ASSERT(e, "Physics actor handle is empty", TEST_LOCATION);
684   }
685
686   END_TEST;
687 }
688
689 int UtcDaliPhysics2DAdaptorGetPhysicsActor(void)
690 {
691   tet_infoline("Test that an actor/body pair can be retrieved");
692
693   ToolkitTestApplication application;
694   Matrix                 transform(false);
695   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
696   Uint16Pair     size(640, 480);
697   auto           scene     = application.GetScene();
698   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
699   Actor          rootActor = adaptor.GetRootActor();
700   scene.Add(rootActor);
701
702   auto accessor = adaptor.GetPhysicsAccessor();
703   auto space    = accessor->GetNative().Get<cpSpace*>();
704
705   cpBody*     body         = CreateBody(space);
706   Dali::Actor ballActor    = Toolkit::ImageView::New("gallery-small-1.jpg");
707   auto        physicsActor = adaptor.AddActorBody(ballActor, body);
708
709   DALI_TEST_CHECK(physicsActor);
710
711   PhysicsActor testActor = adaptor.GetPhysicsActor(body);
712   DALI_TEST_CHECK(testActor);
713   DALI_TEST_CHECK(physicsActor == testActor);
714
715   END_TEST;
716 }
717
718 int UtcDaliPhysics2DAdaptorBuildPickingRay(void)
719 {
720   tet_infoline("Test that picking ray converts screen coords");
721
722   ToolkitTestApplication application;
723   Matrix                 transform(false);
724   transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
725   Uint16Pair     size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
726   const Vector2  center(TestApplication::DEFAULT_SURFACE_WIDTH * 0.5f, TestApplication::DEFAULT_SURFACE_HEIGHT * 0.5f);
727   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
728   Actor          rootActor = adaptor.GetRootActor();
729   auto           scene     = application.GetScene();
730   scene.Add(rootActor);
731
732   Vector3 from, to;
733   adaptor.BuildPickingRay(Vector3(center), Vector3(center), from, to); // Hit test centre of screen
734   Vector3 physCenter = adaptor.TranslateToPhysicsSpace(Vector3(center));
735   DALI_TEST_EQUALS(from, physCenter, 0.001f, TEST_LOCATION);
736
737   END_TEST;
738 }
739
740 int UtcDaliPhysics2DAdaptorProjectPoint(void)
741 {
742   tet_infoline("Test that a point is projected into physics space");
743
744   ToolkitTestApplication application;
745   Matrix                 transform(false);
746   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
747   Uint16Pair     size(640, 480);
748   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
749
750   Vector3 projectedPoint = adaptor.ProjectPoint(Vector3(), -Vector3::ZAXIS, 200);
751
752   DALI_TEST_EQUALS(projectedPoint, Vector3(0.0f, 0.0f, 0.0f), 0.001f, TEST_LOCATION);
753
754   END_TEST;
755 }
756
757 int UtcDaliPhysics2DAdaptorQueue(void)
758 {
759   tet_infoline("Test that Queue and CreateSyncPoint both work");
760
761   ToolkitTestApplication application;
762   Matrix                 transform(false);
763   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
764   Uint16Pair     size(640, 480);
765   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
766   Actor          rootActor = adaptor.GetRootActor();
767   auto           scene     = application.GetScene();
768   scene.Add(rootActor);
769
770   cpBody* body{nullptr};
771   {
772     auto accessor            = adaptor.GetPhysicsAccessor();
773     auto space               = accessor->GetNative().Get<cpSpace*>();
774     body                     = CreateBody(space);
775     Dali::Actor ballActor    = Toolkit::ImageView::New("gallery-small-1.jpg");
776     auto        physicsActor = adaptor.AddActorBody(ballActor, body);
777   }
778
779   tet_infoline("Test that Queue works without accessor");
780   adaptor.Queue([body]() {
781     cpBodySetPosition(body, cpv(100.0f, 20.0f));
782   });
783   adaptor.CreateSyncPoint();
784
785   application.SendNotification();
786   application.Render();
787   // Should trigger an Update
788
789   {
790     auto   accessor = adaptor.GetPhysicsAccessor();
791     cpVect origin   = cpBodyGetPosition(body);
792
793     DALI_TEST_EQUALS(origin.x, cpFloat(100.0f), 0.001f, TEST_LOCATION);
794     DALI_TEST_EQUALS(origin.y, cpFloat(20.0f), 0.001f, TEST_LOCATION);
795   }
796
797   END_TEST;
798 }
799
800 int UtcDaliPhysics2DAdaptorCreateSyncPoint(void)
801 {
802   tet_infoline("Test that a delayed CreateSyncPoint delays update");
803
804   ToolkitTestApplication application;
805   Matrix                 transform(false);
806   transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 1.0f));
807   Uint16Pair     size(640, 480);
808   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
809   Actor          rootActor = adaptor.GetRootActor();
810   auto           scene     = application.GetScene();
811   scene.Add(rootActor);
812
813   cpBody* body{nullptr};
814   {
815     auto accessor            = adaptor.GetPhysicsAccessor();
816     auto space               = accessor->GetNative().Get<cpSpace*>();
817     body                     = CreateBody(space);
818     Dali::Actor ballActor    = Toolkit::ImageView::New("gallery-small-1.jpg");
819     auto        physicsActor = adaptor.AddActorBody(ballActor, body);
820
821     tet_infoline("Test that Queue works with accessor");
822     adaptor.Queue([body]() {
823       cpBodySetPosition(body, cpv(100.0f, 20.0f));
824     });
825   }
826
827   // Should trigger an Update without processing queue
828   application.SendNotification();
829   application.Render();
830
831   {
832     auto accessor = adaptor.GetPhysicsAccessor();
833
834     cpVect origin = cpBodyGetPosition(body);
835     DALI_TEST_EQUALS(origin.x, cpFloat(0.0f), 0.01f, TEST_LOCATION);
836     DALI_TEST_EQUALS(origin.y, cpFloat(0.0f), 0.01f, TEST_LOCATION);
837   }
838
839   // Should now execute queue
840   adaptor.CreateSyncPoint();
841   application.SendNotification();
842   application.Render();
843
844   {
845     auto accessor = adaptor.GetPhysicsAccessor();
846
847     cpVect origin = cpBodyGetPosition(body);
848     DALI_TEST_EQUALS(origin.x, cpFloat(100.0f), 0.01f, TEST_LOCATION);
849     DALI_TEST_EQUALS(origin.y, cpFloat(20.0f), 0.01f, TEST_LOCATION);
850   }
851
852   END_TEST;
853 }
854
855 int UtcDaliPhysics2DAdaptorHitTestP(void)
856 {
857   tet_infoline("Test that hit testing finds a body");
858
859   ToolkitTestApplication application;
860   Matrix                 transform(false);
861   transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
862   Uint16Pair     size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
863   const Vector2  center(TestApplication::DEFAULT_SURFACE_WIDTH * 0.5f, TestApplication::DEFAULT_SURFACE_HEIGHT * 0.5f);
864   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
865   Actor          rootActor = adaptor.GetRootActor();
866   auto           scene     = application.GetScene();
867   scene.Add(rootActor);
868
869   {
870     auto        accessor  = adaptor.GetPhysicsAccessor(); // Prevent integration
871     auto        space     = accessor->GetNative().Get<cpSpace*>();
872     Dali::Actor ballActor = Toolkit::ImageView::New(TEST_RESOURCE_DIR "/gallery-small-1.jpg");
873     cpBody*     body      = CreateBody(space);
874     cpBodySetPosition(body, cpv(center.x, center.y));
875
876     ballActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
877     ballActor[Actor::Property::ANCHOR_POINT]  = AnchorPoint::CENTER;
878
879     auto physicsActor = adaptor.AddActorBody(ballActor, body);
880   }
881   Test::WaitForEventThreadTrigger(1);
882
883   // Should trigger an Update without processing queue
884   application.SendNotification();
885   application.Render();
886
887   Vector3 from, to;
888   adaptor.BuildPickingRay(Vector3(center), Vector3(center), from, to); // Hit test centre of screen
889
890   {
891     auto    accessor = adaptor.GetPhysicsAccessor();
892     Vector3 localPivot;
893     float   distanceFromCamera;
894     auto    body = accessor->HitTest(from, from, localPivot, distanceFromCamera);
895
896     DALI_TEST_CHECK(!body.Empty());
897   }
898
899   END_TEST;
900 }