1/**************************************************************************/
2/* nav_utils.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef NAV_UTILS_H
32#define NAV_UTILS_H
33
34#include "core/math/vector3.h"
35#include "core/templates/hash_map.h"
36#include "core/templates/hashfuncs.h"
37#include "core/templates/local_vector.h"
38
39class NavBase;
40
41namespace gd {
42struct Polygon;
43
44union PointKey {
45 struct {
46 int64_t x : 21;
47 int64_t y : 22;
48 int64_t z : 21;
49 };
50
51 uint64_t key = 0;
52};
53
54struct EdgeKey {
55 PointKey a;
56 PointKey b;
57
58 static uint32_t hash(const EdgeKey &p_val) {
59 return hash_one_uint64(p_val.a.key) ^ hash_one_uint64(p_val.b.key);
60 }
61
62 bool operator==(const EdgeKey &p_key) const {
63 return (a.key == p_key.a.key) && (b.key == p_key.b.key);
64 }
65
66 EdgeKey(const PointKey &p_a = PointKey(), const PointKey &p_b = PointKey()) :
67 a(p_a),
68 b(p_b) {
69 if (a.key > b.key) {
70 SWAP(a, b);
71 }
72 }
73};
74
75struct Point {
76 Vector3 pos;
77 PointKey key;
78};
79
80struct Edge {
81 /// The gateway in the edge, as, in some case, the whole edge might not be navigable.
82 struct Connection {
83 /// Polygon that this connection leads to.
84 Polygon *polygon = nullptr;
85
86 /// Edge of the source polygon where this connection starts from.
87 int edge = -1;
88
89 /// Point on the edge where the gateway leading to the poly starts.
90 Vector3 pathway_start;
91
92 /// Point on the edge where the gateway leading to the poly ends.
93 Vector3 pathway_end;
94 };
95
96 /// Connections from this edge to other polygons.
97 Vector<Connection> connections;
98};
99
100struct Polygon {
101 /// Navigation region or link that contains this polygon.
102 const NavBase *owner = nullptr;
103
104 /// The points of this `Polygon`
105 LocalVector<Point> points;
106
107 /// Are the points clockwise?
108 bool clockwise;
109
110 /// The edges of this `Polygon`
111 LocalVector<Edge> edges;
112
113 /// The center of this `Polygon`
114 Vector3 center;
115};
116
117struct NavigationPoly {
118 uint32_t self_id = 0;
119 /// This poly.
120 const Polygon *poly;
121
122 /// Those 4 variables are used to travel the path backwards.
123 int back_navigation_poly_id = -1;
124 int back_navigation_edge = -1;
125 Vector3 back_navigation_edge_pathway_start;
126 Vector3 back_navigation_edge_pathway_end;
127
128 /// The entry position of this poly.
129 Vector3 entry;
130 /// The distance to the destination.
131 real_t traveled_distance = 0.0;
132
133 NavigationPoly() { poly = nullptr; }
134
135 NavigationPoly(const Polygon *p_poly) :
136 poly(p_poly) {}
137
138 bool operator==(const NavigationPoly &other) const {
139 return this->poly == other.poly;
140 }
141
142 bool operator!=(const NavigationPoly &other) const {
143 return !operator==(other);
144 }
145};
146
147struct ClosestPointQueryResult {
148 Vector3 point;
149 Vector3 normal;
150 RID owner;
151};
152
153} // namespace gd
154
155#endif // NAV_UTILS_H
156