2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
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>
32 #include <bullet/btBulletDynamicsCommon.h>
35 using namespace Dali::Toolkit::Physics;
37 void utc_dali_physics3d_startup(void)
39 test_return_value = TET_UNDEF;
42 void utc_dali_physics3d_cleanup(void)
44 test_return_value = TET_PASS;
47 btRigidBody* CreateBody(btDiscreteDynamicsWorld* bulletWorld)
49 btSphereShape* ball = new btSphereShape(30);
50 btVector3 localInertia(0.f, 0.f, 0.f);
51 ball->calculateLocalInertia(10, localInertia);
52 btTransform transform;
53 transform.setIdentity();
54 auto* motionState = new btDefaultMotionState(transform);
56 btRigidBody::btRigidBodyConstructionInfo ci(10, motionState, ball, localInertia);
58 btRigidBody* body = new btRigidBody(ci);
59 body->setFriction(0.5f);
60 body->setRestitution(0.5f);
61 bulletWorld->addRigidBody(body);
65 int UtcDaliPhysics3DCreateAdaptorP1(void)
67 ToolkitTestApplication application;
69 Matrix transform(true);
70 Uint16Pair size(640, 480);
72 PhysicsAdaptor handle = PhysicsAdaptor::New(transform, size);
73 DALI_TEST_CHECK(handle);
78 int UtcDaliPhysics3DCreateAdaptorN1(void)
80 ToolkitTestApplication application;
82 PhysicsAdaptor handle;
83 DALI_TEST_CHECK(!handle);
88 int UtcDaliPhysics3DDowncastP1(void)
90 ToolkitTestApplication application;
92 Matrix transform(true);
93 Uint16Pair size(640, 480);
95 BaseHandle handle = PhysicsAdaptor::New(transform, size);
97 auto adaptor = PhysicsAdaptor::DownCast(handle);
98 DALI_TEST_CHECK(adaptor);
99 //Following only works if type is registered
100 //DALI_TEST_EQUALS("PhysicsAdaptor", adaptor.GetTypeName(), TEST_LOCATION);
104 int UtcDaliPhysics3DDowncastN1(void)
107 auto adaptor = PhysicsAdaptor::DownCast(handle);
108 DALI_TEST_CHECK(!adaptor);
110 DALI_TEST_CHECK(typeid(PhysicsAdaptor) == typeid(decltype(adaptor)));
114 int UtcDaliPhysics3DAdaptorMoveConstructor(void)
116 ToolkitTestApplication application;
117 tet_infoline("Testing the move constructor");
119 Matrix transform(true);
120 Uint16Pair size(640, 480);
121 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
122 DALI_TEST_CHECK(adaptor);
124 PhysicsAdaptor moved = std::move(adaptor);
125 DALI_TEST_CHECK(moved);
126 DALI_TEST_CHECK(!adaptor);
127 DALI_TEST_CHECK(moved != adaptor);
132 int UtcDaliPhysics3DAdaptorCopyConstructor(void)
134 ToolkitTestApplication application;
135 tet_infoline("Testing the move constructor");
137 Matrix transform(true);
138 Uint16Pair size(640, 480);
139 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
141 DALI_TEST_CHECK(adaptor);
143 PhysicsAdaptor altAdaptor = adaptor;
144 DALI_TEST_CHECK(altAdaptor);
145 DALI_TEST_CHECK(adaptor);
146 DALI_TEST_CHECK(altAdaptor == adaptor); // should point at same object
151 int UtcDaliPhysics3DAdaptorCopyAssign(void)
153 ToolkitTestApplication application;
154 tet_infoline("Testing the copy assign");
156 Matrix transform(true);
157 Uint16Pair size(640, 480);
158 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
159 DALI_TEST_CHECK(adaptor);
161 PhysicsAdaptor altAdaptor = adaptor;
162 DALI_TEST_CHECK(altAdaptor);
163 DALI_TEST_CHECK(adaptor);
164 DALI_TEST_CHECK(altAdaptor == adaptor); // should point at same object
169 int UtcDaliPhysics3DAdaptorMoveAssignment(void)
171 ToolkitTestApplication application;
172 tet_infoline("Testing the move constructor");
174 Matrix transform(true);
175 Uint16Pair size(640, 480);
176 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
177 DALI_TEST_CHECK(adaptor);
179 PhysicsAdaptor moved;
180 moved = std::move(adaptor);
181 DALI_TEST_CHECK(moved);
182 DALI_TEST_CHECK(!adaptor);
187 int UtcDaliPhysics3DSetTimestep(void)
189 ToolkitTestApplication application;
191 Matrix transform(true);
192 Uint16Pair size(640, 480);
194 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
195 adaptor.SetTimestep(1.0f / 60.0f);
197 DALI_TEST_EQUALS(adaptor.GetTimestep(), 1.0f / 60.0f, 0.0001f, TEST_LOCATION);
202 int UtcDaliPhysics3DGetTimestep(void)
204 ToolkitTestApplication application;
206 Matrix transform(true);
207 Uint16Pair size(640, 480);
209 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
210 adaptor.SetTimestep(1.0f / 60.0f);
211 float timestep = adaptor.GetTimestep();
212 float expected = 1.0f / 60.0f;
213 DALI_TEST_EQUALS(timestep, expected, 0.0001f, TEST_LOCATION);
215 adaptor.SetTimestep(1.0f / 120.0f);
216 timestep = adaptor.GetTimestep();
217 expected = 1.0f / 120.0f;
218 DALI_TEST_EQUALS(timestep, expected, 0.0001f, TEST_LOCATION);
223 int UtcDaliPhysics3DGetPhysicsAccessorP1(void)
225 ToolkitTestApplication application;
227 Matrix transform(true);
228 Uint16Pair size(640, 480);
230 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
231 PhysicsAdaptor::ScopedPhysicsAccessorPtr accessor = adaptor.GetPhysicsAccessor();
232 DALI_TEST_CHECK(accessor.get() != nullptr);
234 Dali::Any world = accessor->GetNative();
235 DALI_TEST_CHECK(!world.Empty());
240 int UtcDaliPhysics3DGetPhysicsAccessorN1(void)
242 ToolkitTestApplication application;
244 PhysicsAdaptor handle;
245 DALI_TEST_CHECK(!handle);
249 auto ptr = handle.GetPhysicsAccessor();
250 DALI_TEST_CHECK(ptr == nullptr);
252 tet_result(TET_FAIL);
254 catch(DaliException& e)
256 DALI_TEST_ASSERT(e, "Physics adaptor handle is empty", TEST_LOCATION);
262 int UtcDaliPhysics3DAdaptorGetRootActor(void)
264 tet_infoline("Test that the root actor can be retrieved");
266 ToolkitTestApplication application;
267 Matrix transform(false);
268 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
269 Uint16Pair size(640, 480);
270 auto scene = application.GetScene();
271 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
272 Actor rootActor = adaptor.GetRootActor();
273 scene.Add(rootActor);
275 DALI_TEST_CHECK(rootActor);
276 DALI_TEST_EQUALS(rootActor.GetProperty<Vector2>(Actor::Property::SIZE), Vector2(640.0f, 480.0f), 0.001f, TEST_LOCATION);
281 int UtcDaliPhysics3DAdaptorCreateDebugLayer(void)
283 ToolkitTestApplication application;
284 Matrix transform(true);
285 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
286 Uint16Pair size(640, 480);
287 auto scene = application.GetScene();
289 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
290 Actor rootActor = adaptor.GetRootActor();
291 scene.Add(rootActor);
292 Window window = DevelWindow::Get(rootActor);
294 Layer layer = adaptor.CreateDebugLayer(window);
295 DALI_TEST_CHECK(layer);
297 adaptor.SetDebugState(PhysicsAdaptor::DebugState::ON);
299 btRigidBody* body{nullptr};
301 auto accessor = adaptor.GetPhysicsAccessor();
302 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
303 body = CreateBody(bulletWorld);
304 Dali::Actor ballActor = Toolkit::ImageView::New(TEST_RESOURCE_DIR "/gallery-small-1.jpg");
305 auto physicsActor = adaptor.AddActorBody(ballActor, body);
306 physicsActor.AsyncSetPhysicsPosition(Vector3(0.f, 0.f, 0.f));
308 Test::WaitForEventThreadTrigger(1);
309 application.SendNotification();
310 application.Render();
312 application.SendNotification();
313 application.Render();
318 int UtcDaliPhysics3DAdaptorTranslateToPhysicsSpace1(void)
320 ToolkitTestApplication application;
321 Matrix transform(false);
322 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
323 Uint16Pair size(640, 480);
324 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
326 Vector3 a(30, 20, 10);
327 Vector3 expected = a * 2.0f;
328 DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(a), expected, 0.0001f, TEST_LOCATION);
333 int UtcDaliPhysics3DAdaptorTranslateToPhysicsSpace2(void)
335 ToolkitTestApplication application;
336 Matrix transform(false);
337 tet_infoline("Test that using an alternative scale doesn't change rotation");
338 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
339 Uint16Pair size(640, 480);
340 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
342 // Rotation shouldn't change under this scale
343 Quaternion q(Degree(30.0f), Vector3::XAXIS);
344 DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), q, 0.0001f, TEST_LOCATION);
349 int UtcDaliPhysics3DAdaptorTranslateToPhysicsSpace3(void)
351 ToolkitTestApplication application;
352 Matrix transform(false);
353 tet_infoline("Test that using an inverted Y scale also inverts quaternions");
355 transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
356 Uint16Pair size(640, 480);
357 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
359 Quaternion q(Degree(30.0f), Vector3::ZAXIS);
360 Quaternion qp(Degree(-30.0f), Vector3::ZAXIS); // We have mirrored along Y axis, so Z rot is opposite.
362 DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), qp, 0.0001f, TEST_LOCATION);
367 int UtcDaliPhysics3DAdaptorTranslateToPhysicsSpace4(void)
369 ToolkitTestApplication application;
370 Matrix transform(false);
371 tet_infoline("Test that using an inverted Y scale also inverts quaternions");
373 transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
374 Uint16Pair size(640, 480);
375 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
377 Quaternion q(Degree(30.0f), Vector3::XAXIS);
378 Quaternion qp(Degree(-30.0f), Vector3::XAXIS); // We have mirrored along Y axis, so Z rot is opposite.
380 DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), qp, 0.0001f, TEST_LOCATION);
385 int UtcDaliPhysics3DAdaptorTranslateToPhysicsSpace5(void)
387 ToolkitTestApplication application;
388 Matrix transform(false);
389 tet_infoline("Test that using an inverted Y scale also inverts quaternions, except along Y axis");
391 transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
392 Uint16Pair size(640, 480);
393 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
395 Quaternion q(Degree(30.0f), Vector3::YAXIS);
396 Quaternion qp(Degree(30.0f), Vector3::YAXIS);
398 DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(q), qp, 0.0001f, TEST_LOCATION);
403 int UtcDaliPhysics3DAdaptorTranslateFromPhysicsSpace1(void)
405 ToolkitTestApplication application;
406 Matrix transform(false);
407 tet_infoline("Test that using a double scale halves position");
409 transform.SetIdentityAndScale(Vector3(2.0f, -2.0f, 2.0f));
410 Uint16Pair size(640, 480);
411 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
413 Vector3 position(20.0f, 20.0f, 0.0f);
414 Vector3 expected(10.0f, -10.0f, 0.0f);
416 DALI_TEST_EQUALS(adaptor.TranslateFromPhysicsSpace(position), expected, 0.0001f, TEST_LOCATION);
421 int UtcDaliPhysics3DAdaptorConvertVectorToPhysicsSpace01(void)
423 ToolkitTestApplication application;
424 Matrix transform(false);
425 tet_infoline("Test that using a translation does not translate vector");
427 transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
428 transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
429 Uint16Pair size(640, 480);
430 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
431 Vector3 vector(20.0f, 20.0f, 0.0f);
432 DALI_TEST_EQUALS(adaptor.ConvertVectorToPhysicsSpace(vector), vector, 0.0001f, TEST_LOCATION);
437 int UtcDaliPhysics3DAdaptorConvertVectorToPhysicsSpace02(void)
439 ToolkitTestApplication application;
440 Matrix transform(false);
441 tet_infoline("Test that using a translation with inverse Y does not translate vector");
443 transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
444 transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
445 Uint16Pair size(640, 480);
446 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
447 Vector3 vector(20.0f, 20.0f, 0.0f);
448 Vector3 expected(20.0f, -20.0f, 0.0f);
449 DALI_TEST_EQUALS(adaptor.ConvertVectorToPhysicsSpace(vector), expected, 0.0001f, TEST_LOCATION);
454 int UtcDaliPhysics3DAdaptorConvertVectorFromPhysicsSpace01(void)
456 ToolkitTestApplication application;
457 Matrix transform(false);
458 tet_infoline("Test that using a translation does not translate vector");
460 transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
461 transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
462 Uint16Pair size(640, 480);
463 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
464 Vector3 vector(20.0f, 20.0f, 0.0f);
465 DALI_TEST_EQUALS(adaptor.ConvertVectorFromPhysicsSpace(vector), vector, 0.0001f, TEST_LOCATION);
470 int UtcDaliPhysics3DAdaptorConvertVectorFromPhysicsSpace02(void)
472 ToolkitTestApplication application;
473 Matrix transform(false);
474 tet_infoline("Test that using a translation with inverse Y does not translate vector");
476 transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
477 transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
478 Uint16Pair size(640, 480);
479 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
480 Vector3 vector(20.0f, 20.0f, 0.0f);
481 Vector3 expected(20.0f, -20.0f, 0.0f);
482 DALI_TEST_EQUALS(adaptor.ConvertVectorFromPhysicsSpace(vector), expected, 0.0001f, TEST_LOCATION);
487 int UtcDaliPhysics3DAdaptorSetTransformAndSize(void)
489 ToolkitTestApplication application;
490 Matrix transform(false);
491 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
492 Uint16Pair size(640, 480);
493 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
495 Vector3 a(30, 20, 10);
496 Vector3 expected = a * 2.0f;
497 DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(a), expected, 0.0001f, TEST_LOCATION);
499 transform.SetIdentityAndScale(Vector3(1.0f, -1.0f, 1.0f));
500 transform.SetTranslation(Vector3(0.0f, 100.0f, 0.0f));
501 adaptor.SetTransformAndSize(transform, size);
503 Vector3 expect2(30, 80, 10);
504 DALI_TEST_EQUALS(adaptor.TranslateToPhysicsSpace(a), expect2, 0.0001f, TEST_LOCATION);
509 int UtcDaliPhysics3DAdaptorSetIntegrationState(void)
511 tet_infoline("Test that changing the integration state is reflected");
513 ToolkitTestApplication application;
514 Matrix transform(false);
515 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
516 Uint16Pair size(640, 480);
517 auto scene = application.GetScene();
518 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
519 Actor rootActor = adaptor.GetRootActor();
520 scene.Add(rootActor);
522 DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::ON);
524 adaptor.SetIntegrationState(PhysicsAdaptor::IntegrationState::OFF);
525 DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::OFF);
530 int UtcDaliPhysics3DAdaptorGetIntegrationState(void)
532 tet_infoline("Test that changing the integration state is reflected");
534 ToolkitTestApplication application;
535 Matrix transform(false);
536 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
537 Uint16Pair size(640, 480);
538 auto scene = application.GetScene();
539 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
540 Actor rootActor = adaptor.GetRootActor();
541 scene.Add(rootActor);
543 adaptor.SetIntegrationState(PhysicsAdaptor::IntegrationState::OFF);
544 DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::OFF);
546 adaptor.SetIntegrationState(PhysicsAdaptor::IntegrationState::ON);
547 DALI_TEST_CHECK(adaptor.GetIntegrationState() == PhysicsAdaptor::IntegrationState::ON);
549 // Can't test actual integration step runs without adding actors - see utc-Dali-PhysicsActor.cpp.
553 int UtcDaliPhysics3DAdaptorSetDebugState(void)
555 tet_infoline("Test that changing the debug state is reflected");
557 ToolkitTestApplication application;
558 Matrix transform(false);
559 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
560 Uint16Pair size(640, 480);
561 auto scene = application.GetScene();
562 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
563 Actor rootActor = adaptor.GetRootActor();
564 scene.Add(rootActor);
566 DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::OFF);
568 adaptor.SetDebugState(PhysicsAdaptor::DebugState::ON);
569 DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::ON);
571 adaptor.SetDebugState(PhysicsAdaptor::DebugState::OFF);
572 DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::OFF);
577 int UtcDaliPhysics3DAdaptorGetDebugState(void)
579 tet_infoline("Test that changing the debug state is reflected");
581 ToolkitTestApplication application;
582 Matrix transform(false);
583 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
584 Uint16Pair size(640, 480);
585 auto scene = application.GetScene();
586 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
587 Actor rootActor = adaptor.GetRootActor();
588 scene.Add(rootActor);
590 adaptor.SetDebugState(PhysicsAdaptor::DebugState::OFF);
591 DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::OFF);
593 adaptor.SetDebugState(PhysicsAdaptor::DebugState::ON);
594 DALI_TEST_CHECK(adaptor.GetDebugState() == PhysicsAdaptor::DebugState::ON);
596 // Can't test actual debug step runs without adding actors - see utc-Dali-PhysicsActor.cpp.
600 int UtcDaliPhysics3DAdaptorAddActorBody(void)
602 tet_infoline("Test that an actor/body pair can be added");
604 ToolkitTestApplication application;
605 Matrix transform(false);
606 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
607 Uint16Pair size(640, 480);
608 auto scene = application.GetScene();
609 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
610 Actor rootActor = adaptor.GetRootActor();
611 scene.Add(rootActor);
613 auto accessor = adaptor.GetPhysicsAccessor();
614 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
616 btRigidBody* body = CreateBody(bulletWorld);
617 Dali::Actor ballActor = Toolkit::ImageView::New("gallery-small-1.jpg");
618 auto physicsActor = adaptor.AddActorBody(ballActor, body);
620 DALI_TEST_CHECK(physicsActor);
621 int id = ballActor[Actor::Property::ID];
623 DALI_TEST_EQUALS(physicsActor.GetId(), id, TEST_LOCATION);
624 DALI_TEST_EQUALS(physicsActor.GetBody().Get<btRigidBody*>(), body, TEST_LOCATION);
629 int UtcDaliPhysics3DAdaptorRemoveActorBodyP01(void)
631 tet_infoline("Test that an actor/body pair can be removed");
633 ToolkitTestApplication application;
634 Matrix transform(false);
635 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
636 Uint16Pair size(640, 480);
637 auto scene = application.GetScene();
638 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
639 Actor rootActor = adaptor.GetRootActor();
640 scene.Add(rootActor);
644 auto accessor = adaptor.GetPhysicsAccessor();
645 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
647 body = CreateBody(bulletWorld);
649 Dali::Actor ballActor = Toolkit::ImageView::New("gallery-small-1.jpg");
650 auto physicsActor = adaptor.AddActorBody(ballActor, body);
652 application.SendNotification();
653 application.Render();
654 application.SendNotification();
655 application.Render();
657 adaptor.RemoveActorBody(physicsActor);
658 DALI_TEST_CHECK(!ballActor.GetParent());
661 auto accessor = adaptor.GetPhysicsAccessor();
662 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
664 bulletWorld->removeRigidBody(body);
668 tet_result(TET_PASS);
670 catch(std::exception& e)
672 tet_result(TET_FAIL);
679 int UtcDaliPhysics3DAdaptorRemoveActorBodyN01(void)
681 tet_infoline("Test that an empty actor/body pair doesn't break adaptor");
683 ToolkitTestApplication application;
684 Matrix transform(false);
685 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
686 Uint16Pair size(640, 480);
687 auto scene = application.GetScene();
688 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
689 Actor rootActor = adaptor.GetRootActor();
690 scene.Add(rootActor);
692 tet_infoline("Test that removing a physics actor that hasn't been created with AddActorBody does nothing");
694 Dali::Actor actor = Dali::Actor::New();
697 auto accessor = adaptor.GetPhysicsAccessor();
698 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
700 body = CreateBody(bulletWorld);
703 PhysicsActor physicsActor = PhysicsActor::New(actor, body, adaptor);
707 adaptor.RemoveActorBody(physicsActor);
708 tet_result(TET_PASS);
710 catch(std::exception& e)
712 tet_result(TET_FAIL);
718 int UtcDaliPhysics3DAdaptorRemoveActorBodyN02(void)
720 tet_infoline("Test that an empty actor/body pair doesn't break adaptor");
722 ToolkitTestApplication application;
723 Matrix transform(false);
724 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
725 Uint16Pair size(640, 480);
726 auto scene = application.GetScene();
727 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
728 Actor rootActor = adaptor.GetRootActor();
729 scene.Add(rootActor);
731 PhysicsActor physicsActor;
734 adaptor.RemoveActorBody(physicsActor);
735 tet_result(TET_FAIL);
737 catch(DaliException& e)
739 DALI_TEST_ASSERT(e, "Physics actor handle is empty", TEST_LOCATION);
745 int UtcDaliPhysics3DAdaptorGetPhysicsActor(void)
747 tet_infoline("Test that an actor/body pair can be retrieved");
749 ToolkitTestApplication application;
750 Matrix transform(false);
751 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
752 Uint16Pair size(640, 480);
753 auto scene = application.GetScene();
754 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
755 Actor rootActor = adaptor.GetRootActor();
756 scene.Add(rootActor);
758 auto accessor = adaptor.GetPhysicsAccessor();
759 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
761 btRigidBody* body = CreateBody(bulletWorld);
762 Dali::Actor ballActor = Toolkit::ImageView::New("gallery-small-1.jpg");
763 auto physicsActor = adaptor.AddActorBody(ballActor, body);
765 DALI_TEST_CHECK(physicsActor);
767 PhysicsActor testActor = adaptor.GetPhysicsActor(body);
768 DALI_TEST_CHECK(testActor);
769 DALI_TEST_CHECK(physicsActor == testActor);
774 int UtcDaliPhysics3DAdaptorBuildPickingRay(void)
776 tet_infoline("Test that a touch can be converted to a picking ray");
778 ToolkitTestApplication application;
779 Matrix transform(false);
780 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
781 Uint16Pair size(640, 480);
782 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
785 adaptor.BuildPickingRay(Vector3(), -Vector3::ZAXIS, from, to);
787 DALI_TEST_EQUALS(from, Vector3(), 0.001f, TEST_LOCATION);
788 DALI_TEST_EQUALS(to, Vector3(0.0f, 0.0f, -20000.0f), 0.001f, TEST_LOCATION);
793 int UtcDaliPhysics3DAdaptorProjectPoint(void)
795 tet_infoline("Test that a point is projected into physics space");
797 ToolkitTestApplication application;
798 Matrix transform(false);
799 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
800 Uint16Pair size(640, 480);
801 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
803 // distance is in physics units, not DALi units!
804 Vector3 projectedPoint = adaptor.ProjectPoint(Vector3(), -Vector3::ZAXIS, 200);
806 DALI_TEST_EQUALS(projectedPoint, Vector3(0.0f, 0.0f, -200.0f), 0.001f, TEST_LOCATION);
811 int UtcDaliPhysics3DAdaptorQueue(void)
813 tet_infoline("Test that Queue and CreateSyncPoint both work");
815 ToolkitTestApplication application;
816 Matrix transform(false);
817 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
818 Uint16Pair size(640, 480);
819 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
820 Actor rootActor = adaptor.GetRootActor();
821 auto scene = application.GetScene();
822 scene.Add(rootActor);
824 btRigidBody* body{nullptr};
826 auto accessor = adaptor.GetPhysicsAccessor();
827 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
828 body = CreateBody(bulletWorld);
829 Dali::Actor ballActor = Toolkit::ImageView::New("gallery-small-1.jpg");
830 auto physicsActor = adaptor.AddActorBody(ballActor, body);
833 tet_infoline("Test that Queue works without accessor");
834 adaptor.Queue([body]() {
835 body->getWorldTransform().setOrigin(btVector3(100.0f, 20.0f, 20.0f));
837 adaptor.CreateSyncPoint();
839 application.SendNotification();
840 application.Render();
841 // Should trigger an Update
844 auto accessor = adaptor.GetPhysicsAccessor();
846 btVector3 origin = body->getWorldTransform().getOrigin();
847 DALI_TEST_EQUALS(origin.x(), 100.0f, 0.001f, TEST_LOCATION);
848 DALI_TEST_EQUALS(origin.y(), 20.0f, 0.001f, TEST_LOCATION);
849 DALI_TEST_EQUALS(origin.z(), 20.0f, 0.001f, TEST_LOCATION);
855 int UtcDaliPhysics3DAdaptorCreateSyncPoint(void)
857 tet_infoline("Test that a delayed CreateSyncPoint delays update");
859 ToolkitTestApplication application;
860 Matrix transform(false);
861 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
862 Uint16Pair size(640, 480);
863 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
864 Actor rootActor = adaptor.GetRootActor();
865 auto scene = application.GetScene();
866 scene.Add(rootActor);
868 btRigidBody* body{nullptr};
870 auto accessor = adaptor.GetPhysicsAccessor();
871 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
872 body = CreateBody(bulletWorld);
873 Dali::Actor ballActor = Toolkit::ImageView::New("gallery-small-1.jpg");
874 auto physicsActor = adaptor.AddActorBody(ballActor, body);
876 tet_infoline("Test that Queue works with accessor");
877 adaptor.Queue([body]() {
878 body->getWorldTransform().setOrigin(btVector3(100.0f, 20.0f, 20.0f));
882 // Should trigger an Update without processing queue
883 application.SendNotification();
884 application.Render();
887 auto accessor = adaptor.GetPhysicsAccessor();
889 btVector3 origin = body->getWorldTransform().getOrigin();
890 DALI_TEST_EQUALS(origin.x(), 0.0f, 0.001f, TEST_LOCATION);
891 DALI_TEST_EQUALS(origin.y(), 0.0f, 0.001f, TEST_LOCATION);
892 DALI_TEST_EQUALS(origin.z(), 0.0f, 0.001f, TEST_LOCATION);
895 // Should now execute queue
896 adaptor.CreateSyncPoint();
897 application.SendNotification();
898 application.Render();
901 auto accessor = adaptor.GetPhysicsAccessor();
903 btVector3 origin = body->getWorldTransform().getOrigin();
904 DALI_TEST_EQUALS(origin.x(), 100.0f, 0.001f, TEST_LOCATION);
905 DALI_TEST_EQUALS(origin.y(), 20.0f, 0.001f, TEST_LOCATION);
906 DALI_TEST_EQUALS(origin.z(), 20.0f, 0.001f, TEST_LOCATION);
912 int UtcDaliPhysics3DAdaptorHitTestP(void)
914 tet_infoline("Test that hit testing finds a body");
916 ToolkitTestApplication application;
917 Matrix transform(false);
918 transform.SetIdentityAndScale(Vector3(1.0f, 1.0f, 1.0f));
919 Uint16Pair size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
920 const Vector2 center(TestApplication::DEFAULT_SURFACE_WIDTH * 0.5f, TestApplication::DEFAULT_SURFACE_HEIGHT * 0.5f);
921 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
922 Actor rootActor = adaptor.GetRootActor();
923 auto scene = application.GetScene();
924 scene.Add(rootActor);
927 auto accessor = adaptor.GetPhysicsAccessor(); // Prevent integration
928 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
929 Dali::Actor ballActor = Toolkit::ImageView::New(TEST_RESOURCE_DIR "/gallery-small-1.jpg");
930 btRigidBody* body = CreateBody(bulletWorld);
931 body->getWorldTransform().setOrigin(btVector3(0.f, 0.f, 0.f));
933 ballActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
934 ballActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
936 auto physicsActor = adaptor.AddActorBody(ballActor, body);
938 Test::WaitForEventThreadTrigger(1);
940 // Should trigger an Update without processing queue
941 application.SendNotification();
942 application.Render();
944 Vector3 origin, direction;
945 Dali::HitTestAlgorithm::BuildPickingRay(scene.GetRenderTaskList().GetTask(0), center, origin, direction);
947 adaptor.BuildPickingRay(origin, direction, from, to); // Hit test centre of screen
950 auto accessor = adaptor.GetPhysicsAccessor();
952 float distanceFromCamera;
953 Dali::Any nullFilter;
954 auto body = accessor->HitTest(from, to, nullFilter, localPivot, distanceFromCamera);
956 DALI_TEST_CHECK(!body.Empty());
964 // PhysicsDebugRenderer.... Elide?!