VR-Forces 5.0.2 Developer's Guide
 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 #pragma once
30 
31 #include <stdarg.h>
32 #include <map>
33 #include <vector>
34 #include <tbb/atomic.h>
35 
36 #include <cmdLine/cmdStdOutput.h>
37 
38 #include "geometry/extent.h"
39 #include <boost/unordered_map.hpp>
40 #include <tbb/spin_rw_mutex.h>
41 #include <vrfutil/kinematicTools.h>
42 
43 template<class T> class DtOctreeNode;
44 
47 
48 #define OCTREE_DEBUG 0
49 
50 #if OCTREE_DEBUG
51 
52 static int octree_debug_level = 0;
53 
55 
56 static void DEBUG_OUTPUT(const char* fmt, ...)
57 {
58  char buffer[8192];
59  va_list ap;
60  va_start(ap, fmt);
61  vsprintf(buffer, fmt, ap);
62  va_end(ap);
63 
64  DtInfo("OCT %*s%s\n", octree_debug_level*2, "", buffer);
65 }
66 
67 # define DEBUG_PUSH do { octree_debug_level++; } while(0)
68 # define DEBUG_POP do { octree_debug_level--; } while(0)
69 #else
70 
71 static inline void DEBUG_OUTPUT(const char* fmt, ...)
72 { }
73 
74 # define DEBUG_PUSH do { } while(0)
75 # define DEBUG_POP do { } while(0)
76 #endif
77 
79 static const int NUM_BRANCHES = 8;
80 
81 static const int MAX_BRANCH_DEPTH = 12;
82 
84 static const int MAX_CHILD_MEMBERS = 16;
85 
87 static bool theBitmaskListCreated = false;
88 
89 #define EXT_FMT "[%lf, %lf, %lf] - [%lf, %lf, %lf]"
90 #define EXT_ARGS(x) (x).minX(), (x).minY(), (x).minZ(), (x).maxX(), (x).maxY(), (x).maxZ()
91 #define OBJ_ARGS(x) ((const char*) (x)->objectName())
92 
98 
99 template<class T> class DtOctreeMember
100 {
101 public:
102  DtOctreeMember(T* object, const DtExtent& extent)
103  : myObject(object)
104  , myExtent(extent)
105  {
106  }
107 
109  void bind(DtOctreeNode<T>* node);
110 
112  void unbind(DtOctreeNode<T>* node);
113 
115  void unbind();
116 
117  bool testKey(const unsigned int key)
118  {
119  unsigned int threadId = DtVRFGetThreadId();
120 
121  tbb::spin_rw_mutex::scoped_lock lock(mySearchKeysMutex, false);
122  boost::unordered_map<unsigned int, unsigned int>::const_iterator iter = mySearchKeys.find(threadId);
123 
124  if ((iter != mySearchKeys.end()) && (key == iter->second))
125  {
126  return false;
127  }
128 
129  lock.upgrade_to_writer();
131  mySearchKeys[threadId] = key;
132 
133  return true;
134  }
135 
136 protected:
137  template<class U> friend class DtOctreeNode;
138  template<class U> friend class DtOctree;
139 
142 
145 
146  typedef std::pair<DtOctreeNode<T>*, typename std::list<DtOctreeMember*>::iterator> NodeBinding;
147 
150  std::list<NodeBinding> myBindings;
151 
153  boost::unordered_map<unsigned int, unsigned int> mySearchKeys;
154  tbb::spin_rw_mutex mySearchKeysMutex;
155 };
156 
157 
158 template<class T>
160 {
161 public:
164 
166  virtual bool operator()(const T *object) = 0;
167 };
168 
195 
196 template<class T> class DtOctreeNode
197 {
198 protected:
199 
200  typedef std::list<DtOctreeMember<T>*> MemberContainer;
201  typedef typename std::list<DtOctreeMember<T>*>::iterator MemberIterator;
202 
203  static int sNumNodes;
204  static const int MAX_NUM_NODES = 1000;
205 
207  DtOctreeNode(const DtExtent &region, const unsigned int depth)
208  : myRegion(region)
209  , myDepth(depth)
210  , myCenter(region.center())
211  , myChildren(0)
212  {
213  DEBUG_OUTPUT("Create node " EXT_FMT, EXT_ARGS(region));
214 
215  ++sNumNodes;
216  }
217 
220  {
221  DEBUG_OUTPUT("Destroy node " EXT_FMT, EXT_ARGS(myRegion));
222  DEBUG_PUSH;
223 
224  if (myChildren)
225  {
226  for(int i=0; i<NUM_BRANCHES; i++)
227  delete myChildren[i];
228  }
229  delete[] myChildren;
230 
231  DEBUG_POP;
232 
233  --sNumNodes;
234  }
235 
244 
245  virtual void visitObjects(const unsigned int key, const DtExtent& extent, DtSpatialSelectionFunctorTemplate<T> &callback)
246  {
247  DEBUG_OUTPUT(EXT_FMT "::visit(" EXT_FMT ", cb)", EXT_ARGS(myRegion), EXT_ARGS(extent));
248  DEBUG_PUSH;
249 
250  MemberIterator iter, end;
251 
252  for(iter = myMembers.begin(), end = myMembers.end(); iter != end; ++iter)
253  {
254  DEBUG_OUTPUT("Member %s " EXT_FMT, OBJ_ARGS((*iter)->myObject), EXT_ARGS((*iter)->myExtent));
255  if ((*iter)->testKey(key))
256  {
257  if (!(*iter)->myObject->isDeleted() && callback((*iter)->myObject))
258  {
259  break;
260  }
261  }
262  else
263  {
265  return;
266  }
267  }
268 
269  if (myChildren)
270  {
271  int mask = intersectionMask(extent);
272  for(int i = 0; i < NUM_BRANCHES; ++i)
273  {
274  if (myChildren[i] && (mask & theBitmaskList[i]))
275  {
276  myChildren[i]->visitObjects(key, extent, callback);
277  }
278  }
279  }
280 
281  DEBUG_POP;
282  }
283 
285  virtual void addMember(DtOctreeMember<T>* member, int& depth)
286  {
287  depth++;
288 
289  DEBUG_OUTPUT(EXT_FMT "::addMember(%s)", EXT_ARGS(myRegion), OBJ_ARGS(member->myObject));
290  DEBUG_PUSH;
291 
292 #if OCTREE_DEBUG
293  if (!myRegion.contains(member->myExtent))
294  {
295  DEBUG_OUTPUT("FAIL! " EXT_FMT " does not contain " EXT_FMT, EXT_ARGS(myRegion), EXT_ARGS(member->myExtent));
296  }
297 #endif
298 
299  if (myChildren)
300  {
301  int mask = intersectionMask(member->myExtent);
302 
303  if (mask == 0xff)
304  {
306  member->bind(this);
307  }
308  else
309  {
310  for (int childIndex = 0; childIndex < NUM_BRANCHES; ++childIndex)
311  {
312  if (mask & theBitmaskList[childIndex])
313  {
314  addMemberToChild(member, childIndex, depth);
315  }
316  }
317  }
318  }
319  else
320  {
321  DEBUG_OUTPUT("add as child member (not enough child members yet)");
322 
323  member->bind(this);
324 
325  //if (numChildCandidates() >= MAX_CHILD_MEMBERS && myDepth < MAX_BRANCH_DEPTH)
326  if (numChildCandidates() >= MAX_CHILD_MEMBERS && sNumNodes < MAX_NUM_NODES - 8)
327  {
328  split(depth);
329  }
330  }
331 
332  DEBUG_POP;
333  }
334 
338  {
339  DEBUG_OUTPUT(EXT_FMT "::coalesceEmptyChildren()", EXT_ARGS(myRegion));
340  DEBUG_PUSH;
341 
342  bool retVal = (myMembers.size() == 0);
343 
344  if (myChildren)
345  {
346  for(int i=0; i<NUM_BRANCHES; i++)
347  {
348  if (myChildren[i])
349  {
351  {
352  DEBUG_OUTPUT("Deleting child %d\n", i);
353  delete myChildren[i];
354  myChildren[i] = 0;
355  } else {
356  retVal = false;
357  }
358  }
359  }
360  }
361 
362  DEBUG_POP;
363 
364  return retVal;
365  }
366 
369  {
370  double retVal = 0;
371  DtExtent matchExtent;
372 
373  MemberIterator iter, end;
374  for(iter = myMembers.begin(), end = myMembers.end(); iter != end; ++iter)
375  {
376  double numBuckets = 0;
377  int mask = intersectionMask((*iter)->myExtent);
378 
381  if ((*iter)->myExtent == matchExtent)
382  {
383  continue;
384  }
385 
386  matchExtent = (*iter)->myExtent;
387 
388  if (mask != 0xff)
389  {
390  for(int childIndex = 0; childIndex < NUM_BRANCHES; ++childIndex)
391  {
392  if (mask & theBitmaskList[childIndex])
393  {
394  numBuckets++;
395  }
396  }
397 
398  retVal += (1.0 / numBuckets);
399 
400  if (retVal >= MAX_CHILD_MEMBERS)
401  {
402  break;
403  }
404  }
405  }
406 
407  return retVal;
408  }
409 
415  int intersectionMask(const DtExtent &extent) const
416  {
417  int result = 0xff;
418 
419  if (extent.minX() >= myCenter.x())
420  result &= 0xf0;
421  if (extent.maxX() <= myCenter.x())
422  result &= 0x0f;
423 
424  if (extent.minY() >= myCenter.y())
425  result &= 0xcc;
426  if (extent.maxY() <= myCenter.y())
427  result &= 0x33;
428 
429  if (extent.minZ() >= myCenter.z())
430  result &= 0xaa;
431  if (extent.maxZ() <= myCenter.z())
432  result &= 0x55;
433 
434  if (result == 0)
435  {
439  return 0xff;
440  }
441 
442  return result;
443  }
444 
448  void addMemberToChild(DtOctreeMember<T>* member, int childIndex, int& depth)
449  {
450  DEBUG_OUTPUT(EXT_FMT "::addMemberToChild(%s, %d)", EXT_ARGS(myRegion), OBJ_ARGS(member->myObject), childIndex);
451  DEBUG_PUSH;
452 
453  if (myChildren[childIndex] == 0)
454  {
455  DtPoint childCorner;
456 
457  if (childIndex & 4)
458  childCorner.setX(myRegion.maxX());
459  else
460  childCorner.setX(myRegion.minX());
461 
462  if (childIndex & 2)
463  childCorner.setY(myRegion.maxY());
464  else
465  childCorner.setY(myRegion.minY());
466 
467  if (childIndex & 1)
468  childCorner.setZ(myRegion.maxZ());
469  else
470  childCorner.setZ(myRegion.minZ());
471 
472  myChildren[childIndex] = new DtOctreeNode(DtExtent(childCorner, myCenter), myDepth + 1);
473  }
474 
475  myChildren[childIndex]->addMember(member, depth);
476 
477  DEBUG_POP;
478  }
479 
482  void split(int& depth)
483  {
484  DEBUG_OUTPUT(EXT_FMT "::split()", EXT_ARGS(myRegion));
485  DEBUG_PUSH;
486 
488 
489  for(int i=0; i<NUM_BRANCHES; i++)
490  {
491  myChildren[i] = 0;
492  }
493 
494  MemberIterator iter, next, end;
495  for(iter = myMembers.begin(), end = myMembers.end(); iter != end; iter = next)
496  {
497  next = iter;
498  ++next;
499 
500  DtOctreeMember<T>* member = *iter;
501 
502  int mask = intersectionMask(member->myExtent);
503 
506  if (mask != 0xff)
507  {
508  member->unbind(this);
509 
510  for(int childIndex = 0; childIndex < NUM_BRANCHES; ++childIndex)
511  {
512  if (mask & theBitmaskList[childIndex])
513  {
514  addMemberToChild(member, childIndex, depth);
515  }
516  }
517  }
518  }
519 
520  DEBUG_POP;
521  }
522 
525 
528 
529 
530  unsigned int myDepth;
531 
536 
540 
541  template<class U> friend class DtOctree;
542  template<class U> friend class DtOctreeMember;
543  template<class U> friend class DtOctreeDebugger;
544 };
545 
546 template<class T> int DtOctreeNode<T>::sNumNodes = 0;
547 
559 
560 template<class T> class DtOctree
561 {
562 public:
563 
565  typedef std::map<T*, DtOctreeMember<T>*> MemberContainer;
566  typedef typename std::map<T*, DtOctreeMember<T>*>::iterator MemberIterator;
567 
568  typedef std::list<T*> OutsideAreaContainer;
569  typedef typename std::list<T*>::iterator OutsideAreaIterator;
570 
572 
574  DtOctree(const DtExtent &region) : mySearchKey(0)
575  {
576  myRootNode = new DtOctreeNode<T>(region, 0);
577 
578  if (!theBitmaskListCreated)
579  {
580  theBitmaskListCreated = true;
581  for (int childIndex = 0; childIndex < NUM_BRANCHES; ++childIndex)
582  {
583  theBitmaskList[childIndex] = (1 << childIndex);
584  }
585  }
586  }
587 
589  virtual ~DtOctree()
590  {
591  delete myRootNode;
592 
593  MemberIterator iter, end;
594  for(iter = myMemberMap.begin(), end = myMemberMap.end(); iter != end; ++iter)
595  {
596  delete (*iter).second;
597  }
598  }
599 
603  virtual void visitObjects(const DtExtent& extent, DtSpatialSelectionFunctorTemplate<T> &callback)
604  {
605  tbb::spin_rw_mutex::scoped_lock lock(myMutex, false);
606  ++mySearchKey;
607 
611  if (myRootNode->myRegion.intersects(extent))
612  {
613  myRootNode->visitObjects(mySearchKey, extent, callback);
614  }
615 
616  OutsideAreaIterator iter, end;
617  for(iter = myObjectsOutsideArea.begin(), end = myObjectsOutsideArea.end(); iter != end; ++iter)
618  {
619  callback(*iter);
620  }
621  }
622 
625 
627  virtual void addObject(T* object, const DtExtent& extent)
628  {
629  DEBUG_OUTPUT("DtOctree::addObject(%s, " EXT_FMT ")", OBJ_ARGS(object), EXT_ARGS(extent));
630  DEBUG_PUSH;
631 
632  tbb::spin_rw_mutex::scoped_lock lock(myMutex);
633  if (myRootNode->myRegion.contains(extent))
634  {
635  DtOctreeMember<T>* newMember = new DtOctreeMember<T>(object, extent);
636  int depth = 0;
637 
638  myRootNode->addMember(newMember, depth);
639  myMemberMap[object] = newMember;
640 
642  }
643  else
644  {
645  DtWarn("Member %s (" EXT_FMT ") added outside octree (" EXT_FMT ")\n",
646  OBJ_ARGS(object), EXT_ARGS(extent), EXT_ARGS(myRootNode->myRegion));
647  myObjectsOutsideArea.push_back(object);
648  }
649 
650  DEBUG_POP;
651  }
652 
654  virtual void removeObject(T* object, bool needsLock = true)
655  {
656  DEBUG_OUTPUT("DtOctree::removeObject(%s)", OBJ_ARGS(object));
657  DEBUG_PUSH;
658 
659  tbb::spin_rw_mutex::scoped_lock* lock = 0;
660 
661  if (needsLock)
662  {
663  lock = new tbb::spin_rw_mutex::scoped_lock(myMutex, true);
664  }
665 
666  MemberIterator iter;
667  iter = myMemberMap.find(object);
668  if (iter != myMemberMap.end())
669  {
670  DtOctreeMember<T>* member = (*iter).second;
671  member->unbind();
672  myMemberMap.erase(iter);
673  delete member;
674  }
675  else if (!removeObjectOutsideArea(object))
676  {
680 
681  //DtWarn("Tried to remove %s from octree, but couldn't find!\n", OBJ_ARGS(object));
682  }
683 
684  DEBUG_POP;
685 
686  if (lock)
687  {
688  delete lock;
689  }
690  }
691 
697  virtual void updatePositions()
698  {
699  tbb::spin_rw_mutex::scoped_lock lock(myMutex, false);
700  MemberIterator cur = myMemberMap.begin();
701  while (cur != myMemberMap.end())
702  {
703  MemberIterator iter = cur++;
704 
705  T* object = (*iter).first;
706 
707  if (object->isValid())
708  {
709  DtOctreeMember<T>* member = (*iter).second;
710  DtExtent roughExtent = object->extent();
711 
713  if (member->myExtent != roughExtent)
714  {
715  member->myExtent = roughExtent;
716 
717  if (!myRootNode->myRegion.contains(member->myExtent))
718  {
720 
721  DtWarn("Object %s (" EXT_FMT ") moving outside octree (" EXT_FMT ")\n",
722  OBJ_ARGS(object), EXT_ARGS(member->myExtent), EXT_ARGS(myRootNode->myRegion));
723  lock.upgrade_to_writer();
724  removeObject(object, false);
725  myObjectsOutsideArea.push_back(object);
726  lock.downgrade_to_reader();
727  }
728  else
729  {
731 
732  member->unbind();
733  int depth = 0;
734 
735  myRootNode->addMember(member, depth);
737  }
738  }
739  }
740  }
741 
742  myRootNode->coalesceEmptyChildren();
743  }
744 
745  bool containsObject(T* object)
746  {
747  tbb::spin_rw_mutex::scoped_lock lock(myMutex, false);
748  if (myMemberMap.find(object) != myMemberMap.end())
749  {
750  return true;
751  }
752  else
753  {
754  OutsideAreaIterator iter, end;
755  for(iter = myObjectsOutsideArea.begin(), end = myObjectsOutsideArea.end(); iter != end; ++iter)
756  {
757  if (*iter == object)
758  {
759  return true;
760  }
761  }
762  }
763  return false;
764  }
765 
767  {
768  return myMemberMap.size() + myObjectsOutsideArea.size();
769  }
770 
772  {
773  return myObjectsOutsideArea.size();
774  }
775 
776 protected:
777  bool removeObjectOutsideArea(T* object)
778  {
779  OutsideAreaIterator iter, end;
780  for(iter = myObjectsOutsideArea.begin(), end = myObjectsOutsideArea.end(); iter != end; ++iter)
781  {
782  if (*iter == object)
783  {
784  myObjectsOutsideArea.erase(iter);
785  return true;
786  }
787  }
788 
789  return false;
790  }
791 
792  tbb::spin_rw_mutex myMutex;
795 
798 
801 
803  tbb::atomic<unsigned int> mySearchKey;
804 };
805 
809 
810 #if OCTREE_DEBUG
811 
812 class DtDebugOctreeFunctor : public DtSpatialSelectionFunctor
813 {
814 public:
815  DtDebugOctreeFunctor(DtSpatialSelectionFunctor& inner)
816  : myInner(inner)
817  {
818  }
819 
821  virtual bool operator()(const DtSimObject* object)
822  {
823  mySeenObjects.insert(object);
824  return myInner(object);
825  }
826 
827  std::set<const DtSimObject*> mySeenObjects;
828  DtSpatialSelectionFunctor& myInner;
829 };
830 
831 template<class T> class DtOctreeDebugger : public DtOctree<T>
832 {
833 public:
834  DtOctreeDebugger(const DtExtent& extent)
835  : DtOctree<T>(extent)
836  { }
837 
838  void addObject(T* object, const DtExtent& extent)
839  {
840  allObjects[object] = extent;
841  DtOctree<T>::addObject(object, extent);
842  }
843 
844  void removeObject(T* object)
845  {
846  allObjects.erase(object);
848  }
849 
850  void updatePositions()
851  {
852  std::map<T*, DtExtent>::iterator iter = allObjects.begin();
853  std::map<T*, DtExtent>::iterator end = allObjects.end();
854 
855  for(; iter != end; ++iter)
856  {
857  T* object = (*iter).first;
858  DtExtent& extent = (*iter).second;
859 
860  extent = object->roughExtent();
861  }
862 
864  }
865 
866  void visitObjects(const DtExtent& extent, DtSpatialSelectionFunctor &callback)
867  {
868  DtDebugOctreeFunctor debugFunctor(callback);
869  DtOctree<T>::visitObjects(extent, debugFunctor);
870 
871  std::map<T*, DtExtent>::iterator iter = allObjects.begin();
872  std::map<T*, DtExtent>::iterator end = allObjects.end();
873 
874  for(; iter != end; ++iter)
875  {
876  T* object = (*iter).first;
877  const DtExtent& objectExtent = (*iter).second;
878 
879  if (objectExtent.intersects(extent) && debugFunctor.mySeenObjects.count(object) == 0)
880  {
881  DEBUG_OUTPUT("FAILED to visit object %s", OBJ_ARGS(object));
882  DEBUG_PUSH;
883  DEBUG_OUTPUT("Old extent is " EXT_FMT, EXT_ARGS(objectExtent));
884  DEBUG_OUTPUT("New extent is " EXT_FMT, EXT_ARGS(object->roughExtent()));
885  DEBUG_POP;
886  }
887  }
888  }
889 protected:
890  std::map<T*, DtExtent> allObjects;
891 };
892 
894 
895 static DtOctree<DtSimObject>* createOctree(const DtExtent& extent)
896 {
897  return new DtOctreeDebugger<DtSimObject>(extent);
898 }
899 
900 #else
901 
902 
903 
904 #endif
905 
907 
908 template<class T> void DtOctreeMember<T>::bind(DtOctreeNode<T>* node)
909 {
910  for (typename std::list<NodeBinding>::const_iterator it = myBindings.begin(); it != myBindings.end(); ++it)
911  {
912  if (node == (*it).first)
913  {
914  return;
915  }
916  }
917 
918  myBindings.push_back(NodeBinding(node, node->myMembers.insert(node->myMembers.end(), this)));
919 }
920 
921 template<class T> void DtOctreeMember<T>::unbind(DtOctreeNode<T>* node)
922 {
923  for (typename std::list<NodeBinding>::iterator it = myBindings.begin(); it != myBindings.end(); ++it)
924  {
925  if (node == (*it).first)
926  {
927  node->myMembers.erase((*it).second);
928  myBindings.erase(it);
929  return;
930  }
931  }
932 }
933 
934 template<class T> void DtOctreeMember<T>::unbind()
935 {
936  for (typename std::list<NodeBinding>::const_iterator it = myBindings.begin(); it != myBindings.end(); ++it)
937  {
938  (*it).first->myMembers.erase((*it).second);
939  }
940  myBindings.clear();
941 }
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:79
virtual bool contains(const DtExtent &otherExtent) const
Determine if another extents box is entirely contained by this one. On the border counts as &quot;containe...
virtual ~DtOctree()
Destructor. Deletes the octree and any members in it (though not the corresponding objects)...
Definition: octree.h:589
T * myObject
The object corresponding to this member.
Definition: octree.h:141
DtExtent myExtent
The extent of the member at the time it was added or last updated.
Definition: octree.h:144
void unbind()
Remove this member from all nodes.
Definition: octree.h:934
static bool theBitmaskListCreated
Definition: octree.h:87
bool coalesceEmptyChildren()
Look for any empty, childless nodes and coalesce them up to their parents. Returns true if this node ...
Definition: octree.h:337
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:482
bool removeObjectOutsideArea(T *object)
Definition: octree.h:777
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:207
friend class DtOctreeDebugger
Definition: octree.h:543
MemberContainer myMemberMap
Mapping of T* pointers to DtOctreeMember objects in the tree.
Definition: octree.h:800
DtOctreeNode< T > * myRootNode
Root node of the octree.
Definition: octree.h:794
DtSpatialSelectionFunctorTemplate< T > SpatialSelectionFunctor
Definition: octree.h:571
#define EXT_FMT
Definition: octree.h:89
tbb::spin_rw_mutex myMutex
Definition: octree.h:792
The DtSpatialVrfObjectManager is responsible for maintaining a spatial organization of all specified ...
Definition: spatialVrfObjectManager.h:31
DtOctree class.
Definition: octree.h:560
DtOctreeNode< T > ** myChildren
Child nodes of this node, if any. This is NULL for a childless node. For nodes with children...
Definition: octree.h:535
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:285
static const int MAX_BRANCH_DEPTH
Definition: octree.h:81
static void DEBUG_OUTPUT(const char *fmt,...)
Definition: octree.h:71
#define DEBUG_POP
Definition: octree.h:75
tbb::atomic< unsigned int > mySearchKey
Definition: octree.h:803
#define OBJ_ARGS(x)
Definition: octree.h:91
int numObjects()
Definition: octree.h:766
Octree support.
Definition: octree.h:43
double maxZ() const
Access and/or mutate individual values.
double minZ() const
Access and/or mutate individual values.
DtOctreeMember class.
Definition: octree.h:99
#define DEBUG_PUSH
Definition: octree.h:74
DT_DLL_vrfutil unsigned int DtVRFGetThreadId()
Gets the current thread id.
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:574
bool intersects(const DtExtent &otherExtent) const
Determine if the two extents overlap (either partially or fully). A shared &quot;wall&quot; counts as intersect...
static const int MAX_NUM_NODES
Definition: octree.h:204
Definition: octree.h:159
int numObjectsOutside()
Definition: octree.h:771
bool containsObject(T *object)
Definition: octree.h:745
~DtOctreeNode()
Destructor. No DtOctreeMember objects are deleted.
Definition: octree.h:219
static DtOctree< const DtSimObject > * createOctree(const DtExtent &extent)
Definition: spatialVrfObjectManager.h:295
void bind(DtOctreeNode< T > *node)
Add this member to the specified node.
Definition: octree.h:908
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:524
boost::unordered_map< unsigned int, unsigned int > mySearchKeys
Definition: octree.h:153
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:627
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:150
double minY() const
Access and/or mutate individual values.
void setY(const double &y)
Definition: point.h:203
virtual bool operator()(const DtSimObject *object)=0
Abstract function call interface.
tbb::spin_rw_mutex mySearchKeysMutex
Definition: octree.h:154
std::pair< DtOctreeNode< T > *, typename std::list< DtOctreeMember * >::iterator > NodeBinding
Definition: octree.h:146
const DtPoint myCenter
The center of myRegion.
Definition: octree.h:527
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. This does not test for exact intersection; it only returns a list of objects that might intersect the given extent.
Definition: octree.h:245
const double & y() const
Definition: point.h:198
virtual ~DtSpatialSelectionFunctorTemplate()
Virtual Destructor which does nothing.
Definition: octree.h:163
std::list< DtOctreeMember< T > * >::iterator MemberIterator
Definition: octree.h:201
bool testKey(const unsigned int key)
Definition: octree.h:117
Represents a single simulation object in the exercise. Object may be VRF simulation, or non-VRF simulated, and may be simulated by the local sim engine, or by a remote sim engine. Only public (external) state of the object is available. All data is read-only. All access to data of the object is thread safe within the simulation frame.
Definition: simObject.h:79
int numChildCandidates()
Return the number of members of this node that can go into child nodes.
Definition: octree.h:368
std::list< DtOctreeMember< T > * > MemberContainer
This class is only for use from DtOctree and DtOctreeDebugger.
Definition: octree.h:200
Contains the declaration of the DtExtent class.
static int theBitmaskList[NUM_BRANCHES]
Definition: octree.h:86
std::list< T * > OutsideAreaContainer
Definition: octree.h:568
MemberContainer myMembers
Members which are in this node. If myChildren is not NULL, then this must not contain any members tha...
Definition: octree.h:539
unsigned int myDepth
Definition: octree.h:530
virtual void visitObjects(const DtExtent &extent, DtSpatialSelectionFunctorTemplate< T > &callback)
Call the given functor for every member that shares a node with the specified extent. This does not test for exact intersection; it only iterates over any objects that might intersect the given extent (i.e. there may be extras).
Definition: octree.h:603
double maxX() const
Access and/or mutate individual values.
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:697
void setX(const double &x)
Definition: point.h:193
const double & z() const
Definition: point.h:208
double maxY() const
Access and/or mutate individual values.
virtual void removeObject(T *object, bool needsLock=true)
Remove a member from the octree.
Definition: octree.h:654
void addMemberToChild(DtOctreeMember< T > *member, int childIndex, int &depth)
Add a member to a child of this node, creating the child if necessary. This function will call addMem...
Definition: octree.h:448
std::map< T *, DtOctreeMember< T > * >::iterator MemberIterator
Definition: octree.h:566
std::map< T *, DtOctreeMember< T > * > MemberContainer
Container and iterator typedefs for the STL structures used.
Definition: octree.h:565
OutsideAreaContainer myObjectsOutsideArea
List of objects which are at least partially outside the octree&#39;s root extent.
Definition: octree.h:797
#define EXT_ARGS(x)
Definition: octree.h:90
std::list< T * >::iterator OutsideAreaIterator
Definition: octree.h:569
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:415
DtOctreeMember(T *object, const DtExtent &extent)
Definition: octree.h:102
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:84
static int sNumNodes
Definition: octree.h:203
void unbind(DtOctreeNode< T > *node)
Remove this member from the specified node.
Definition: octree.h:921

Document ID: Generated on Sun Dec 4 20:22:03 EST 2022 from SVN revision 249613
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)