-
Notifications
You must be signed in to change notification settings - Fork 3
/
FlowFieldPathfinding.h
134 lines (110 loc) · 3.51 KB
/
FlowFieldPathfinding.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#ifndef FLOW_FIELD_PATHFINDING_H
#define FLOW_FIELD_PATHFINDING_H
#include "core/reference.h"
#include "core/array.h"
#define FFP_MAX_AGENT_SIZE (20 * 20)
#define FFP_MAX_AGENTS (1000)
#define FFP_NO_AGENT (-1)
class FlowFieldPathfinding : public Reference {
GDCLASS(FlowFieldPathfinding, Reference);
public:
enum Dir : uint8_t {
NONE,
LEFT,
RIGHT,
UP,
DOWN,
TOPLEFT,
TOPRIGHT,
BOTLEFT,
BOTRIGHT
};
private:
struct TileVector2 {
int x;
int y;
TileVector2 (int x_, int y_) {
x = x_;
y = y_;
}
};
struct Agent {
int x;
int y;
int width;
int height;
Agent () {
x = -1;
}
inline bool has_been_updated () const {
return x >= 0;
}
};
struct Tile {
bool wall;
bool visited;
Dir dir;
double distance;
int dirx;
int diry;
int occupied_by;
Tile () {
wall = true;
visited = false;
occupied_by = FFP_NO_AGENT;
dir = Dir::NONE;
dirx = -1;
diry = -1;
distance = 0;
}
};
public:
FlowFieldPathfinding () {
m_width = -1;
m_height = -1;
m_tiles = NULL;
m_open_tile_indices = NULL;
m_visited_integrity = false;
m_agents_top = 0;
}
~FlowFieldPathfinding () {
delete[] m_tiles;
delete[] m_open_tile_indices;
}
void Init (const Array& tile_positions);
void Update (const Vector2& target_pos);
int RegisterAgent ();
void UpdateAgent (int id, int x, int y, int width, int height);
void RemoveAgent (int id);
int GetWidth () const { return m_width; }
int GetHeight () const { return m_height; }
const Vector2& GetTargetPosition () const { return m_target_pos; }
Variant GetNextAgentPosition (int id) const; // NULL or Vector2
bool IsTileWall (const Vector2 & pos) const;
int GetTileDistance (const Vector2 & pos) const;
Dir GetTileDirection (const Vector2 & pos) const;
bool IsTileOccupied (const Vector2 & pos) const;
protected:
static void _bind_methods ();
private:
void set_agent_tiles (const Agent & agent, int occupied_by, int to_id);
inline bool is_valid_idx (int idx) const;
inline Vector2 idx_to_vec2 (int idx) const;
inline int xy_to_idx (int x, int y) const;
inline int vec2_to_idx (const Vector2 &v) const;
inline Dir xy_to_dir (int x, int y) const;
inline const Tile * get_tile (int x, int y) const;
inline const Agent * get_agent (int id) const;
inline Tile * get_tile (int x, int y) { return const_cast<Tile*>(const_cast<const FlowFieldPathfinding*>(this)->get_tile(x, y)); }
inline Agent * get_agent (int id) { return const_cast<Agent*>(const_cast<const FlowFieldPathfinding*>(this)->get_agent(id)); }
Vector2 m_target_pos;
int m_width;
int m_height;
Tile * m_tiles;
bool m_visited_integrity;
int m_agents_top;
Agent m_agents[FFP_MAX_AGENTS];
int * m_open_tile_indices;
};
VARIANT_ENUM_CAST(FlowFieldPathfinding::Dir);
#endif // FLOW_FIELD_PATHFINDING_H