TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
KDTree.h
Go to the documentation of this file.
1 
13 #ifndef G3D_KDTree_h
14 #define G3D_KDTree_h
15 
16 #include "G3D/platform.h"
17 #include "G3D/Array.h"
18 #include "G3D/Table.h"
19 #include "G3D/Vector2.h"
20 #include "G3D/Vector3.h"
21 #include "G3D/Vector4.h"
22 #include "G3D/AABox.h"
23 #include "G3D/Sphere.h"
24 #include "G3D/Box.h"
25 #include "G3D/Triangle.h"
26 #include "G3D/Ray.h"
27 #include "G3D/Frustum.h"
28 #include "G3D/BinaryInput.h"
29 #include "G3D/BinaryOutput.h"
30 #include "G3D/CollisionDetection.h"
31 #include "G3D/BoundsTrait.h"
32 #include <algorithm>
33 
34 // If defined, in debug mode the tree is checked for consistency
35 // as a way of detecting corruption due to implementation bugs
36 // #define VERIFY_TREE
37 
38 template<> struct BoundsTrait<class G3D::Vector2> {
39  static void getBounds(const G3D::Vector2& v, G3D::AABox& out) { out = G3D::AABox(G3D::Vector3(v, 0)); }
40 };
41 
42 template<> struct BoundsTrait<class G3D::Vector3> {
43  static void getBounds(const G3D::Vector3& v, G3D::AABox& out) { out = G3D::AABox(v); }
44 };
45 
46 template<> struct BoundsTrait<class G3D::Vector4> {
47  static void getBounds(const G3D::Vector4& v, G3D::AABox& out) { out = G3D::AABox(v.xyz()); }
48 };
49 
50 template<> struct BoundsTrait<class G3D::AABox> {
51  static void getBounds(const G3D::AABox& v, G3D::AABox& out) { out = v; }
52 };
53 
54 template<> struct BoundsTrait<class G3D::Sphere> {
55  static void getBounds(const G3D::Sphere& s, G3D::AABox& out) { s.getBounds(out); }
56 };
57 
58 template<> struct BoundsTrait<class G3D::Box> {
59  static void getBounds(const G3D::Box& b, G3D::AABox& out) { b.getBounds(out); }
60 };
61 
62 template<> struct BoundsTrait<class G3D::Vector2*> {
63  static void getBounds(const G3D::Vector2*& v, G3D::AABox& out) { out = G3D::AABox(G3D::Vector3(*v, 0)); }
64 };
65 
66 template<> struct BoundsTrait<class G3D::Vector3*> {
67  static void getBounds(const G3D::Vector3*& v, G3D::AABox& out) { out = G3D::AABox(*v); }
68 };
69 
70 template<> struct BoundsTrait<class G3D::Vector4*> {
71  static void getBounds(const G3D::Vector4*& v, G3D::AABox& out) { out = G3D::AABox(v->xyz()); }
72 };
73 
74 template<> struct BoundsTrait<class G3D::AABox*> {
75  static void getBounds(const G3D::AABox*& v, G3D::AABox& out) { out = *v; }
76 };
77 
78 template<> struct BoundsTrait<class G3D::Sphere*> {
79  static void getBounds(const G3D::Sphere*& s, G3D::AABox& out) { s->getBounds(out); }
80 };
81 
82 template<> struct BoundsTrait<class G3D::Box*> {
83  static void getBounds(const G3D::Box*& b, G3D::AABox& out) { b->getBounds(out); }
84 };
85 
86 
87 template<> struct BoundsTrait<class G3D::Triangle*> {
88  static void getBounds(const G3D::Triangle*& t, G3D::AABox& out) { t->getBounds(out); }
89 };
90 
91 namespace G3D {
92  namespace _internal {
93 
99  template<class Type>
100  class Indirector {
101  public:
103 
104  inline Indirector(Type* h) : handle(h) {}
105 
106  inline Indirector() : handle(NULL) {}
107 
109  inline bool operator==(const Indirector& m) const {
110  return *handle == *(m.handle);
111  }
112 
113  inline bool operator==(const Type& m) const {
114  return *handle == m;
115  }
116 
117  inline size_t hashCode() const {
118  return handle->hashCode();
119  }
120  };
121  } // namespace internal
122 } // namespace G3D
123 
124 template <class Handle> struct HashTrait<typename G3D::_internal::Indirector<Handle> > {
125  static size_t hashCode(const G3D::_internal::Indirector<Handle>& key) { return key.hashCode(); }
126 };
127 
128 namespace G3D {
129 
189 template< class T,
190  class BoundsFunc = BoundsTrait<T>,
191  class HashFunc = HashTrait<T>,
192  class EqualsFunc = EqualsTrait<T> >
193 class KDTree {
194 protected:
195 #define TreeType KDTree<T, BoundsFunc, HashFunc, EqualsFunc>
196 
203  class Handle {
204  public:
207 
213 
214  T value;
215 
216  Handle() {}
217 
218  inline Handle(const T& v) : value(v) {
219  BoundsFunc::getBounds(v, bounds);
220  bounds = bounds.intersect(AABox::large());
221  center = bounds.center();
222  }
223 
224  inline bool operator==(const Handle& other) const {
225  return EqualsFunc::equals(value, other.value);
226  }
227 
228  inline size_t hashCode() const {
229  return HashFunc::hashCode(value);
230  }
231  };
232 
235  const Array<Handle*>& point,
236  int beginIndex,
237  int endIndex) {
238 
239  Vector3 lo = Vector3::inf();
240  Vector3 hi = -lo;
241 
242  debugAssertM(beginIndex <= endIndex, "No points");
243  for (int p = beginIndex; p <= endIndex; ++p) {
244  // This code is written with the vector min and max expanded
245  // because otherwise it compiles incorrectly with -O3 on
246  // gcc 3.4
247 
248  const Vector3& pLo = point[p]->bounds.low();
249  const Vector3& pHi = point[p]->bounds.high();
250  for (int a = 0; a < 3; ++a) {
251  lo[a] = G3D::min(lo[a], pLo[a]);
252  hi[a] = G3D::max(hi[a], pHi[a]);
253  }
254  }
255 
256  return AABox(lo, hi);
257  }
258 
261  public:
263 
264  CenterComparator(Vector3::Axis a) : sortAxis(a) {}
265 
266  inline int operator()(Handle* A, const Handle* B) const {
267  float a = A->center[sortAxis];
268  float b = B->center[sortAxis];
269 
270  if (a < b) {
271  return 1;
272  } else if (a > b) {
273  return -1;
274  } else {
275  return 0;
276  }
277  }
278  };
279 
280 
283  public:
285 
286  BoundsComparator(Vector3::Axis a) : sortAxis(a) {}
287 
288  inline int operator()(Handle* A, const Handle* B) const {
289  const AABox& a = A->bounds;
290  const AABox& b = B->bounds;
291 
292  if (a.high()[sortAxis] < b.low()[sortAxis]) {
293  return 1;
294  } else if (a.low()[sortAxis] > b.high()[sortAxis]) {
295  return -1;
296  } else {
297  return 0;
298  }
299  }
300  };
301 
302 
304  class Comparator {
305  public:
308 
309  Comparator(Vector3::Axis a, float l) : sortAxis(a), sortLocation(l) {}
310 
311  inline int operator()(Handle* ignore, const Handle* handle) const {
312  (void)ignore;
313  const AABox& box = handle->bounds;
314  debugAssert(ignore == NULL);
315 
316  if (box.high()[sortAxis] < sortLocation) {
317  // Box is strictly below the sort location
318  return -1;
319  } else if (box.low()[sortAxis] > sortLocation) {
320  // Box is strictly above the sort location
321  return 1;
322  } else {
323  // Box overlaps the sort location
324  return 0;
325  }
326  }
327  };
328 
329  // Using System::malloc with this class provided no speed improvement.
330  class Node {
331  public:
332 
336 
338 
341 
351  Node* child[2];
352 
362 
370 
372  Node() {
373  splitAxis = Vector3::X_AXIS;
374  splitLocation = 0;
375  splitBounds = AABox(-Vector3::inf(), Vector3::inf());
376  for (int i = 0; i < 2; ++i) {
377  child[i] = NULL;
378  }
379  }
380 
384  Node(const Node& other) : valueArray(other.valueArray), boundsArray(other.boundsArray) {
385  splitAxis = other.splitAxis;
386  splitLocation = other.splitLocation;
387  splitBounds = other.splitBounds;
388  for (int i = 0; i < 2; ++i) {
389  child[i] = NULL;
390  }
391  }
392 
395  Node(const Array<Handle*>& pt) : valueArray(pt) {
396  splitAxis = Vector3::X_AXIS;
397  splitLocation = 0;
398  for (int i = 0; i < 2; ++i) {
399  child[i] = NULL;
400  }
401 
402  boundsArray.resize(valueArray.size());
403  for (int i = 0; i < valueArray.size(); ++i) {
404  boundsArray[i] = valueArray[i]->bounds;
405  }
406  }
407 
409  ~Node() {
410  for (int i = 0; i < 2; ++i) {
411  delete child[i];
412  }
413  }
414 
416  inline bool isLeaf() const {
417  return (child[0] == NULL) && (child[1] == NULL);
418  }
419 
420 
425  void getHandles(Array<Handle*>& handleArray) const {
426  handleArray.append(valueArray);
427  for (int i = 0; i < 2; ++i) {
428  if (child[i] != NULL) {
429  child[i]->getHandles(handleArray);
430  }
431  }
432  }
433 
434  void verifyNode(const Vector3& lo, const Vector3& hi) {
435  // debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
436  // splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
437 
438  debugAssertM(lo == splitBounds.low(),
439  format("lo = %s, splitBounds.lo = %s",
440  lo.toString().c_str(), splitBounds.low().toString().c_str()));
441  debugAssert(hi == splitBounds.high());
442 
443  for (int i = 0; i < valueArray.length(); ++i) {
444  const AABox& b = valueArray[i]->bounds;
445  debugAssert(b == boundsArray[i]);
446  (void)b;
447 
448  for(int axis = 0; axis < 3; ++axis) {
449  debugAssert(b.low()[axis] <= b.high()[axis]);
450  debugAssert(b.low()[axis] >= lo[axis]);
451  debugAssert(b.high()[axis] <= hi[axis]);
452  }
453  }
454 
455  if (child[0] || child[1]) {
456  debugAssert(lo[splitAxis] < splitLocation);
457  debugAssert(hi[splitAxis] > splitLocation);
458  }
459 
460  Vector3 newLo = lo;
461  newLo[splitAxis] = splitLocation;
462  Vector3 newHi = hi;
463  newHi[splitAxis] = splitLocation;
464 
465  if (child[0] != NULL) {
466  child[0]->verifyNode(lo, newHi);
467  }
468 
469  if (child[1] != NULL) {
470  child[1]->verifyNode(newLo, hi);
471  }
472  }
473 
474 
480  static void serializeStructure(const Node* n, BinaryOutput& bo) {
481  if (n == NULL) {
482  bo.writeUInt8(0);
483  } else {
484  bo.writeUInt8(1);
485  n->splitBounds.serialize(bo);
486  serialize(n->splitAxis, bo);
488  for (int c = 0; c < 2; ++c) {
489  serializeStructure(n->child[c], bo);
490  }
491  }
492  }
493 
496  if (bi.readUInt8() == 0) {
497  return NULL;
498  } else {
499  Node* n = new Node();
500  n->splitBounds.deserialize(bi);
501  deserialize(n->splitAxis, bi);
502  n->splitLocation = bi.readFloat32();
503  for (int c = 0; c < 2; ++c) {
504  n->child[c] = deserializeStructure(bi);
505  }
506  return n;
507  }
508  }
509 
512 
513  // See which side of the splitting plane the bounds are on
514  if (bounds.high()[splitAxis] < splitLocation) {
515  // Bounds are on the low side. Recurse into the child
516  // if it exists.
517  if (child[0] != NULL) {
518  return child[0]->findDeepestContainingNode(bounds);
519  }
520  } else if (bounds.low()[splitAxis] > splitLocation) {
521  // Bounds are on the high side, recurse into the child
522  // if it exists.
523  if (child[1] != NULL) {
524  return child[1]->findDeepestContainingNode(bounds);
525  }
526  }
527 
528  // There was no containing child, so this node is the
529  // deepest containing node.
530  return this;
531  }
532 
533 
538  const AABox& box,
539  const Sphere& sphere,
540  Array<T*>& members,
541  bool useSphere) const {
542 
543  // Test all values at this node
544  for (int v = 0; v < boundsArray.size(); ++v) {
545  const AABox& bounds = boundsArray[v];
546  if (bounds.intersects(box) &&
547  (! useSphere || bounds.intersects(sphere))) {
548  members.append(& (valueArray[v]->value));
549  }
550  }
551 
552  // If the left child overlaps the box, recurse into it
553  if ((child[0] != NULL) && (box.low()[splitAxis] < splitLocation)) {
554  child[0]->getIntersectingMembers(box, sphere, members, useSphere);
555  }
556 
557  // If the right child overlaps the box, recurse into it
558  if ((child[1] != NULL) && (box.high()[splitAxis] > splitLocation)) {
559  child[1]->getIntersectingMembers(box, sphere, members, useSphere);
560  }
561  }
562 
566  void assignSplitBounds(const AABox& myBounds) {
567  splitBounds = myBounds;
568 
569  AABox childBounds[2];
570  myBounds.split(splitAxis, splitLocation, childBounds[0], childBounds[1]);
571 
572 # if defined(G3D_DEBUG) && defined(VERIFY_TREE)
573  // Verify the split
574  for (int v = 0; v < boundsArray.size(); ++v) {
575  const AABox& bounds = boundsArray[v];
576  debugAssert(myBounds.contains(bounds));
577  }
578 # endif
579 
580  for (int c = 0; c < 2; ++c) {
581  if (child[c]) {
582  child[c]->assignSplitBounds(childBounds[c]);
583  }
584  }
585  }
586 
588  bool intersects(const Ray& ray, float distance) const {
589  // See if the ray will ever hit this node or its children
590  Vector3 location;
591  bool alreadyInsideBounds = false;
592  bool rayWillHitBounds =
594  ray.origin(), ray.direction(), splitBounds, location, alreadyInsideBounds);
595 
596  bool canHitThisNode = (alreadyInsideBounds ||
597  (rayWillHitBounds && ((location - ray.origin()).squaredLength() < square(distance))));
598 
599  return canHitThisNode;
600  }
601 
602  template<typename RayCallback>
604  const Ray& ray,
605  RayCallback& intersectCallback,
606  float& distance,
607  bool intersectCallbackIsFast) const {
608 
609  if (! intersects(ray, distance)) {
610  // The ray doesn't hit this node, so it can't hit the children of the node.
611  return;
612  }
613 
614  // Test for intersection against every object at this node.
615  for (int v = 0; v < valueArray.size(); ++v) {
616  bool canHitThisObject = true;
617 
618  if (! intersectCallbackIsFast) {
619  // See if
620  Vector3 location;
621  const AABox& bounds = boundsArray[v];
622  bool alreadyInsideBounds = false;
623  bool rayWillHitBounds =
625  ray.origin(), ray.direction(), bounds, location, alreadyInsideBounds);
626 
627  canHitThisObject = (alreadyInsideBounds ||
628  (rayWillHitBounds && ((location - ray.origin()).squaredLength() < square(distance))));
629  }
630 
631  if (canHitThisObject) {
632  // It is possible that this ray hits this object. Look for the intersection using the
633  // callback.
634  const T& value = valueArray[v]->value;
635  intersectCallback(ray, value, distance);
636  }
637  }
638 
639  // There are three cases to consider next:
640  //
641  // 1. the ray can start on one side of the splitting plane and never enter the other,
642  // 2. the ray can start on one side and enter the other, and
643  // 3. the ray can travel exactly down the splitting plane
644 
645  enum {NONE = -1};
646  int firstChild = NONE;
647  int secondChild = NONE;
648 
649  if (ray.origin()[splitAxis] < splitLocation) {
650 
651  // The ray starts on the small side
652  firstChild = 0;
653 
654  if (ray.direction()[splitAxis] > 0) {
655  // The ray will eventually reach the other side
656  secondChild = 1;
657  }
658 
659  } else if (ray.origin()[splitAxis] > splitLocation) {
660 
661  // The ray starts on the large side
662  firstChild = 1;
663 
664  if (ray.direction()[splitAxis] < 0) {
665  secondChild = 0;
666  }
667  } else {
668  // The ray starts on the splitting plane
669  if (ray.direction()[splitAxis] < 0) {
670  // ...and goes to the small side
671  firstChild = 0;
672  } else if (ray.direction()[splitAxis] > 0) {
673  // ...and goes to the large side
674  firstChild = 1;
675  }
676  }
677 
678  // Test on the side closer to the ray origin.
679  if ((firstChild != NONE) && child[firstChild]) {
680  child[firstChild]->intersectRay(ray, intersectCallback, distance, intersectCallbackIsFast);
681  }
682 
683  if (ray.direction()[splitAxis] != 0) {
684  // See if there was an intersection before hitting the splitting plane.
685  // If so, there is no need to look on the far side and recursion terminates.
686  float distanceToSplittingPlane = (splitLocation - ray.origin()[splitAxis]) / ray.direction()[splitAxis];
687  if (distanceToSplittingPlane > distance) {
688  // We aren't going to hit anything else before hitting the splitting plane,
689  // so don't bother looking on the far side of the splitting plane at the other
690  // child.
691  return;
692  }
693  }
694 
695  // Test on the side farther from the ray origin.
696  if ((secondChild != NONE) && child[secondChild]) {
697  child[secondChild]->intersectRay(ray, intersectCallback, distance, intersectCallbackIsFast);
698  }
699 
700  }
701  };
702 
703 
712  Array<Handle*>& source,
713  int valuesPerNode,
714  int numMeanSplits,
715  Array<Handle*>& temp) {
716 
717  Node* node = NULL;
718 
719  if (source.size() <= valuesPerNode) {
720  // Make a new leaf node
721  node = new Node(source);
722 
723  // Set the pointers in the memberTable
724  for (int i = 0; i < source.size(); ++i) {
725  memberTable.set(Member(source[i]), node);
726  }
727  source.clear();
728 
729  } else {
730  // Make a new internal node
731  node = new Node();
732 
733  const AABox& bounds = computeBounds(source, 0, source.size() - 1);
734  const Vector3& extent = bounds.high() - bounds.low();
735 
736  Vector3::Axis splitAxis = extent.primaryAxis();
737 
738  float splitLocation;
739 
740  // Arrays for holding the children
741  Array<Handle*> lt, gt;
742 
743  if (numMeanSplits <= 0) {
744 
745  source.medianPartition(lt, node->valueArray, gt, temp, CenterComparator(splitAxis));
746 
747  // Choose the split location to be the center of whatever fell in the center
748  splitLocation = node->valueArray[0]->center[splitAxis];
749 
750  // Some of the elements in the lt or gt array might really overlap the split location.
751  // Move them as needed.
752  for (int i = 0; i < lt.size(); ++i) {
753  const AABox& bounds = lt[i]->bounds;
754  if ((bounds.low()[splitAxis] <= splitLocation) && (bounds.high()[splitAxis] >= splitLocation)) {
755  node->valueArray.append(lt[i]);
756  // Remove this element and process the new one that
757  // is swapped in in its place.
758  lt.fastRemove(i); --i;
759  }
760  }
761 
762  for (int i = 0; i < gt.size(); ++i) {
763  const AABox& bounds = gt[i]->bounds;
764  if ((bounds.low()[splitAxis] <= splitLocation) && (bounds.high()[splitAxis] >= splitLocation)) {
765  node->valueArray.append(gt[i]);
766  // Remove this element and process the new one that
767  // is swapped in in its place.
768  gt.fastRemove(i); --i;
769  }
770  }
771 
772  if ((node->valueArray.size() > (source.size() / 2)) &&
773  (source.size() > 6)) {
774  // This was a bad partition; we ended up putting the splitting plane right in the middle of most of the
775  // objects. We could try to split on a different axis, or use a different partition (e.g., the extents mean,
776  // or geometric mean). This implementation falls back on the extents mean, since that case is already handled
777  // below.
778  numMeanSplits = 1;
779  }
780  }
781 
782  // Note: numMeanSplits may have been increased by the code in the previous case above in order to
783  // force a re-partition.
784 
785  if (numMeanSplits > 0) {
786  // Split along the mean
787  splitLocation =
788  bounds.high()[splitAxis] * 0.5f +
789  bounds.low()[splitAxis] * 0.5f;
790 
791  debugAssertM(isFinite(splitLocation),
792  "Internal error: split location must be finite.");
793 
794  source.partition(NULL, lt, node->valueArray, gt, Comparator(splitAxis, splitLocation));
795 
796  // The Comparator ensures that elements are strictly on the correct side of the split
797  }
798 
799 
800 # if defined(G3D_DEBUG) && defined(VERIFY_TREE)
801  debugAssert(lt.size() + node->valueArray.size() + gt.size() == source.size());
802  // Verify that all objects ended up on the correct side of the split.
803  // (i.e., make sure that the Array partition was correct)
804  for (int i = 0; i < lt.size(); ++i) {
805  const AABox& bounds = lt[i]->bounds;
806  debugAssert(bounds.high()[splitAxis] < splitLocation);
807  }
808 
809  for (int i = 0; i < gt.size(); ++i) {
810  const AABox& bounds = gt[i]->bounds;
811  debugAssert(bounds.low()[splitAxis] > splitLocation);
812  }
813 
814  for (int i = 0; i < node->valueArray.size(); ++i) {
815  const AABox& bounds = node->valueArray[i]->bounds;
816  debugAssert(bounds.high()[splitAxis] >= splitLocation);
817  debugAssert(bounds.low()[splitAxis] <= splitLocation);
818  }
819 # endif
820 
821  // The source array is no longer needed
822  source.clear();
823 
824  node->splitAxis = splitAxis;
825  node->splitLocation = splitLocation;
826 
827  // Update the bounds array and member table
828  node->boundsArray.resize(node->valueArray.size());
829  for (int i = 0; i < node->valueArray.size(); ++i) {
830  Handle* v = node->valueArray[i];
831  node->boundsArray[i] = v->bounds;
832  memberTable.set(Member(v), node);
833  }
834 
835  if (lt.size() > 0) {
836  node->child[0] = makeNode(lt, valuesPerNode, numMeanSplits - 1, temp);
837  }
838 
839  if (gt.size() > 0) {
840  node->child[1] = makeNode(gt, valuesPerNode, numMeanSplits - 1, temp);
841  }
842 
843  }
844 
845  return node;
846  }
847 
853  Node* cloneTree(Node* src) {
854  Node* dst = new Node(*src);
855 
856  // Make back pointers
857  for (int i = 0; i < dst->valueArray.size(); ++i) {
858  memberTable.set(Member(dst->valueArray[i]), dst);
859  }
860 
861  // Clone children
862  for (int i = 0; i < 2; ++i) {
863  if (src->child[i] != NULL) {
864  dst->child[i] = cloneTree(src->child[i]);
865  }
866  }
867 
868  return dst;
869  }
870 
876 
878 
880  MemberTable memberTable;
881 
883 
884 public:
885 
888  KDTree() : root(NULL) {}
889 
890 
891  KDTree(const KDTree& src) : root(NULL) {
892  *this = src;
893  }
894 
895 
896  KDTree& operator=(const KDTree& src) {
897  delete root;
898  // Clone tree takes care of filling out the memberTable.
899  root = cloneTree(src.root);
900  return *this;
901  }
902 
903 
905  clear();
906  }
907 
911  void clear() {
913 
914  // Delete all handles stored in the member table
915  It cur = memberTable.begin();
916  It end = memberTable.end();
917  while (cur != end) {
918  delete cur->key.handle;
919  cur->key.handle = NULL;
920  ++cur;
921  }
922  memberTable.clear();
923 
924  // Delete the tree structure itself
925  delete root;
926  root = NULL;
927  }
928 
929  int size() const {
930  return memberTable.size();
931  }
932 
938  void insert(const T& value) {
939  if (contains(value)) {
940  // Already in the set
941  return;
942  }
943 
944  Handle* h = new Handle(value);
945 
946  if (root == NULL) {
947  // This is the first node; create a root node
948  root = new Node();
949  }
950 
951  Node* node = root->findDeepestContainingNode(h->bounds);
952 
953  // Insert into the node
954  node->valueArray.append(h);
955  node->boundsArray.append(h->bounds);
956 
957  // Insert into the node table
958  Member m(h);
959  memberTable.set(m, node);
960  }
961 
966  void insert(const Array<T>& valueArray) {
967  if (root == NULL) {
968  // Optimized case for an empty tree; don't bother
969  // searching or reallocating the root node's valueArray
970  // as we incrementally insert.
971  root = new Node();
972  root->valueArray.resize(valueArray.size());
973  root->boundsArray.resize(root->valueArray.size());
974  for (int i = 0; i < valueArray.size(); ++i) {
975  // Insert in opposite order so that we have the exact same
976  // data structure as if we inserted each (i.e., order is reversed
977  // from array).
978  Handle* h = new Handle(valueArray[i]);
979  int j = valueArray.size() - i - 1;
980  root->valueArray[j] = h;
981  root->boundsArray[j] = h->bounds;
982  memberTable.set(Member(h), root);
983  }
984 
985  } else {
986  // Insert at appropriate tree depth.
987  for (int i = 0; i < valueArray.size(); ++i) {
988  insert(valueArray[i]);
989  }
990  }
991  }
992 
993 
998  bool contains(const T& value) {
999  // Temporarily create a handle and member
1000  Handle h(value);
1001  return memberTable.containsKey(Member(&h));
1002  }
1003 
1004 
1015  void remove(const T& value) {
1017  "Tried to remove an element from a "
1018  "KDTree that was not present");
1019 
1020  // Get the list of elements at the node
1021  Handle h(value);
1022  Member m(&h);
1023 
1024  Array<Handle*>& list = memberTable[m]->valueArray;
1025 
1026  Handle* ptr = NULL;
1027 
1028  // Find the element and remove it
1029  for (int i = list.length() - 1; i >= 0; --i) {
1030  if (list[i]->value == value) {
1031  // This was the element. Grab the pointer so that
1032  // we can delete it below
1033  ptr = list[i];
1034 
1035  // Remove the handle from the node
1036  list.fastRemove(i);
1037 
1038  // Remove the corresponding bounds
1039  memberTable[m]->boundsArray.fastRemove(i);
1040  break;
1041  }
1042  }
1043 
1044  // Remove the member
1045  memberTable.remove(m);
1046 
1047  // Delete the handle data structure
1048  delete ptr;
1049  ptr = NULL;
1050  }
1051 
1052 
1064  void update(const T& value) {
1065  if (contains(value)) {
1066  remove(value);
1067  }
1068  insert(value);
1069  }
1070 
1071 
1093  void balance(int valuesPerNode = 5, int numMeanSplits = 3) {
1094  if (root == NULL) {
1095  // Tree is empty
1096  return;
1097  }
1098 
1099  // Get all handles and delete the old tree structure
1100  Node* oldRoot = root;
1101  for (int c = 0; c < 2; ++c) {
1102  if (root->child[c] != NULL) {
1103  root->child[c]->getHandles(root->valueArray);
1104 
1105  // Delete the child; this will delete all structure below it
1106  delete root->child[c];
1107  root->child[c] = NULL;
1108  }
1109  }
1110 
1111  Array<Handle*> temp;
1112  // Make a new root. Work with a copy of the value array because
1113  // makeNode clears the source array as it progresses
1114  Array<Handle*> copy(oldRoot->valueArray);
1115  root = makeNode(copy, valuesPerNode, numMeanSplits, temp);
1116 
1117  // Throw away the old root node
1118  delete oldRoot;
1119  oldRoot = NULL;
1120 
1121  // Walk the tree, assigning splitBounds. We start with unbounded
1122  // space. This will override the current member table.
1123  const AABox& LARGE = AABox::large();
1124  root->assignSplitBounds(LARGE);
1125 
1126 # ifdef _DEBUG
1127  {
1128  // Ensure that the balanced tree is still correct
1129  root->verifyNode(LARGE.low(), LARGE.high());
1130  }
1131 # endif
1132  }
1133 
1134 
1136  void setContents(const Array<T>& array, int valuesPerNode = 5, int numMeanSplits = 3) {
1137  clear();
1138  insert(array);
1139  balance(valuesPerNode, numMeanSplits);
1140  }
1141 
1142 
1143 protected:
1144 
1149  const Array<Plane>& plane,
1150  Array<T*>& members,
1151  Node* node,
1152  uint32 parentMask) {
1153 
1154  int dummy;
1155 
1156  if (parentMask == 0) {
1157  // None of these planes can cull anything
1158  for (int v = node->valueArray.size() - 1; v >= 0; --v) {
1159  members.append(& (node->valueArray[v]->value));
1160  }
1161 
1162  // Iterate through child nodes
1163  for (int c = 0; c < 2; ++c) {
1164  if (node->child[c]) {
1165  getIntersectingMembers(plane, members, node->child[c], 0);
1166  }
1167  }
1168  } else {
1169 
1170  // Test values at this node against remaining planes
1171  for (int v = node->boundsArray.size() - 1; v >= 0; --v) {
1172  if (! node->boundsArray[v].culledBy(plane, dummy, parentMask)) {
1173  members.append(&(node->valueArray[v]->value));
1174  }
1175  }
1176 
1177  uint32 childMask = 0xFFFFFF;
1178 
1179  // Iterate through child nodes
1180  for (int c = 0; c < 2; ++c) {
1181  if (node->child[c] &&
1182  ! node->child[c]->splitBounds.culledBy(plane, dummy, parentMask, childMask)) {
1183  // This node was not culled
1184  getIntersectingMembers(plane, members, node->child[c], childMask);
1185  }
1186  }
1187  }
1188  }
1189 
1190 public:
1191 
1196  void getIntersectingMembers(const Array<Plane>& plane, Array<T*>& members) const {
1197  if (root == NULL) {
1198  return;
1199  }
1200 
1201  getIntersectingMembers(plane, members, root, 0xFFFFFF);
1202  }
1203 
1204  void getIntersectingMembers(const Array<Plane>& plane, Array<T>& members) const {
1205  Array<T*> temp;
1206  getIntersectingMembers(plane, temp, root, 0xFFFFFF);
1207  for (int i = 0; i < temp.size(); ++i) {
1208  members.append(*temp[i]);
1209  }
1210  }
1211 
1225  void getIntersectingMembers(const Frustum& frustum, Array<T*>& members) const {
1226  Array<Plane> plane;
1227 
1228  for (int i = 0; i < frustum.faceArray.size(); ++i) {
1229  plane.append(frustum.faceArray[i].plane);
1230  }
1231 
1232  getIntersectingMembers(plane, members);
1233  }
1234 
1235  void getIntersectingMembers(const Frustum& frustum, Array<T>& members) const {
1236  Array<T*> temp;
1237  getIntersectingMembers(frustum, temp);
1238  for (int i = 0; i < temp.size(); ++i) {
1239  members.append(*temp[i]);
1240  }
1241  }
1242 
1248  // This iterator turns Node::getIntersectingMembers into a
1249  // coroutine. It first translates that method from recursive to
1250  // stack based, then captures the system state (analogous to a Scheme
1251  // continuation) after each element is appended to the member array,
1252  // and allowing the computation to be restarted.
1254  private:
1255  friend class TreeType;
1256 
1258  bool isEnd;
1259 
1262 
1266 
1268  // We could use backpointers within the tree and careful
1269  // state management to avoid ever storing the stack-- but
1270  // it is much easier this way and only inefficient if the
1271  // caller uses post increment (which they shouldn't!).
1273 
1277 
1279 
1280  BoxIntersectionIterator(const AABox& b, const Node* root) :
1281  isEnd(root == NULL), box(b),
1282  node(const_cast<Node*>(root)), nextValueArrayIndex(-1) {
1283 
1284  // We intentionally start at the "-1" index of the current
1285  // node so we can use the preincrement operator to move
1286  // ourselves to element 0 instead of repeating all of the
1287  // code from the preincrement method. Note that this might
1288  // cause us to become the "end" instance.
1289  ++(*this);
1290  }
1291 
1292  public:
1293 
1294  inline bool operator!=(const BoxIntersectionIterator& other) const {
1295  return ! (*this == other);
1296  }
1297 
1298  bool operator==(const BoxIntersectionIterator& other) const {
1299  if (isEnd) {
1300  return other.isEnd;
1301  } else if (other.isEnd) {
1302  return false;
1303  } else {
1304  // Two non-end iterators; see if they match. This is kind of
1305  // silly; users shouldn't call == on iterators in general unless
1306  // one of them is the end iterator.
1307  if ((box != other.box) || (node != other.node) ||
1308  (nextValueArrayIndex != other.nextValueArrayIndex) ||
1309  (stack.length() != other.stack.length())) {
1310  return false;
1311  }
1312 
1313  // See if the stacks are the same
1314  for (int i = 0; i < stack.length(); ++i) {
1315  if (stack[i] != other.stack[i]) {
1316  return false;
1317  }
1318  }
1319 
1320  // We failed to find a difference; they must be the same
1321  return true;
1322  }
1323  }
1324 
1330 
1331  bool foundIntersection = false;
1332  while (! isEnd && ! foundIntersection) {
1333 
1334  // Search for the next node if we've exhausted this one
1335  while ((! isEnd) && (nextValueArrayIndex >= node->valueArray.length())) {
1336  // If we entered this loop, then the iterator has exhausted the elements at
1337  // node (possibly because it just switched to a child node with no members).
1338  // This loop continues until it finds a node with members or reaches
1339  // the end of the whole intersection search.
1340 
1341  // If the right child overlaps the box, push it onto the stack for
1342  // processing.
1343  if ((node->child[1] != NULL) &&
1344  (box.high()[node->splitAxis] > node->splitLocation)) {
1345  stack.push(node->child[1]);
1346  }
1347 
1348  // If the left child overlaps the box, push it onto the stack for
1349  // processing.
1350  if ((node->child[0] != NULL) &&
1351  (box.low()[node->splitAxis] < node->splitLocation)) {
1352  stack.push(node->child[0]);
1353  }
1354 
1355  if (stack.length() > 0) {
1356  // Go on to the next node (which may be either one of the ones we
1357  // just pushed, or one from farther back the tree).
1358  node = stack.pop();
1359  nextValueArrayIndex = 0;
1360  } else {
1361  // That was the last node; we're done iterating
1362  isEnd = true;
1363  }
1364  }
1365 
1366  // Search for the next intersection at this node until we run out of children
1367  while (! isEnd && ! foundIntersection && (nextValueArrayIndex < node->valueArray.length())) {
1368  if (box.intersects(node->boundsArray[nextValueArrayIndex])) {
1369  foundIntersection = true;
1370  } else {
1372  // If we exhaust this node, we'll loop around the master loop
1373  // to find a new node.
1374  }
1375  }
1376  }
1377 
1378  return *this;
1379  }
1380 
1381  private:
1387  /*{
1388  BoxIntersectionIterator old = *this;
1389  ++this;
1390  return old;
1391  }*/
1392 
1393  public:
1394 
1397  const T& operator*() const {
1398  alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator");
1399  return node->valueArray[nextValueArrayIndex]->value;
1400  }
1401 
1404  T const * operator->() const {
1405  alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator");
1406  return &(stack.last()->valueArray[nextValueArrayIndex]->value);
1407  }
1408 
1411  operator T*() const {
1412  alwaysAssertM(! isEnd, "Can't dereference the end element of an iterator");
1413  return &(stack.last()->valueArray[nextValueArrayIndex]->value);
1414  }
1415  };
1416 
1417 
1422  return BoxIntersectionIterator(box, root);
1423  }
1424 
1426  // The "end" iterator instance
1427  return BoxIntersectionIterator();
1428  }
1429 
1434  void getIntersectingMembers(const AABox& box, Array<T*>& members) const {
1435  if (root == NULL) {
1436  return;
1437  }
1438  root->getIntersectingMembers(box, Sphere(Vector3::zero(), 0), members, false);
1439  }
1440 
1441  void getIntersectingMembers(const AABox& box, Array<T>& members) const {
1442  Array<T*> temp;
1443  getIntersectingMembers(box, temp);
1444  for (int i = 0; i < temp.size(); ++i) {
1445  members.append(*temp[i]);
1446  }
1447  }
1448 
1449 
1508  template<typename RayCallback>
1510  const Ray& ray,
1511  RayCallback& intersectCallback,
1512  float& distance,
1513  bool intersectCallbackIsFast = false) const {
1514 
1515  root->intersectRay(ray, intersectCallback, distance, intersectCallbackIsFast);
1516  }
1517 
1518 
1525  void getIntersectingMembers(const Sphere& sphere, Array<T*>& members) const {
1526  if (root == NULL) {
1527  return;
1528  }
1529 
1530  AABox box;
1531  sphere.getBounds(box);
1532  root->getIntersectingMembers(box, sphere, members, true);
1533  }
1534 
1535  void getIntersectingMembers(const Sphere& sphere, Array<T>& members) const {
1536  Array<T*> temp;
1537  getIntersectingMembers(sphere, temp);
1538  for (int i = 0; i < temp.size(); ++i) {
1539  members.append(*temp[i]);
1540  }
1541  }
1542 
1549  Node::serializeStructure(root, bo);
1550  }
1551 
1554  clear();
1555  root = Node::deserializeStructure(bi);
1556  }
1557 
1561  void getMembers(Array<T>& members) const {
1562  Array<Member> temp;
1563  memberTable.getKeys(temp);
1564  for (int i = 0; i < temp.size(); ++i) {
1565  members.append(*(temp.handle));
1566  }
1567  }
1568 
1569 
1573  const T* getPointer(const T& value) const {
1574  // Temporarily create a handle and member
1575  Handle h(value);
1576  const Member* member = memberTable.getKeyPointer(Member(&h));
1577  if (member == NULL) {
1578  // Not found
1579  return NULL;
1580  } else {
1581  return &(member->handle->value);
1582  }
1583  }
1584 
1585 
1591  class Iterator {
1592  private:
1593  friend class TreeType;
1594 
1595  // Note: this is a Table iterator, we are currently defining
1596  // Set iterator
1598 
1599  Iterator(const typename Table<Member, Node*>::Iterator& it) : it(it) {}
1600 
1601  public:
1602 
1603  inline bool operator!=(const Iterator& other) const {
1604  return !(*this == other);
1605  }
1606 
1607  bool operator==(const Iterator& other) const {
1608  return it == other.it;
1609  }
1610 
1615  ++it;
1616  return *this;
1617  }
1618 
1619  private:
1623  Iterator operator++(int);/* {
1624  Iterator old = *this;
1625  ++(*this);
1626  return old;
1627  }*/
1628  public:
1629 
1630  const T& operator*() const {
1631  return it->key.handle->value;
1632  }
1633 
1634  T* operator->() const {
1635  return &(it->key.handle->value);
1636  }
1637 
1638  operator T*() const {
1639  return &(it->key.handle->value);
1640  }
1641  };
1642 
1643 
1650  Iterator begin() const {
1651  return Iterator(memberTable.begin());
1652  }
1653 
1654 
1659  Iterator end() const {
1660  return Iterator(memberTable.end());
1661  }
1662 #undef TreeType
1663 };
1664 
1665 
1666 }
1667 
1668 #endif
Iterator & operator++()
Definition: KDTree.h:1614
Array< Handle * > valueArray
Definition: KDTree.h:361
bool operator==(const Handle &other) const
Definition: KDTree.h:224
bool intersects(const AABox &other) const
Definition: AABox.cpp:175
void deserialize(class BinaryInput &b)
Definition: AABox.cpp:99
void getIntersectingMembers(const AABox &box, Array< T * > &members) const
Definition: KDTree.h:1434
void getBounds(class AABox &) const
Definition: Box.cpp:463
size_t hashCode() const
Definition: KDTree.h:228
bool operator==(const Type &m) const
Definition: KDTree.h:113
Definition: Vector2.h:40
static void getBounds(const G3D::AABox &v, G3D::AABox &out)
Definition: KDTree.h:51
int nextValueArrayIndex
Definition: KDTree.h:1276
void getIntersectingMembers(const Frustum &frustum, Array< T > &members) const
Definition: KDTree.h:1235
void push(const T &value)
Definition: Array.h:770
~KDTree()
Definition: KDTree.h:904
T pop(bool shrinkUnderlyingArrayIfNecessary=true)
Definition: Array.h:837
T const * operator->() const
Definition: KDTree.h:1404
Definition: Frustum.h:24
static void getBounds(const G3D::Sphere *&s, G3D::AABox &out)
Definition: KDTree.h:79
Definition: KDTree.h:193
Node * child[2]
Definition: KDTree.h:351
Indirector()
Definition: KDTree.h:106
static void getBounds(const G3D::Vector3 &v, G3D::AABox &out)
Definition: KDTree.h:43
static void getBounds(const G3D::Triangle *&t, G3D::AABox &out)
Definition: KDTree.h:88
Handle()
Definition: KDTree.h:216
int operator()(Handle *ignore, const Handle *handle) const
Definition: KDTree.h:311
Vector3::Axis sortAxis
Definition: KDTree.h:284
AABox intersect(const AABox &other) const
Definition: AABox.h:282
Node * findDeepestContainingNode(const AABox &bounds)
Definition: KDTree.h:511
void setContents(const Array< T > &array, int valuesPerNode=5, int numMeanSplits=3)
Definition: KDTree.h:1136
void getIntersectingMembers(const Frustum &frustum, Array< T * > &members) const
Definition: KDTree.h:1225
void resize(size_t n, bool shrinkIfNecessary=true)
Definition: Array.h:490
size_t hashCode() const
Definition: Vector2unorm16.h:76
static void getBounds(const G3D::Vector4 *&v, G3D::AABox &out)
Definition: KDTree.h:71
Definition: Vector3.h:122
bool contains(const T &value)
Definition: KDTree.h:998
KDTree(const KDTree &src)
Definition: KDTree.h:891
Definition: BinaryInput.h:69
Comparator(Vector3::Axis a, float l)
Definition: KDTree.h:309
bool contains(const AABox &other) const
Definition: AABox.h:238
CenterComparator(Vector3::Axis a)
Definition: KDTree.h:264
void getMembers(Array< T > &members) const
Definition: KDTree.h:1561
void balance(int valuesPerNode=5, int numMeanSplits=3)
Definition: KDTree.h:1093
Node * makeNode(Array< Handle * > &source, int valuesPerNode, int numMeanSplits, Array< Handle * > &temp)
Definition: KDTree.h:711
bool operator==(const Iterator &other) const
Definition: KDTree.h:1607
bool operator==(const Indirector &m) const
Definition: KDTree.h:109
void clear()
Definition: Table.h:578
size_t size() const
Definition: Table.h:589
static void getBounds(const G3D::Vector3 *&v, G3D::AABox &out)
Definition: KDTree.h:67
Definition: HashTrait.h:105
Definition: KDTree.h:1253
Definition: AABox.h:25
Iterator begin() const
Definition: KDTree.h:1650
Dynamic 1D array tuned for performance.
Definition: Array.h:95
Node * root
Definition: KDTree.h:882
Axis primaryAxis() const
Definition: Vector3.cpp:129
Iterator begin() const
Definition: Table.h:562
BoxIntersectionIterator endBoxIntersection() const
Definition: KDTree.h:1425
const T & last() const
Definition: Array.h:923
void getIntersectingMembers(const AABox &box, const Sphere &sphere, Array< T * > &members, bool useSphere) const
Definition: KDTree.h:537
void writeUInt8(uint8 i)
Definition: BinaryOutput.h:283
arena_t NULL
Definition: jemalloc_internal.h:624
void assignSplitBounds(const AABox &myBounds)
Definition: KDTree.h:566
Definition: KDTree.h:100
void deserialize(std::string &s, BinaryInput &b)
Definition: serialize.h:16
static void getIntersectingMembers(const Array< Plane > &plane, Array< T * > &members, Node *node, uint32 parentMask)
Definition: KDTree.h:1148
Type * handle
Definition: KDTree.h:102
int length() const
Definition: Array.h:438
static AABox computeBounds(const Array< Handle * > &point, int beginIndex, int endIndex)
Definition: KDTree.h:234
void set(const Key &key, const Value &value)
Definition: Table.h:599
const Point3 & low() const
Definition: AABox.h:136
Array< AABox > boundsArray
Definition: KDTree.h:369
void getBounds(class AABox &out) const
Definition: Sphere.cpp:252
void getIntersectingMembers(const Array< Plane > &plane, Array< T > &members) const
Definition: KDTree.h:1204
Axis
Definition: Vector3.h:122
float32 readFloat32()
Definition: BinaryInput.h:352
void verifyNode(const Vector3 &lo, const Vector3 &hi)
Definition: KDTree.h:434
bool operator!=(const Iterator &other) const
Definition: KDTree.h:1603
void getHandles(Array< Handle * > &handleArray) const
Definition: KDTree.h:425
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
Definition: KDTree.h:330
KDTree()
Definition: KDTree.h:888
bool isLeaf() const
Definition: KDTree.h:416
Definition: KDTree.h:282
~Node()
Definition: KDTree.h:409
An arbitrary (oriented) 3D box, useful as a bounding box.
Definition: Box.h:35
double distance(double x, double y)
Definition: g3dmath.h:731
static size_t hashCode(const G3D::_internal::Indirector< Handle > &key)
Definition: KDTree.h:125
Vector3 xyz() const
Definition: Vector4.cpp:233
T max(const T &x, const T &y)
Definition: g3dmath.h:320
static void getBounds(const G3D::Vector2 &v, G3D::AABox &out)
Definition: KDTree.h:39
bool operator!=(const BoxIntersectionIterator &other) const
Definition: KDTree.h:1294
BoundsComparator(Vector3::Axis a)
Definition: KDTree.h:286
Definition: Vector3.h:58
T * operator->() const
Definition: KDTree.h:1634
Vector3::Axis splitAxis
Definition: KDTree.h:337
#define true
Definition: CascPort.h:17
BoxIntersectionIterator beginBoxIntersection(const AABox &box) const
Definition: KDTree.h:1421
bool intersects(const Ray &ray, float distance) const
Definition: KDTree.h:588
Indirector(Type *h)
Definition: KDTree.h:104
void medianPartition(Array< T > &ltMedian, Array< T > &eqMedian, Array< T > &gtMedian, Array< T > &tempArray, const Comparator &comparator) const
Definition: Array.h:1247
void getBounds(class AABox &) const
Definition: Triangle.cpp:124
static const Vector3 & zero()
Definition: Vector3.cpp:119
Vector3::Axis sortAxis
Definition: KDTree.h:262
uint8 readUInt8()
Definition: BinaryInput.h:278
Definition: Sphere.h:24
T min(const T &x, const T &y)
Definition: g3dmath.h:305
void fastRemove(int index, bool shrinkIfNecessary=false)
Definition: Array.h:446
const T * getPointer(const T &value) const
Definition: KDTree.h:1573
BoxIntersectionIterator()
Definition: KDTree.h:1278
static void getBounds(const G3D::Vector4 &v, G3D::AABox &out)
Definition: KDTree.h:47
static void getBounds(const G3D::AABox *&v, G3D::AABox &out)
Definition: KDTree.h:75
void intersectRay(const Ray &ray, RayCallback &intersectCallback, float &distance, bool intersectCallbackIsFast) const
Definition: KDTree.h:603
Definition: KDTree.h:1591
float splitLocation
Definition: KDTree.h:340
Handle(const T &v)
Definition: KDTree.h:218
friend class TreeType
Definition: KDTree.h:1255
bool culledBy(const Array< Plane > &plane, int32 &cullingPlaneIndex, const uint32 testMask, uint32 &childMask) const
void serialize(const std::string &s, BinaryOutput &b)
Definition: serialize.h:12
Vector3::Axis sortAxis
Definition: KDTree.h:306
BoxIntersectionIterator & operator++()
Definition: KDTree.h:1328
#define debugAssert(exp)
Definition: debugAssert.h:160
static void getBounds(const G3D::Box &b, G3D::AABox &out)
Definition: KDTree.h:59
SmallArray< Face, 6 > faceArray
Definition: Frustum.h:49
static bool collisionLocationForMovingPointFixedAABox(const Vector3 &point, const Vector3 &velocity, const class AABox &box, Vector3 &outLocation, bool &inside=ignoreBool, Vector3 &normal=ignore)
Definition: CollisionDetection.cpp:1226
void clear()
Definition: KDTree.h:911
Node * node
Definition: KDTree.h:1265
int size() const
Definition: KDTree.h:929
bool remove(const Key &key, Key &removedKey, Value &removedValue, bool updateRemoved)
Definition: Table.h:606
void getIntersectingMembers(const Sphere &sphere, Array< T * > &members) const
Finds all members whose bounding boxes intersect the sphere. The actual elements may not intersect th...
Definition: KDTree.h:1525
bool operator==(const BoxIntersectionIterator &other) const
Definition: KDTree.h:1298
Definition: Vector4.h:39
T value
Definition: KDTree.h:214
double square(double fValue)
Definition: g3dmath.h:698
Point3 center() const
Definition: AABox.h:163
void clear(bool shrink=true)
Definition: Array.h:407
void serialize(class BinaryOutput &b) const
Definition: AABox.cpp:93
AABox bounds
Definition: KDTree.h:206
std::string __cdecl format(const char *fmt...) G3D_CHECK_PRINTF_ARGS
Table< Member, Node * > MemberTable
Definition: KDTree.h:877
friend class TreeType
Definition: KDTree.h:1593
MemberTable memberTable
Definition: KDTree.h:880
int size() const
Definition: Array.h:430
Definition: Ray.h:24
Node(const Node &other)
Definition: KDTree.h:384
Definition: AABox.h:32
void insert(const Array< T > &valueArray)
Definition: KDTree.h:966
Iterator end() const
Definition: KDTree.h:1659
Definition: KDTree.h:304
float sortLocation
Definition: KDTree.h:307
Definition: BoundsTrait.h:17
size_t hashCode() const
Definition: KDTree.h:117
void intersectRay(const Ray &ray, RayCallback &intersectCallback, float &distance, bool intersectCallbackIsFast=false) const
Definition: KDTree.h:1509
const Iterator end() const
Definition: Table.h:570
BoxIntersectionIterator(const AABox &b, const Node *root)
Definition: KDTree.h:1280
Array< Node * > stack
Definition: KDTree.h:1272
static const AABox & large()
Definition: AABox.cpp:74
KDTree & operator=(const KDTree &src)
Definition: KDTree.h:896
void serializeStructure(BinaryOutput &bo) const
Definition: KDTree.h:1548
const Point3 & origin() const
Definition: Ray.h:56
Array< Key > getKeys() const
Definition: Table.h:907
const Key * getKeyPointer(const Key &key) const
Definition: Table.h:701
int operator()(Handle *A, const Handle *B) const
Definition: KDTree.h:266
Definition: BinaryOutput.h:52
static Node * deserializeStructure(BinaryInput &bi)
Definition: KDTree.h:495
int operator()(Handle *A, const Handle *B) const
Definition: KDTree.h:288
Node()
Definition: KDTree.h:372
Iterator(const typename Table< Member, Node * >::Iterator &it)
Definition: KDTree.h:1599
AABox splitBounds
Definition: KDTree.h:335
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
bool isEnd
Definition: KDTree.h:1258
Definition: KDTree.h:203
void split(const Vector3::Axis &axis, float location, AABox &low, AABox &high) const
Definition: AABox.cpp:112
static void getBounds(const G3D::Vector2 *&v, G3D::AABox &out)
Definition: KDTree.h:63
const FieldDescriptor value
Definition: descriptor.h:1522
uint32_t uint32
Definition: g3dmath.h:168
void getIntersectingMembers(const Array< Plane > &plane, Array< T * > &members) const
Definition: KDTree.h:1196
void getIntersectingMembers(const Sphere &sphere, Array< T > &members) const
Definition: KDTree.h:1535
const Point3 & high() const
Definition: AABox.h:141
Definition: EqualsTrait.h:19
static const Vector3 & inf()
Definition: Vector3.cpp:124
void update(const T &value)
Definition: KDTree.h:1064
void append(const T &value)
Definition: Array.h:583
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
Node * cloneTree(Node *src)
Definition: KDTree.h:853
const T & operator*() const
Definition: KDTree.h:1397
Type
Type of JSON value.
Definition: rapidjson.h:642
Node(const Array< Handle * > &pt)
Definition: KDTree.h:395
Definition: Triangle.h:34
const Vector3 & direction() const
Definition: Ray.h:61
AABox box
Definition: KDTree.h:1261
Vector3 center
Definition: KDTree.h:212
static void serializeStructure(const Node *n, BinaryOutput &bo)
Definition: KDTree.h:480
Definition: KDTree.h:260
static void getBounds(const G3D::Box *&b, G3D::AABox &out)
Definition: KDTree.h:83
bool containsKey(const Key &key) const
Definition: Table.h:874
static void getBounds(const G3D::Sphere &s, G3D::AABox &out)
Definition: KDTree.h:55
bool isFinite(double x)
Definition: g3dmath.h:525
std::string toString() const
Definition: Vector3.cpp:386
const T & operator*() const
Definition: KDTree.h:1630
void insert(const T &value)
Definition: KDTree.h:938
_internal::Indirector< Handle > Member
Definition: KDTree.h:875
void deserializeStructure(BinaryInput &bi)
Definition: KDTree.h:1553
Table< Member, Node * >::Iterator it
Definition: KDTree.h:1597
void getIntersectingMembers(const AABox &box, Array< T > &members) const
Definition: KDTree.h:1441