00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef LASS_GUARDIAN_OF_INCLUSION_SPAT_AABB_TREE_H
00053 #define LASS_GUARDIAN_OF_INCLUSION_SPAT_AABB_TREE_H
00054
00055
00056
00057 #include "spat_common.h"
00058 #include "default_object_traits.h"
00059 #include "split_heuristics.h"
00060
00061 namespace lass
00062 {
00063 namespace spat
00064 {
00065
00066 template
00067 <
00068 typename ObjectType,
00069 typename ObjectTraits = DefaultObjectTraits<ObjectType>,
00070 typename SplitHeuristics = DefaultSplitHeuristics<>
00071 >
00072 class AabbTree
00073 {
00074 public:
00075
00076 typedef AabbTree<ObjectType, ObjectTraits, SplitHeuristics> TSelf;
00077
00078 typedef ObjectType TObject;
00079 typedef ObjectTraits TObjectTraits;
00080 typedef SplitHeuristics TSplitHeuristics;
00081
00082 typedef typename TObjectTraits::TObjectIterator TObjectIterator;
00083 typedef typename TObjectTraits::TObjectReference TObjectReference;
00084 typedef typename TObjectTraits::TAabb TAabb;
00085 typedef typename TObjectTraits::TRay TRay;
00086 typedef typename TObjectTraits::TPoint TPoint;
00087 typedef typename TObjectTraits::TVector TVector;
00088 typedef typename TObjectTraits::TValue TValue;
00089 typedef typename TObjectTraits::TParam TParam;
00090 typedef typename TObjectTraits::TReference TReference;
00091 typedef typename TObjectTraits::TConstReference TConstReference;
00092 typedef typename TObjectTraits::TInfo TInfo;
00093
00094 enum { dimension = TObjectTraits::dimension };
00095
00096 typedef std::vector<TObjectIterator> TObjectIterators;
00097
00098 class Neighbour
00099 {
00100 public:
00101 Neighbour() {}
00102 Neighbour(TObjectIterator object, TValue squaredDistance):
00103 object_(object), squaredDistance_(squaredDistance) {}
00104 TObjectIterator object() const { return object_; }
00105 TValue squaredDistance() const { return squaredDistance_; }
00106 TObjectIterator operator->() const { return object_; }
00107 TObjectReference operator*() const { return TObjectTraits::object(object_); }
00108 bool operator<(const Neighbour& other) const { return squaredDistance_ < other.squaredDistance_; }
00109 private:
00110 TObjectIterator object_;
00111 TValue squaredDistance_;
00112 };
00113
00114 AabbTree();
00115 AabbTree(TObjectIterator first, TObjectIterator last);
00116
00117 void reset();
00118 void reset(TObjectIterator first, TObjectIterator last);
00119
00120 const TAabb aabb() const;
00121
00122 bool contains(const TPoint& point, const TInfo* info = 0) const;
00123 template <typename OutputIterator>
00124 OutputIterator find(const TPoint& point, OutputIterator result, const TInfo* info = 0) const;
00125 TObjectIterator intersect(const TRay& ray, TReference t, TParam tMin = 0, const TInfo* info = 0) const;
00126 bool intersects(const TRay& ray, TParam tMin = 0,
00127 TParam tMax = std::numeric_limits<TValue>::infinity(), const TInfo* info = 0) const;
00128 const Neighbour nearestNeighbour(const TPoint& point, const TInfo* info = 0) const;
00129 template <typename RandomIterator>
00130 RandomIterator rangeSearch(const TPoint& center, TParam maxRadius, size_t maxCount,
00131 RandomIterator first, const TInfo* info = 0) const;
00132
00133 const bool isEmpty() const;
00134 const TObjectIterator end() const;
00135 void swap(TSelf& other);
00136
00137 private:
00138
00139 struct Input
00140 {
00141 TAabb aabb;
00142 TObjectIterator object;
00143 Input(const TAabb& aabb, TObjectIterator object): aabb(aabb), object(object) {}
00144 };
00145 typedef std::vector<Input> TInputs;
00146 typedef typename TInputs::iterator TInputIterator;
00147
00148 class Node
00149 {
00150 public:
00151 explicit Node(const TAabb& aabb):
00152 aabb_(aabb),
00153 first_(-1)
00154 {
00155 }
00156 Node(const TAabb& aabb, int first, int last):
00157 aabb_(aabb),
00158 first_(first)
00159 {
00160 LASS_ASSERT(first >= 0 && last > first);
00161 last_ = last;
00162 }
00163
00164 const bool isInternal() const { return first_ < 0; }
00165 const TAabb& aabb() const { return aabb_; }
00166 const int right() const { LASS_ASSERT(isInternal()); return right_; }
00167 int& right() { LASS_ASSERT(isInternal()); return right_; }
00168
00169 const bool isLeaf() const { return first_ >= 0; }
00170 const int first() const { LASS_ASSERT(isLeaf()); return first_; }
00171 const int last() const { LASS_ASSERT(isLeaf()); return last_; }
00172 private:
00173 TAabb aabb_;
00174 int first_;
00175 union
00176 {
00177 int right_;
00178 int last_;
00179 };
00180 };
00181 typedef std::deque<Node> TNodes;
00182
00183 const int balance(TInputIterator first, TInputIterator last);
00184 const int addLeafNode(const TAabb& aabb, TInputIterator first, TInputIterator last);
00185 const int addInternalNode(const TAabb& aabb);
00186
00187 bool doContains(int index, const TPoint& point, const TInfo* info) const;
00188 template <typename OutputIterator>
00189 OutputIterator doFind(int index, const TPoint& point, OutputIterator first, const TInfo* info) const;
00190 TObjectIterator doIntersect(int index, const TRay& ray, TReference t, TParam tMin, const TInfo* info) const;
00191 bool doIntersects(int iIndex, const TRay& ray, TParam tMin, TParam tMax, const TInfo* info) const;
00192 void doNearestNeighbour(int index, const TPoint& point, const TInfo* info, Neighbour& best) const;
00193 template <typename RandomIterator>
00194 RandomIterator doRangeSearch(int index, const TPoint& point, TReference squaredRadius,
00195 size_t maxCount, RandomIterator first, RandomIterator last, const TInfo* info) const;
00196
00197 void getChildren(int index, const TPoint& target, int indices[2], TValue squaredDistances[2]) const;
00198
00199 TObjectIterators objects_;
00200 TNodes nodes_;
00201 TObjectIterator end_;
00202 };
00203
00204
00205 }
00206
00207 }
00208
00209 #include "aabb_tree.inl"
00210
00211 #endif
00212
00213