[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-physics2d / utc-Dali-IntegPhysics.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
25 #include <dali-physics/integration-api/integ-physics-adaptor.h>
26 #include <dali-physics/integration-api/physics-world.h>
27
28 #include <dali-toolkit-test-suite-utils.h>
29 #include <toolkit-event-thread-callback.h>
30
31 #include <dali-toolkit/devel-api/controls/alignment/alignment.h>
32 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
33 #include <dali/devel-api/adaptor-framework/window-devel.h>
34 #include <dali/devel-api/events/hit-test-algorithm.h>
35
36 #include <chipmunk/chipmunk.h>
37
38 using namespace Dali;
39 using namespace Dali::Toolkit::Physics;
40
41 static const char* BALL_IMAGE = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
42
43 static cpBody* CreateBody(cpSpace* space)
44 {
45   const float BALL_MASS       = 10.0f;
46   const float BALL_RADIUS     = 26.0f;
47   const float BALL_ELASTICITY = 0.5f;
48   const float BALL_FRICTION   = 0.5f;
49
50   cpBody* body = cpSpaceAddBody(space, cpBodyNew(BALL_MASS, cpMomentForCircle(BALL_MASS, 0.0f, BALL_RADIUS, cpvzero)));
51
52   cpShape* shape = cpSpaceAddShape(space, cpCircleShapeNew(body, BALL_RADIUS, cpvzero));
53   cpShapeSetElasticity(shape, BALL_ELASTICITY);
54   cpShapeSetFriction(shape, BALL_FRICTION);
55
56   return body;
57 }
58
59 // Defines a PolyShape
60 static cpBody* CreateHexBody(cpSpace* space)
61 {
62   const float MASS       = 10.0f;
63   const float RADIUS     = 26.0f;
64   const float ELASTICITY = 0.5f;
65   const float FRICTION   = 0.5f;
66
67   cpVect hexagon[6];
68   for(int i = 0; i < 6; i++)
69   {
70     cpFloat angle = -CP_PI * 2.0f * i / 6.0f;
71     hexagon[i]    = cpvmult(cpv(cos(angle), sin(angle)), RADIUS - 1.0f);
72   }
73
74   cpBody*  body  = cpSpaceAddBody(space, cpBodyNew(MASS, cpMomentForPoly(MASS, 6, hexagon, cpvzero, 0.0f)));
75   cpShape* shape = cpSpaceAddShape(space, cpPolyShapeNew(body, 6, hexagon, cpTransformIdentity, 1.0f));
76
77   cpShapeSetElasticity(shape, ELASTICITY);
78   cpShapeSetFriction(shape, FRICTION);
79
80   return body;
81 }
82
83 int UtcDaliPhysics2DIntegrationGetPhysicsWorld(void)
84 {
85   ToolkitTestApplication application;
86   tet_infoline("Testing getting the physics world");
87
88   Matrix         transform(true);
89   Uint16Pair     size(640, 480);
90   PhysicsAdaptor adaptor = PhysicsAdaptor::New(transform, size);
91   DALI_TEST_CHECK(adaptor);
92
93   Dali::Toolkit::Physics::Integration::PhysicsWorld world = Dali::Toolkit::Physics::Integration::GetPhysicsWorld(adaptor);
94
95   DALI_TEST_CHECK(world.GetImpl() != nullptr);
96
97   END_TEST;
98 }
99
100 int UtcDaliPhysics2DIntegrationPhysicsWorldLockUnlock(void)
101 {
102   ToolkitTestApplication application;
103
104   Matrix         transform(true);
105   Uint16Pair     size(640, 480);
106   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
107   Actor          rootActor = adaptor.GetRootActor();
108   auto           scene     = application.GetScene();
109   scene.Add(rootActor);
110
111   Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
112
113   cpBody*      body{nullptr};
114   PhysicsActor physicsActor;
115   {
116     auto accessor = adaptor.GetPhysicsAccessor();
117     auto space    = accessor->GetNative().Get<cpSpace*>();
118     body          = CreateBody(space);
119     physicsActor  = adaptor.AddActorBody(ballActor, body);
120   }
121
122   DALI_TEST_CHECK(adaptor);
123   Dali::Toolkit::Physics::Integration::PhysicsWorld world = Dali::Toolkit::Physics::Integration::GetPhysicsWorld(adaptor);
124
125   world.Lock();
126   world.Unlock();
127
128   {
129     tet_infoline("Test that creating accessor after unlocking this does not lock up!");
130     auto accessor = adaptor.GetPhysicsAccessor();
131   }
132
133   tet_result(TET_PASS);
134   END_TEST;
135 }
136
137 int UtcDaliPhysics2DIntegrationPhysicsWorldGetNative(void)
138 {
139   ToolkitTestApplication application;
140   tet_infoline("Testing getting the native world through Integ API");
141
142   Matrix         transform(true);
143   Uint16Pair     size(640, 480);
144   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
145   Actor          rootActor = adaptor.GetRootActor();
146   auto           scene     = application.GetScene();
147   scene.Add(rootActor);
148
149   Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
150
151   cpBody*      body{nullptr};
152   PhysicsActor physicsActor;
153   {
154     auto accessor = adaptor.GetPhysicsAccessor();
155     auto space    = accessor->GetNative().Get<cpSpace*>();
156     body          = CreateBody(space);
157     physicsActor  = adaptor.AddActorBody(ballActor, body);
158   }
159
160   DALI_TEST_CHECK(adaptor);
161   Dali::Toolkit::Physics::Integration::PhysicsWorld world = Dali::Toolkit::Physics::Integration::GetPhysicsWorld(adaptor);
162
163   world.Lock();
164   cpBody* newBody{nullptr};
165   try
166   {
167     auto     worldImpl = world.GetNative();
168     cpSpace* space     = worldImpl.Get<cpSpace*>();
169     DALI_TEST_CHECK(space != nullptr);
170
171     newBody = CreateHexBody(space);
172   }
173   catch(DaliException& e)
174   {
175     tet_result(TET_FAIL);
176   }
177   world.Unlock();
178
179   DALI_TEST_CHECK(newBody != nullptr);
180   END_TEST;
181 }
182
183 int UtcDaliPhysics2DIntegrationPhysicsWorldHitTest(void)
184 {
185   ToolkitTestApplication application;
186   tet_infoline("Testing the Hit Test works through Integ API");
187
188   const Vector2 center(TestApplication::DEFAULT_SURFACE_WIDTH * 0.5f, TestApplication::DEFAULT_SURFACE_HEIGHT * 0.5f);
189
190   Matrix         transform(true);
191   Uint16Pair     size(640, 480);
192   PhysicsAdaptor adaptor   = PhysicsAdaptor::New(transform, size);
193   Actor          rootActor = adaptor.GetRootActor();
194   auto           scene     = application.GetScene();
195   scene.Add(rootActor);
196
197   Dali::Actor ballActor = Toolkit::ImageView::New(BALL_IMAGE);
198
199   cpBody*      body{nullptr};
200   PhysicsActor physicsActor;
201   {
202     auto accessor = adaptor.GetPhysicsAccessor();
203     auto space    = accessor->GetNative().Get<cpSpace*>();
204     body          = CreateBody(space);
205     physicsActor  = adaptor.AddActorBody(ballActor, body);
206   }
207
208   DALI_TEST_CHECK(adaptor);
209
210   Vector3 from, to;
211   adaptor.BuildPickingRay(Vector3(center), Vector3(center), from, to);
212
213   Dali::Toolkit::Physics::Integration::PhysicsWorld world = Dali::Toolkit::Physics::Integration::GetPhysicsWorld(adaptor);
214   world.Lock();
215   try
216   {
217     auto     worldImpl = world.GetNative();
218     cpSpace* space     = worldImpl.Get<cpSpace*>();
219     DALI_TEST_CHECK(space != nullptr);
220
221     cpShapeFilter GRAB_FILTER = {CP_NO_GROUP, 1u << 31, 1u << 31};
222     Dali::Any     nativeFilter{GRAB_FILTER};
223     Vector3       localPivot;
224     float         distanceFromCamera;
225     auto          body = world.HitTest(from, from, nativeFilter, localPivot, distanceFromCamera);
226
227     DALI_TEST_CHECK(!body.Empty());
228     cpBody* cbody = body.Get<cpBody*>();
229
230     DALI_TEST_CHECK(cbody != nullptr);
231   }
232   catch(DaliException& e)
233   {
234     tet_result(TET_FAIL);
235   }
236   world.Unlock();
237
238   END_TEST;
239 }