VR-Forces 4.10 Class Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
octree.h
Go to the documentation of this file.
1 /*******************************************************************************
2 ** Copyright (c) 2020 MAK Technologies, Inc.
3 ** All rights reserved.
4 *******************************************************************************/
5 
8 
28 
29 #ifndef octree_H_
30 #define octree_H_
31 
32 #include <stdarg.h>
33 #include <map>
34 #include <vector>
35 
36 #include <cmdLine/cmdStdOutput.h>
37 
38 //#include "vrfobjcore/spatialVrfObjectManager.h"
39 #include "geometry/extent.h"
40 
41 template<class T> class DtOctreeNode;
42 
45 
46 #define OCTREE_DEBUG 0
47 
48 #if OCTREE_DEBUG
49 
50 static int octree_debug_level = 0;
51 
53 
54 static void DEBUG(const char* fmt, ...)
55 {
56  char buffer[8192];
57  va_list ap;
58  va_start(ap, fmt);
59  vsprintf(buffer, fmt, ap);
60  va_end(ap);
61 
62  DtInfo("OCT %*s%s\n", octree_debug_level*2, "", buffer);
63 }
64 
65 # define DEBUG_PUSH do { octree_debug_level++; } while(0)
66 # define DEBUG_POP do { octree_debug_level--; } while(0)
67 #else
68 
69 static inline void DEBUG(const char* fmt, ...)
70 { }
71 
72 # define DEBUG_PUSH do { } while(0)
73 # define DEBUG_POP do { } while(0)
74 #endif
75 
77 static const int NUM_BRANCHES = 8;
78 
79 static const int MAX_BRANCH_DEPTH = 12;
80 
82 static const int MAX_CHILD_MEMBERS = 16;
83 
85 static bool theBitmaskListCreated = false;
86 
87 #define EXT_FMT "[%lf, %lf, %lf] - [%lf, %lf, %lf]"
88 #define EXT_ARGS(x) (x).minX(), (x).minY(), (x).minZ(), (x).maxX(), (x).maxY(), (x).maxZ()
89 #define OBJ_ARGS(x) ((const char*) (x)->markingText())
90 
96 
97 template<class T> class DtOctreeMember
98 {
99 public:
100  DtOctreeMember(T* object, const DtExtent& extent)
101  : myObject(object)
102  , myExtent(extent)
103  , mySearchKey(0)
104  {
105  }
106 
108  void bind(DtOctreeNode<T>* node);
109 
111  void unbind(DtOctreeNode<T>* node);
112 
114  void unbind();
115 
116  bool testKey(const unsigned int key)
117  {
118  if (key == mySearchKey)
119  {
120  return false;
121  }
123  mySearchKey = key;
124  return true;
125  }
126 
127 protected:
128  template<class U> friend class DtOctreeNode;
129  template<class U> friend class DtOctree;
130 
133 
136 
137  typedef std::pair<DtOctreeNode<T>*, typename std::list<DtOctreeMember*>::iterator> NodeBinding;
138 
141  std::list<NodeBinding> myBindings;
142 
144  unsigned int mySearchKey;
145 };
146 
147 
148 template<class T>
150 {
151 public:
154 
156  virtual bool operator()(const T *object) = 0;
157 };
158 
185 
186 template<class T> class DtOctreeNode
187 {
188 protected:
189 
190  typedef std::list<DtOctreeMember<T>*> MemberContainer;
191  typedef typename std::list<DtOctreeMember<T>*>::iterator MemberIterator;
192 
193  static int sNumNodes;
194  static const int MAX_NUM_NODES = 1000;
195 
197  DtOctreeNode(const DtExtent &region, const unsigned int depth)
198  : myRegion(region)
199  , myDepth(depth)
200  , myCenter(region.center())
201  , myChildren(0)
202  {
203  DEBUG("Create node " EXT_FMT, EXT_ARGS(region));
204 
205  ++sNumNodes;
206  }
207 
210  {
211  DEBUG("Destroy node " EXT_FMT, EXT_ARGS(myRegion));
212  DEBUG_PUSH;
213 
214  if (myChildren)
215  {
216  for(int i=0; i<NUM_BRANCHES; i++)
217  delete myChildren[i];
218  }
219  delete[] myChildren;
220 
221  DEBUG_POP;
222 
223  --sNumNodes;
224  }
225 
234 
235  virtual void visitObjects(const unsigned int key, const DtExtent& extent, DtSpatialSelectionFunctorTemplate<T> &callback)
236  {
237  DEBUG(EXT_FMT "::visit(" EXT_FMT ", cb)", EXT_ARGS(myRegion), EXT_ARGS(extent));
238  DEBUG_PUSH;
239 
240  MemberIterator iter, end;
241 
242  for(iter = myMembers.begin(), end = myMembers.end(); iter != end; ++iter)
243  {
244  DEBUG("Member %s " EXT_FMT, OBJ_ARGS((*iter)->myObject), EXT_ARGS((*iter)->myExtent));
245  if ((*iter)->testKey(key))
246  {
247  if (callback((*iter)->myObject))
248  {
249  break;
250  }
251  }
252  }
253 
254  if (myChildren)
255  {
256  int mask = intersectionMask(extent);
257  for(int i = 0; i < NUM_BRANCHES; ++i)
258  {
259  if (myChildren[i] && (mask & theBitmaskList[i]))
260  {
261  myChildren[i]->visitObjects(key, extent, callback);
262  }
263  }
264  }
265 
266  DEBUG_POP;
267  }
268 
270  virtual void addMember(DtOctreeMember<T>* member, int& depth)
271  {
272  depth++;
273 
274  DEBUG(EXT_FMT "::addMember(%s)", EXT_ARGS(myRegion), OBJ_ARGS(member->myObject));
275  DEBUG_PUSH;
276 
277 #if OCTREE_DEBUG
278  if (!myRegion.contains(member->myExtent))
279  {
280  DEBUG("FAIL! " EXT_FMT " does not contain " EXT_FMT, EXT_ARGS(myRegion), EXT_ARGS(member->myExtent));
281  }
282 #endif
283 
284  if (myChildren)
285  {
286  int mask = intersectionMask(member->myExtent);
287 
288  if (mask == 0xff)
289  {
291  member->bind(this);
292  }
293  else
294  {
295  for (int childIndex = 0; childIndex < NUM_BRANCHES; ++childIndex)
296  {
297  if (mask & theBitmaskList[childIndex])
298  {
299  addMemberToChild(member, childIndex, depth);
300  }
301  }
302  }
303  }
304  else
305  {
306  DEBUG("add as child member (not enough child members yet)");
307 
308  member->bind(this);
309 
310  //if (numChildCandidates() >= MAX_CHILD_MEMBERS && myDepth < MAX_BRANCH_DEPTH)
311  if (numChildCandidates() >= MAX_CHILD_MEMBERS && sNumNodes < MAX_NUM_NODES - 8)
312  {
313  split(depth);
314  }
315  }
316 
317  DEBUG_POP;
318  }
319 
323  {
324  DEBUG(EXT_FMT "::coalesceEmptyChildren()", EXT_ARGS(myRegion));
325  DEBUG_PUSH;
326 
327  bool retVal = (myMembers.size() == 0);
328 
329  if (myChildren)
330  {
331  for(int i=0; i<NUM_BRANCHES; i++)
332  {
333  if (myChildren[i])
334  {
336  {
337  DEBUG("Deleting child %d\n", i);
338  delete myChildren[i];
339  myChildren[i] = 0;
340  } else {
341  retVal = false;
342  }
343  }
344  }
345  }
346 
347  DEBUG_POP;
348 
349  return retVal;
350  }
351 
354  {
355  double retVal = 0;
356  DtExtent matchExtent;
357 
358  MemberIterator iter, end;
359  for(iter = myMembers.begin(), end = myMembers.end(); iter != end; ++iter)
360  {
361  double numBuckets = 0;
362  int mask = intersectionMask((*iter)->myExtent);
363 
366  if ((*iter)->myExtent == matchExtent)
367  {
368  continue;
369  }
370 
371  matchExtent = (*iter)->myExtent;
372 
373  if (mask != 0xff)
374  {
375  for(int childIndex = 0; childIndex < NUM_BRANCHES; ++childIndex)
376  {
377  if (mask & theBitmaskList[childIndex])
378  {
379  numBuckets++;
380  }
381  }
382 
383  retVal += (1.0 / numBuckets);
384 
385  if (retVal >= MAX_CHILD_MEMBERS)
386  {
387  break;
388  }
389  }
390  }
391 
392  return retVal;
393  }
394 
400  int intersectionMask(const DtExtent &extent) const
401  {
402  int result = 0xff;
403 
404  if (extent.minX() >= myCenter.x())
405  result &= 0xf0;
406  if (extent.maxX() <= myCenter.x())
407  result &= 0x0f;
408 
409  if (extent.minY() >= myCenter.y())
410  result &= 0xcc;
411  if (extent.maxY() <= myCenter.y())
412  result &= 0x33;
413 
414  if (extent.minZ() >= myCenter.z())
415  result &= 0xaa;
416  if (extent.maxZ() <= myCenter.z())
417  result &= 0x55;
418 
419  if (result == 0)
420  {
424  return 0xff;
425  }
426 
427  return result;
428  }
429 
433  void addMemberToChild(DtOctreeMember<T>* member, int childIndex, int& depth)
434  {
435  DEBUG(EXT_FMT "::addMemberToChild(%s, %d)", EXT_ARGS(myRegion), OBJ_ARGS(member->myObject), childIndex);
436  DEBUG_PUSH;
437 
438  if (myChildren[childIndex] == 0)
439  {
440  DtPoint childCorner;
441 
442  if (childIndex & 4)
443  childCorner.setX(myRegion.maxX());
444  else
445  childCorner.setX(myRegion.minX());
446 
447  if (childIndex & 2)
448  childCorner.setY(myRegion.maxY());
449  else
450  childCorner.setY(myRegion.minY());
451 
452  if (childIndex & 1)
453  childCorner.setZ(myRegion.maxZ());
454  else
455  childCorner.setZ(myRegion.minZ());
456 
457  myChildren[childIndex] = new DtOctreeNode(DtExtent(childCorner, myCenter), myDepth + 1);
458  }
459 
460  myChildren[childIndex]->addMember(member, depth);
461 
462  DEBUG_POP;
463  }
464 
467  void split(int& depth)
468  {
469  DEBUG(EXT_FMT "::split()", EXT_ARGS(myRegion));
470  DEBUG_PUSH;
471 
473 
474  for(int i=0; i<NUM_BRANCHES; i++)
475  {
476  myChildren[i] = 0;
477  }
478 
479  MemberIterator iter, next, end;
480  for(iter = myMembers.begin(), end = myMembers.end(); iter != end; iter = next)
481  {
482  next = iter;
483  ++next;
484 
485  DtOctreeMember<T>* member = *iter;
486 
487  int mask = intersectionMask(member->myExtent);
488 
491  if (mask != 0xff)
492  {
493  member->unbind(this);
494 
495  for(int childIndex = 0; childIndex < NUM_BRANCHES; ++childIndex)
496  {
497  if (mask & theBitmaskList[childIndex])
498  {
499  addMemberToChild(member, childIndex, depth);
500  }
501  }
502  }
503  }
504 
505  DEBUG_POP;
506  }
507 
510 
513 
514 
515  unsigned int myDepth;
516 
521 
525 
526  template<class U> friend class DtOctree;
527  template<class U> friend class DtOctreeMember;
528  template<class U> friend class DtOctreeDebugger;
529 };
530 
531 template<class T> int DtOctreeNode<T>::sNumNodes = 0;
532 
544 
545 template<class T> class DtOctree
546 {
547 public:
548 
550  typedef std::map<T*, DtOctreeMember<T>*> MemberContainer;
551  typedef typename std::map<T*, DtOctreeMember<T>*>::iterator MemberIterator;
552 
553  typedef std::list<T*> OutsideAreaContainer;
554  typedef typename std::list<T*>::iterator OutsideAreaIterator;
555 
557 
559  DtOctree(const DtExtent &region) : mySearchKey(0)
560  {
561  myRootNode = new DtOctreeNode<T>(region, 0);
562 
563  if (!theBitmaskListCreated)
564  {
565  theBitmaskListCreated = true;
566  for (int childIndex = 0; childIndex < NUM_BRANCHES; ++childIndex)
567  {
568  theBitmaskList[childIndex] = (1 << childIndex);
569  }
570  }
571  }
572 
574  virtual ~DtOctree()
575  {
576  delete myRootNode;
577 
578  MemberIterator iter, end;
579  for(iter = myMemberMap.begin(), end = myMemberMap.end(); iter != end; ++iter)
580  {
581  delete (*iter).second;
582  }
583  }
584 
588  virtual void visitObjects(const DtExtent& extent, DtSpatialSelectionFunctorTemplate<T> &callback)
589  {
590  ++mySearchKey;
591 
595  if (myRootNode->myRegion.intersects(extent))
596  {
597  myRootNode->visitObjects(mySearchKey, extent, callback);
598  }
599 
600  OutsideAreaIterator iter, end;
601  for(iter = myObjectsOutsideArea.begin(), end = myObjectsOutsideArea.end(); iter != end; ++iter)
602  {
603  callback(*iter);
604  }
605  }
606 
609 
611  virtual void addObject(T* object, const DtExtent& extent)
612  {
613  DEBUG("DtOctree::addObject(%s, " EXT_FMT ")", OBJ_ARGS(object), EXT_ARGS(extent));
614  DEBUG_PUSH;
615 
616  if (myRootNode->myRegion.contains(extent))
617  {
618  DtOctreeMember<T>* newMember = new DtOctreeMember<T>(object, extent);
619  int depth = 0;
620 
621  myRootNode->addMember(newMember, depth);
622  myMemberMap[object] = newMember;
623 
625  }
626  else
627  {
628  DtWarn("Member %s (" EXT_FMT ") added outside octree (" EXT_FMT ")\n",
629  OBJ_ARGS(object), EXT_ARGS(extent), EXT_ARGS(myRootNode->myRegion));
630  myObjectsOutsideArea.push_back(object);
631  }
632 
633  DEBUG_POP;
634  }
635 
637  virtual void removeObject(T* object)
638  {
639  DEBUG("DtOctree::removeObject(%s)", OBJ_ARGS(object));
640  DEBUG_PUSH;
641 
642  MemberIterator iter;
643  iter = myMemberMap.find(object);
644  if (iter != myMemberMap.end())
645  {
646  DtOctreeMember<T>* member = (*iter).second;
647  member->unbind();
648  myMemberMap.erase(iter);
649  delete member;
650  }
651  else if (!removeObjectOutsideArea(object))
652  {
656 
657  //DtWarn("Tried to remove %s from octree, but couldn't find!\n", OBJ_ARGS(object));
658  }
659 
660  DEBUG_POP;
661  }
662 
668  virtual void updatePositions()
669  {
670  MemberIterator cur = myMemberMap.begin();
671  while (cur != myMemberMap.end())
672  {
673  MemberIterator iter = cur++;
674 
675  T* object = (*iter).first;
676  DtOctreeMember<T>* member = (*iter).second;
677  DtExtent roughExtent = object->roughExtent();
678 
680  if (member->myExtent != roughExtent)
681  {
682  member->myExtent = roughExtent;
683 
684  if (!myRootNode->myRegion.contains(member->myExtent))
685  {
687 
688  DtWarn("Object %s (" EXT_FMT ") moving outside octree (" EXT_FMT ")\n",
689  OBJ_ARGS(object), EXT_ARGS(member->myExtent), EXT_ARGS(myRootNode->myRegion));
690  removeObject(object);
691  myObjectsOutsideArea.push_back(object);
692  }
693  else
694  {
696 
697  member->unbind();
698  int depth = 0;
699 
700  myRootNode->addMember(member, depth);
702  }
703  }
704  }
705 
706  myRootNode->coalesceEmptyChildren();
707  }
708 
709  bool containsObject(T* object)
710  {
711  if (myMemberMap.find(object) != myMemberMap.end())
712  {
713  return true;
714  }
715  else
716  {
717  OutsideAreaIterator iter, end;
718  for(iter = myObjectsOutsideArea.begin(), end = myObjectsOutsideArea.end(); iter != end; ++iter)
719  {
720  if (*iter == object)
721  {
722  return true;
723  }
724  }
725  }
726  return false;
727  }
728 
730  {
731  return myMemberMap.size() + myObjectsOutsideArea.size();
732  }
733 
735  {
736  return myObjectsOutsideArea.size();
737  }
738 
739 protected:
740  bool removeObjectOutsideArea(T* object)
741  {
742  OutsideAreaIterator iter, end;
743  for(iter = myObjectsOutsideArea.begin(), end = myObjectsOutsideArea.end(); iter != end; ++iter)
744  {
745  if (*iter == object)
746  {
747  myObjectsOutsideArea.erase(iter);
748  return true;
749  }
750  }
751 
752  return false;
753  }
754 
757 
760 
763 
765  unsigned int mySearchKey;
766 };
767 
771 
772 #if OCTREE_DEBUG
773 
774 class DtDebugOctreeFunctor : public DtSpatialSelectionFunctor
775 {
776 public:
777  DtDebugOctreeFunctor(DtSpatialSelectionFunctor& inner)
778  : myInner(inner)
779  {
780  }
781 
783  virtual bool operator()(const DtVrfObject* object)
784  {
785  mySeenObjects.insert(object);
786  return myInner(object);
787  }
788 
789  std::set<const DtVrfObject*> mySeenObjects;
790  DtSpatialSelectionFunctor& myInner;
791 };
792 
793 template<class T> class DtOctreeDebugger : public DtOctree<T>
794 {
795 public:
796  DtOctreeDebugger(const DtExtent& extent)
797  : DtOctree<T>(extent)
798  { }
799 
800  void addObject(T* object, const DtExtent& extent)
801  {
802  allObjects[object] = extent;
803  DtOctree<T>::addObject(object, extent);
804  }
805 
806  void removeObject(T* object)
807  {
808  allObjects.erase(object);
810  }
811 
812  void updatePositions()
813  {
814  std::map<T*, DtExtent>::iterator iter = allObjects.begin();
815  std::map<T*, DtExtent>::iterator end = allObjects.end();
816 
817  for(; iter != end; ++iter)
818  {
819  T* object = (*iter).first;
820  DtExtent& extent = (*iter).second;
821 
822  extent = object->roughExtent();
823  }
824 
826  }
827 
828  void visitObjects(const DtExtent& extent, DtSpatialSelectionFunctor &callback)
829  {
830  DtDebugOctreeFunctor debugFunctor(callback);
831  DtOctree<T>::visitObjects(extent, debugFunctor);
832 
833  std::map<T*, DtExtent>::iterator iter = allObjects.begin();
834  std::map<T*, DtExtent>::iterator end = allObjects.end();
835 
836  for(; iter != end; ++iter)
837  {
838  T* object = (*iter).first;
839  const DtExtent& objectExtent = (*iter).second;
840 
841  if (objectExtent.intersects(extent) && debugFunctor.mySeenObjects.count(object) == 0)
842  {
843  DEBUG("FAILED to visit object %s", OBJ_ARGS(object));
844  DEBUG_PUSH;
845  DEBUG("Old extent is " EXT_FMT, EXT_ARGS(objectExtent));
846  DEBUG("New extent is " EXT_FMT, EXT_ARGS(object->roughExtent()));
847  DEBUG_POP;
848  }
849  }
850  }
851 protected:
852  std::map<T*, DtExtent> allObjects;
853 };
854 
856 
857 static DtOctree<DtVrfObject>* createOctree(const DtExtent& extent)
858 {
859  return new DtOctreeDebugger<DtVrfObject>(extent);
860 }
861 
862 #else
863 
864 
865 
866 #endif
867 
869 
870 template<class T> void DtOctreeMember<T>::bind(DtOctreeNode<T>* node)
871 {
872  for (typename std::list<NodeBinding>::const_iterator it = myBindings.begin(); it != myBindings.end(); ++it)
873  {
874  if (node == (*it).first)
875  {
876  return;
877  }
878  }
879 
880  myBindings.push_back(NodeBinding(node, node->myMembers.insert(node->myMembers.end(), this)));
881 }
882 
883 template<class T> void DtOctreeMember<T>::unbind(DtOctreeNode<T>* node)
884 {
885  for (typename std::list<NodeBinding>::iterator it = myBindings.begin(); it != myBindings.end(); ++it)
886  {
887  if (node == (*it).first)
888  {
889  node->myMembers.erase((*it).second);
890  myBindings.erase(it);
891  return;
892  }
893  }
894 }
895 
896 template<class T> void DtOctreeMember<T>::unbind()
897 {
898  for (typename std::list<NodeBinding>::const_iterator it = myBindings.begin(); it != myBindings.end(); ++it)
899  {
900  (*it).first->myMembers.erase((*it).second);
901  }
902  myBindings.clear();
903 }
904 
905 #endif
unsigned int mySearchKey
Definition: octree.h:765
const double & x() const
Definition: point.h:188
static const int NUM_BRANCHES
The number of children of each node. Don&#39;t change this without rewriting everything.
Definition: octree.h:77
DtVrfObject is used to represent any type of simulated object (entities, aggregate, control objects) in a VR-Forces application.
Definition: vrfObject.h:215
virtual bool contains(const DtExtent &otherExtent) const
Determine if another extents box is entirely contained by this one.
virtual ~DtOctree()
Destructor. Deletes the octree and any members in it (though not the corresponding objects)...
Definition: octree.h:574
T * myObject
The object corresponding to this member.
Definition: octree.h:132
DtExtent myExtent
The extent of the member at the time it was added or last updated.
Definition: octree.h:135
void unbind()
Remove this member from all nodes.
Definition: octree.h:896
unsigned int mySearchKey
Definition: octree.h:144
static bool theBitmaskListCreated
Definition: octree.h:85
static void DEBUG(const char *fmt,...)
Definition: octree.h:69
bool coalesceEmptyChildren()
Look for any empty, childless nodes and coalesce them up to their parents.
Definition: octree.h:322
void split(int &depth)
Create child nodes to hold all the members that can go into child nodes, and move those members into ...
Definition: octree.h:467
bool removeObjectOutsideArea(T *object)
Definition: octree.h:740
DtOctreeNode(const DtExtent &region, const unsigned int depth)
Constructor. The extent covered by an octree node may not be changed once the octree is created...
Definition: octree.h:197
friend class DtOctreeDebugger
Definition: octree.h:528
MemberContainer myMemberMap
Mapping of T* pointers to DtOctreeMember objects in the tree.
Definition: octree.h:762
DtOctreeNode< T > * myRootNode
Root node of the octree.
Definition: octree.h:756
DtSpatialSelectionFunctorTemplate< T > SpatialSelectionFunctor
Definition: octree.h:556
#define EXT_FMT
Definition: octree.h:87
The DtSpatialVrfObjectManager is responsible for maintaining a spatial organization of all specified ...
Definition: spatialVrfObjectManager.h:34
DtOctree class.
Definition: octree.h:545
DtOctreeNode< T > ** myChildren
Child nodes of this node, if any.
Definition: octree.h:520
The DtExtent represents an axis-aligned 3d bounding box.
Definition: extent.h:43
virtual void addMember(DtOctreeMember< T > *member, int &depth)
Add a member to this node or one of its children (splitting the node if necessary).
Definition: octree.h:270
static const int MAX_BRANCH_DEPTH
Definition: octree.h:79
#define DEBUG_POP
Definition: octree.h:73
#define OBJ_ARGS(x)
Definition: octree.h:89
int numObjects()
Definition: octree.h:729
Octree support.
Definition: octree.h:41
double maxZ() const
double minZ() const
DtOctreeMember class.
Definition: octree.h:97
#define DEBUG_PUSH
Definition: octree.h:72
virtual bool operator()(const T *object)=0
Abstract function call interface.
DtOctree(const DtExtent &region)
Constructor. The extent covered by an octree may not be changed once the octree is created...
Definition: octree.h:559
bool intersects(const DtExtent &otherExtent) const
Determine if the two extents overlap (either partially or fully).
static const int MAX_NUM_NODES
Definition: octree.h:194
Definition: octree.h:149
int numObjectsOutside()
Definition: octree.h:734
bool containsObject(T *object)
Definition: octree.h:709
~DtOctreeNode()
Destructor. No DtOctreeMember objects are deleted.
Definition: octree.h:209
static DtOctree< const DtVrfObject > * createOctree(const DtExtent &extent)
Definition: spatialVrfObjectManager.h:295
void bind(DtOctreeNode< T > *node)
Add this member to the specified node.
Definition: octree.h:870
double minX() const
Access and/or mutate individual values.
const DtExtent myRegion
The region intersecting members contained by this node (and this node&#39;s children).
Definition: octree.h:509
virtual void addObject(T *object, const DtExtent &extent)
TODO: Add search key to outside octree list so that objects which fall completely outside the octree ...
Definition: octree.h:611
std::list< NodeBinding > myBindings
A list of the nodes this member is bound to, if any, and iterators to this member&#39;s position in the b...
Definition: octree.h:141
double minY() const
void setY(const double &y)
Definition: point.h:203
std::pair< DtOctreeNode< T > *, typename std::list< DtOctreeMember * >::iterator > NodeBinding
Definition: octree.h:137
const DtPoint myCenter
The center of myRegion.
Definition: octree.h:512
virtual void visitObjects(const unsigned int key, const DtExtent &extent, DtSpatialSelectionFunctorTemplate< T > &callback)
Call the given functor for every member that shares a node with the specified extent.
Definition: octree.h:235
const double & y() const
Definition: point.h:198
virtual void removeObject(T *object)
Remove a member from the octree.
Definition: octree.h:637
virtual ~DtSpatialSelectionFunctorTemplate()
Virtual Destructor which does nothing.
Definition: octree.h:153
std::list< DtOctreeMember< T > * >::iterator MemberIterator
Definition: octree.h:191
bool testKey(const unsigned int key)
Definition: octree.h:116
int numChildCandidates()
Return the number of members of this node that can go into child nodes.
Definition: octree.h:353
std::list< DtOctreeMember< T > * > MemberContainer
This class is only for use from DtOctree and DtOctreeDebugger.
Definition: octree.h:190
Contains the declaration of the DtExtent class.
static int theBitmaskList[NUM_BRANCHES]
Definition: octree.h:84
std::list< T * > OutsideAreaContainer
Definition: octree.h:553
virtual bool operator()(const DtVrfObject *object)=0
Abstract function call interface.
MemberContainer myMembers
Members which are in this node.
Definition: octree.h:524
unsigned int myDepth
Definition: octree.h:515
virtual void visitObjects(const DtExtent &extent, DtSpatialSelectionFunctorTemplate< T > &callback)
Call the given functor for every member that shares a node with the specified extent.
Definition: octree.h:588
double maxX() const
void setZ(const double &z)
Definition: point.h:213
virtual void updatePositions()
Process any updates to the objects&#39; positions that have happened since they were added to the octree...
Definition: octree.h:668
void setX(const double &x)
Definition: point.h:193
const double & z() const
Definition: point.h:208
double maxY() const
void addMemberToChild(DtOctreeMember< T > *member, int childIndex, int &depth)
Add a member to a child of this node, creating the child if necessary.
Definition: octree.h:433
std::map< T *, DtOctreeMember< T > * >::iterator MemberIterator
Definition: octree.h:551
std::map< T *, DtOctreeMember< T > * > MemberContainer
Container and iterator typedefs for the STL structures used.
Definition: octree.h:550
OutsideAreaContainer myObjectsOutsideArea
List of objects which are at least partially outside the octree&#39;s root extent.
Definition: octree.h:759
#define EXT_ARGS(x)
Definition: octree.h:88
std::list< T * >::iterator OutsideAreaIterator
Definition: octree.h:554
int intersectionMask(const DtExtent &extent) const
Returns a bit-mask where the ith bit is set iff the ith child of this node intersects the specified e...
Definition: octree.h:400
DtOctreeMember(T *object, const DtExtent &extent)
Definition: octree.h:100
Definition: point.h:34
static const int MAX_CHILD_MEMBERS
The maximum length of myChildMembers; see implementation notes at the top of the class.
Definition: octree.h:82
static int sNumNodes
Definition: octree.h:193
void unbind(DtOctreeNode< T > *node)
Remove this member from the specified node.
Definition: octree.h:883

Document ID: Generated on Tue Sep 21 17:42:52 EDT 2021 from SVN revision 234861
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)