1 #ifndef DALI_SCENE3D_NAVIGATION_MESH_H
2 #define DALI_SCENE3D_NAVIGATION_MESH_H
5 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <dali-scene3d/public-api/api.h>
24 #include <dali/public-api/math/matrix.h>
25 #include <dali/public-api/math/vector3.h>
26 #include <dali/public-api/math/vector4.h>
33 namespace Dali::Scene3D::Internal::Algorithm
38 namespace Dali::Scene3D::Loader
40 class NavigationMeshFactory;
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;
48 namespace Dali::Scene3D::Algorithm
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;
54 * @class NavigationMesh
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).
60 * NavigationMesh uses any coordinate system that it has been exported with.
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.
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()).
72 class DALI_SCENE3D_API NavigationMesh
79 * Describes a single polygon
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
92 * Describes a single edge
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
103 * Describes a single Vertex
110 float co[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Coordinates of vertex
118 NavigationMesh() = delete;
128 * @brief Returns total number of faces
130 * @return number of faces
132 [[nodiscard]] uint32_t GetFaceCount() const;
135 * @brief Returns total number of edges
137 * @return number of edges
139 [[nodiscard]] uint32_t GetEdgeCount() const;
142 * @brief Returns total number of vertices
144 * @return number of vertices
146 [[nodiscard]] uint32_t GetVertexCount() const;
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
154 * @return True if floor has been found, False otherwise
156 bool FindFloor(const Dali::Vector3& position, Dali::Vector3& outPosition, uint32_t& faceIndex);
159 * @brief Looks for a floor starting from specified face
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.
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
170 * @return True on success, false otherwise
172 bool FindFloorForFace(const Dali::Vector3& position, uint32_t faceIndex, bool dontCheckNeighbours, Dali::Vector3& outPosition);
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
180 [[nodiscard]] const Face* GetFace(int index) const;
183 * @brief Returns edge structure
184 * @param[in] index Index of edge to retrieve
185 * @return Pointer to valid Edge structure or nullptr
187 [[nodiscard]] const Edge* GetEdge(int index) const;
190 * @brief Returns vertex structure
191 * @param[in] index Index of vertex to retrieve
192 * @return Pointer to valid Vertex structure or nullptr
194 [[nodiscard]] const Vertex* GetVertex(int index) const;
197 * @brief Sets static transform for the navigation mesh object
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).
204 * The scene transform matrix can be set in the DALi event thread using
205 * Dali::DevelActor::GetWorldTransform(sceneActor)
209 * Actor parentActorOfNavigationMesh; // non-null object
210 * Dali::DevelActor::GetWorldTransform(parentActorOfNavigationMesh);
211 * navigationMesh->SetSceneTransform(parentActorOfNavigationMesh);
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.
218 * @param[in] transform Valid transform 4x4 matrix
220 void SetSceneTransform(const Dali::Matrix& transform);
223 * @brief transforms point into the NavigationMesh local space
225 * Transforms a 3D point into navigation mesh space (space used when
226 * NavigationMesh has been created, most likely 3D editor space).
228 * @param[in] point Point to transform
229 * @return Point transformed to the local space
231 Dali::Vector3 PointSceneToLocal(const Dali::Vector3& point);
234 * @brief Transforms point into the parent transform space
236 * Transforms the given point into the parent space (set with SetSceneTransform()).
238 * @param[in] point Point to transform
239 * @return Point transformed into the parent space
241 Dali::Vector3 PointLocalToScene(const Dali::Vector3& point);
244 * @brief Returns direction of the gravity vector
246 * Gravity vector points down.
248 * @return Gravity vector 3D
250 Dali::Vector3 GetGravityVector() const;
252 static constexpr uint16_t NULL_FACE{0xffff}; ///< Represents null polygon
253 static constexpr uint16_t NULL_EDGE{0xffff}; ///< represents null edge
257 DALI_INTERNAL explicit NavigationMesh( NavigationMeshImpl* impl );
259 std::unique_ptr<NavigationMeshImpl> mImpl;
261 } // namespace Dali::Scene3D::Algorithm
262 #endif // DALI_SCENE3D_NAVIGATION_MESH_H