1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #pragma once19 20 #include "../Math/MathTypes.h"21 #include "../Math/myassert.h"22 #include "[Triangle.h]"23 24 #ifdef MATH_CONTAINERLIB_SUPPORT25 #include "Container/MaxHeap.h"26 #endif27 28 [MATH_BEGIN_NAMESPACE]29 30 enum [CardinalAxis]31 {32 [AxisX] = 0,33 [AxisY],34 [AxisZ],35 [AxisNone]36 };37 38 struct [KdTreeNode]39 {40 41 42 unsigned [splitAxis] : 2;43 44 45 unsigned [childIndex] : 30;46 union47 {48 float [splitPos]; 49 50 51 u32 [bucketIndex];52 };53 54 55 bool [IsEmptyLeaf]() const { [assert]([IsLeaf]()); return [bucketIndex] == 0; }56 bool [IsLeaf]() const { return [splitAxis] == [AxisNone]; }57 int [LeftChildIndex]() const { return (int)[childIndex]; }58 int [RightChildIndex]() const { return (int)[childIndex]+1; }59 [CardinalAxis] [SplitAxis]() const { return ([CardinalAxis])[splitAxis]; }60 };61 62 63 template<typename T>64 class [KdTree]65 {66 public:67 68 static const u32 [BUCKET_SENTINEL] = 0xFFFFFFFF;69 70 71 [KdTree]()72 #ifdef _DEBUG73 :needsBuilding(false)74 #endif75 {}76 77 [~KdTree]();78 79 80 81 82 void [AddObjects](const T *objects, int numObjects);83 84 85 86 void [Build]();87 88 89 90 91 void [Clear]();92 93 94 95 96 u32 *[Bucket](int bucketIndex);97 const u32 *[Bucket](int bucketIndex) const;98 99 100 T &[Object](int objectIndex);101 const T &[Object](int objectIndex) const;102 103 104 int [NumObjects]() const;105 106 107 int [NumNodes]() const;108 109 110 111 int [NumLeaves]() const;112 113 114 115 int [NumInnerNodes]() const;116 117 118 int [TreeHeight]() const;119 120 121 [KdTreeNode] *[Root]();122 const [KdTreeNode] *[Root]() const;123 124 125 126 bool [IsPartOfThisTree](const [KdTreeNode] *node) const;127 128 bool [IsPartOfThisTree](const [KdTreeNode] *root, const [KdTreeNode] *node) const;129 130 131 132 const [AABB] &[BoundingAABB]() const { return rootAABB; }133 134 135 136 137 138 139 140 141 template<typename Func>142 inline void [RayQuery](const [Ray] &r, Func &leafCallback);143 144 145 146 147 148 149 150 151 template<typename Func>152 inline void [AABBQuery](const [AABB] &aabb, Func &leafCallback);153 154 #if 0 155 156 157 158 159 160 161 162 template<typename Func>163 inline void KdTreeQuery([KdTree<T>] &tree2, const [float3x4] &thisWorldTransform, const [float3x4] &tree2WorldTransform, Func &leafCallback);164 #endif165 166 #ifdef MATH_CONTAINERLIB_SUPPORT167 168 169 170 171 172 173 174 template<typename Func>175 inline void NearestObjects(const vec &point, Func &leafCallback);176 #endif177 178 private:179 static const int maxNodes = 256 * 1024;180 static const int maxTreeDepth = 30;181 182 std::vector<KdTreeNode> nodes;183 std::vector<u8, AlignedAllocator<u8, 16> > objects;184 std::vector<u32*> buckets;185 186 int AllocateNodePair();187 188 void FreeBuckets();189 190 [AABB] [BoundingAABB](const u32 *bucket) const;191 192 void SplitLeaf(int nodeIndex, const [AABB] &nodeAABB, int numObjectsInBucket, int leafDepth);193 194 195 [KdTree](const [KdTree] &);196 void operator =(const [KdTree] &);197 198 [AABB] rootAABB;199 200 #ifdef _DEBUG201 bool needsBuilding; 202 #endif203 204 int [TreeHeight](int nodeIndex) const;205 };206 207 208 struct [TriangleKdTreeRayQueryNearestHitVisitor]209 {210 float [rayT];211 vec [pos];212 u32 [triangleIndex];213 [float2] [barycentricUV];214 215 [TriangleKdTreeRayQueryNearestHitVisitor]()216 {217 [rayT] = [FLOAT_INF];218 [triangleIndex] = [KdTree<Triangle>::BUCKET_SENTINEL];219 [pos] = [vec::nan];220 [barycentricUV] = [float2::nan];221 }222 bool [operator()]([KdTree<Triangle>] &tree, const [KdTreeNode] &leaf, const [Ray] &ray, float tNear, float tFar)223 {224 u32 *bucket = tree.[Bucket](leaf.[bucketIndex]);225 [assert](bucket);226 while(*bucket != [KdTree<Triangle>::BUCKET_SENTINEL])227 {228 const [Triangle] &tri = tree.[Object](*bucket);229 float u, v, t;230 t = [Triangle::IntersectLineTri](ray.[pos], ray.[dir], tri.[a], tri.[b], tri.[c], u, v);231 bool intersects = t < std::numeric_limits<float>::infinity();232 if (intersects && t >= tNear && t <= tFar && t < [rayT])233 {234 [rayT] = t;235 [pos] = ray.[GetPoint](t);236 [barycentricUV] = [float2](u,v);237 [triangleIndex] = *bucket;238 }239 ++bucket;240 }241 return [rayT] < [FLOAT_INF]; 242 }243 };244 245 [MATH_END_NAMESPACE]246 247 #include "[KDTree.inl]" Go back to previous page