FlightGear next
PositionedOctree.hxx
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: (C) 2012 James Turner <james@flightgear.org>
3 * SPDX_FileComment: define a spatial octree containing Positioned items
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#pragma once
8
9// std
10#include <array>
11#include <cassert>
12#include <functional>
13#include <map>
14#include <queue>
15#include <set>
16#include <vector>
17
18// SimGear
19#include <simgear/math/SGGeometry.hxx>
20
23
24namespace flightgear
25{
26
27// forward decls
28class PolyLine;
29typedef SGSharedPtr<PolyLine> PolyLineRef;
30typedef std::vector<PolyLineRef> PolyLineList;
31
32
33namespace Octree
34{
35
36 const double LEAF_SIZE = SG_NM_TO_METER * 8.0;
38
43 template <class T>
44 class Ordered
45 {
46 public:
47 Ordered(const T& v, double x) :
48 _order(x),
49 _inner(v)
50 {
51 assert(!SGMisc<double>::isNaN(x));
52 }
53
54 Ordered(const Ordered<T>& a) :
55 _order(a._order),
56 _inner(a._inner)
57 {
58 }
59
61 {
62 _order = a._order;
63 _inner = a._inner;
64 return *this;
65 }
66
67 bool operator<(const Ordered<T>& other) const
68 {
69 return _order < other._order;
70 }
71
72 bool operator>(const Ordered<T>& other) const
73 {
74 return _order > other._order;
75 }
76
77 const T& get() const
78 { return _inner; }
79
80 double order() const
81 { return _order; }
82
83 private:
84 double _order;
85 T _inner;
86 };
87
88 class Node;
90 typedef std::greater<OrderedNode> FNPQCompare;
91
99 typedef std::priority_queue<OrderedNode, std::vector<OrderedNode>, FNPQCompare> FindNearestPQueue;
100
102 typedef std::vector<OrderedPositioned> FindNearestResults;
103
104 // for extracting lines, we don't care about distance ordering, since
105 // we're always grabbing all the lines in an area
106 typedef std::deque<Node*> FindLinesDeque;
107
109
111
112 class Leaf;
113
118 class Node
119 {
120 public:
121 int64_t guid() const
122 { return _ident; }
123
124 const SGBoxd& bbox() const
125 { return _box; }
126
127 bool contains(const SGVec3d& aPos) const
128 {
129 return intersects(aPos, _box);
130 }
131
132 double distToNearest(const SGVec3d& aPos) const
133 {
134 return dist(aPos, _box.getClosestPoint(aPos));
135 }
136
137 virtual void visit(const SGVec3d& aPos, double aCutoff,
138 FGPositioned::Filter* aFilter,
139 FindNearestResults& aResults, FindNearestPQueue&) = 0;
140
141 virtual Leaf* findLeafForPos(const SGVec3d& aPos) const = 0;
142
143 virtual void visitForLines(const SGVec3d& aPos, double aCutoff,
144 PolyLineList& aLines,
145 FindLinesDeque& aQ) const;
146
147 virtual Node* findNodeForBox(const SGBoxd& box) const;
148
149 virtual ~Node();
150
151 void addPolyLine(const PolyLineRef&);
152 protected:
153 Node(const SGBoxd& aBox, int64_t aIdent, bool persistent);
154
155
156 const int64_t _ident;
157 const bool _persistent = false;
158 const SGBoxd _box;
159
161 };
162
163 class Leaf : public Node
164 {
165 public:
166 Leaf(const SGBoxd& aBox, int64_t aIdent, bool persistent);
167
168 virtual void visit(const SGVec3d& aPos, double aCutoff,
169 FGPositioned::Filter* aFilter,
171
172 virtual Leaf* findLeafForPos(const SGVec3d&) const
173 {
174 return const_cast<Leaf*>(this);
175 }
176
178 void removeChild(PositionedID id);
179
180private:
181 bool _childrenLoaded = false;
182
183 typedef std::multimap<FGPositioned::Type, PositionedID> ChildMap;
184 ChildMap children;
185
186 void loadChildren();
187 };
188
189 class Branch : public Node
190 {
191 public:
192 Branch(const SGBoxd& aBox, int64_t aIdent, bool persistent);
193
194 virtual void visit(const SGVec3d& aPos, double aCutoff,
197
198 virtual Leaf* findLeafForPos(const SGVec3d& aPos) const
199 {
200 loadChildren();
201 return childForPos(aPos)->findLeafForPos(aPos);
202 }
203
204 int childMask() const;
205
206 virtual void visitForLines(const SGVec3d& aPos, double aCutoff,
207 PolyLineList& aLines,
208 FindLinesDeque& aQ) const;
209
210 virtual Node* findNodeForBox(const SGBoxd& box) const;
211
212 private:
213 Node* childForPos(const SGVec3d& aCart) const;
214 Node* childAtIndex(int childIndex) const;
215
219 SGBoxd boxForChild(unsigned int aCorner) const
220 {
221 SGBoxd r(_box.getCenter());
222 r.expandBy(_box.getCorner(aCorner));
223 return r;
224 }
225
226 void loadChildren() const;
227
228 mutable std::array<Node*, 8> _children;
229 mutable bool _childrenLoaded = false;
230 };
231
232 bool findNearestN(const SGVec3d& aPos, unsigned int aN, double aCutoffM, FGPositioned::Filter* aFilter, FGPositionedList& aResults, int aCutoffMsec);
233 bool findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filter* aFilter, FGPositionedList& aResults, int aCutoffMsec);
234} // of namespace Octree
235
236
237} // of namespace flightgear
238
Predicate class to support custom filtering of FGPositioned queries Default implementation of this pa...
virtual Leaf * findLeafForPos(const SGVec3d &aPos) const
Branch(const SGBoxd &aBox, int64_t aIdent, bool persistent)
virtual Node * findNodeForBox(const SGBoxd &box) const
virtual void visit(const SGVec3d &aPos, double aCutoff, FGPositioned::Filter *, FindNearestResults &, FindNearestPQueue &aQ)
virtual void visitForLines(const SGVec3d &aPos, double aCutoff, PolyLineList &aLines, FindLinesDeque &aQ) const
Leaf(const SGBoxd &aBox, int64_t aIdent, bool persistent)
void removeChild(PositionedID id)
virtual void visit(const SGVec3d &aPos, double aCutoff, FGPositioned::Filter *aFilter, FindNearestResults &aResults, FindNearestPQueue &)
void insertChild(FGPositioned::Type ty, PositionedID id)
virtual Leaf * findLeafForPos(const SGVec3d &) const
Octree node base class, tracks its bounding box and provides various queries relating to it.
double distToNearest(const SGVec3d &aPos) const
virtual void visit(const SGVec3d &aPos, double aCutoff, FGPositioned::Filter *aFilter, FindNearestResults &aResults, FindNearestPQueue &)=0
void addPolyLine(const PolyLineRef &)
virtual void visitForLines(const SGVec3d &aPos, double aCutoff, PolyLineList &aLines, FindLinesDeque &aQ) const
Node(const SGBoxd &aBox, int64_t aIdent, bool persistent)
bool contains(const SGVec3d &aPos) const
const SGBoxd & bbox() const
virtual Leaf * findLeafForPos(const SGVec3d &aPos) const =0
virtual Node * findNodeForBox(const SGBoxd &box) const
Decorate an object with a double value, and use that value to order items, for the purpoises of the S...
Ordered< T > & operator=(const Ordered< T > &a)
bool operator>(const Ordered< T > &other) const
bool operator<(const Ordered< T > &other) const
Ordered(const Ordered< T > &a)
Ordered(const T &v, double x)
Ordered< FGPositioned * > OrderedPositioned
std::deque< Node * > FindLinesDeque
bool findAllWithinRange(const SGVec3d &aPos, double aRangeM, FGPositioned::Filter *aFilter, FGPositionedList &aResults, int aCutoffMsec)
std::vector< OrderedPositioned > FindNearestResults
bool findNearestN(const SGVec3d &aPos, unsigned int aN, double aCutoffM, FGPositioned::Filter *aFilter, FGPositionedList &aResults, int aCutoffMsec)
std::greater< OrderedNode > FNPQCompare
std::priority_queue< OrderedNode, std::vector< OrderedNode >, FNPQCompare > FindNearestPQueue
the priority queue is fundamental to our search algorithm.
Ordered< Node * > OrderedNode
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
Definition Addon.cxx:53
std::vector< PolyLineRef > PolyLineList
Definition PolyLine.hxx:41
SGSharedPtr< PolyLine > PolyLineRef
Definition PolyLine.hxx:40
std::vector< FGPositionedRef > FGPositionedList
int64_t PositionedID