Merge "Remove useless warning message when multiline TextLabel SceneOff" into devel...
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / algorithm / navigation-mesh.h
1 #ifndef DALI_SCENE3D_NAVIGATION_MESH_H
2 #define DALI_SCENE3D_NAVIGATION_MESH_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // INTERNAL INCLUDES
21 #include <dali-scene3d/public-api/api.h>
22
23 // EXTERNAL INCLUDES
24 #include <dali/public-api/math/matrix.h>
25 #include <dali/public-api/math/vector3.h>
26 #include <dali/public-api/math/vector4.h>
27
28 #include <cinttypes>
29 #include <cstdio>
30 #include <vector>
31 #include <memory>
32
33 namespace Dali::Scene3D::Internal::Algorithm
34 {
35 class NavigationMesh;
36 }
37
38 namespace Dali::Scene3D::Loader
39 {
40 class NavigationMeshFactory;
41 }
42
43 constexpr auto NAVIGATION_MESH_MAX_VERTICES_PER_FACE = 3u;
44 constexpr auto NAVIGATION_MESH_MAX_EDGES_PER_FACE = 3u;
45 constexpr auto NAVIGATION_MESH_MAX_COMPONENTS_3D = 3u;
46 constexpr auto NAVIGATION_MESH_MAX_COMPONENTS_2D = 2u;
47
48 namespace Dali::Scene3D::Algorithm
49 {
50 // Using PImpling but not usual DALi handles as this object isn't supposed to be refcounted
51 using NavigationMeshImpl = Dali::Scene3D::Internal::Algorithm::NavigationMesh;
52
53 /**
54  * @class NavigationMesh
55  *
56  * NavigationMesh is a set of connected faces. The data contains
57  * Polygons (Polys), Edges and Vertices and describes relations
58  * between (for example, edge knows which polys are on each side).
59  *
60  * NavigationMesh uses any coordinate system that it has been exported with.
61  *
62  * The mesh is exported with gravity direction. This is because various editors
63  * may define UP vector differently. Note, the Gravity vector points DOWN.
64  *
65  * - All calculation take place in the navigation mesh local space
66  * - The NavigationMesh should use a correct transformation matrix (SetSceneTransform())
67  * - Without transform, the NavigationMesh space stays local (compatible with exporter tool)
68  * - The NavigationMesh defines Gravity vector (down)
69  * - The finding floor results are returned back into the scene space (set with SetSceneTransform()).
70  *
71  */
72 class DALI_SCENE3D_API NavigationMesh
73 {
74 public:
75
76   /**
77    * @struct Face
78    *
79    * Describes a single polygon
80    */
81   struct Face
82   {
83     uint16_t vertex[NAVIGATION_MESH_MAX_VERTICES_PER_FACE]; ///< Vertices per face
84     uint16_t edge[NAVIGATION_MESH_MAX_EDGES_PER_FACE]; ///< Edges per face
85     float    normal[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Normal vector
86     float    center[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Barycentric coordinates
87   };
88
89   /**
90    * @struct Edge
91    *
92    * Describes a single edge
93    */
94   struct Edge
95   {
96     uint16_t vertex[NAVIGATION_MESH_MAX_COMPONENTS_2D]; ///< Vertices making the edge
97     uint16_t face[NAVIGATION_MESH_MAX_COMPONENTS_2D];   ///< Faces on both sides of edge
98   };
99
100   /**
101    * @struct Vertex
102    *
103    * Describes a single Vertex
104    *
105    */
106   struct Vertex
107   {
108     union
109     {
110       float co[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Coordinates of vertex
111       struct
112       {
113         float x, y, z;
114       };
115     };
116   };
117
118   NavigationMesh() = delete;
119
120 public:
121
122   /**
123    * @brief Destructor
124    */
125   ~NavigationMesh();
126
127   /**
128    * @brief Returns total number of faces
129    *
130    * @return number of faces
131    */
132   [[nodiscard]] uint32_t GetFaceCount() const;
133
134   /**
135    * @brief Returns total number of edges
136    *
137    * @return number of edges
138    */
139   [[nodiscard]] uint32_t GetEdgeCount() const;
140
141   /**
142    * @brief Returns total number of vertices
143    *
144    * @return number of vertices
145    */
146   [[nodiscard]] uint32_t GetVertexCount() const;
147
148   /**
149    * @brief Looks for the floor under specified position
150    * @param[in] position Position to investigate
151    * @param[in] outPosition Position on the floor in found
152    * @param[in] faceIndex Index of NavigationMesh face associated with floor
153    *
154    * @return True if floor has been found, False otherwise
155    */
156   bool FindFloor(const Dali::Vector3& position, Dali::Vector3& outPosition, uint32_t& faceIndex);
157
158   /**
159    * @brief Looks for a floor starting from specified face
160    *
161    * The function performs lookup starting from the specified face. If 'dontCheckNeighbours' is 'true'
162    * then function will fail if 'position' falls outside boundries of face. If 'dontCheckNeighbours'
163    * is 'false' the function will continue search expanding onto neighbouring faces.
164    *
165    * @param[in] position Position to investigate
166    * @param[in] faceIndex Face index to start lookup
167    * @param[in] dontCheckNeighbours If true, the neighbouring faces won't be tested
168    * @param[out] outPosition Result of lookup
169    *
170    * @return True on success, false otherwise
171    */
172   bool FindFloorForFace(const Dali::Vector3& position, uint32_t faceIndex, bool dontCheckNeighbours, Dali::Vector3& outPosition);
173
174
175   /**
176    * @brief Returns pointer to Face structure
177    * @param[in] index Index of face to retrieve
178    * @return Pointer to valid Face structure or nullptr
179    */
180   [[nodiscard]] const Face* GetFace(int index) const;
181
182   /**
183    * @brief Returns edge structure
184    * @param[in] index Index of edge to retrieve
185    * @return Pointer to valid Edge structure or nullptr
186    */
187   [[nodiscard]] const Edge* GetEdge(int index) const;
188
189   /**
190    * @brief Returns vertex structure
191    * @param[in] index Index of vertex to retrieve
192    * @return Pointer to valid Vertex structure or nullptr
193    */
194   [[nodiscard]] const Vertex* GetVertex(int index) const;
195
196   /**
197    * @brief Sets static transform for the navigation mesh object
198    *
199    * The NavigationMesh may require to be transformed into the coordinates
200    * of the scene object. The exporter exports navigation geometry in a local
201    * space. The transform must be set in order to use the navigation mesh
202    * in the scene space (most likely DALi coordinate space).
203    *
204    * The scene transform matrix can be set in the DALi event thread using
205    * Dali::DevelActor::GetWorldTransform(sceneActor)
206    *
207    * For example:
208    * @code
209    * Actor parentActorOfNavigationMesh; // non-null object
210    * Dali::DevelActor::GetWorldTransform(parentActorOfNavigationMesh);
211    * navigationMesh->SetSceneTransform(parentActorOfNavigationMesh);
212    * @endcode
213    *
214    * The transform remains static until changed by calling SetSceneTransform() again.
215    * It means that if the matrix is obtained from the actor and actor transform will
216    * change the navigation mesh won't be aligned anymore.
217    *
218    * @param[in] transform Valid transform 4x4 matrix
219    */
220   void SetSceneTransform(const Dali::Matrix& transform);
221
222   /**
223    * @brief transforms point into the NavigationMesh local space
224    *
225    * Transforms a 3D point into navigation mesh space (space used when
226    * NavigationMesh has been created, most likely 3D editor space).
227    *
228    * @param[in] point Point to transform
229    * @return Point transformed to the local space
230    */
231   Dali::Vector3 PointSceneToLocal(const Dali::Vector3& point);
232
233   /**
234    * @brief Transforms point into the parent transform space
235    *
236    * Transforms the given point into the parent space (set with SetSceneTransform()).
237    *
238    * @param[in] point Point to transform
239    * @return Point transformed into the parent space
240    */
241   Dali::Vector3 PointLocalToScene(const Dali::Vector3& point);
242
243   /**
244    * @brief Returns direction of the gravity vector
245    *
246    * Gravity vector points down.
247    *
248    * @return Gravity vector 3D
249    */
250   Dali::Vector3 GetGravityVector() const;
251
252   static constexpr uint16_t NULL_FACE{0xffff}; ///< Represents null polygon
253   static constexpr uint16_t NULL_EDGE{0xffff}; ///< represents null edge
254
255 public:
256
257   DALI_INTERNAL explicit NavigationMesh( NavigationMeshImpl* impl );
258
259   std::unique_ptr<NavigationMeshImpl> mImpl;
260 };
261 } // namespace Dali::Scene3D::Algorithm
262 #endif // DALI_SCENE3D_NAVIGATION_MESH_H