TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
PointKDTree.h
Go to the documentation of this file.
1 
14 #ifndef G3D_PointKDTree_h
15 #define G3D_PointKDTree_h
16 
17 #include "G3D/platform.h"
18 #include "G3D/Array.h"
19 #include "G3D/Table.h"
20 #include "G3D/Vector2.h"
21 #include "G3D/Vector3.h"
22 #include "G3D/Vector4.h"
23 #include "G3D/AABox.h"
24 #include "G3D/Sphere.h"
25 #include "G3D/Box.h"
26 #include "G3D/BinaryInput.h"
27 #include "G3D/BinaryOutput.h"
28 #include "G3D/CollisionDetection.h"
29 #include "G3D/Frustum.h"
30 #include "G3D/PositionTrait.h"
31 #include <algorithm>
32 
33 namespace G3D {
34 
98 template<class T,
99  class PositionFunc = PositionTrait<T>,
100  class HashFunc = HashTrait<T>,
101  class EqualsFunc = EqualsTrait<T> >
102 class PointKDTree {
103 protected:
104 #define TreeType PointKDTree<T, PositionFunc, HashFunc, EqualsFunc>
105 
106  // Unlike the KDTree, the PointKDTree assumes that T elements are
107  // small and keeps the handle and cached position together instead of
108  // placing them in separate bounds arrays. Also note that a copy of T
109  // is kept in the member table and that there is no indirection.
110  class Handle {
111  private:
113 
114  public:
115  T value;
116 
117  inline Handle() {}
118  inline Handle(const T& v) : value(v) {
119  PositionFunc::getPosition(v, m_position);
120  }
121 
123  void setPosition(const Vector3& v) {
124  m_position = v;
125  }
126 
127  inline const Vector3& position() const {
128  return m_position;
129  }
130  };
131 
134  const Array<Handle>& point) {
135 
136  if (point.size() == 0) {
137  return AABox(Vector3::inf(), Vector3::inf());
138  }
139 
140  AABox bounds(point[0].position());
141 
142  for (int p = 0; p < point.size(); ++p) {
143  bounds.merge(point[p].position());
144  }
145 
146  return bounds;
147  }
148 
149  class Node {
150  public:
151 
155 
157 
160 
170  Node* child[2];
171 
174 
176  Node() {
177  splitAxis = Vector3::X_AXIS;
178  splitLocation = 0;
179  splitBounds = AABox(-Vector3::inf(), Vector3::inf());
180  for (int i = 0; i < 2; ++i) {
181  child[i] = NULL;
182  }
183  }
184 
188  Node(const Node& other) : valueArray(other.valueArray) {
189  splitAxis = other.splitAxis;
190  splitLocation = other.splitLocation;
191  splitBounds = other.splitBounds;
192  for (int i = 0; i < 2; ++i) {
193  child[i] = NULL;
194  }
195  }
196 
199  Node(const Array<Handle>& pt) {
200  splitAxis = Vector3::X_AXIS;
201  splitLocation = 0;
202  for (int i = 0; i < 2; ++i) {
203  child[i] = NULL;
204  }
205  valueArray = pt;
206  }
207 
208 
210  ~Node() {
211  for (int i = 0; i < 2; ++i) {
212  delete child[i];
213  }
214  }
215 
216 
218  inline bool isLeaf() const {
219  return (child[0] == NULL) && (child[1] == NULL);
220  }
221 
222 
227  void getHandles(Array<Handle>& handleArray) const {
228  handleArray.append(valueArray);
229  for (int i = 0; i < 2; ++i) {
230  if (child[i] != NULL) {
231  child[i]->getHandles(handleArray);
232  }
233  }
234  }
235 
236 
237  void verifyNode(const Vector3& lo, const Vector3& hi) {
238  // debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
239  // splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
240 
241  debugAssert(lo == splitBounds.low());
242  debugAssert(hi == splitBounds.high());
243 
244 # ifdef G3D_DEBUG
245  for (int i = 0; i < valueArray.length(); ++i) {
246  const Vector3& b = valueArray[i].position();
247  debugAssert(splitBounds.contains(b));
248  }
249 # endif
250 
251  if (child[0] || child[1]) {
252  debugAssert(lo[splitAxis] < splitLocation);
253  debugAssert(hi[splitAxis] > splitLocation);
254  }
255 
256  Vector3 newLo = lo;
257  newLo[splitAxis] = splitLocation;
258  Vector3 newHi = hi;
259  newHi[splitAxis] = splitLocation;
260 
261  if (child[0] != NULL) {
262  child[0]->verifyNode(lo, newHi);
263  }
264 
265  if (child[1] != NULL) {
266  child[1]->verifyNode(newLo, hi);
267  }
268  }
269 
270 
276  static void serializeStructure(const Node* n, BinaryOutput& bo) {
277  if (n == NULL) {
278  bo.writeUInt8(0);
279  } else {
280  bo.writeUInt8(1);
281  n->splitBounds.serialize(bo);
282  serialize(n->splitAxis, bo);
284  for (int c = 0; c < 2; ++c) {
285  serializeStructure(n->child[c], bo);
286  }
287  }
288  }
289 
292  if (bi.readUInt8() == 0) {
293  return NULL;
294  } else {
295  Node* n = new Node();
296  n->splitBounds.deserialize(bi);
297  deserialize(n->splitAxis, bi);
298  n->splitLocation = bi.readFloat32();
299  for (int c = 0; c < 2; ++c) {
300  n->child[c] = deserializeStructure(bi);
301  }
302  return n;
303  }
304  }
305 
308 
309  // See which side of the splitting plane the bounds are on
310  if (point[splitAxis] < splitLocation) {
311  // Point is on the low side. Recurse into the child
312  // if it exists.
313  if (child[0] != NULL) {
314  return child[0]->findDeepestContainingNode(point);
315  }
316  } else if (point[splitAxis] > splitLocation) {
317  // Point is on the high side, recurse into the child
318  // if it exists.
319  if (child[1] != NULL) {
320  return child[1]->findDeepestContainingNode(point);
321  }
322  }
323 
324  // There was no containing child, so this node is the
325  // deepest containing node.
326  return this;
327  }
328 
332  const AABox& sphereBounds,
333  const Sphere& sphere,
334  Array<T>& members) const {
335 
336  // Test all values at this node. Extract the
337  // underlying C array for speed
338  const int N = valueArray.size();
339  const Handle* handleArray = valueArray.getCArray();
340 
341  const float r2 = square(sphere.radius);
342 
343  // Copy the sphere center so that it is on the stack near the radius
344  const Vector3 center = sphere.center;
345  for (int v = 0; v < N; ++v) {
346  if ((center - handleArray[v].position()).squaredLength() <= r2) {
347  members.append(handleArray[v].value);
348  }
349  }
350 
351  // If the left child overlaps the box, recurse into it
352  if (child[0] && (sphereBounds.low()[splitAxis] < splitLocation)) {
353  child[0]->getIntersectingMembers(sphereBounds, sphere, members);
354  }
355 
356  // If the right child overlaps the box, recurse into it
357  if (child[1] && (sphereBounds.high()[splitAxis] > splitLocation)) {
358  child[1]->getIntersectingMembers(sphereBounds, sphere, members);
359  }
360  }
361 
370  const AABox& box,
371  const Sphere& sphere,
372  Array<T>& members,
373  bool useSphere) const {
374 
375  // Test all values at this node
376  for (int v = 0; v < valueArray.size(); ++v) {
377  if ((useSphere && sphere.contains(valueArray[v].position())) ||
378  (! useSphere && box.contains(valueArray[v].position()))) {
379  members.append(valueArray[v].value);
380  }
381  }
382 
383  // If the left child overlaps the box, recurse into it
384  if ((child[0] != NULL) && (box.low()[splitAxis] < splitLocation)) {
385  child[0]->getIntersectingMembers(box, sphere, members, useSphere);
386  }
387 
388  // If the right child overlaps the box, recurse into it
389  if ((child[1] != NULL) && (box.high()[splitAxis] > splitLocation)) {
390  child[1]->getIntersectingMembers(box, sphere, members, useSphere);
391  }
392  }
393 
397  void assignSplitBounds(const AABox& myBounds) {
398  splitBounds = myBounds;
399 
400 # ifdef G3D_DEBUG
401  if (child[0] || child[1]) {
402  debugAssert(splitBounds.high()[splitAxis] > splitLocation);
403  debugAssert(splitBounds.low()[splitAxis] < splitLocation);
404  }
405 # endif
406 
407  AABox childBounds[2];
408  myBounds.split(splitAxis, splitLocation, childBounds[0], childBounds[1]);
409 
410  for (int c = 0; c < 2; ++c) {
411  if (child[c]) {
412  child[c]->assignSplitBounds(childBounds[c]);
413  }
414  }
415  }
416  };
417 
419  private:
421 
422  public:
423 
424  AxisComparator(Vector3::Axis s) : sortAxis(s) {}
425 
426  inline int operator()(const Handle& A, const Handle& B) const {
427  if (A.position()[sortAxis] > B.position()[sortAxis]) {
428  return -1;
429  } else if (A.position()[sortAxis] < B.position()[sortAxis]) {
430  return 1;
431  } else {
432  return 0;
433  }
434  }
435  };
436 
445  Array<Handle>& source,
446  Array<Handle>& temp,
447  int valuesPerNode,
448  int numMeanSplits) {
449 
450  Node* node = NULL;
451 
452  if (source.size() <= valuesPerNode) {
453  // Make a new leaf node
454  node = new Node(source);
455 
456  // Set the pointers in the memberTable
457  for (int i = 0; i < source.size(); ++i) {
458  memberTable.set(source[i].value, node);
459  }
460 
461  } else {
462  // Make a new internal node
463  node = new Node();
464 
465  const AABox bounds = computeBounds(source);
466  const Vector3 extent = bounds.high() - bounds.low();
467 
468  Vector3::Axis splitAxis = extent.primaryAxis();
469 
470  float splitLocation;
471 
472  Array<Handle> lt, gt;
473 
474  if (numMeanSplits <= 0) {
475  source.medianPartition(lt, node->valueArray, gt, temp, AxisComparator(splitAxis));
476  splitLocation = node->valueArray[0].position()[splitAxis];
477 
478  if ((node->valueArray.size() > source.size() / 2) &&
479  (source.size() > 10)) {
480  // Our median split put an awful lot of points on the splitting plane. Try a mean
481  // split instead
482  numMeanSplits = 1;
483  }
484  }
485 
486  if (numMeanSplits > 0) {
487  // Compute the mean along the axis
488 
489  splitLocation = (bounds.high()[splitAxis] +
490  bounds.low()[splitAxis]) / 2.0f;
491 
492  Handle splitHandle;
493  Vector3 v;
494  v[splitAxis] = splitLocation;
495  splitHandle.setPosition(v);
496 
497  source.partition(splitHandle, lt, node->valueArray, gt, AxisComparator(splitAxis));
498  }
499 
500 # if defined(G3D_DEBUG) && defined(VERIFY_TREE)
501  for (int i = 0; i < lt.size(); ++i) {
502  const Vector3& v = lt[i].position();
503  debugAssert(v[splitAxis] < splitLocation);
504  }
505  for (int i = 0; i < gt.size(); ++i) {
506  debugAssert(gt[i].position()[splitAxis] > splitLocation);
507  }
508  for (int i = 0; i < node->valueArray.size(); ++i) {
509  debugAssert(node->valueArray[i].position()[splitAxis] == splitLocation);
510  }
511 # endif
512 
513  node->splitAxis = splitAxis;
514  node->splitLocation = splitLocation;
515 
516  // Throw away the source array to save memory
517  source.fastClear();
518 
519  if (lt.size() > 0) {
520  node->child[0] = makeNode(lt, temp, valuesPerNode, numMeanSplits - 1);
521  }
522 
523  if (gt.size() > 0) {
524  node->child[1] = makeNode(gt, temp, valuesPerNode, numMeanSplits - 1);
525  }
526 
527  // Add the values stored at this interior node to the member table
528  for(int i = 0; i < node->valueArray.size(); ++i) {
529  memberTable.set(node->valueArray[i].value, node);
530  }
531 
532  }
533 
534  return node;
535  }
536 
542  Node* cloneTree(Node* src) {
543  Node* dst = new Node(*src);
544 
545  // Make back pointers
546  for (int i = 0; i < dst->valueArray.size(); ++i) {
547  memberTable.set(dst->valueArray[i].value, dst);
548  }
549 
550  // Clone children
551  for (int i = 0; i < 2; ++i) {
552  if (src->child[i] != NULL) {
553  dst->child[i] = cloneTree(src->child[i]);
554  }
555  }
556 
557  return dst;
558  }
559 
562  MemberTable memberTable;
563 
565 
566 public:
567 
570  PointKDTree() : root(NULL) {}
571 
572 
573  PointKDTree(const PointKDTree& src) : root(NULL) {
574  *this = src;
575  }
576 
577 
579  delete root;
580  // Clone tree takes care of filling out the memberTable.
581  root = cloneTree(src.root);
582  return *this;
583  }
584 
585 
587  clear();
588  }
589 
593  void clear() {
594  memberTable.clear();
595  delete root;
596  root = NULL;
597  }
598 
600  void clearData() {
601  memberTable.clear();
602  Array<Node*> stack;
603  stack.push(root);
604  while (stack.size() > 0) {
605  Node* node = stack.pop();
606  node->valueArray.fastClear();
607 
608  for (int i = 0; i < 2; ++i) {
609  if (node->child[i] != NULL) {
610  stack.push(node->child[i]);
611  }
612  }
613  }
614  }
615 
616 
617  size_t size() const {
618  return memberTable.size();
619  }
620 
626  void insert(const T& value) {
627  if (contains(value)) {
628  // Already in the set
629  return;
630  }
631 
632  Handle h(value);
633 
634  if (root == NULL) {
635  // This is the first node; create a root node
636  root = new Node();
637  }
638 
639  Node* node = root->findDeepestContainingNode(h.position());
640 
641  // Insert into the node
642  node->valueArray.append(h);
643 
644  // Insert into the node table
645  memberTable.set(value, node);
646  }
647 
652  void insert(const Array<T>& valueArray) {
653  // Pre-size the member table to avoid multiple allocations
654  memberTable.setSizeHint(valueArray.size() + size());
655 
656  if (root == NULL) {
657  // Optimized case for an empty tree; don't bother
658  // searching or reallocating the root node's valueArray
659  // as we incrementally insert.
660  root = new Node();
661  root->valueArray.resize(valueArray.size());
662  for (int i = 0; i < valueArray.size(); ++i) {
663  // Insert in opposite order so that we have the exact same
664  // data structure as if we inserted each (i.e., order is reversed
665  // from array).
666  root->valueArray[valueArray.size() - i - 1] = Handle(valueArray[i]);
667  memberTable.set(valueArray[i], root);
668  }
669  } else {
670  // Insert at appropriate tree depth.
671  for (int i = 0; i < valueArray.size(); ++i) {
672  insert(valueArray[i]);
673  }
674  }
675  }
676 
677 
682  bool contains(const T& value) {
683  return memberTable.containsKey(value);
684  }
685 
686 
697  void remove(const T& value) {
699  "Tried to remove an element from a "
700  "PointKDTree that was not present");
701 
702  Array<Handle>& list = memberTable[value]->valueArray;
703 
704  // Find the element and remove it
705  for (int i = list.length() - 1; i >= 0; --i) {
706  if (list[i].value == value) {
707  list.fastRemove(i);
708  break;
709  }
710  }
711  memberTable.remove(value);
712  }
713 
714 
726  void update(const T& value) {
727  if (contains(value)) {
728  remove(value);
729  }
730  insert(value);
731  }
732 
733 
754  void balance(int valuesPerNode = 40, int numMeanSplits = 3) {
755  if (root == NULL) {
756  // Tree is empty
757  return;
758  }
759 
760  Array<Handle> handleArray;
761  root->getHandles(handleArray);
762 
763  // Delete the old tree
764  clear();
765 
766  Array<Handle> temp;
767  root = makeNode(handleArray, temp, valuesPerNode, numMeanSplits);
768  temp.fastClear();
769 
770  // Walk the tree, assigning splitBounds. We start with unbounded
771  // space.
773 
774 # ifdef _DEBUG
776 # endif
777  }
778 
779 private:
780 
787  const Array<Plane>& plane,
788  Array<T>& members,
789  Node* node,
790  uint32 parentMask) {
791 
792  int dummy;
793 
794  if (parentMask == 0) {
795  // None of these planes can cull anything
796  for (int v = node->valueArray.size() - 1; v >= 0; --v) {
797  members.append(node->valueArray[v].value);
798  }
799 
800  // Iterate through child nodes
801  for (int c = 0; c < 2; ++c) {
802  if (node->child[c]) {
803  getIntersectingMembers(plane, members, node->child[c], 0);
804  }
805  }
806  } else {
807 
808  if (node->valueArray.size() > 0) {
809  // This is a leaf; check the points
810  debugAssertM(node->child[0] == NULL, "Malformed Point tree");
811  debugAssertM(node->child[1] == NULL, "Malformed Point tree");
812 
813  // Test values at this node against remaining planes
814  for (int p = 0; p < plane.size(); ++p) {
815  if (((parentMask >> p) & 1) != 0) {
816  // Test against this plane
817  const Plane& curPlane = plane[p];
818  for (int v = node->valueArray.size() - 1; v >= 0; --v) {
819  if (curPlane.halfSpaceContains(node->valueArray[v].position())) {
820  members.append(node->valueArray[v].value);
821  }
822  }
823  }
824  }
825  } else {
826 
827  uint32 childMask = 0xFFFFFF;
828 
829  // Iterate through child nodes
830  for (int c = 0; c < 2; ++c) {
831  if (node->child[c] &&
832  ! node->child[c]->splitBounds.culledBy(plane, dummy, parentMask, childMask)) {
833  // This node was not culled
834  getIntersectingMembers(plane, members, node->child[c], childMask);
835  }
836  }
837  }
838  }
839  }
840 
841 public:
842 
847  void getIntersectingMembers(const Array<Plane>& plane, Array<T>& members) const {
848  if (root == NULL) {
849  return;
850  }
851 
852  getIntersectingMembers(plane, members, root, 0xFFFFFF);
853  }
854 
868  void getIntersectingMembers(const Frustum& frustum, Array<T>& members) const {
869  Array<Plane> plane;
870 
871  for (int i = 0; i < frustum.faceArray.size(); ++i) {
872  plane.append(frustum.faceArray[i].plane);
873  }
874 
875  getIntersectingMembers(plane, members);
876  }
877 
883  // This iterator turns Node::getIntersectingMembers into a
884  // coroutine. It first translates that method from recursive to
885  // stack based, then captures the system state (analogous to a Scheme
886  // continuation) after each element is appended to the member array,
887  // and allowing the computation to be restarted.
889  private:
890  friend class TreeType;
891 
893  bool isEnd;
894 
897 
901 
903  // We could use backpointers within the tree and careful
904  // state management to avoid ever storing the stack-- but
905  // it is much easier this way and only inefficient if the
906  // caller uses post increment (which they shouldn't!).
908 
912 
914 
915  BoxIntersectionIterator(const AABox& b, const Node* root) :
916  isEnd(root == NULL), box(b),
917  node(const_cast<Node*>(root)), nextValueArrayIndex(-1) {
918 
919  // We intentionally start at the "-1" index of the current
920  // node so we can use the preincrement operator to move
921  // ourselves to element 0 instead of repeating all of the
922  // code from the preincrement method. Note that this might
923  // cause us to become the "end" instance.
924  ++(*this);
925  }
926 
927  public:
928 
929  inline bool operator!=(const BoxIntersectionIterator& other) const {
930  return ! (*this == other);
931  }
932 
933  bool operator==(const BoxIntersectionIterator& other) const {
934  if (isEnd) {
935  return other.isEnd;
936  } else if (other.isEnd) {
937  return false;
938  } else {
939  // Two non-end iterators; see if they match. This is kind of
940  // silly; users shouldn't call == on iterators in general unless
941  // one of them is the end iterator.
942  if ((box != other.box) || (node != other.node) ||
943  (nextValueArrayIndex != other.nextValueArrayIndex) ||
944  (stack.length() != other.stack.length())) {
945  return false;
946  }
947 
948  // See if the stacks are the same
949  for (int i = 0; i < stack.length(); ++i) {
950  if (stack[i] != other.stack[i]) {
951  return false;
952  }
953  }
954 
955  // We failed to find a difference; they must be the same
956  return true;
957  }
958  }
959 
965 
966  bool foundIntersection = false;
967  while (! isEnd && ! foundIntersection) {
968 
969  // Search for the next node if we've exhausted this one
970  while ((! isEnd) && (nextValueArrayIndex >= node->valueArray.length())) {
971  // If we entered this loop, then the iterator has exhausted the elements at
972  // node (possibly because it just switched to a child node with no members).
973  // This loop continues until it finds a node with members or reaches
974  // the end of the whole intersection search.
975 
976  // If the right child overlaps the box, push it onto the stack for
977  // processing.
978  if ((node->child[1] != NULL) &&
979  (box.high()[node->splitAxis] > node->splitLocation)) {
980  stack.push(node->child[1]);
981  }
982 
983  // If the left child overlaps the box, push it onto the stack for
984  // processing.
985  if ((node->child[0] != NULL) &&
986  (box.low()[node->splitAxis] < node->splitLocation)) {
987  stack.push(node->child[0]);
988  }
989 
990  if (stack.length() > 0) {
991  // Go on to the next node (which may be either one of the ones we
992  // just pushed, or one from farther back the tree).
993  node = stack.pop();
994  nextValueArrayIndex = 0;
995  } else {
996  // That was the last node; we're done iterating
997  isEnd = true;
998  }
999  }
1000 
1001  // Search for the next intersection at this node until we run out of children
1002  while (! isEnd && ! foundIntersection && (nextValueArrayIndex < node->valueArray.length())) {
1003  if (box.intersects(node->valueArray[nextValueArrayIndex].bounds)) {
1004  foundIntersection = true;
1005  } else {
1007  // If we exhaust this node, we'll loop around the master loop
1008  // to find a new node.
1009  }
1010  }
1011  }
1012 
1013  return *this;
1014  }
1015 
1020  BoxIntersectionIterator old = *this;
1021  ++this;
1022  return old;
1023  }
1024 
1027  const T& operator*() const {
1028  alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator");
1029  return node->valueArray[nextValueArrayIndex].value;
1030  }
1031 
1034  T const * operator->() const {
1035  alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator");
1036  return &(stack.last()->valueArray[nextValueArrayIndex].value);
1037  }
1038 
1041  operator T*() const {
1042  alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator");
1043  return &(stack.last()->valueArray[nextValueArrayIndex].value);
1044  }
1045  };
1046 
1047 
1052  return BoxIntersectionIterator(box, root);
1053  }
1054 
1056  // The "end" iterator instance
1057  return BoxIntersectionIterator();
1058  }
1059 
1064  void getIntersectingMembers(const AABox& box, Array<T>& members) const {
1065  if (root == NULL) {
1066  return;
1067  }
1068  root->getIntersectingMembers(box, Sphere(Vector3::zero(), 0), members, false);
1069  }
1070 
1071 
1075  void getIntersectingMembers(const Sphere& sphere, Array<T>& members) const {
1076  if (root == NULL) {
1077  return;
1078  }
1079 
1080  AABox box;
1081  sphere.getBounds(box);
1082  root->getIntersectingMembers(box, sphere, members);
1083 
1084  }
1085 
1086 
1093  Node::serializeStructure(root, bo);
1094  }
1095 
1098  clear();
1099  root = Node::deserializeStructure(bi);
1100  }
1101 
1105  void getMembers(Array<T>& members) const {
1106  memberTable.getKeys(members);
1107  }
1108 
1109 
1115  class Iterator {
1116  private:
1117  friend class TreeType;
1118 
1119  // Note: this is a Table iterator, we are currently defining
1120  // Set iterator
1121  typename MemberTable::Iterator it;
1122 
1123  Iterator(const typename MemberTable::Iterator& it) : it(it) {}
1124 
1125  public:
1126  inline bool operator!=(const Iterator& other) const {
1127  return !(*this == other);
1128  }
1129 
1130  bool operator==(const Iterator& other) const {
1131  return it == other.it;
1132  }
1133 
1138  ++it;
1139  return *this;
1140  }
1141 
1146  Iterator old = *this;
1147  ++(*this);
1148  return old;
1149  }
1150 
1151  const T& operator*() const {
1152  return it->key;
1153  }
1154 
1155  T* operator->() const {
1156  return &(it->key);
1157  }
1158 
1159  operator T*() const {
1160  return &(it->key);
1161  }
1162  };
1163 
1164 
1171  Iterator begin() const {
1172  return Iterator(memberTable.begin());
1173  }
1174 
1175 
1180  Iterator end() const {
1181  return Iterator(memberTable.end());
1182  }
1183 #undef TreeType
1184 };
1185 
1186 }
1187 
1188 #endif
static void serializeStructure(const Node *n, BinaryOutput &bo)
Definition: PointKDTree.h:276
Node * root
Definition: PointKDTree.h:564
friend class TreeType
Definition: PointKDTree.h:1117
bool intersects(const AABox &other) const
Definition: AABox.cpp:175
void deserialize(class BinaryInput &b)
Definition: AABox.cpp:99
void getIntersectingMembers(const Frustum &frustum, Array< T > &members) const
Definition: PointKDTree.h:868
Vector3 m_position
Definition: PointKDTree.h:112
Node * findDeepestContainingNode(const Vector3 &point)
Definition: PointKDTree.h:307
int nextValueArrayIndex
Definition: PointKDTree.h:911
BoxIntersectionIterator beginBoxIntersection(const AABox &box) const
Definition: PointKDTree.h:1051
void push(const T &value)
Definition: Array.h:770
Node(const Array< Handle > &pt)
Definition: PointKDTree.h:199
void getMembers(Array< T > &members) const
Definition: PointKDTree.h:1105
const T & operator*() const
Definition: PointKDTree.h:1151
T pop(bool shrinkUnderlyingArrayIfNecessary=true)
Definition: Array.h:837
Definition: Frustum.h:24
void merge(const AABox &a)
Definition: AABox.h:106
Handle()
Definition: PointKDTree.h:117
void fastClear()
Definition: Array.h:419
Definition: Plane.h:25
void setSizeHint(size_t n)
Definition: Table.h:318
Definition: PointKDTree.h:110
Definition: Vector3.h:122
BoxIntersectionIterator & operator++()
Definition: PointKDTree.h:963
float splitLocation
Definition: PointKDTree.h:159
static const Vector3 & minFinite()
Definition: Vector3.cpp:126
Definition: BinaryInput.h:69
PointKDTree()
Definition: PointKDTree.h:570
bool contains(const AABox &other) const
Definition: AABox.h:238
T const * operator->() const
Definition: PointKDTree.h:1034
void clear()
Definition: PointKDTree.h:593
float radius
Definition: Sphere.h:31
Handle(const T &v)
Definition: PointKDTree.h:118
void clear()
Definition: Table.h:578
size_t size() const
Definition: Table.h:589
void serializeStructure(BinaryOutput &bo) const
Definition: PointKDTree.h:1092
Definition: HashTrait.h:105
static Node * deserializeStructure(BinaryInput &bi)
Definition: PointKDTree.h:291
Definition: PositionTrait.h:5
T * getCArray()
Definition: Array.h:256
Definition: AABox.h:25
Dynamic 1D array tuned for performance.
Definition: Array.h:95
Axis primaryAxis() const
Definition: Vector3.cpp:129
Iterator begin() const
Definition: Table.h:562
const T & last() const
Definition: Array.h:923
void writeUInt8(uint8 i)
Definition: BinaryOutput.h:283
arena_t NULL
Definition: jemalloc_internal.h:624
BoxIntersectionIterator(const AABox &b, const Node *root)
Definition: PointKDTree.h:915
Definition: PointKDTree.h:102
void deserialize(std::string &s, BinaryInput &b)
Definition: serialize.h:16
static const AABox & maxFinite()
Definition: AABox.cpp:67
void setPosition(const Vector3 &v)
Definition: PointKDTree.h:123
int length() const
Definition: Array.h:438
void set(const Key &key, const Value &value)
Definition: Table.h:599
const Point3 & low() const
Definition: AABox.h:136
bool contains(const T &value)
Definition: PointKDTree.h:682
void getBounds(class AABox &out) const
Definition: Sphere.cpp:252
Axis
Definition: Vector3.h:122
float32 readFloat32()
Definition: BinaryInput.h:352
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
bool isLeaf() const
Definition: PointKDTree.h:218
BoxIntersectionIterator operator++(int)
Definition: PointKDTree.h:1019
void balance(int valuesPerNode=40, int numMeanSplits=3)
Definition: PointKDTree.h:754
Definition: Vector3.h:58
#define true
Definition: CascPort.h:17
void medianPartition(Array< T > &ltMedian, Array< T > &eqMedian, Array< T > &gtMedian, Array< T > &tempArray, const Comparator &comparator) const
Definition: Array.h:1247
MemberTable memberTable
Definition: PointKDTree.h:562
Iterator operator++(int)
Definition: PointKDTree.h:1145
void getIntersectingMembers(const Array< Plane > &plane, Array< T > &members) const
Definition: PointKDTree.h:847
bool operator==(const Iterator &other) const
Definition: PointKDTree.h:1130
BoxIntersectionIterator endBoxIntersection() const
Definition: PointKDTree.h:1055
static const Vector3 & zero()
Definition: Vector3.cpp:119
void getHandles(Array< Handle > &handleArray) const
Definition: PointKDTree.h:227
uint8 readUInt8()
Definition: BinaryInput.h:278
Definition: Sphere.h:24
Definition: PointKDTree.h:1115
void fastRemove(int index, bool shrinkIfNecessary=false)
Definition: Array.h:446
void clearData()
Definition: PointKDTree.h:600
Node * node
Definition: PointKDTree.h:900
bool culledBy(const Array< Plane > &plane, int32 &cullingPlaneIndex, const uint32 testMask, uint32 &childMask) const
T value
Definition: PointKDTree.h:115
void serialize(const std::string &s, BinaryOutput &b)
Definition: serialize.h:12
void getIntersectingMembers(const AABox &sphereBounds, const Sphere &sphere, Array< T > &members) const
Definition: PointKDTree.h:331
Node * cloneTree(Node *src)
Definition: PointKDTree.h:542
const T & operator*() const
Definition: PointKDTree.h:1027
#define debugAssert(exp)
Definition: debugAssert.h:160
Iterator & operator++()
Definition: PointKDTree.h:1137
SmallArray< Face, 6 > faceArray
Definition: Frustum.h:49
const Vector3 & position() const
Definition: PointKDTree.h:127
PointKDTree & operator=(const PointKDTree &src)
Definition: PointKDTree.h:578
void insert(const T &value)
Definition: PointKDTree.h:626
bool remove(const Key &key, Key &removedKey, Value &removedValue, bool updateRemoved)
Definition: Table.h:606
void getIntersectingMembers(const AABox &box, Array< T > &members) const
Definition: PointKDTree.h:1064
void getIntersectingMembers(const Sphere &sphere, Array< T > &members) const
Definition: PointKDTree.h:1075
static void getIntersectingMembers(const Array< Plane > &plane, Array< T > &members, Node *node, uint32 parentMask)
Definition: PointKDTree.h:786
Definition: PointKDTree.h:888
double square(double fValue)
Definition: g3dmath.h:698
void serialize(class BinaryOutput &b) const
Definition: AABox.cpp:93
int size() const
Definition: Array.h:430
T * operator->() const
Definition: PointKDTree.h:1155
Definition: AABox.h:32
bool operator==(const BoxIntersectionIterator &other) const
Definition: PointKDTree.h:933
size_t size() const
Definition: PointKDTree.h:617
Node * child[2]
Definition: PointKDTree.h:170
bool contains(const Point3 &point) const
Definition: Sphere.cpp:79
int operator()(const Handle &A, const Handle &B) const
Definition: PointKDTree.h:426
const Iterator end() const
Definition: Table.h:570
static const Vector3 & maxFinite()
Definition: Vector3.cpp:127
Node()
Definition: PointKDTree.h:176
void insert(const Array< T > &valueArray)
Definition: PointKDTree.h:652
Array< Node * > stack
Definition: PointKDTree.h:907
Array< Key > getKeys() const
Definition: Table.h:907
Point3 center
Definition: Sphere.h:30
bool operator!=(const Iterator &other) const
Definition: PointKDTree.h:1126
Node * makeNode(Array< Handle > &source, Array< Handle > &temp, int valuesPerNode, int numMeanSplits)
Definition: PointKDTree.h:444
Definition: BinaryOutput.h:52
Node(const Node &other)
Definition: PointKDTree.h:188
Iterator(const typename MemberTable::Iterator &it)
Definition: PointKDTree.h:1123
~PointKDTree()
Definition: PointKDTree.h:586
BoxIntersectionIterator()
Definition: PointKDTree.h:913
Definition: PointKDTree.h:418
Vector3::Axis splitAxis
Definition: PointKDTree.h:156
friend class TreeType
Definition: PointKDTree.h:890
~Node()
Definition: PointKDTree.h:210
static AABox computeBounds(const Array< Handle > &point)
Definition: PointKDTree.h:133
void writeFloat32(float32 f)
Definition: BinaryOutput.h:312
void partition(const T &partitionElement, Array< T > &ltArray, Array< T > &eqArray, Array< T > &gtArray, const Comparator &comparator) const
Definition: Array.h:1194
void split(const Vector3::Axis &axis, float location, AABox &low, AABox &high) const
Definition: AABox.cpp:112
const FieldDescriptor value
Definition: descriptor.h:1522
PointKDTree(const PointKDTree &src)
Definition: PointKDTree.h:573
uint32_t uint32
Definition: g3dmath.h:168
AABox box
Definition: PointKDTree.h:896
Vector3::Axis sortAxis
Definition: PointKDTree.h:420
bool operator!=(const BoxIntersectionIterator &other) const
Definition: PointKDTree.h:929
void verifyNode(const Vector3 &lo, const Vector3 &hi)
Definition: PointKDTree.h:237
const Point3 & high() const
Definition: AABox.h:141
Definition: EqualsTrait.h:19
static const Vector3 & inf()
Definition: Vector3.cpp:124
void append(const T &value)
Definition: Array.h:583
Table< T, Node *, HashFunc, EqualsFunc > MemberTable
Definition: PointKDTree.h:561
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
Iterator end() const
Definition: PointKDTree.h:1180
bool isEnd
Definition: PointKDTree.h:893
void assignSplitBounds(const AABox &myBounds)
Definition: PointKDTree.h:397
bool halfSpaceContains(Point3 point) const
Definition: Plane.h:87
void deserializeStructure(BinaryInput &bi)
Definition: PointKDTree.h:1097
bool containsKey(const Key &key) const
Definition: Table.h:874
AxisComparator(Vector3::Axis s)
Definition: PointKDTree.h:424
Array< Handle > valueArray
Definition: PointKDTree.h:173
AABox splitBounds
Definition: PointKDTree.h:154
Definition: PointKDTree.h:149
MemberTable::Iterator it
Definition: PointKDTree.h:1121
void getIntersectingMembers(const AABox &box, const Sphere &sphere, Array< T > &members, bool useSphere) const
Definition: PointKDTree.h:369
Iterator begin() const
Definition: PointKDTree.h:1171
void update(const T &value)
Definition: PointKDTree.h:726