b0cfeb4afd7e01be309b63040d3c5910646e3ec5
[platform/core/uifw/dali-toolkit.git] / utc-Dali-PathFinding.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
18 #include <dali-test-suite-utils.h>
19 #include "dali-scene3d/public-api/algorithm/navigation-mesh.h"
20 #include "dali-scene3d/public-api/algorithm/path-finder.h"
21 #include "dali-scene3d/public-api/loader/navigation-mesh-factory.h"
22
23 using namespace Dali;
24 using namespace Dali::Scene3D::Algorithm;
25 using namespace Dali::Scene3D::Loader;
26
27 bool CompareResults(const std::vector<FaceIndex>& nodes, const WayPointList& waypoints)
28 {
29   if(nodes.size() != waypoints.size())
30   {
31     std::ostringstream oss;
32     oss << "expect indexs : [";
33     for(const auto& index : nodes)
34     {
35       oss << index << ", ";
36     }
37     oss << "]\n";
38     oss << "your indexs : [";
39     for(const auto& waypoint : waypoints)
40     {
41       oss << waypoint.GetNavigationMeshFaceIndex() << ", ";
42     }
43     oss << "]\n";
44     tet_printf("%s\n", oss.str().c_str());
45     return false;
46   }
47   for(auto i = 0u; i < nodes.size(); ++i)
48   {
49     if(nodes[i] != waypoints[i].GetNavigationMeshFaceIndex())
50     {
51       std::ostringstream oss;
52       oss << "expect indexs : [";
53       for(const auto& index : nodes)
54       {
55         oss << index << ", ";
56       }
57       oss << "]\n";
58       oss << "your indexs : [";
59       for(const auto& waypoint : waypoints)
60       {
61         oss << waypoint.GetNavigationMeshFaceIndex() << ", ";
62       }
63       oss << "]\n";
64       tet_printf("%s\n", oss.str().c_str());
65       return false;
66     }
67   }
68   return true;
69 }
70
71 int UtcDaliPathFinderNewP(void)
72 {
73   auto navmesh = NavigationMeshFactory::CreateFromFile("resources/navmesh-test.bin");
74
75   auto pathfinder = PathFinder::New(*navmesh, PathFinderAlgorithm::DEFAULT);
76
77   DALI_TEST_CHECK(navmesh);
78   DALI_TEST_CHECK(pathfinder);
79
80   END_TEST;
81 }
82
83 int UtcDaliPathFinderNewFail(void)
84 {
85   auto navmesh = NavigationMeshFactory::CreateFromFile("resources/navmesh-test.bin");
86
87   auto pathfinder = PathFinder::New(*navmesh, static_cast<PathFinderAlgorithm>(-1));
88
89   DALI_TEST_CHECK(navmesh);
90   DALI_TEST_CHECK(!pathfinder);
91
92   END_TEST;
93 }
94
95 void printWaypointForPython(WayPointList& waypoints)
96 {
97   tet_printf("size: %d\n", waypoints.size());
98   tet_printf("[");
99   for(auto& wp : waypoints)
100   {
101     auto index = wp.GetNavigationMeshFaceIndex();
102     tet_printf("%d, ", index);
103   }
104   tet_printf("]");
105 }
106
107 int UtcDaliPathFinderFindShortestPath0(void)
108 {
109   auto navmesh = NavigationMeshFactory::CreateFromFile("resources/navmesh-test.bin");
110
111   std::vector<PathFinderAlgorithm> testAlgorithms = {
112     PathFinderAlgorithm::DJIKSTRA_SHORTEST_PATH,
113     PathFinderAlgorithm::SPFA,
114   };
115
116   for(const auto& algorithm : testAlgorithms)
117   {
118     tet_printf("Test algorithm type : %d\n", static_cast<int>(algorithm));
119     auto pathfinder = PathFinder::New(*navmesh, algorithm);
120
121     DALI_TEST_CHECK(navmesh);
122     DALI_TEST_CHECK(pathfinder);
123
124     {
125       auto waypoints = pathfinder->FindPath(18, 139);
126       DALI_TEST_NOT_EQUALS(int(waypoints.size()), 0, 0, TEST_LOCATION);
127
128       // Results are verified in the Blender
129       std::vector<FaceIndex> expectedResults =
130         {18, 97, 106, 82, 50, 139};
131
132       DALI_TEST_EQUALS(CompareResults(expectedResults, waypoints), true, TEST_LOCATION);
133     }
134     //printWaypointForPython(waypoints);
135
136     {
137       // Top floor middle to the tree
138
139       auto waypoints = pathfinder->FindPath(18, 157);
140       DALI_TEST_NOT_EQUALS(int(waypoints.size()), 0, 0, TEST_LOCATION);
141
142       //printWaypointForPython(waypoints);
143
144       // Results are verified in the Blender
145       std::vector<FaceIndex> expectedResults =
146         {18, 97, 106, 82, 50, 6, 89, 33, 157};
147
148       DALI_TEST_EQUALS(CompareResults(expectedResults, waypoints), true, TEST_LOCATION);
149     }
150   }
151
152   END_TEST;
153 }
154
155 int UtcDaliPathFinderFindShortestPath1(void)
156 {
157   auto navmesh = NavigationMeshFactory::CreateFromFile("resources/navmesh-test.bin");
158   // All coordinates in navmesh local space
159   navmesh->SetSceneTransform(Matrix(Matrix::IDENTITY));
160
161   std::vector<PathFinderAlgorithm> testAlgorithms = {
162     PathFinderAlgorithm::DJIKSTRA_SHORTEST_PATH,
163     PathFinderAlgorithm::SPFA,
164     PathFinderAlgorithm::SPFA_DOUBLE_WAY, /* Note : Even this algorithm doesn't found shortest path, UTC will pass. */
165   };
166
167   for(const auto& algorithm : testAlgorithms)
168   {
169     tet_printf("Test algorithm type : %d\n", static_cast<int>(algorithm));
170     auto pathfinder = PathFinder::New(*navmesh, algorithm);
171
172     DALI_TEST_CHECK(navmesh);
173     DALI_TEST_CHECK(pathfinder);
174
175     {
176       Vector3 from(-6.0767, -1.7268, 0.1438); // ground floor
177       Vector3 to(-6.0767, -1.7268, 4.287);    // first floor
178
179       auto waypoints = pathfinder->FindPath(from, to);
180       DALI_TEST_NOT_EQUALS(int(waypoints.size()), 0, 0, TEST_LOCATION);
181
182       // Results are verified in the Blender
183       std::vector<FaceIndex> expectedResults =
184         {154, 58, 85, 106, 128, 132, 137};
185
186       DALI_TEST_EQUALS(CompareResults(expectedResults, waypoints), true, TEST_LOCATION);
187
188       // Verify last and first points by finding floor points
189       {
190         Vector3   verifyPos   = Vector3::ZERO;
191         FaceIndex verifyIndex = NavigationMesh::NULL_FACE;
192         auto      result      = navmesh->FindFloor(from, verifyPos, verifyIndex);
193
194         DALI_TEST_EQUALS(result, true, TEST_LOCATION);
195         DALI_TEST_EQUALS(verifyPos, waypoints[0].GetScenePosition(), TEST_LOCATION);
196         DALI_TEST_EQUALS(verifyIndex, waypoints[0].GetNavigationMeshFaceIndex(), TEST_LOCATION);
197
198         // Verified with Blender
199         Vector2 local(1.064201f, -0.273200f);
200         DALI_TEST_EQUALS(local, waypoints[0].GetFaceLocalSpacePosition(), TEST_LOCATION);
201       }
202
203       {
204         Vector3   verifyPos   = Vector3::ZERO;
205         FaceIndex verifyIndex = NavigationMesh::NULL_FACE;
206         auto      result      = navmesh->FindFloor(to, verifyPos, verifyIndex);
207
208         DALI_TEST_EQUALS(result, true, TEST_LOCATION);
209         DALI_TEST_EQUALS(verifyPos, waypoints.back().GetScenePosition(), TEST_LOCATION);
210         DALI_TEST_EQUALS(verifyIndex, waypoints.back().GetNavigationMeshFaceIndex(), TEST_LOCATION);
211
212         // Verified with Blender
213         Vector2 local(0.165907f, 0.142597f);
214         DALI_TEST_EQUALS(local, waypoints.back().GetFaceLocalSpacePosition(), TEST_LOCATION);
215       }
216     }
217   }
218
219   END_TEST;
220 }