Merge "Load bvh and facial animations from buffer" into devel/master
[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 // EXTERNAL INCLUDES
21 #include <dali/public-api/common/vector-wrapper.h>
22 #include <dali/public-api/math/matrix.h>
23 #include <dali/public-api/math/vector3.h>
24 #include <dali/public-api/math/vector4.h>
25
26 #include <cinttypes>
27 #include <cstdio>
28 #include <memory>
29
30 // INTERNAL INCLUDES
31 #include <dali-scene3d/public-api/api.h>
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    * @struct Face
77    *
78    * Describes a single polygon
79    */
80   struct Face
81   {
82     uint16_t vertex[NAVIGATION_MESH_MAX_VERTICES_PER_FACE]; ///< Vertices per face
83     uint16_t edge[NAVIGATION_MESH_MAX_EDGES_PER_FACE];      ///< Edges per face
84     float    normal[NAVIGATION_MESH_MAX_COMPONENTS_3D];     ///< Normal vector
85     float    center[NAVIGATION_MESH_MAX_COMPONENTS_3D];     ///< Barycentric coordinates
86   };
87
88   /**
89    * @struct Edge
90    *
91    * Describes a single edge
92    */
93   struct Edge
94   {
95     uint16_t vertex[NAVIGATION_MESH_MAX_COMPONENTS_2D]; ///< Vertices making the edge
96     uint16_t face[NAVIGATION_MESH_MAX_COMPONENTS_2D];   ///< Faces on both sides of edge
97   };
98
99   /**
100    * @struct Vertex
101    *
102    * Describes a single Vertex
103    *
104    */
105   struct Vertex
106   {
107     union
108     {
109       float co[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Coordinates of vertex
110       struct
111       {
112         float x, y, z;
113       };
114     };
115   };
116
117   NavigationMesh() = delete;
118
119 public:
120   /**
121    * @brief Destructor
122    */
123   ~NavigationMesh();
124
125   /**
126    * @brief Returns total number of faces
127    *
128    * @return number of faces
129    */
130   [[nodiscard]] uint32_t GetFaceCount() const;
131
132   /**
133    * @brief Returns total number of edges
134    *
135    * @return number of edges
136    */
137   [[nodiscard]] uint32_t GetEdgeCount() const;
138
139   /**
140    * @brief Returns total number of vertices
141    *
142    * @return number of vertices
143    */
144   [[nodiscard]] uint32_t GetVertexCount() const;
145
146   /**
147    * @brief Looks for the floor under specified position
148    * @param[in] position Position to investigate
149    * @param[in] outPosition Position on the floor in found
150    * @param[in] faceIndex Index of NavigationMesh face associated with floor
151    *
152    * @return True if floor has been found, False otherwise
153    */
154   bool FindFloor(const Dali::Vector3& position, Dali::Vector3& outPosition, uint32_t& faceIndex);
155
156   /**
157    * @brief Looks for a floor starting from specified face
158    *
159    * The function performs lookup starting from the specified face. If 'dontCheckNeighbours' is 'true'
160    * then function will fail if 'position' falls outside boundries of face. If 'dontCheckNeighbours'
161    * is 'false' the function will continue search expanding onto neighbouring faces.
162    *
163    * @param[in] position Position to investigate
164    * @param[in] faceIndex Face index to start lookup
165    * @param[in] dontCheckNeighbours If true, the neighbouring faces won't be tested
166    * @param[out] outPosition Result of lookup
167    *
168    * @return True on success, false otherwise
169    */
170   bool FindFloorForFace(const Dali::Vector3& position, uint32_t faceIndex, bool dontCheckNeighbours, Dali::Vector3& outPosition);
171
172   /**
173    * @brief Returns pointer to Face structure
174    * @param[in] index Index of face to retrieve
175    * @return Pointer to valid Face structure or nullptr
176    */
177   [[nodiscard]] const Face* GetFace(int index) const;
178
179   /**
180    * @brief Returns edge structure
181    * @param[in] index Index of edge to retrieve
182    * @return Pointer to valid Edge structure or nullptr
183    */
184   [[nodiscard]] const Edge* GetEdge(int index) const;
185
186   /**
187    * @brief Returns vertex structure
188    * @param[in] index Index of vertex to retrieve
189    * @return Pointer to valid Vertex structure or nullptr
190    */
191   [[nodiscard]] const Vertex* GetVertex(int index) const;
192
193   /**
194    * @brief Sets static transform for the navigation mesh object
195    *
196    * The NavigationMesh may require to be transformed into the coordinates
197    * of the scene object. The exporter exports navigation geometry in a local
198    * space. The transform must be set in order to use the navigation mesh
199    * in the scene space (most likely DALi coordinate space).
200    *
201    * The scene transform matrix can be set in the DALi event thread using
202    * Dali::DevelActor::GetWorldTransform(sceneActor)
203    *
204    * For example:
205    * @code
206    * Actor parentActorOfNavigationMesh; // non-null object
207    * Dali::DevelActor::GetWorldTransform(parentActorOfNavigationMesh);
208    * navigationMesh->SetSceneTransform(parentActorOfNavigationMesh);
209    * @endcode
210    *
211    * The transform remains static until changed by calling SetSceneTransform() again.
212    * It means that if the matrix is obtained from the actor and actor transform will
213    * change the navigation mesh won't be aligned anymore.
214    *
215    * @param[in] transform Valid transform 4x4 matrix
216    */
217   void SetSceneTransform(const Dali::Matrix& transform);
218
219   /**
220    * @brief transforms point into the NavigationMesh local space
221    *
222    * Transforms a 3D point into navigation mesh space (space used when
223    * NavigationMesh has been created, most likely 3D editor space).
224    *
225    * @param[in] point Point to transform
226    * @return Point transformed to the local space
227    */
228   Dali::Vector3 PointSceneToLocal(const Dali::Vector3& point);
229
230   /**
231    * @brief Transforms point into the parent transform space
232    *
233    * Transforms the given point into the parent space (set with SetSceneTransform()).
234    *
235    * @param[in] point Point to transform
236    * @return Point transformed into the parent space
237    */
238   Dali::Vector3 PointLocalToScene(const Dali::Vector3& point);
239
240   /**
241    * @brief Returns direction of the gravity vector
242    *
243    * Gravity vector points down.
244    *
245    * @return Gravity vector 3D
246    */
247   Dali::Vector3 GetGravityVector() const;
248
249   static constexpr uint16_t NULL_FACE{0xffff}; ///< Represents null polygon
250   static constexpr uint16_t NULL_EDGE{0xffff}; ///< represents null edge
251
252 public:
253   DALI_INTERNAL explicit NavigationMesh(NavigationMeshImpl* impl);
254
255   std::unique_ptr<NavigationMeshImpl> mImpl;
256 };
257 } // namespace Dali::Scene3D::Algorithm
258 #endif // DALI_SCENE3D_NAVIGATION_MESH_H