lloctree.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  1. /**
  2. * @file lloctree.h
  3. * @brief Octree declaration.
  4. *
  5. * $LicenseInfo:firstyear=2005&license=viewergpl$
  6. *
  7. * Copyright (c) 2005-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_LLOCTREE_H
  33. #define LL_LLOCTREE_H
  34. #include <vector>
  35. #include "llpointer.h"
  36. #include "llrefcount.h"
  37. #include "llvector3.h"
  38. #include "llxform.h"
  39. #define NO_CHILD_NODES 255
  40. extern U32 gOctreeMaxCapacity;
  41. extern F32 gOctreeMinSize;
  42. extern LLVector4a gOctreeMaxMag;
  43. ///////////////////////////////////////////////////////////////////////////////
  44. // These classes used to be defined in a different lltreenode.h header but are
  45. // only used by LLOctree* classes defined in this header... HB
  46. ///////////////////////////////////////////////////////////////////////////////
  47. template <class T> class LLTreeNode;
  48. template <class T> class LLTreeTraveler;
  49. template <class T> class LLTreeListener;
  50. template <class T>
  51. class LLTreeListener : public LLRefCount
  52. {
  53. public:
  54. LL_VOLUME_AREANA_NEW_DELETE
  55. virtual void handleInsertion(const LLTreeNode<T>* node, T* data) = 0;
  56. virtual void handleRemoval(const LLTreeNode<T>* node, T* data) = 0;
  57. virtual void handleDestruction(const LLTreeNode<T>* node) = 0;
  58. virtual void handleStateChange(const LLTreeNode<T>* node) = 0;
  59. };
  60. template <class T>
  61. class LLTreeNode
  62. {
  63. public:
  64. LL_VOLUME_AREANA_NEW_DELETE
  65. virtual ~LLTreeNode()
  66. {
  67. destroyListeners();
  68. }
  69. virtual bool insert(T* data)
  70. {
  71. for (U32 i = 0, count = mListeners.size(); i < count; ++i)
  72. {
  73. if (mListeners[i].notNull())
  74. {
  75. mListeners[i]->handleInsertion(this, data);
  76. }
  77. }
  78. return true;
  79. }
  80. virtual bool remove(T* data)
  81. {
  82. return true;
  83. }
  84. virtual void notifyRemoval(T* data)
  85. {
  86. for (U32 i = 0, count = mListeners.size(); i < count; ++i)
  87. {
  88. if (mListeners[i].notNull())
  89. {
  90. mListeners[i]->handleRemoval(this, data);
  91. }
  92. }
  93. }
  94. LL_INLINE virtual U32 getListenerCount()
  95. {
  96. return mListeners.size();
  97. }
  98. LL_INLINE virtual LLTreeListener<T>* getListener(U32 index) const
  99. {
  100. if (index < mListeners.size())
  101. {
  102. return mListeners[index];
  103. }
  104. return NULL;
  105. }
  106. LL_INLINE virtual void addListener(LLTreeListener<T>* listener)
  107. {
  108. mListeners.push_back(listener);
  109. }
  110. protected:
  111. void destroyListeners()
  112. {
  113. for (U32 i = 0, count = mListeners.size(); i < count; ++i)
  114. {
  115. if (mListeners[i].notNull())
  116. {
  117. mListeners[i]->handleDestruction(this);
  118. }
  119. }
  120. mListeners.clear();
  121. }
  122. public:
  123. std::vector<LLPointer<LLTreeListener<T> > > mListeners;
  124. };
  125. template <class T>
  126. class LLTreeTraveler
  127. {
  128. public:
  129. virtual ~LLTreeTraveler() = default;
  130. virtual void traverse(const LLTreeNode<T>* node) = 0;
  131. virtual void visit(const LLTreeNode<T>* node) = 0;
  132. };
  133. ///////////////////////////////////////////////////////////////////////////////
  134. template <class T, typename T_PTR> class _LLOctreeNode;
  135. // This version takes ownership of inserted pointers. It deletes elements
  136. // removed from the tree.
  137. template<class T>
  138. using LLOctreeNode = _LLOctreeNode< T, LLPointer<T> >;
  139. // This version does not take ownership of inserted pointers. The API user is
  140. // responsible for managing the lifecycle of what it provides to the tree.
  141. template<class T>
  142. using LLOctreeNodeNoOwnership = _LLOctreeNode<T, T*>;
  143. template <class T, typename T_PTR>
  144. class _LLOctreeListener : public LLTreeListener<T>
  145. {
  146. public:
  147. typedef LLTreeListener<T> BaseType;
  148. typedef _LLOctreeNode<T, T_PTR> oct_node;
  149. virtual void handleChildAddition(const oct_node* parent,
  150. oct_node* child) = 0;
  151. virtual void handleChildRemoval(const oct_node* parent,
  152. const oct_node* child) = 0;
  153. };
  154. template<class T>
  155. using LLOctreeListener = _LLOctreeListener<T, LLPointer<T> >;
  156. template<class T>
  157. using LLOctreeListenerNoOwnership = _LLOctreeListener<T, T*>;
  158. template <class T, typename T_PTR>
  159. class _LLOctreeTraveler
  160. {
  161. public:
  162. LL_VOLUME_AREANA_NEW_DELETE
  163. virtual ~_LLOctreeTraveler() = default;
  164. virtual void traverse(const _LLOctreeNode<T, T_PTR>* nodep)
  165. {
  166. if (nodep)
  167. {
  168. nodep->accept(this);
  169. for (U32 i = 0; i < nodep->getChildCount(); ++i)
  170. {
  171. traverse(nodep->getChild(i));
  172. }
  173. }
  174. }
  175. virtual void visit(const _LLOctreeNode<T, T_PTR>* branch) = 0;
  176. };
  177. template<class T>
  178. using LLOctreeTraveler = _LLOctreeTraveler<T, LLPointer<T> >;
  179. template<class T>
  180. using LLOctreeTravelerNoOwnership = _LLOctreeTraveler<T, T*>;
  181. template <class T, typename T_PTR>
  182. class _LLOctreeTravelerDepthFirst : public _LLOctreeTraveler<T, T_PTR>
  183. {
  184. public:
  185. void traverse(const _LLOctreeNode<T, T_PTR>* nodep) override
  186. {
  187. if (nodep)
  188. {
  189. for (U32 i = 0; i < nodep->getChildCount(); ++i)
  190. {
  191. traverse(nodep->getChild(i));
  192. }
  193. nodep->accept(this);
  194. }
  195. }
  196. };
  197. template<class T>
  198. using LLOctreeTravelerDepthFirst = _LLOctreeTravelerDepthFirst<T, LLPointer<T> >;
  199. template<class T>
  200. using LLOctreeTravelerDepthFirstNoOwnership = _LLOctreeTravelerDepthFirst<T, T* >;
  201. template <class T, typename T_PTR>
  202. class alignas(16) _LLOctreeNode : public LLTreeNode<T>
  203. {
  204. public:
  205. typedef _LLOctreeTraveler<T, T_PTR> oct_traveler;
  206. typedef LLTreeTraveler<T> tree_traveler;
  207. typedef std::vector<T_PTR> element_list;
  208. typedef typename element_list::iterator element_iter;
  209. typedef typename element_list::const_iterator const_element_iter;
  210. typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
  211. typedef _LLOctreeNode<T, T_PTR>** child_list;
  212. typedef _LLOctreeNode<T, T_PTR>** child_iter;
  213. typedef LLTreeNode<T> BaseType;
  214. typedef _LLOctreeNode<T, T_PTR> oct_node;
  215. typedef _LLOctreeListener<T, T_PTR> oct_listener;
  216. _LLOctreeNode(const LLVector4a& center, const LLVector4a& size,
  217. BaseType* parent, U8 octant = NO_CHILD_NODES)
  218. : mParent((oct_node*)parent),
  219. mOctant(octant),
  220. mCenter(center),
  221. mSize(size)
  222. {
  223. llassert(size[0] >= gOctreeMinSize * 0.5f);
  224. updateMinMax();
  225. if (mOctant == NO_CHILD_NODES && mParent)
  226. {
  227. mOctant = ((oct_node*)mParent)->getOctant(mCenter);
  228. }
  229. clearChildren();
  230. }
  231. ~_LLOctreeNode() override
  232. {
  233. BaseType::destroyListeners();
  234. for (U32 i = 0, count = getElementCount(); i < count; ++i)
  235. {
  236. if (mData[i])
  237. {
  238. mData[i]->setBinIndex(-1);
  239. mData[i] = NULL;
  240. }
  241. }
  242. mData.clear();
  243. for (U32 i = 0; i < getChildCount(); ++i)
  244. {
  245. delete getChild(i);
  246. }
  247. }
  248. LL_INLINE const BaseType* getParent() const { return mParent; }
  249. LL_INLINE void setParent(BaseType* parent) { mParent = (oct_node*)parent; }
  250. LL_INLINE const LLVector4a& getCenter() const { return mCenter; }
  251. LL_INLINE const LLVector4a& getSize() const { return mSize; }
  252. LL_INLINE void setCenter(const LLVector4a& center) { mCenter = center; }
  253. LL_INLINE void setSize(const LLVector4a& size) { mSize = size; }
  254. LL_INLINE oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); }
  255. LL_INLINE U8 getOctant() const { return mOctant; }
  256. LL_INLINE const oct_node* getOctParent() const { return (const oct_node*)getParent(); }
  257. LL_INLINE oct_node* getOctParent() { return (oct_node*)getParent(); }
  258. U8 getOctant(const LLVector4a& pos) const // get the octant pos is in
  259. {
  260. return (U8)(pos.greaterThan(mCenter).getGatheredBits() & 0x7);
  261. }
  262. LL_INLINE bool isInside(const LLVector4a& pos, F32 rad) const
  263. {
  264. return rad <= mSize[0] * 2.f && isInside(pos);
  265. }
  266. LL_INLINE bool isInside(T* data) const
  267. {
  268. return isInside(data->getPositionGroup(), data->getBinRadius());
  269. }
  270. bool isInside(const LLVector4a& pos) const
  271. {
  272. if (pos.greaterThan(mMax).getGatheredBits() & 0x7)
  273. {
  274. return false;
  275. }
  276. return !(pos.lessEqual(mMin).getGatheredBits() & 0x7);
  277. }
  278. void updateMinMax()
  279. {
  280. mMax.setAdd(mCenter, mSize);
  281. mMin.setSub(mCenter, mSize);
  282. }
  283. LL_INLINE oct_listener* getOctListener(U32 index)
  284. {
  285. return (oct_listener*)BaseType::getListener(index);
  286. }
  287. LL_INLINE bool contains(T* xform)
  288. {
  289. return contains(xform->getBinRadius());
  290. }
  291. bool contains(F32 radius)
  292. {
  293. if (!mParent)
  294. {
  295. // Root node contains nothing
  296. return false;
  297. }
  298. F32 size = mSize[0];
  299. F32 p_size = size * 2.f;
  300. return (radius <= gOctreeMinSize && size <= gOctreeMinSize) ||
  301. (radius <= p_size && radius > size);
  302. }
  303. static void pushCenter(LLVector4a& center, const LLVector4a& size,
  304. const T* data)
  305. {
  306. const LLVector4a& pos = data->getPositionGroup();
  307. LLVector4Logical gt = pos.greaterThan(center);
  308. LLVector4a up;
  309. up = _mm_and_ps(size, gt);
  310. LLVector4a down;
  311. down = _mm_andnot_ps(gt, size);
  312. center.add(up);
  313. center.sub(down);
  314. }
  315. void accept(oct_traveler* visitor) { visitor->visit(this); }
  316. virtual bool isLeaf() const { return mChildCount == 0; }
  317. const element_list& getData() const { return mData; }
  318. U32 getElementCount() const { return mData.size(); }
  319. bool isEmpty() const { return mData.empty(); }
  320. element_iter getDataBegin() { return mData.begin(); }
  321. element_iter getDataEnd() { return mData.end(); }
  322. const_element_iter getDataBegin() const { return mData.cbegin(); }
  323. const_element_iter getDataEnd() const { return mData.cend(); }
  324. U32 getChildCount() const { return mChildCount; }
  325. oct_node* getChild(U32 index) { return mChild[index]; }
  326. const oct_node* getChild(U32 index) const { return mChild[index]; }
  327. child_list& getChildren() { return mChild; }
  328. const child_list& getChildren() const { return mChild; }
  329. void accept(tree_traveler* visitor) const { visitor->visit(this); }
  330. void accept(oct_traveler* visitor) const { visitor->visit(this); }
  331. oct_node* getNodeAt(const LLVector4a& pos, F32 rad)
  332. {
  333. oct_node* node = this;
  334. if (node->isInside(pos, rad))
  335. {
  336. // Do a quick search by octant
  337. U8 octant = node->getOctant(pos);
  338. // Traverse the tree until we find a node that has no node at the
  339. // appropriate octant or is smaller than the object. By definition,
  340. // that node is the smallest node that contains the data
  341. U8 next_node = node->mChildMap[octant];
  342. while (next_node != NO_CHILD_NODES && node->getSize()[0] >= rad)
  343. {
  344. node = node->getChild(next_node);
  345. octant = node->getOctant(pos);
  346. next_node = node->mChildMap[octant];
  347. }
  348. }
  349. else if (!node->contains(rad) && node->getParent())
  350. {
  351. // If we got here, data does not exist in this node
  352. return ((oct_node*)node->getParent())->getNodeAt(pos, rad);
  353. }
  354. return node;
  355. }
  356. bool insert(T* data) override
  357. {
  358. if (!data || data->getBinIndex() != -1)
  359. {
  360. llwarns << "Invalid element added to octree branch !" << llendl;
  361. return false;
  362. }
  363. oct_node* parent = getOctParent();
  364. // Is it here ?
  365. const LLVector4a& pos_group = data->getPositionGroup();
  366. if (isInside(pos_group))
  367. {
  368. if (((getElementCount() < gOctreeMaxCapacity ||
  369. getSize()[0] <= gOctreeMinSize) &&
  370. contains(data->getBinRadius())) ||
  371. (data->getBinRadius() > getSize()[0] && parent &&
  372. parent->getElementCount() >= gOctreeMaxCapacity))
  373. {
  374. // It belongs here
  375. mData.push_back(data);
  376. data->setBinIndex(getElementCount() - 1);
  377. BaseType::insert(data);
  378. return true;
  379. }
  380. // Find a child to give it to
  381. oct_node* child = NULL;
  382. for (U32 i = 0; i < getChildCount(); ++i)
  383. {
  384. child = getChild(i);
  385. if (child->isInside(pos_group))
  386. {
  387. child->insert(data);
  388. return false;
  389. }
  390. }
  391. // It is here, but no kids are in the right place, make a new kid
  392. LLVector4a center = getCenter();
  393. LLVector4a size = getSize();
  394. size.mul(0.5f);
  395. // Push center in direction of data
  396. oct_node::pushCenter(center, size, data);
  397. // Handle case where floating point number gets too small
  398. LLVector4a val;
  399. val.setSub(center, getCenter());
  400. val.setAbs(val);
  401. LLVector4a min_diff(gOctreeMinSize);
  402. if ((val.lessThan(min_diff).getGatheredBits() & 0x7) == 0x7)
  403. {
  404. mData.push_back(data);
  405. data->setBinIndex(getElementCount() - 1);
  406. BaseType::insert(data);
  407. return true;
  408. }
  409. llassert(size[0] >= gOctreeMinSize * 0.5f);
  410. // Make the new child
  411. child = new oct_node(center, size, this);
  412. addChild(child);
  413. child->insert(data);
  414. }
  415. #if 1 // We used to crash in here, but we did not yet test for parent...
  416. else if (parent)
  417. {
  418. // It is not in here, give it to the root
  419. llwarns << "Octree insertion failed, starting over from root !"
  420. << llendl;
  421. oct_node* node = this;
  422. while (parent)
  423. {
  424. node = parent;
  425. parent = node->getOctParent();
  426. }
  427. node->insert(data);
  428. }
  429. #endif
  430. else
  431. {
  432. llwarns << "Octree insertion failed !" << llendl;
  433. }
  434. return false;
  435. }
  436. void _remove(T* data, S32 i)
  437. {
  438. // Precondition -- getElementCount() > 0, i is in range
  439. // [0, getElementCount())
  440. S32 element_count = getElementCount();
  441. if (element_count == 0 || i < 0 || i > element_count)
  442. {
  443. llwarns << "Index out of range: element_count = " << element_count
  444. << " - index = " << i << " - Aborted." << llendl;
  445. return;
  446. }
  447. data->setBinIndex(-1);
  448. if (--element_count > 0)
  449. {
  450. if (element_count != i)
  451. {
  452. // Might unref data, do not access data after this point
  453. mData[i] = mData[element_count];
  454. mData[i]->setBinIndex(i);
  455. }
  456. mData[element_count] = NULL;
  457. mData.pop_back();
  458. }
  459. else
  460. {
  461. mData.clear();
  462. }
  463. this->notifyRemoval(data);
  464. checkAlive();
  465. }
  466. bool remove(T* data) override
  467. {
  468. S32 i = data->getBinIndex();
  469. if (i >= 0 && i < (S32)getElementCount())
  470. {
  471. if (mData[i] == data)
  472. {
  473. // Found it
  474. _remove(data, i);
  475. llassert(data->getBinIndex() == -1);
  476. return true;
  477. }
  478. }
  479. if (isInside(data))
  480. {
  481. oct_node* dest = getNodeAt(data);
  482. if (dest != this)
  483. {
  484. bool ret = dest->remove(data);
  485. llassert(data->getBinIndex() == -1);
  486. return ret;
  487. }
  488. }
  489. // SHE IS GONE MISSING...
  490. // None of the children have it, let's just brute force this bastard
  491. // out starting with the root node (UGLY CODE COMETH !)
  492. oct_node* parent = getOctParent();
  493. oct_node* node = this;
  494. while (parent)
  495. {
  496. node = parent;
  497. parent = node->getOctParent();
  498. }
  499. // Node is now root
  500. llwarns << "Octree removing element by address, severe performance penalty !"
  501. << llendl;
  502. node->removeByAddress(data);
  503. llassert(data->getBinIndex() == -1);
  504. return true;
  505. }
  506. void removeByAddress(T* data)
  507. {
  508. for (U32 i = 0, count = getElementCount(); i < count; ++i)
  509. {
  510. if (mData[i] == data)
  511. {
  512. // We have data
  513. _remove(data, i);
  514. return;
  515. }
  516. }
  517. for (U32 i = 0; i < getChildCount(); ++i)
  518. {
  519. // We do not contain data, so pass this guy down
  520. oct_node* child = (oct_node*)getChild(i);
  521. child->removeByAddress(data);
  522. }
  523. }
  524. void clearChildren()
  525. {
  526. mChildCount = 0;
  527. memset((void*)mChildMap, NO_CHILD_NODES, sizeof(mChildMap));
  528. }
  529. virtual bool balance()
  530. {
  531. return false;
  532. }
  533. void destroy()
  534. {
  535. for (U32 i = 0; i < getChildCount(); ++i)
  536. {
  537. mChild[i]->destroy();
  538. delete mChild[i];
  539. }
  540. }
  541. void addChild(oct_node* child, bool silent = false)
  542. {
  543. mChildMap[child->getOctant()] = mChildCount;
  544. mChild[mChildCount++] = child;
  545. child->setParent(this);
  546. if (!silent)
  547. {
  548. for (U32 i = 0; i < this->getListenerCount(); ++i)
  549. {
  550. oct_listener* listener = this->getOctListener(i);
  551. if (listener)
  552. {
  553. listener->handleChildAddition(this, child);
  554. }
  555. else
  556. {
  557. llwarns << "NULL listener found !" << llendl;
  558. }
  559. }
  560. }
  561. }
  562. void removeChild(S32 index, bool destroy = false)
  563. {
  564. for (U32 i = 0; i < this->getListenerCount(); ++i)
  565. {
  566. oct_listener* listener = this->getOctListener(i);
  567. if (listener)
  568. {
  569. listener->handleChildRemoval(this, getChild(index));
  570. }
  571. else
  572. {
  573. llwarns << "NULL listener found !" << llendl;
  574. }
  575. }
  576. if (destroy)
  577. {
  578. mChild[index]->destroy();
  579. delete mChild[index];
  580. }
  581. mChild[index] = mChild[--mChildCount];
  582. // Rebuild child map
  583. memset((void*)mChildMap, NO_CHILD_NODES, sizeof(mChildMap));
  584. for (U32 i = 0; i < mChildCount; ++i)
  585. {
  586. mChildMap[mChild[i]->getOctant()] = i;
  587. }
  588. checkAlive();
  589. }
  590. void checkAlive()
  591. {
  592. if (getChildCount() == 0 && getElementCount() == 0)
  593. {
  594. oct_node* parent = getOctParent();
  595. if (parent)
  596. {
  597. parent->deleteChild(this);
  598. }
  599. }
  600. }
  601. void deleteChild(oct_node* node)
  602. {
  603. for (U32 i = 0; i < getChildCount(); ++i)
  604. {
  605. if (getChild(i) == node)
  606. {
  607. removeChild(i, true);
  608. return;
  609. }
  610. }
  611. llwarns << "Octree failed to delete requested child." << llendl;
  612. }
  613. protected:
  614. typedef enum
  615. {
  616. CENTER = 0,
  617. SIZE = 1,
  618. MAX = 2,
  619. MIN = 3
  620. } eDName;
  621. LLVector4a mCenter;
  622. LLVector4a mSize;
  623. LLVector4a mMax;
  624. LLVector4a mMin;
  625. element_list mData;
  626. oct_node* mParent;
  627. oct_node* mChild[8];
  628. U8 mChildMap[8];
  629. U32 mChildCount;
  630. U8 mOctant;
  631. };
  632. // Just like a regular node, except it might expand on insert and compress on
  633. // balance.
  634. template <class T, typename T_PTR>
  635. class _LLOctreeRoot : public _LLOctreeNode<T, T_PTR>
  636. {
  637. public:
  638. typedef _LLOctreeNode<T, T_PTR> BaseType;
  639. typedef _LLOctreeNode<T, T_PTR> oct_node;
  640. _LLOctreeRoot(const LLVector4a& center, const LLVector4a& size,
  641. BaseType* parent)
  642. : BaseType(center, size, parent)
  643. {
  644. }
  645. bool balance() override
  646. {
  647. if (this->getChildCount() == 1 && !this->mChild[0]->isLeaf() &&
  648. this->mChild[0]->getElementCount() == 0)
  649. {
  650. // If we have only one child and that child is an empty branch,
  651. // make that child the root
  652. oct_node* child = this->mChild[0];
  653. // Make the root node look like the child
  654. this->setCenter(this->mChild[0]->getCenter());
  655. this->setSize(this->mChild[0]->getSize());
  656. this->updateMinMax();
  657. // Reset root node child list
  658. this->clearChildren();
  659. // Copy the child's children into the root node silently (do not
  660. // notify listeners of addition)
  661. for (U32 i = 0; i < child->getChildCount(); ++i)
  662. {
  663. this->addChild(child->getChild(i), true);
  664. }
  665. // Destroy child
  666. child->clearChildren();
  667. delete child;
  668. return false;
  669. }
  670. return true;
  671. }
  672. // LLOctreeRoot::insert
  673. bool insert(T* data) override
  674. {
  675. if (!data)
  676. {
  677. llwarns_sparse << "Attempt to add a NULL element added to octree root !"
  678. << llendl;
  679. return false;
  680. }
  681. S32 binradius = data->getBinRadius();
  682. if (binradius > 4096.f)
  683. {
  684. llwarns_sparse << "Element exceeds maximum size in octree root !"
  685. << llendl;
  686. return false;
  687. }
  688. const LLVector4a& pos_group = data->getPositionGroup();
  689. LLVector4a val;
  690. val.setSub(pos_group, BaseType::mCenter);
  691. val.setAbs(val);
  692. if ((val.lessThan(gOctreeMaxMag).getGatheredBits() & 0x7) != 0x7)
  693. {
  694. llwarns_sparse << "Element exceeds range of spatial partition ! Insertion skipped, expect occlusion issues."
  695. << llendl;
  696. return false;
  697. }
  698. if (this->getSize()[0] > binradius && this->isInside(pos_group))
  699. {
  700. // We got it, just act like a branch
  701. oct_node* node = this->getNodeAt(data);
  702. if (node == this)
  703. {
  704. oct_node::insert(data);
  705. return false;
  706. }
  707. if (node->isInside(pos_group))
  708. {
  709. node->insert(data);
  710. return false;
  711. }
  712. llwarns << "Failed to insert data at child node" << llendl;
  713. return false;
  714. }
  715. if (this->getChildCount() == 0)
  716. {
  717. // First object being added, just wrap it up
  718. LLVector4a center, size;
  719. while (!(this->getSize()[0] > binradius &&
  720. this->isInside(pos_group)))
  721. {
  722. center = this->getCenter();
  723. size = this->getSize();
  724. oct_node::pushCenter(center, size, data);
  725. this->setCenter(center);
  726. size.mul(2.f);
  727. this->setSize(size);
  728. this->updateMinMax();
  729. }
  730. oct_node::insert(data);
  731. return false;
  732. }
  733. while (!(this->getSize()[0] > binradius && this->isInside(pos_group)))
  734. {
  735. // The data is outside the root node, we need to grow
  736. LLVector4a center(this->getCenter());
  737. LLVector4a size(this->getSize());
  738. // Expand this node
  739. LLVector4a newcenter(center);
  740. oct_node::pushCenter(newcenter, size, data);
  741. this->setCenter(newcenter);
  742. LLVector4a size2 = size;
  743. size2.mul(2.f);
  744. this->setSize(size2);
  745. this->updateMinMax();
  746. llassert(size[0] >= gOctreeMinSize);
  747. // Copy our children to a new branch
  748. oct_node* newnode = new oct_node(center, size, this);
  749. for (U32 i = 0; i < this->getChildCount(); ++i)
  750. {
  751. oct_node* child = this->getChild(i);
  752. newnode->addChild(child);
  753. }
  754. // Clear our children and add the root copy
  755. this->clearChildren();
  756. this->addChild(newnode);
  757. }
  758. // Insert the data
  759. insert(data);
  760. return false;
  761. }
  762. // Root cannot be a leaf
  763. LL_INLINE bool isLeaf() const override { return false; }
  764. };
  765. // This version takes ownership of inserted pointers. It deletes elements
  766. // removed from the tree.
  767. template<typename T>
  768. using LLOctreeRoot = _LLOctreeRoot<T, LLPointer<T> >;
  769. // This version does not take ownership of inserted pointers. The API user is
  770. // responsible for managing the lifecycle of what it provides to the tree.
  771. template<typename T>
  772. using LLOctreeRootNoOwnership = _LLOctreeRoot<T, T*>;
  773. #endif