The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

773 lines
17KB

  1. /*
  2. * Copyright (c) 2009 Erin Catto http://www.box2d.org
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software
  12. * in a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. * 2. Altered source versions must be plainly marked as such, and must not be
  15. * misrepresented as being the original software.
  16. * 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "b2DynamicTree.h"
  19. #include <cstring>
  20. #include <cfloat>
  21. using namespace std;
  22. b2DynamicTree::b2DynamicTree()
  23. {
  24. m_root = b2_nullNode;
  25. m_nodeCapacity = 16;
  26. m_nodeCount = 0;
  27. m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode));
  28. memset((void*)m_nodes, 0, m_nodeCapacity * sizeof(b2TreeNode));
  29. // Build a linked list for the free list.
  30. for (int32 i = 0; i < m_nodeCapacity - 1; ++i)
  31. {
  32. m_nodes[i].next = i + 1;
  33. m_nodes[i].height = -1;
  34. }
  35. m_nodes[m_nodeCapacity-1].next = b2_nullNode;
  36. m_nodes[m_nodeCapacity-1].height = -1;
  37. m_freeList = 0;
  38. m_path = 0;
  39. m_insertionCount = 0;
  40. }
  41. b2DynamicTree::~b2DynamicTree()
  42. {
  43. // This frees the entire tree in one shot.
  44. b2Free(m_nodes);
  45. }
  46. // Allocate a node from the pool. Grow the pool if necessary.
  47. int32 b2DynamicTree::AllocateNode()
  48. {
  49. // Expand the node pool as needed.
  50. if (m_freeList == b2_nullNode)
  51. {
  52. b2Assert(m_nodeCount == m_nodeCapacity);
  53. // The free list is empty. Rebuild a bigger pool.
  54. b2TreeNode* oldNodes = m_nodes;
  55. m_nodeCapacity *= 2;
  56. m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode));
  57. memcpy(m_nodes, oldNodes, m_nodeCount * sizeof(b2TreeNode));
  58. b2Free(oldNodes);
  59. // Build a linked list for the free list. The parent
  60. // pointer becomes the "next" pointer.
  61. for (int32 i = m_nodeCount; i < m_nodeCapacity - 1; ++i)
  62. {
  63. m_nodes[i].next = i + 1;
  64. m_nodes[i].height = -1;
  65. }
  66. m_nodes[m_nodeCapacity-1].next = b2_nullNode;
  67. m_nodes[m_nodeCapacity-1].height = -1;
  68. m_freeList = m_nodeCount;
  69. }
  70. // Peel a node off the free list.
  71. int32 nodeId = m_freeList;
  72. m_freeList = m_nodes[nodeId].next;
  73. m_nodes[nodeId].parent = b2_nullNode;
  74. m_nodes[nodeId].child1 = b2_nullNode;
  75. m_nodes[nodeId].child2 = b2_nullNode;
  76. m_nodes[nodeId].height = 0;
  77. m_nodes[nodeId].userData = NULL;
  78. ++m_nodeCount;
  79. return nodeId;
  80. }
  81. // Return a node to the pool.
  82. void b2DynamicTree::FreeNode(int32 nodeId)
  83. {
  84. b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);
  85. b2Assert(0 < m_nodeCount);
  86. m_nodes[nodeId].next = m_freeList;
  87. m_nodes[nodeId].height = -1;
  88. m_freeList = nodeId;
  89. --m_nodeCount;
  90. }
  91. // Create a proxy in the tree as a leaf node. We return the index
  92. // of the node instead of a pointer so that we can grow
  93. // the node pool.
  94. int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData)
  95. {
  96. int32 proxyId = AllocateNode();
  97. // Fatten the aabb.
  98. b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
  99. m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r;
  100. m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r;
  101. m_nodes[proxyId].userData = userData;
  102. m_nodes[proxyId].height = 0;
  103. InsertLeaf(proxyId);
  104. return proxyId;
  105. }
  106. void b2DynamicTree::DestroyProxy(int32 proxyId)
  107. {
  108. b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
  109. b2Assert(m_nodes[proxyId].IsLeaf());
  110. RemoveLeaf(proxyId);
  111. FreeNode(proxyId);
  112. }
  113. bool b2DynamicTree::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement)
  114. {
  115. b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
  116. b2Assert(m_nodes[proxyId].IsLeaf());
  117. if (m_nodes[proxyId].aabb.Contains(aabb))
  118. {
  119. return false;
  120. }
  121. RemoveLeaf(proxyId);
  122. // Extend AABB.
  123. b2AABB b = aabb;
  124. b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
  125. b.lowerBound = b.lowerBound - r;
  126. b.upperBound = b.upperBound + r;
  127. // Predict AABB displacement.
  128. b2Vec2 d = b2_aabbMultiplier * displacement;
  129. if (d.x < 0.0f)
  130. {
  131. b.lowerBound.x += d.x;
  132. }
  133. else
  134. {
  135. b.upperBound.x += d.x;
  136. }
  137. if (d.y < 0.0f)
  138. {
  139. b.lowerBound.y += d.y;
  140. }
  141. else
  142. {
  143. b.upperBound.y += d.y;
  144. }
  145. m_nodes[proxyId].aabb = b;
  146. InsertLeaf(proxyId);
  147. return true;
  148. }
  149. void b2DynamicTree::InsertLeaf(int32 leaf)
  150. {
  151. ++m_insertionCount;
  152. if (m_root == b2_nullNode)
  153. {
  154. m_root = leaf;
  155. m_nodes[m_root].parent = b2_nullNode;
  156. return;
  157. }
  158. // Find the best sibling for this node
  159. b2AABB leafAABB = m_nodes[leaf].aabb;
  160. int32 index = m_root;
  161. while (m_nodes[index].IsLeaf() == false)
  162. {
  163. int32 child1 = m_nodes[index].child1;
  164. int32 child2 = m_nodes[index].child2;
  165. float32 area = m_nodes[index].aabb.GetPerimeter();
  166. b2AABB combinedAABB;
  167. combinedAABB.Combine(m_nodes[index].aabb, leafAABB);
  168. float32 combinedArea = combinedAABB.GetPerimeter();
  169. // Cost of creating a new parent for this node and the new leaf
  170. float32 cost = 2.0f * combinedArea;
  171. // Minimum cost of pushing the leaf further down the tree
  172. float32 inheritanceCost = 2.0f * (combinedArea - area);
  173. // Cost of descending into child1
  174. float32 cost1;
  175. if (m_nodes[child1].IsLeaf())
  176. {
  177. b2AABB aabb;
  178. aabb.Combine(leafAABB, m_nodes[child1].aabb);
  179. cost1 = aabb.GetPerimeter() + inheritanceCost;
  180. }
  181. else
  182. {
  183. b2AABB aabb;
  184. aabb.Combine(leafAABB, m_nodes[child1].aabb);
  185. float32 oldArea = m_nodes[child1].aabb.GetPerimeter();
  186. float32 newArea = aabb.GetPerimeter();
  187. cost1 = (newArea - oldArea) + inheritanceCost;
  188. }
  189. // Cost of descending into child2
  190. float32 cost2;
  191. if (m_nodes[child2].IsLeaf())
  192. {
  193. b2AABB aabb;
  194. aabb.Combine(leafAABB, m_nodes[child2].aabb);
  195. cost2 = aabb.GetPerimeter() + inheritanceCost;
  196. }
  197. else
  198. {
  199. b2AABB aabb;
  200. aabb.Combine(leafAABB, m_nodes[child2].aabb);
  201. float32 oldArea = m_nodes[child2].aabb.GetPerimeter();
  202. float32 newArea = aabb.GetPerimeter();
  203. cost2 = newArea - oldArea + inheritanceCost;
  204. }
  205. // Descend according to the minimum cost.
  206. if (cost < cost1 && cost < cost2)
  207. {
  208. break;
  209. }
  210. // Descend
  211. if (cost1 < cost2)
  212. {
  213. index = child1;
  214. }
  215. else
  216. {
  217. index = child2;
  218. }
  219. }
  220. int32 sibling = index;
  221. // Create a new parent.
  222. int32 oldParent = m_nodes[sibling].parent;
  223. int32 newParent = AllocateNode();
  224. m_nodes[newParent].parent = oldParent;
  225. m_nodes[newParent].userData = NULL;
  226. m_nodes[newParent].aabb.Combine(leafAABB, m_nodes[sibling].aabb);
  227. m_nodes[newParent].height = m_nodes[sibling].height + 1;
  228. if (oldParent != b2_nullNode)
  229. {
  230. // The sibling was not the root.
  231. if (m_nodes[oldParent].child1 == sibling)
  232. {
  233. m_nodes[oldParent].child1 = newParent;
  234. }
  235. else
  236. {
  237. m_nodes[oldParent].child2 = newParent;
  238. }
  239. m_nodes[newParent].child1 = sibling;
  240. m_nodes[newParent].child2 = leaf;
  241. m_nodes[sibling].parent = newParent;
  242. m_nodes[leaf].parent = newParent;
  243. }
  244. else
  245. {
  246. // The sibling was the root.
  247. m_nodes[newParent].child1 = sibling;
  248. m_nodes[newParent].child2 = leaf;
  249. m_nodes[sibling].parent = newParent;
  250. m_nodes[leaf].parent = newParent;
  251. m_root = newParent;
  252. }
  253. // Walk back up the tree fixing heights and AABBs
  254. index = m_nodes[leaf].parent;
  255. while (index != b2_nullNode)
  256. {
  257. index = Balance(index);
  258. int32 child1 = m_nodes[index].child1;
  259. int32 child2 = m_nodes[index].child2;
  260. b2Assert(child1 != b2_nullNode);
  261. b2Assert(child2 != b2_nullNode);
  262. m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
  263. m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
  264. index = m_nodes[index].parent;
  265. }
  266. //Validate();
  267. }
  268. void b2DynamicTree::RemoveLeaf(int32 leaf)
  269. {
  270. if (leaf == m_root)
  271. {
  272. m_root = b2_nullNode;
  273. return;
  274. }
  275. int32 parent = m_nodes[leaf].parent;
  276. int32 grandParent = m_nodes[parent].parent;
  277. int32 sibling;
  278. if (m_nodes[parent].child1 == leaf)
  279. {
  280. sibling = m_nodes[parent].child2;
  281. }
  282. else
  283. {
  284. sibling = m_nodes[parent].child1;
  285. }
  286. if (grandParent != b2_nullNode)
  287. {
  288. // Destroy parent and connect sibling to grandParent.
  289. if (m_nodes[grandParent].child1 == parent)
  290. {
  291. m_nodes[grandParent].child1 = sibling;
  292. }
  293. else
  294. {
  295. m_nodes[grandParent].child2 = sibling;
  296. }
  297. m_nodes[sibling].parent = grandParent;
  298. FreeNode(parent);
  299. // Adjust ancestor bounds.
  300. int32 index = grandParent;
  301. while (index != b2_nullNode)
  302. {
  303. index = Balance(index);
  304. int32 child1 = m_nodes[index].child1;
  305. int32 child2 = m_nodes[index].child2;
  306. m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
  307. m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
  308. index = m_nodes[index].parent;
  309. }
  310. }
  311. else
  312. {
  313. m_root = sibling;
  314. m_nodes[sibling].parent = b2_nullNode;
  315. FreeNode(parent);
  316. }
  317. //Validate();
  318. }
  319. // Perform a left or right rotation if node A is imbalanced.
  320. // Returns the new root index.
  321. int32 b2DynamicTree::Balance(int32 iA)
  322. {
  323. b2Assert(iA != b2_nullNode);
  324. b2TreeNode* A = m_nodes + iA;
  325. if (A->IsLeaf() || A->height < 2)
  326. {
  327. return iA;
  328. }
  329. int32 iB = A->child1;
  330. int32 iC = A->child2;
  331. b2Assert(0 <= iB && iB < m_nodeCapacity);
  332. b2Assert(0 <= iC && iC < m_nodeCapacity);
  333. b2TreeNode* B = m_nodes + iB;
  334. b2TreeNode* C = m_nodes + iC;
  335. int32 balance = C->height - B->height;
  336. // Rotate C up
  337. if (balance > 1)
  338. {
  339. int32 iF = C->child1;
  340. int32 iG = C->child2;
  341. b2TreeNode* F = m_nodes + iF;
  342. b2TreeNode* G = m_nodes + iG;
  343. b2Assert(0 <= iF && iF < m_nodeCapacity);
  344. b2Assert(0 <= iG && iG < m_nodeCapacity);
  345. // Swap A and C
  346. C->child1 = iA;
  347. C->parent = A->parent;
  348. A->parent = iC;
  349. // A's old parent should point to C
  350. if (C->parent != b2_nullNode)
  351. {
  352. if (m_nodes[C->parent].child1 == iA)
  353. {
  354. m_nodes[C->parent].child1 = iC;
  355. }
  356. else
  357. {
  358. b2Assert(m_nodes[C->parent].child2 == iA);
  359. m_nodes[C->parent].child2 = iC;
  360. }
  361. }
  362. else
  363. {
  364. m_root = iC;
  365. }
  366. // Rotate
  367. if (F->height > G->height)
  368. {
  369. C->child2 = iF;
  370. A->child2 = iG;
  371. G->parent = iA;
  372. A->aabb.Combine(B->aabb, G->aabb);
  373. C->aabb.Combine(A->aabb, F->aabb);
  374. A->height = 1 + b2Max(B->height, G->height);
  375. C->height = 1 + b2Max(A->height, F->height);
  376. }
  377. else
  378. {
  379. C->child2 = iG;
  380. A->child2 = iF;
  381. F->parent = iA;
  382. A->aabb.Combine(B->aabb, F->aabb);
  383. C->aabb.Combine(A->aabb, G->aabb);
  384. A->height = 1 + b2Max(B->height, F->height);
  385. C->height = 1 + b2Max(A->height, G->height);
  386. }
  387. return iC;
  388. }
  389. // Rotate B up
  390. if (balance < -1)
  391. {
  392. int32 iD = B->child1;
  393. int32 iE = B->child2;
  394. b2TreeNode* D = m_nodes + iD;
  395. b2TreeNode* E = m_nodes + iE;
  396. b2Assert(0 <= iD && iD < m_nodeCapacity);
  397. b2Assert(0 <= iE && iE < m_nodeCapacity);
  398. // Swap A and B
  399. B->child1 = iA;
  400. B->parent = A->parent;
  401. A->parent = iB;
  402. // A's old parent should point to B
  403. if (B->parent != b2_nullNode)
  404. {
  405. if (m_nodes[B->parent].child1 == iA)
  406. {
  407. m_nodes[B->parent].child1 = iB;
  408. }
  409. else
  410. {
  411. b2Assert(m_nodes[B->parent].child2 == iA);
  412. m_nodes[B->parent].child2 = iB;
  413. }
  414. }
  415. else
  416. {
  417. m_root = iB;
  418. }
  419. // Rotate
  420. if (D->height > E->height)
  421. {
  422. B->child2 = iD;
  423. A->child1 = iE;
  424. E->parent = iA;
  425. A->aabb.Combine(C->aabb, E->aabb);
  426. B->aabb.Combine(A->aabb, D->aabb);
  427. A->height = 1 + b2Max(C->height, E->height);
  428. B->height = 1 + b2Max(A->height, D->height);
  429. }
  430. else
  431. {
  432. B->child2 = iE;
  433. A->child1 = iD;
  434. D->parent = iA;
  435. A->aabb.Combine(C->aabb, D->aabb);
  436. B->aabb.Combine(A->aabb, E->aabb);
  437. A->height = 1 + b2Max(C->height, D->height);
  438. B->height = 1 + b2Max(A->height, E->height);
  439. }
  440. return iB;
  441. }
  442. return iA;
  443. }
  444. int32 b2DynamicTree::GetHeight() const
  445. {
  446. if (m_root == b2_nullNode)
  447. {
  448. return 0;
  449. }
  450. return m_nodes[m_root].height;
  451. }
  452. //
  453. float32 b2DynamicTree::GetAreaRatio() const
  454. {
  455. if (m_root == b2_nullNode)
  456. {
  457. return 0.0f;
  458. }
  459. const b2TreeNode* root = m_nodes + m_root;
  460. float32 rootArea = root->aabb.GetPerimeter();
  461. float32 totalArea = 0.0f;
  462. for (int32 i = 0; i < m_nodeCapacity; ++i)
  463. {
  464. const b2TreeNode* node = m_nodes + i;
  465. if (node->height < 0)
  466. {
  467. // Free node in pool
  468. continue;
  469. }
  470. totalArea += node->aabb.GetPerimeter();
  471. }
  472. return totalArea / rootArea;
  473. }
  474. // Compute the height of a sub-tree.
  475. int32 b2DynamicTree::ComputeHeight(int32 nodeId) const
  476. {
  477. b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);
  478. b2TreeNode* node = m_nodes + nodeId;
  479. if (node->IsLeaf())
  480. {
  481. return 0;
  482. }
  483. int32 height1 = ComputeHeight(node->child1);
  484. int32 height2 = ComputeHeight(node->child2);
  485. return 1 + b2Max(height1, height2);
  486. }
  487. int32 b2DynamicTree::ComputeHeight() const
  488. {
  489. int32 height = ComputeHeight(m_root);
  490. return height;
  491. }
  492. void b2DynamicTree::ValidateStructure(int32 index) const
  493. {
  494. if (index == b2_nullNode)
  495. {
  496. return;
  497. }
  498. if (index == m_root)
  499. {
  500. b2Assert(m_nodes[index].parent == b2_nullNode);
  501. }
  502. const b2TreeNode* node = m_nodes + index;
  503. int32 child1 = node->child1;
  504. int32 child2 = node->child2;
  505. if (node->IsLeaf())
  506. {
  507. b2Assert(child1 == b2_nullNode);
  508. b2Assert(child2 == b2_nullNode);
  509. b2Assert(node->height == 0);
  510. return;
  511. }
  512. b2Assert(0 <= child1 && child1 < m_nodeCapacity);
  513. b2Assert(0 <= child2 && child2 < m_nodeCapacity);
  514. b2Assert(m_nodes[child1].parent == index);
  515. b2Assert(m_nodes[child2].parent == index);
  516. ValidateStructure(child1);
  517. ValidateStructure(child2);
  518. }
  519. void b2DynamicTree::ValidateMetrics(int32 index) const
  520. {
  521. if (index == b2_nullNode)
  522. {
  523. return;
  524. }
  525. const b2TreeNode* node = m_nodes + index;
  526. int32 child1 = node->child1;
  527. int32 child2 = node->child2;
  528. if (node->IsLeaf())
  529. {
  530. b2Assert(child1 == b2_nullNode);
  531. b2Assert(child2 == b2_nullNode);
  532. b2Assert(node->height == 0);
  533. return;
  534. }
  535. b2Assert(0 <= child1 && child1 < m_nodeCapacity);
  536. b2Assert(0 <= child2 && child2 < m_nodeCapacity);
  537. int32 height1 = m_nodes[child1].height;
  538. int32 height2 = m_nodes[child2].height;
  539. int32 height;
  540. height = 1 + b2Max(height1, height2);
  541. b2Assert(node->height == height);
  542. juce::ignoreUnused (height);
  543. b2AABB aabb;
  544. aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
  545. b2Assert(aabb.lowerBound == node->aabb.lowerBound);
  546. b2Assert(aabb.upperBound == node->aabb.upperBound);
  547. ValidateMetrics(child1);
  548. ValidateMetrics(child2);
  549. }
  550. void b2DynamicTree::Validate() const
  551. {
  552. ValidateStructure(m_root);
  553. ValidateMetrics(m_root);
  554. int32 freeCount = 0;
  555. int32 freeIndex = m_freeList;
  556. while (freeIndex != b2_nullNode)
  557. {
  558. b2Assert(0 <= freeIndex && freeIndex < m_nodeCapacity);
  559. freeIndex = m_nodes[freeIndex].next;
  560. ++freeCount;
  561. }
  562. b2Assert(GetHeight() == ComputeHeight());
  563. b2Assert(m_nodeCount + freeCount == m_nodeCapacity);
  564. }
  565. int32 b2DynamicTree::GetMaxBalance() const
  566. {
  567. int32 maxBalance = 0;
  568. for (int32 i = 0; i < m_nodeCapacity; ++i)
  569. {
  570. const b2TreeNode* node = m_nodes + i;
  571. if (node->height <= 1)
  572. {
  573. continue;
  574. }
  575. b2Assert(node->IsLeaf() == false);
  576. int32 child1 = node->child1;
  577. int32 child2 = node->child2;
  578. int32 balance = b2Abs(m_nodes[child2].height - m_nodes[child1].height);
  579. maxBalance = b2Max(maxBalance, balance);
  580. }
  581. return maxBalance;
  582. }
  583. void b2DynamicTree::RebuildBottomUp()
  584. {
  585. int32* nodes = (int32*)b2Alloc(m_nodeCount * sizeof(int32));
  586. int32 count = 0;
  587. // Build array of leaves. Free the rest.
  588. for (int32 i = 0; i < m_nodeCapacity; ++i)
  589. {
  590. if (m_nodes[i].height < 0)
  591. {
  592. // free node in pool
  593. continue;
  594. }
  595. if (m_nodes[i].IsLeaf())
  596. {
  597. m_nodes[i].parent = b2_nullNode;
  598. nodes[count] = i;
  599. ++count;
  600. }
  601. else
  602. {
  603. FreeNode(i);
  604. }
  605. }
  606. while (count > 1)
  607. {
  608. float32 minCost = b2_maxFloat;
  609. int32 iMin = -1, jMin = -1;
  610. for (int32 i = 0; i < count; ++i)
  611. {
  612. b2AABB aabbi = m_nodes[nodes[i]].aabb;
  613. for (int32 j = i + 1; j < count; ++j)
  614. {
  615. b2AABB aabbj = m_nodes[nodes[j]].aabb;
  616. b2AABB b;
  617. b.Combine(aabbi, aabbj);
  618. float32 cost = b.GetPerimeter();
  619. if (cost < minCost)
  620. {
  621. iMin = i;
  622. jMin = j;
  623. minCost = cost;
  624. }
  625. }
  626. }
  627. int32 index1 = nodes[iMin];
  628. int32 index2 = nodes[jMin];
  629. b2TreeNode* child1 = m_nodes + index1;
  630. b2TreeNode* child2 = m_nodes + index2;
  631. int32 parentIndex = AllocateNode();
  632. b2TreeNode* parent = m_nodes + parentIndex;
  633. parent->child1 = index1;
  634. parent->child2 = index2;
  635. parent->height = 1 + b2Max(child1->height, child2->height);
  636. parent->aabb.Combine(child1->aabb, child2->aabb);
  637. parent->parent = b2_nullNode;
  638. child1->parent = parentIndex;
  639. child2->parent = parentIndex;
  640. nodes[jMin] = nodes[count-1];
  641. nodes[iMin] = parentIndex;
  642. --count;
  643. }
  644. m_root = nodes[0];
  645. b2Free(nodes);
  646. Validate();
  647. }