OPC_AABBTree.cpp 22 KB

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