OPC_AABBTree.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. /*
  3. * OPCODE - Optimized Collision Detection
  4. * Copyright (C) 2001 Pierre Terdiman
  5. * Homepage: http://www.codercorner.com/Opcode.htm
  6. */
  7. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. /**
  10. * Contains code for a versatile AABB tree.
  11. * \file OPC_AABBTree.cpp
  12. * \author Pierre Terdiman
  13. * \date March, 20, 2001
  14. */
  15. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  16. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. /**
  18. * Contains a generic AABB tree node.
  19. *
  20. * \class AABBTreeNode
  21. * \author Pierre Terdiman
  22. * \version 1.3
  23. * \date March, 20, 2001
  24. */
  25. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  27. /**
  28. * Contains a generic AABB tree.
  29. * This is a vanilla AABB tree, without any particular optimization. It contains anonymous references to
  30. * user-provided primitives, which can theoretically be anything - triangles, boxes, etc. Each primitive
  31. * is surrounded by an AABB, regardless of the primitive's nature. When the primitive is a triangle, the
  32. * resulting tree can be converted into an optimized tree. If the primitive is a box, the resulting tree
  33. * can be used for culling - VFC or occlusion -, assuming you cull on a mesh-by-mesh basis (modern way).
  34. *
  35. * \class AABBTree
  36. * \author Pierre Terdiman
  37. * \version 1.3
  38. * \date March, 20, 2001
  39. */
  40. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  41. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  42. // Precompiled Header
  43. #include "Stdafx.h"
  44. using namespace Opcode;
  45. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  46. /**
  47. * Constructor.
  48. */
  49. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  50. AABBTreeNode::AABBTreeNode() :
  51. mPos (null),
  52. #ifndef OPC_NO_NEG_VANILLA_TREE
  53. mNeg (null),
  54. #endif
  55. mNodePrimitives (null),
  56. mNbPrimitives (0)
  57. {
  58. #ifdef OPC_USE_TREE_COHERENCE
  59. mBitmask = 0;
  60. #endif
  61. }
  62. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. /**
  64. * Destructor.
  65. */
  66. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  67. AABBTreeNode::~AABBTreeNode()
  68. {
  69. // Opcode 1.3:
  70. const AABBTreeNode* Pos = GetPos();
  71. #ifndef OPC_NO_NEG_VANILLA_TREE
  72. const AABBTreeNode* Neg = GetNeg();
  73. if(!(mPos&1)) DELETESINGLE(Pos);
  74. if(!(mNeg&1)) DELETESINGLE(Neg);
  75. #else
  76. if(!(mPos&1)) DELETEARRAY(Pos);
  77. #endif
  78. mNodePrimitives = null; // This was just a shortcut to the global list => no release
  79. mNbPrimitives = 0;
  80. }
  81. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  82. /**
  83. * Splits the node along a given axis.
  84. * The list of indices is reorganized according to the split values.
  85. * \param axis [in] splitting axis index
  86. * \param builder [in] the tree builder
  87. * \return the number of primitives assigned to the first child
  88. * \warning this method reorganizes the internal list of primitives
  89. */
  90. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  91. udword AABBTreeNode::Split(udword axis, AABBTreeBuilder* builder)
  92. {
  93. // Get node split value
  94. float SplitValue = builder->GetSplittingValue(mNodePrimitives, mNbPrimitives, mBV, axis);
  95. udword NbPos = 0;
  96. // Loop through all node-related primitives. Their indices range from mNodePrimitives[0] to mNodePrimitives[mNbPrimitives-1].
  97. // Those indices map the global list in the tree builder.
  98. for(udword i=0;i<mNbPrimitives;i++)
  99. {
  100. // Get index in global list
  101. udword Index = mNodePrimitives[i];
  102. // Test against the splitting value. The primitive value is tested against the enclosing-box center.
  103. // [We only need an approximate partition of the enclosing box here.]
  104. float PrimitiveValue = builder->GetSplittingValue(Index, axis);
  105. // Reorganize the list of indices in this order: positive - negative.
  106. if(PrimitiveValue > SplitValue)
  107. {
  108. // Swap entries
  109. udword Tmp = mNodePrimitives[i];
  110. mNodePrimitives[i] = mNodePrimitives[NbPos];
  111. mNodePrimitives[NbPos] = Tmp;
  112. // Count primitives assigned to positive space
  113. NbPos++;
  114. }
  115. }
  116. return NbPos;
  117. }
  118. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  119. /**
  120. * Subdivides the node.
  121. *
  122. * N
  123. * / \
  124. * / \
  125. * N/2 N/2
  126. * / \ / \
  127. * N/4 N/4 N/4 N/4
  128. * (etc)
  129. *
  130. * A well-balanced tree should have a O(log n) depth.
  131. * A degenerate tree would have a O(n) depth.
  132. * Note a perfectly-balanced tree is not well-suited to collision detection anyway.
  133. *
  134. * \param builder [in] the tree builder
  135. * \return true if success
  136. */
  137. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  138. bool AABBTreeNode::Subdivide(AABBTreeBuilder* builder)
  139. {
  140. // Checkings
  141. if(!builder) return false;
  142. // Stop subdividing if we reach a leaf node. This is always performed here,
  143. // else we could end in trouble if user overrides this.
  144. if(mNbPrimitives==1) return true;
  145. // Let the user validate the subdivision
  146. if(!builder->ValidateSubdivision(mNodePrimitives, mNbPrimitives, mBV)) return true;
  147. bool ValidSplit = true; // Optimism...
  148. udword NbPos;
  149. if(builder->mSettings.mRules & SPLIT_LARGEST_AXIS)
  150. {
  151. // Find the largest axis to split along
  152. Point Extents; mBV.GetExtents(Extents); // Box extents
  153. udword Axis = Extents.LargestAxis(); // Index of largest axis
  154. // Split along the axis
  155. NbPos = Split(Axis, builder);
  156. // Check split validity
  157. if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false;
  158. }
  159. else if(builder->mSettings.mRules & SPLIT_SPLATTER_POINTS)
  160. {
  161. // Compute the means
  162. Point Means(0.0f, 0.0f, 0.0f);
  163. for(udword i=0;i<mNbPrimitives;i++)
  164. {
  165. udword Index = mNodePrimitives[i];
  166. Means.x+=builder->GetSplittingValue(Index, 0);
  167. Means.y+=builder->GetSplittingValue(Index, 1);
  168. Means.z+=builder->GetSplittingValue(Index, 2);
  169. }
  170. Means/=float(mNbPrimitives);
  171. // Compute variances
  172. Point Vars(0.0f, 0.0f, 0.0f);
  173. for(udword i=0;i<mNbPrimitives;i++)
  174. {
  175. udword Index = mNodePrimitives[i];
  176. float Cx = builder->GetSplittingValue(Index, 0);
  177. float Cy = builder->GetSplittingValue(Index, 1);
  178. float Cz = builder->GetSplittingValue(Index, 2);
  179. Vars.x += (Cx - Means.x)*(Cx - Means.x);
  180. Vars.y += (Cy - Means.y)*(Cy - Means.y);
  181. Vars.z += (Cz - Means.z)*(Cz - Means.z);
  182. }
  183. Vars/=float(mNbPrimitives-1);
  184. // Choose axis with greatest variance
  185. udword Axis = Vars.LargestAxis();
  186. // Split along the axis
  187. NbPos = Split(Axis, builder);
  188. // Check split validity
  189. if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false;
  190. }
  191. else if(builder->mSettings.mRules & SPLIT_BALANCED)
  192. {
  193. // Test 3 axis, take the best
  194. float Results[3];
  195. NbPos = Split(0, builder); Results[0] = float(NbPos)/float(mNbPrimitives);
  196. NbPos = Split(1, builder); Results[1] = float(NbPos)/float(mNbPrimitives);
  197. NbPos = Split(2, builder); Results[2] = float(NbPos)/float(mNbPrimitives);
  198. Results[0]-=0.5f; Results[0]*=Results[0];
  199. Results[1]-=0.5f; Results[1]*=Results[1];
  200. Results[2]-=0.5f; Results[2]*=Results[2];
  201. udword Min=0;
  202. if(Results[1]<Results[Min]) Min = 1;
  203. if(Results[2]<Results[Min]) Min = 2;
  204. // Split along the axis
  205. NbPos = Split(Min, builder);
  206. // Check split validity
  207. if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false;
  208. }
  209. else if(builder->mSettings.mRules & SPLIT_BEST_AXIS)
  210. {
  211. // Test largest, then middle, then smallest axis...
  212. // Sort axis
  213. Point Extents; mBV.GetExtents(Extents); // Box extents
  214. udword SortedAxis[] = { 0, 1, 2 };
  215. float* Keys = (float*)&Extents.x;
  216. for(udword j=0;j<3;j++)
  217. {
  218. for(udword i=0;i<2;i++)
  219. {
  220. if(Keys[SortedAxis[i]]<Keys[SortedAxis[i+1]])
  221. {
  222. udword Tmp = SortedAxis[i];
  223. SortedAxis[i] = SortedAxis[i+1];
  224. SortedAxis[i+1] = Tmp;
  225. }
  226. }
  227. }
  228. // Find the largest axis to split along
  229. udword CurAxis = 0;
  230. ValidSplit = false;
  231. while(!ValidSplit && CurAxis!=3)
  232. {
  233. NbPos = Split(SortedAxis[CurAxis], builder);
  234. // Check the subdivision has been successful
  235. if(!NbPos || NbPos==mNbPrimitives) CurAxis++;
  236. else ValidSplit = true;
  237. }
  238. }
  239. else if(builder->mSettings.mRules & SPLIT_FIFTY)
  240. {
  241. // Don't even bother splitting (mainly a performance test)
  242. NbPos = mNbPrimitives>>1;
  243. }
  244. else return false; // Unknown splitting rules
  245. // Check the subdivision has been successful
  246. if(!ValidSplit)
  247. {
  248. // Here, all boxes lie in the same sub-space. Two strategies:
  249. // - if the tree *must* be complete, make an arbitrary 50-50 split
  250. // - else stop subdividing
  251. // if(builder->mSettings.mRules&SPLIT_COMPLETE)
  252. if(builder->mSettings.mLimit==1)
  253. {
  254. builder->IncreaseNbInvalidSplits();
  255. NbPos = mNbPrimitives>>1;
  256. }
  257. else return true;
  258. }
  259. // Now create children and assign their pointers.
  260. if(builder->mNodeBase)
  261. {
  262. // We use a pre-allocated linear pool for complete trees [Opcode 1.3]
  263. AABBTreeNode* Pool = (AABBTreeNode*)builder->mNodeBase;
  264. udword Count = builder->GetCount() - 1; // Count begins to 1...
  265. // Set last bit to tell it shouldn't be freed ### pretty ugly, find a better way. Maybe one bit in mNbPrimitives
  266. ASSERT(!(udword(&Pool[Count+0])&1));
  267. ASSERT(!(udword(&Pool[Count+1])&1));
  268. mPos = size_t(&Pool[Count+0])|1;
  269. #ifndef OPC_NO_NEG_VANILLA_TREE
  270. mNeg = size_t(&Pool[Count+1])|1;
  271. #endif
  272. }
  273. else
  274. {
  275. // Non-complete trees and/or Opcode 1.2 allocate nodes on-the-fly
  276. #ifndef OPC_NO_NEG_VANILLA_TREE
  277. mPos = (size_t)new AABBTreeNode; CHECKALLOC(mPos);
  278. mNeg = (size_t)new AABBTreeNode; CHECKALLOC(mNeg);
  279. #else
  280. AABBTreeNode* PosNeg = new AABBTreeNode[2];
  281. CHECKALLOC(PosNeg);
  282. mPos = (size_t)PosNeg;
  283. #endif
  284. }
  285. // Update stats
  286. builder->IncreaseCount(2);
  287. // Assign children
  288. AABBTreeNode* Pos = (AABBTreeNode*)GetPos();
  289. AABBTreeNode* Neg = (AABBTreeNode*)GetNeg();
  290. Pos->mNodePrimitives = &mNodePrimitives[0];
  291. Pos->mNbPrimitives = NbPos;
  292. Neg->mNodePrimitives = &mNodePrimitives[NbPos];
  293. Neg->mNbPrimitives = mNbPrimitives - NbPos;
  294. return true;
  295. }
  296. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  297. /**
  298. * Recursive hierarchy building in a top-down fashion.
  299. * \param builder [in] the tree builder
  300. */
  301. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  302. void AABBTreeNode::_BuildHierarchy(AABBTreeBuilder* builder)
  303. {
  304. // 1) Compute the global box for current node. The box is stored in mBV.
  305. builder->ComputeGlobalBox(mNodePrimitives, mNbPrimitives, mBV);
  306. // 2) Subdivide current node
  307. Subdivide(builder);
  308. // 3) Recurse
  309. AABBTreeNode* Pos = (AABBTreeNode*)GetPos();
  310. AABBTreeNode* Neg = (AABBTreeNode*)GetNeg();
  311. if(Pos) Pos->_BuildHierarchy(builder);
  312. if(Neg) Neg->_BuildHierarchy(builder);
  313. }
  314. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  315. /**
  316. * Refits the tree (top-down).
  317. * \param builder [in] the tree builder
  318. */
  319. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  320. void AABBTreeNode::_Refit(AABBTreeBuilder* builder)
  321. {
  322. // 1) Recompute the new global box for current node
  323. builder->ComputeGlobalBox(mNodePrimitives, mNbPrimitives, mBV);
  324. // 2) Recurse
  325. AABBTreeNode* Pos = (AABBTreeNode*)GetPos();
  326. AABBTreeNode* Neg = (AABBTreeNode*)GetNeg();
  327. if(Pos) Pos->_Refit(builder);
  328. if(Neg) Neg->_Refit(builder);
  329. }
  330. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  331. /**
  332. * Constructor.
  333. */
  334. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  335. AABBTree::AABBTree() : mIndices(null), mPool(null), mTotalNbNodes(0)
  336. {
  337. }
  338. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  339. /**
  340. * Destructor.
  341. */
  342. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  343. AABBTree::~AABBTree()
  344. {
  345. Release();
  346. }
  347. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  348. /**
  349. * Releases the tree.
  350. */
  351. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  352. void AABBTree::Release()
  353. {
  354. DELETEARRAY(mPool);
  355. DELETEARRAY(mIndices);
  356. }
  357. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  358. /**
  359. * Builds a generic AABB tree from a tree builder.
  360. * \param builder [in] the tree builder
  361. * \return true if success
  362. */
  363. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  364. bool AABBTree::Build(AABBTreeBuilder* builder)
  365. {
  366. // Checkings
  367. if(!builder || !builder->mNbPrimitives) return false;
  368. // Release previous tree
  369. Release();
  370. // Init stats
  371. builder->SetCount(1);
  372. builder->SetNbInvalidSplits(0);
  373. // Initialize indices. This list will be modified during build.
  374. mIndices = new dTriIndex[builder->mNbPrimitives];
  375. CHECKALLOC(mIndices);
  376. // Identity permutation
  377. for(udword i=0;i<builder->mNbPrimitives;i++) mIndices[i] = i;
  378. // Setup initial node. Here we have a complete permutation of the app's primitives.
  379. mNodePrimitives = mIndices;
  380. mNbPrimitives = builder->mNbPrimitives;
  381. // Use a linear array for complete trees (since we can predict the final number of nodes) [Opcode 1.3]
  382. // if(builder->mRules&SPLIT_COMPLETE)
  383. if(builder->mSettings.mLimit==1)
  384. {
  385. // Allocate a pool of nodes
  386. mPool = new AABBTreeNode[builder->mNbPrimitives*2 - 1];
  387. builder->mNodeBase = mPool; // ### ugly !
  388. }
  389. // Build the hierarchy
  390. _BuildHierarchy(builder);
  391. // Get back total number of nodes
  392. mTotalNbNodes = builder->GetCount();
  393. // For complete trees, check the correct number of nodes has been created [Opcode 1.3]
  394. if(mPool) ASSERT(mTotalNbNodes==builder->mNbPrimitives*2 - 1);
  395. return true;
  396. }
  397. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  398. /**
  399. * Computes the depth of the tree.
  400. * A well-balanced tree should have a log(n) depth. A degenerate tree O(n) depth.
  401. * \return depth of the tree
  402. */
  403. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  404. udword AABBTree::ComputeDepth() const
  405. {
  406. return Walk(null, null); // Use the walking code without callback
  407. }
  408. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  409. /**
  410. * Walks the tree, calling the user back for each node.
  411. */
  412. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  413. udword AABBTree::Walk(WalkingCallback callback, void* user_data) const
  414. {
  415. // Call it without callback to compute max depth
  416. udword MaxDepth = 0;
  417. udword CurrentDepth = 0;
  418. struct Local
  419. {
  420. static void _Walk(const AABBTreeNode* current_node, udword& max_depth, udword& current_depth, WalkingCallback callback, void* user_data)
  421. {
  422. // Checkings
  423. if(!current_node) return;
  424. // Entering a new node => increase depth
  425. current_depth++;
  426. // Keep track of max depth
  427. if(current_depth>max_depth) max_depth = current_depth;
  428. // Callback
  429. if(callback && !(callback)(current_node, current_depth, user_data)) return;
  430. // Recurse
  431. if(current_node->GetPos()) { _Walk(current_node->GetPos(), max_depth, current_depth, callback, user_data); current_depth--; }
  432. if(current_node->GetNeg()) { _Walk(current_node->GetNeg(), max_depth, current_depth, callback, user_data); current_depth--; }
  433. }
  434. };
  435. Local::_Walk(this, MaxDepth, CurrentDepth, callback, user_data);
  436. return MaxDepth;
  437. }
  438. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  439. /**
  440. * Refits the tree in a top-down way.
  441. * \param builder [in] the tree builder
  442. */
  443. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  444. bool AABBTree::Refit(AABBTreeBuilder* builder)
  445. {
  446. if(!builder) return false;
  447. _Refit(builder);
  448. return true;
  449. }
  450. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  451. /**
  452. * Refits the tree in a bottom-up way.
  453. * \param builder [in] the tree builder
  454. */
  455. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  456. bool AABBTree::Refit2(AABBTreeBuilder* builder)
  457. {
  458. // Checkings
  459. if(!builder) return false;
  460. ASSERT(mPool);
  461. // Bottom-up update
  462. Point Min,Max;
  463. Point Min_,Max_;
  464. udword Index = mTotalNbNodes;
  465. while(Index--)
  466. {
  467. AABBTreeNode& Current = mPool[Index];
  468. if(Current.IsLeaf())
  469. {
  470. builder->ComputeGlobalBox(Current.GetPrimitives(), Current.GetNbPrimitives(), *(AABB*)Current.GetAABB());
  471. }
  472. else
  473. {
  474. Current.GetPos()->GetAABB()->GetMin(Min);
  475. Current.GetPos()->GetAABB()->GetMax(Max);
  476. Current.GetNeg()->GetAABB()->GetMin(Min_);
  477. Current.GetNeg()->GetAABB()->GetMax(Max_);
  478. Min.Min(Min_);
  479. Max.Max(Max_);
  480. ((AABB*)Current.GetAABB())->SetMinMax(Min, Max);
  481. }
  482. }
  483. return true;
  484. }
  485. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  486. /**
  487. * Computes the number of bytes used by the tree.
  488. * \return number of bytes used
  489. */
  490. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  491. udword AABBTree::GetUsedBytes() const
  492. {
  493. udword TotalSize = mTotalNbNodes*GetNodeSize();
  494. if(mIndices) TotalSize+=mNbPrimitives*sizeof(udword);
  495. return TotalSize;
  496. }
  497. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  498. /**
  499. * Checks the tree is a complete tree or not.
  500. * A complete tree is made of 2*N-1 nodes, where N is the number of primitives in the tree.
  501. * \return true for complete trees
  502. */
  503. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  504. bool AABBTree::IsComplete() const
  505. {
  506. return (GetNbNodes()==GetNbPrimitives()*2-1);
  507. }