ScummVM API documentation
route_finder_jps.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef AGS_ROUTE_FINDER_JPS_H
23#define AGS_ROUTE_FINDER_JPS_H
24
25#include "common/std/queue.h"
26#include "common/std/vector.h"
27#include "common/std/algorithm.h"
28#include "common/std/functional.h"
29#include "common/std/xutility.h"
30
31// Not all platforms define INFINITY
32#ifndef INFINITY
33#define INFINITY ((float)(1e+300 * 1e+300)) // This must overflow
34#endif
35
36namespace AGS3 {
37
38// TODO: this could be cleaned up/simplified ...
39
40// further optimizations possible:
41// - forward refinement should use binary search
42
44public:
45 Navigation();
46
47 void Resize(int width, int height);
48
49 enum NavResult {
50 // unreachable
51 NAV_UNREACHABLE,
52 // straight line exists
53 NAV_STRAIGHT,
54 // path used
55 NAV_PATH
56 };
57
58 // ncpath = navpoint-compressed path
59 // opath = path composed of individual grid elements
60 NavResult NavigateRefined(int sx, int sy, int ex, int ey, std::vector<int> &opath,
61 std::vector<int> &ncpath);
62
63 NavResult Navigate(int sx, int sy, int ex, int ey, std::vector<int> &opath);
64
65 bool TraceLine(int srcx, int srcy, int targx, int targy, int &lastValidX, int &lastValidY) const;
66 bool TraceLine(int srcx, int srcy, int targx, int targy, std::vector<int> *rpath = nullptr) const;
67
68 inline void SetMapRow(int y, const unsigned char *row) {
69 map[y] = row;
70 }
71
72 static int PackSquare(int x, int y);
73 static void UnpackSquare(int sq, int &x, int &y);
74
75private:
76 // priority queue entry
77 struct Entry {
78 float cost;
79 int index;
80
81 inline Entry() {}
82
83 inline Entry(float ncost, int nindex)
84 : cost(ncost)
85 , index(nindex) {
86 }
87
88 inline bool operator <(const Entry &b) const {
89 return cost < b.cost;
90 }
91
92 inline bool operator >(const Entry &b) const {
93 return cost > b.cost;
94 }
95 };
96
97 int mapWidth;
98 int mapHeight;
100
101 typedef unsigned short tFrameId;
102 typedef int tPrev;
103
104 struct NodeInfo {
105 // quantized min distance from origin
106 unsigned short dist;
107 // frame id (counter to detect new search)
108 tFrameId frameId;
109 // previous node index (packed, relative to current node)
110 tPrev prev;
111
112 inline NodeInfo()
113 : dist(0)
114 , frameId(0)
115 , prev(-1) {
116 }
117 };
118
119 static const float DIST_SCALE_PACK;
120 static const float DIST_SCALE_UNPACK;
121
122 std::vector<NodeInfo> mapNodes;
123 tFrameId frameId;
124
126
127 // temporary buffers:
128 mutable std::vector<int> fpath;
129 std::vector<int> ncpathIndex;
130 std::vector<int> rayPath, orayPath;
131
132 // temps for routing towards unreachable areas
133 int cnode;
134 int closest;
135
136 // orthogonal only (this should correspond to what AGS is doing)
137 bool nodiag;
138
139 bool navLock;
140
141 void IncFrameId();
142
143 // outside map test
144 inline bool Outside(int x, int y) const;
145 // stronger inside test
146 bool Passable(int x, int y) const;
147 // plain access, unchecked
148 inline bool Walkable(int x, int y) const;
149
150 void AddPruned(int *buf, int &bcount, int x, int y) const;
151 bool HasForcedNeighbor(int x, int y, int dx, int dy) const;
152 int FindJump(int x, int y, int dx, int dy, int ex, int ey);
153 int FindOrthoJump(int x, int y, int dx, int dy, int ex, int ey);
154
155 // neighbor reachable (nodiag only)
156 bool Reachable(int x0, int y0, int x1, int y1) const;
157
158 static inline int sign(int n) {
159 return n < 0 ? -1 : (n > 0 ? 1 : 0);
160 }
161
162 static inline int iabs(int n) {
163 return n < 0 ? -n : n;
164 }
165
166 static inline int iclamp(int v, int min, int max) {
167 return v < min ? min : (v > max ? max : v);
168 }
169
170 static inline int ClosestDist(int dx, int dy) {
171 return dx * dx + dy * dy;
172 // Manhattan?
173 //return iabs(dx) + iabs(dy);
174 }
175};
176
177inline int Navigation::PackSquare(int x, int y) {
178 return (y << 16) + x;
179}
180
181inline void Navigation::UnpackSquare(int sq, int &x, int &y) {
182 y = sq >> 16;
183 x = sq & ((1 << 16) - 1);
184}
185
186inline bool Navigation::Outside(int x, int y) const {
187 return
188 (unsigned)x >= (unsigned)mapWidth ||
189 (unsigned)y >= (unsigned)mapHeight;
190}
191
192inline bool Navigation::Walkable(int x, int y) const {
193 // invert condition because of AGS
194 return map[y][x] != 0;
195}
196
197} // namespace AGS3
198
199#endif // AGS_ROUTE_FINDER_JPS_H
Definition: route_finder_jps.h:43
Definition: map.h:40
Definition: queue.h:49