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.
17 #include <bullet/btBulletDynamicsCommon.h>
21 // Need to override adaptor classes for toolkit test harness, so include
22 // test harness headers before dali headers.
23 #include <dali-toolkit-test-suite-utils.h>
24 #include <toolkit-event-thread-callback.h>
26 #include <dali-physics/dali-physics.h>
27 #include <dali-toolkit/dali-toolkit.h>
28 #include <dali-toolkit/devel-api/controls/alignment/alignment.h>
31 using namespace Dali::Toolkit::Physics;
33 extern btRigidBody* CreateBody(btDiscreteDynamicsWorld* bulletWorld);
35 const char* BALL_IMAGE = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
37 int UtcDaliPhysics3DActorNew(void)
39 ToolkitTestApplication application;
41 btRigidBody* body{nullptr};
43 Matrix transform(true);
44 Uint16Pair size(640, 480);
45 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
47 auto accessor = adaptor.GetPhysicsAccessor();
48 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
49 body = CreateBody(bulletWorld);
50 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
52 PhysicsActor physicsActor = PhysicsActor::New(ballActor, body, adaptor);
54 DALI_TEST_CHECK(physicsActor);
58 int UtcDaliPhysics3DActorDownCastP(void)
60 ToolkitTestApplication application;
62 Matrix transform(true);
63 Uint16Pair size(640, 480);
64 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
66 btRigidBody* body{nullptr};
67 auto accessor = adaptor.GetPhysicsAccessor();
68 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
69 body = CreateBody(bulletWorld);
70 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
71 PhysicsActor physicsActor = PhysicsActor::New(ballActor, body, adaptor);
72 BaseHandle handle(physicsActor);
74 PhysicsActor actor2 = PhysicsActor::DownCast(handle);
75 DALI_TEST_CHECK(actor2);
76 DALI_TEST_EQUALS(physicsActor.GetId(), actor2.GetId(), TEST_LOCATION);
81 int UtcDaliPhysics3DActorDownCastN(void)
83 BaseHandle uninitializedHandle;
84 PhysicsActor actor = PhysicsActor::DownCast(uninitializedHandle);
85 DALI_TEST_CHECK(!actor);
89 int UtcDaliPhysics3DActorMoveConstructor(void)
91 ToolkitTestApplication application;
92 tet_infoline("Testing the move constructor");
94 Matrix transform(true);
95 Uint16Pair size(640, 480);
96 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
98 btRigidBody* body{nullptr};
99 auto accessor = adaptor.GetPhysicsAccessor();
100 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
101 body = CreateBody(bulletWorld);
102 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
103 PhysicsActor physicsActor = PhysicsActor::New(ballActor, body, adaptor);
105 DALI_TEST_CHECK(physicsActor);
106 uint32_t id = physicsActor.GetId();
108 PhysicsActor moved = std::move(physicsActor);
109 DALI_TEST_CHECK(moved);
110 DALI_TEST_CHECK(!physicsActor);
111 DALI_TEST_CHECK(moved != physicsActor);
112 DALI_TEST_EQUALS(moved.GetId(), id, TEST_LOCATION);
117 int UtcDaliPhysics3DActorCopyConstructor(void)
119 ToolkitTestApplication application;
120 tet_infoline("Testing the move constructor");
122 Matrix transform(true);
123 Uint16Pair size(640, 480);
124 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
126 btRigidBody* body{nullptr};
127 auto accessor = adaptor.GetPhysicsAccessor();
128 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
129 body = CreateBody(bulletWorld);
130 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
131 PhysicsActor physicsActor = PhysicsActor::New(ballActor, body, adaptor);
133 DALI_TEST_CHECK(physicsActor);
134 uint32_t id = physicsActor.GetId();
136 PhysicsActor selectedActor(physicsActor);
137 DALI_TEST_CHECK(selectedActor);
138 DALI_TEST_CHECK(physicsActor);
139 DALI_TEST_CHECK(selectedActor == physicsActor); // should point at same object
140 DALI_TEST_EQUALS(selectedActor.GetId(), id, TEST_LOCATION);
145 int UtcDaliPhysics3DActorCopyAssign(void)
147 ToolkitTestApplication application;
148 tet_infoline("Testing the copy assign");
150 Matrix transform(true);
151 Uint16Pair size(640, 480);
152 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
154 btRigidBody* body{nullptr};
155 auto accessor = adaptor.GetPhysicsAccessor();
156 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
157 body = CreateBody(bulletWorld);
158 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
159 PhysicsActor physicsActor = PhysicsActor::New(ballActor, body, adaptor);
161 DALI_TEST_CHECK(physicsActor);
162 uint32_t id = physicsActor.GetId();
164 PhysicsActor selectedActor = physicsActor;
165 DALI_TEST_CHECK(selectedActor);
166 DALI_TEST_CHECK(physicsActor);
167 DALI_TEST_CHECK(selectedActor == physicsActor); // should point at same object
168 DALI_TEST_EQUALS(selectedActor.GetId(), id, TEST_LOCATION);
173 int UtcDaliPhysics3DActorMoveAssignment(void)
175 ToolkitTestApplication application;
176 tet_infoline("Testing the move constructor");
178 Matrix transform(true);
179 Uint16Pair size(640, 480);
180 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
182 btRigidBody* body{nullptr};
183 auto accessor = adaptor.GetPhysicsAccessor();
184 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
185 body = CreateBody(bulletWorld);
186 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
187 PhysicsActor physicsActor = PhysicsActor::New(ballActor, body, adaptor);
189 DALI_TEST_CHECK(physicsActor);
190 uint32_t id = physicsActor.GetId();
193 moved = std::move(physicsActor);
194 DALI_TEST_CHECK(moved);
195 DALI_TEST_CHECK(!physicsActor);
196 DALI_TEST_EQUALS(moved.GetId(), id, TEST_LOCATION);
201 int UtcDaliPhysics3DActorGetIdP(void)
203 ToolkitTestApplication application;
204 tet_infoline("Testing the ID Getter");
206 Matrix transform(true);
207 Uint16Pair size(640, 480);
208 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
210 btRigidBody* body{nullptr};
211 auto accessor = adaptor.GetPhysicsAccessor();
212 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
213 body = CreateBody(bulletWorld);
214 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
215 PhysicsActor physicsActor = adaptor.AddActorBody(ballActor, body);
216 int id = physicsActor.GetId();
217 int actorId = ballActor[Actor::Property::ID];
218 DALI_TEST_EQUALS(id, actorId, TEST_LOCATION);
223 int UtcDaliPhysics3DActorGetIdN(void)
225 ToolkitTestApplication application;
226 tet_infoline("Testing the ID Getter");
228 PhysicsActor physicsActor;
231 uint32_t id __attribute__((unused)) = physicsActor.GetId();
232 tet_result(TET_FAIL);
234 catch(DaliException e)
236 DALI_TEST_ASSERT(e, "Physics actor handle is empty", TEST_LOCATION);
242 int UtcDaliPhysics3DActorGetBodyP(void)
244 ToolkitTestApplication application;
245 tet_infoline("Testing the body Getter");
247 Matrix transform(true);
248 Uint16Pair size(640, 480);
249 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
250 Actor rootActor = adaptor.GetRootActor();
251 auto scene = application.GetScene();
252 scene.Add(rootActor);
254 PhysicsActor physicsActor;
255 btRigidBody* body{nullptr};
257 auto accessor = adaptor.GetPhysicsAccessor();
258 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
259 body = CreateBody(bulletWorld);
260 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
262 physicsActor = adaptor.AddActorBody(ballActor, body);
265 application.Render();
266 Test::WaitForEventThreadTrigger(1);
268 Dali::Any any = physicsActor.GetBody();
269 DALI_TEST_EQUALS(any.Get<btRigidBody*>(), body, TEST_LOCATION);
274 int UtcDaliPhysics3DActorGetBodyN(void)
276 ToolkitTestApplication application;
277 tet_infoline("Testing the ID Getter");
279 PhysicsActor physicsActor;
282 Dali::Any any __attribute__((unused)) = physicsActor.GetBody();
283 tet_result(TET_FAIL);
285 catch(DaliException e)
287 DALI_TEST_ASSERT(e, "Physics actor handle is empty", TEST_LOCATION);
292 int UtcDaliPhysics3DActorSetPosition(void)
294 tet_infoline("Test the AsyncSetPhysicsPosition() function");
296 ToolkitTestApplication application;
297 Matrix transform(false);
298 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
299 Uint16Pair size(640, 480);
300 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
301 Actor rootActor = adaptor.GetRootActor();
302 auto scene = application.GetScene();
303 scene.Add(rootActor);
305 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
307 btRigidBody* body{nullptr};
308 PhysicsActor physicsActor;
310 auto accessor = adaptor.GetPhysicsAccessor();
311 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
312 body = CreateBody(bulletWorld);
313 physicsActor = adaptor.AddActorBody(ballActor, body);
314 physicsActor.AsyncSetPhysicsPosition(Vector3(10, 20, -30));
317 Test::WaitForEventThreadTrigger(1);
318 adaptor.CreateSyncPoint();
319 application.SendNotification();
320 application.Render();
322 // Run 2 frames to ensure both buffers are set.
323 application.SendNotification();
324 application.Render();
326 auto accessor = adaptor.GetPhysicsAccessor();
327 auto actor = rootActor.FindChildById(physicsActor.GetId());
328 // Warning - physics properties are never reflected in the event size cache.
329 // Have to use GetCurrentProperty to see the updated values.
330 DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3(10, 20, -30), 0.0001f, TEST_LOCATION);
336 int UtcDaliPhysics3DActorSetRotation1(void)
338 tet_infoline("Test the AsyncSetPhysicsRotation() function");
340 ToolkitTestApplication application;
341 Matrix transform(false);
342 transform.SetIdentityAndScale(Vector3(2.0f, -2.0f, 2.0f));
343 Uint16Pair size(640, 480);
344 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
345 Actor rootActor = adaptor.GetRootActor();
346 auto scene = application.GetScene();
347 scene.Add(rootActor);
349 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
351 btRigidBody* body{nullptr};
352 PhysicsActor physicsActor;
354 auto accessor = adaptor.GetPhysicsAccessor();
355 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
356 body = CreateBody(bulletWorld);
357 physicsActor = adaptor.AddActorBody(ballActor, body);
358 physicsActor.AsyncSetPhysicsRotation(Quaternion(Degree(30), Vector3::YAXIS));
361 Test::WaitForEventThreadTrigger(1);
362 adaptor.CreateSyncPoint();
363 application.SendNotification();
364 application.Render();
366 // Run 2 frames to ensure both buffers are set.
367 application.SendNotification();
368 application.Render();
370 auto accessor = adaptor.GetPhysicsAccessor();
371 auto actor = rootActor.FindChildById(physicsActor.GetId());
372 // Warning - physics properties are never reflected in the event size cache.
373 // Have to use GetCurrentProperty to see the updated values.
374 Quaternion q = actor.GetCurrentProperty<Quaternion>(Actor::Property::ORIENTATION);
375 Quaternion expected(Degree(30), Vector3::YAXIS);
376 DALI_TEST_EQUALS(q, expected, 0.0001f, TEST_LOCATION);
382 int UtcDaliPhysics3DActorSetRotation2(void)
384 tet_infoline("Test the AsyncSetPhysicsRotation() function");
386 ToolkitTestApplication application;
387 Matrix transform(false);
388 transform.SetIdentityAndScale(Vector3(2.0f, -2.0f, 2.0f));
389 Uint16Pair size(640, 480);
390 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
391 Actor rootActor = adaptor.GetRootActor();
392 auto scene = application.GetScene();
393 scene.Add(rootActor);
395 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
397 btRigidBody* body{nullptr};
398 PhysicsActor physicsActor;
400 auto accessor = adaptor.GetPhysicsAccessor();
401 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
402 body = CreateBody(bulletWorld);
403 physicsActor = adaptor.AddActorBody(ballActor, body);
404 physicsActor.AsyncSetPhysicsRotation(Quaternion(Degree(30), Vector3::ZAXIS));
407 Test::WaitForEventThreadTrigger(1);
408 adaptor.CreateSyncPoint();
409 application.SendNotification();
410 application.Render();
412 // Run 2 frames to ensure both buffers are set.
413 application.SendNotification();
414 application.Render();
416 auto accessor = adaptor.GetPhysicsAccessor();
417 auto actor = rootActor.FindChildById(physicsActor.GetId());
418 // Warning - physics properties are never reflected in the event size cache.
419 // Have to use GetCurrentProperty to see the updated values.
420 Quaternion q = actor.GetCurrentProperty<Quaternion>(Actor::Property::ORIENTATION);
421 Quaternion expected(Degree(30), Vector3::ZAXIS);
422 DALI_TEST_EQUALS(q, expected, 0.0001f, TEST_LOCATION);
428 int UtcDaliPhysics3DActorGetActorPosition(void)
430 tet_infoline("Test the GetActorPosition() function");
432 ToolkitTestApplication application;
433 Matrix transform(false);
434 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
435 Uint16Pair size(640, 480);
436 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
437 Actor rootActor = adaptor.GetRootActor();
438 auto scene = application.GetScene();
439 scene.Add(rootActor);
441 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
443 btRigidBody* body{nullptr};
444 PhysicsActor physicsActor;
446 auto accessor = adaptor.GetPhysicsAccessor();
447 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
448 body = CreateBody(bulletWorld);
449 physicsActor = adaptor.AddActorBody(ballActor, body);
450 physicsActor.AsyncSetPhysicsPosition(Vector3(10, 20, -30));
453 Test::WaitForEventThreadTrigger(1);
454 adaptor.CreateSyncPoint();
455 application.SendNotification();
456 application.Render();
458 // Run 2 frames to ensure both buffers are set.
459 application.SendNotification();
460 application.Render();
462 auto accessor = adaptor.GetPhysicsAccessor();
463 DALI_TEST_EQUALS(physicsActor.GetActorPosition(), Vector3(10, 20, -30), 0.0001f, TEST_LOCATION);
469 int UtcDaliPhysics3DActorGetActorRotation(void)
471 tet_infoline("Test the GetActorRotation() function");
473 ToolkitTestApplication application;
474 Matrix transform(false);
475 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
476 Uint16Pair size(640, 480);
477 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
478 Actor rootActor = adaptor.GetRootActor();
479 auto scene = application.GetScene();
480 scene.Add(rootActor);
482 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
484 btRigidBody* body{nullptr};
485 PhysicsActor physicsActor;
487 auto accessor = adaptor.GetPhysicsAccessor();
488 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
489 body = CreateBody(bulletWorld);
490 physicsActor = adaptor.AddActorBody(ballActor, body);
491 physicsActor.AsyncSetPhysicsRotation(Quaternion(Degree(30), Vector3::ZAXIS));
494 Test::WaitForEventThreadTrigger(1);
495 adaptor.CreateSyncPoint();
496 application.SendNotification();
497 application.Render();
499 // Run 2 frames to ensure both buffers are set.
500 application.SendNotification();
501 application.Render();
503 auto accessor = adaptor.GetPhysicsAccessor();
504 DALI_TEST_EQUALS(physicsActor.GetActorRotation(), Quaternion(Degree(30), Vector3::ZAXIS), 0.0001f, TEST_LOCATION);
510 int UtcDaliPhysics3DActorGetPhysicsPosition(void)
512 tet_infoline("Test the GetPhysicsPosition() function");
514 ToolkitTestApplication application;
515 Matrix transform(false);
516 transform.SetIdentityAndScale(Vector3(2.0f, 2.0f, 2.0f));
518 Uint16Pair size(640, 480);
519 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
520 Actor rootActor = adaptor.GetRootActor();
521 auto scene = application.GetScene();
522 scene.Add(rootActor);
524 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
526 btRigidBody* body{nullptr};
527 PhysicsActor physicsActor;
529 auto accessor = adaptor.GetPhysicsAccessor();
530 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
531 body = CreateBody(bulletWorld);
532 physicsActor = adaptor.AddActorBody(ballActor, body);
533 physicsActor.AsyncSetPhysicsPosition(Vector3(10, 20, -30));
536 Test::WaitForEventThreadTrigger(1);
537 adaptor.CreateSyncPoint();
538 application.SendNotification();
539 application.Render();
541 // Run 2 frames to ensure both buffers are set.
542 application.SendNotification();
543 application.Render();
545 auto accessor = adaptor.GetPhysicsAccessor();
546 Vector4 pos = transform * Vector4(10, 20, -30, 1);
547 DALI_TEST_EQUALS(physicsActor.GetPhysicsPosition(), Vector3(pos), 0.0001f, TEST_LOCATION);
553 int UtcDaliPhysics3DActorGetPhysicsRotation(void)
555 tet_infoline("Test the GetPhysicsRotation() function");
557 ToolkitTestApplication application;
558 Matrix transform(false);
559 transform.SetIdentityAndScale(Vector3(2.0f, -2.0f, 2.0f));
560 Uint16Pair size(640, 480);
561 PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
562 Actor rootActor = adaptor.GetRootActor();
563 auto scene = application.GetScene();
564 scene.Add(rootActor);
566 Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
568 btRigidBody* body{nullptr};
569 PhysicsActor physicsActor;
571 auto accessor = adaptor.GetPhysicsAccessor();
572 auto bulletWorld = accessor->GetNative().Get<btDiscreteDynamicsWorld*>();
573 body = CreateBody(bulletWorld);
574 physicsActor = adaptor.AddActorBody(ballActor, body);
575 physicsActor.AsyncSetPhysicsRotation(Quaternion(Degree(30), Vector3::ZAXIS));
578 Test::WaitForEventThreadTrigger(1);
579 adaptor.CreateSyncPoint();
580 application.SendNotification();
581 application.Render();
583 // Run 2 frames to ensure both buffers are set.
584 application.SendNotification();
585 application.Render();
587 auto accessor = adaptor.GetPhysicsAccessor();
588 DALI_TEST_EQUALS(physicsActor.GetPhysicsRotation(), Quaternion(Degree(-30), Vector3::ZAXIS), 0.0001f, TEST_LOCATION);