DynamicTree.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. /*
  2. * Farseer Physics Engine based on Box2D.XNA port:
  3. * Copyright (c) 2010 Ian Qvist
  4. *
  5. * Box2D.XNA port of Box2D:
  6. * Copyright (c) 2009 Brandon Furtwangler, Nathan Furtwangler
  7. *
  8. * Original source Box2D:
  9. * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
  10. *
  11. * This software is provided 'as-is', without any express or implied
  12. * warranty. In no event will the authors be held liable for any damages
  13. * arising from the use of this software.
  14. * Permission is granted to anyone to use this software for any purpose,
  15. * including commercial applications, and to alter it and redistribute it
  16. * freely, subject to the following restrictions:
  17. * 1. The origin of this software must not be misrepresented; you must not
  18. * claim that you wrote the original software. If you use this software
  19. * in a product, an acknowledgment in the product documentation would be
  20. * appreciated but is not required.
  21. * 2. Altered source versions must be plainly marked as such, and must not be
  22. * misrepresented as being the original software.
  23. * 3. This notice may not be removed or altered from any source distribution.
  24. */
  25. using System;
  26. using System.Collections.Generic;
  27. using System.Diagnostics;
  28. using FarseerPhysics.Common;
  29. using Microsoft.Xna.Framework;
  30. namespace FarseerPhysics.Collision
  31. {
  32. /// <summary>
  33. /// A node in the dynamic tree. The client does not interact with this directly.
  34. /// </summary>
  35. internal struct DynamicTreeNode<T>
  36. {
  37. /// <summary>
  38. /// This is the fattened AABB.
  39. /// </summary>
  40. internal AABB AABB;
  41. internal int Child1;
  42. internal int Child2;
  43. internal int LeafCount;
  44. internal int ParentOrNext;
  45. internal T UserData;
  46. internal bool IsLeaf()
  47. {
  48. return Child1 == DynamicTree<T>.NullNode;
  49. }
  50. }
  51. /// <summary>
  52. /// A dynamic tree arranges data in a binary tree to accelerate
  53. /// queries such as volume queries and ray casts. Leafs are proxies
  54. /// with an AABB. In the tree we expand the proxy AABB by Settings.b2_fatAABBFactor
  55. /// so that the proxy AABB is bigger than the client object. This allows the client
  56. /// object to move by small amounts without triggering a tree update.
  57. ///
  58. /// Nodes are pooled and relocatable, so we use node indices rather than pointers.
  59. /// </summary>
  60. public class DynamicTree<T>
  61. {
  62. internal const int NullNode = -1;
  63. private static Stack<int> _stack = new Stack<int>(256);
  64. private int _freeList;
  65. private int _insertionCount;
  66. private int _nodeCapacity;
  67. private int _nodeCount;
  68. private DynamicTreeNode<T>[] _nodes;
  69. /// <summary>
  70. /// This is used incrementally traverse the tree for re-balancing.
  71. /// </summary>
  72. private int _path;
  73. private int _root;
  74. /// <summary>
  75. /// Constructing the tree initializes the node pool.
  76. /// </summary>
  77. public DynamicTree()
  78. {
  79. _root = NullNode;
  80. _nodeCapacity = 16;
  81. _nodes = new DynamicTreeNode<T>[_nodeCapacity];
  82. // Build a linked list for the free list.
  83. for (int i = 0; i < _nodeCapacity - 1; ++i)
  84. {
  85. _nodes[i].ParentOrNext = i + 1;
  86. }
  87. _nodes[_nodeCapacity - 1].ParentOrNext = NullNode;
  88. }
  89. /// <summary>
  90. /// Create a proxy in the tree as a leaf node. We return the index
  91. /// of the node instead of a pointer so that we can grow
  92. /// the node pool.
  93. /// /// </summary>
  94. /// <param name="aabb">The aabb.</param>
  95. /// <param name="userData">The user data.</param>
  96. /// <returns>Index of the created proxy</returns>
  97. public int AddProxy(ref AABB aabb, T userData)
  98. {
  99. int proxyId = AllocateNode();
  100. // Fatten the aabb.
  101. Vector2 r = new Vector2(Settings.AABBExtension, Settings.AABBExtension);
  102. _nodes[proxyId].AABB.LowerBound = aabb.LowerBound - r;
  103. _nodes[proxyId].AABB.UpperBound = aabb.UpperBound + r;
  104. _nodes[proxyId].UserData = userData;
  105. _nodes[proxyId].LeafCount = 1;
  106. InsertLeaf(proxyId);
  107. return proxyId;
  108. }
  109. /// <summary>
  110. /// Destroy a proxy. This asserts if the id is invalid.
  111. /// </summary>
  112. /// <param name="proxyId">The proxy id.</param>
  113. public void RemoveProxy(int proxyId)
  114. {
  115. Debug.Assert(0 <= proxyId && proxyId < _nodeCapacity);
  116. Debug.Assert(_nodes[proxyId].IsLeaf());
  117. RemoveLeaf(proxyId);
  118. FreeNode(proxyId);
  119. }
  120. /// <summary>
  121. /// Move a proxy with a swepted AABB. If the proxy has moved outside of its fattened AABB,
  122. /// then the proxy is removed from the tree and re-inserted. Otherwise
  123. /// the function returns immediately.
  124. /// </summary>
  125. /// <param name="proxyId">The proxy id.</param>
  126. /// <param name="aabb">The aabb.</param>
  127. /// <param name="displacement">The displacement.</param>
  128. /// <returns>true if the proxy was re-inserted.</returns>
  129. public bool MoveProxy(int proxyId, ref AABB aabb, Vector2 displacement)
  130. {
  131. Debug.Assert(0 <= proxyId && proxyId < _nodeCapacity);
  132. Debug.Assert(_nodes[proxyId].IsLeaf());
  133. if (_nodes[proxyId].AABB.Contains(ref aabb))
  134. {
  135. return false;
  136. }
  137. RemoveLeaf(proxyId);
  138. // Extend AABB.
  139. AABB b = aabb;
  140. Vector2 r = new Vector2(Settings.AABBExtension, Settings.AABBExtension);
  141. b.LowerBound = b.LowerBound - r;
  142. b.UpperBound = b.UpperBound + r;
  143. // Predict AABB displacement.
  144. Vector2 d = Settings.AABBMultiplier * displacement;
  145. if (d.X < 0.0f)
  146. {
  147. b.LowerBound.X += d.X;
  148. }
  149. else
  150. {
  151. b.UpperBound.X += d.X;
  152. }
  153. if (d.Y < 0.0f)
  154. {
  155. b.LowerBound.Y += d.Y;
  156. }
  157. else
  158. {
  159. b.UpperBound.Y += d.Y;
  160. }
  161. _nodes[proxyId].AABB = b;
  162. InsertLeaf(proxyId);
  163. return true;
  164. }
  165. /// <summary>
  166. /// Perform some iterations to re-balance the tree.
  167. /// </summary>
  168. /// <param name="iterations">The iterations.</param>
  169. public void Rebalance(int iterations)
  170. {
  171. if (_root == NullNode)
  172. {
  173. return;
  174. }
  175. // Rebalance the tree by removing and re-inserting leaves.
  176. for (int i = 0; i < iterations; ++i)
  177. {
  178. int node = _root;
  179. int bit = 0;
  180. while (_nodes[node].IsLeaf() == false)
  181. {
  182. // Child selector based on a bit in the path
  183. int selector = (_path >> bit) & 1;
  184. // Select the child nod
  185. node = (selector == 0) ? _nodes[node].Child1 : _nodes[node].Child2;
  186. // Keep bit between 0 and 31 because _path has 32 bits
  187. // bit = (bit + 1) % 31
  188. bit = (bit + 1) & 0x1F;
  189. }
  190. ++_path;
  191. RemoveLeaf(node);
  192. InsertLeaf(node);
  193. }
  194. }
  195. /// <summary>
  196. /// Get proxy user data.
  197. /// </summary>
  198. /// <typeparam name="T"></typeparam>
  199. /// <param name="proxyId">The proxy id.</param>
  200. /// <returns>the proxy user data or 0 if the id is invalid.</returns>
  201. public T GetUserData(int proxyId)
  202. {
  203. Debug.Assert(0 <= proxyId && proxyId < _nodeCapacity);
  204. return _nodes[proxyId].UserData;
  205. }
  206. /// <summary>
  207. /// Get the fat AABB for a proxy.
  208. /// </summary>
  209. /// <param name="proxyId">The proxy id.</param>
  210. /// <param name="fatAABB">The fat AABB.</param>
  211. public void GetFatAABB(int proxyId, out AABB fatAABB)
  212. {
  213. Debug.Assert(0 <= proxyId && proxyId < _nodeCapacity);
  214. fatAABB = _nodes[proxyId].AABB;
  215. }
  216. /// <summary>
  217. /// Compute the height of the binary tree in O(N) time. Should not be
  218. /// called often.
  219. /// </summary>
  220. /// <returns></returns>
  221. public int ComputeHeight()
  222. {
  223. return ComputeHeight(_root);
  224. }
  225. /// <summary>
  226. /// Query an AABB for overlapping proxies. The callback class
  227. /// is called for each proxy that overlaps the supplied AABB.
  228. /// </summary>
  229. /// <param name="callback">The callback.</param>
  230. /// <param name="aabb">The aabb.</param>
  231. public void Query(Func<int, bool> callback, ref AABB aabb)
  232. {
  233. _stack.Clear();
  234. _stack.Push(_root);
  235. while (_stack.Count > 0)
  236. {
  237. int nodeId = _stack.Pop();
  238. if (nodeId == NullNode)
  239. {
  240. continue;
  241. }
  242. DynamicTreeNode<T> node = _nodes[nodeId];
  243. if (AABB.TestOverlap(ref node.AABB, ref aabb))
  244. {
  245. if (node.IsLeaf())
  246. {
  247. bool proceed = callback(nodeId);
  248. if (proceed == false)
  249. {
  250. return;
  251. }
  252. }
  253. else
  254. {
  255. _stack.Push(node.Child1);
  256. _stack.Push(node.Child2);
  257. }
  258. }
  259. }
  260. }
  261. /// <summary>
  262. /// Ray-cast against the proxies in the tree. This relies on the callback
  263. /// to perform a exact ray-cast in the case were the proxy contains a Shape.
  264. /// The callback also performs the any collision filtering. This has performance
  265. /// roughly equal to k * log(n), where k is the number of collisions and n is the
  266. /// number of proxies in the tree.
  267. /// </summary>
  268. /// <param name="callback">A callback class that is called for each proxy that is hit by the ray.</param>
  269. /// <param name="input">The ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).</param>
  270. public void RayCast(Func<RayCastInput, int, float> callback, ref RayCastInput input)
  271. {
  272. Vector2 p1 = input.Point1;
  273. Vector2 p2 = input.Point2;
  274. Vector2 r = p2 - p1;
  275. Debug.Assert(r.LengthSquared() > 0.0f);
  276. r.Normalize();
  277. // v is perpendicular to the segment.
  278. Vector2 absV = MathUtils.Abs(new Vector2(-r.Y, r.X));
  279. // Separating axis for segment (Gino, p80).
  280. // |dot(v, p1 - c)| > dot(|v|, h)
  281. float maxFraction = input.MaxFraction;
  282. // Build a bounding box for the segment.
  283. AABB segmentAABB = new AABB();
  284. {
  285. Vector2 t = p1 + maxFraction * (p2 - p1);
  286. Vector2.Min(ref p1, ref t, out segmentAABB.LowerBound);
  287. Vector2.Max(ref p1, ref t, out segmentAABB.UpperBound);
  288. }
  289. _stack.Clear();
  290. _stack.Push(_root);
  291. while (_stack.Count > 0)
  292. {
  293. int nodeId = _stack.Pop();
  294. if (nodeId == NullNode)
  295. {
  296. continue;
  297. }
  298. DynamicTreeNode<T> node = _nodes[nodeId];
  299. if (AABB.TestOverlap(ref node.AABB, ref segmentAABB) == false)
  300. {
  301. continue;
  302. }
  303. // Separating axis for segment (Gino, p80).
  304. // |dot(v, p1 - c)| > dot(|v|, h)
  305. Vector2 c = node.AABB.Center;
  306. Vector2 h = node.AABB.Extents;
  307. float separation = Math.Abs(Vector2.Dot(new Vector2(-r.Y, r.X), p1 - c)) - Vector2.Dot(absV, h);
  308. if (separation > 0.0f)
  309. {
  310. continue;
  311. }
  312. if (node.IsLeaf())
  313. {
  314. RayCastInput subInput;
  315. subInput.Point1 = input.Point1;
  316. subInput.Point2 = input.Point2;
  317. subInput.MaxFraction = maxFraction;
  318. float value = callback(subInput, nodeId);
  319. if (value == 0.0f)
  320. {
  321. // the client has terminated the raycast.
  322. return;
  323. }
  324. if (value > 0.0f)
  325. {
  326. // Update segment bounding box.
  327. maxFraction = value;
  328. Vector2 t = p1 + maxFraction * (p2 - p1);
  329. segmentAABB.LowerBound = Vector2.Min(p1, t);
  330. segmentAABB.UpperBound = Vector2.Max(p1, t);
  331. }
  332. }
  333. else
  334. {
  335. _stack.Push(node.Child1);
  336. _stack.Push(node.Child2);
  337. }
  338. }
  339. }
  340. private int CountLeaves(int nodeId)
  341. {
  342. if (nodeId == NullNode)
  343. {
  344. return 0;
  345. }
  346. Debug.Assert(0 <= nodeId && nodeId < _nodeCapacity);
  347. DynamicTreeNode<T> node = _nodes[nodeId];
  348. if (node.IsLeaf())
  349. {
  350. Debug.Assert(node.LeafCount == 1);
  351. return 1;
  352. }
  353. int count1 = CountLeaves(node.Child1);
  354. int count2 = CountLeaves(node.Child2);
  355. int count = count1 + count2;
  356. Debug.Assert(count == node.LeafCount);
  357. return count;
  358. }
  359. private void Validate()
  360. {
  361. CountLeaves(_root);
  362. }
  363. private int AllocateNode()
  364. {
  365. // Expand the node pool as needed.
  366. if (_freeList == NullNode)
  367. {
  368. Debug.Assert(_nodeCount == _nodeCapacity);
  369. // The free list is empty. Rebuild a bigger pool.
  370. DynamicTreeNode<T>[] oldNodes = _nodes;
  371. _nodeCapacity *= 2;
  372. _nodes = new DynamicTreeNode<T>[_nodeCapacity];
  373. Array.Copy(oldNodes, _nodes, _nodeCount);
  374. // Build a linked list for the free list. The parent
  375. // pointer becomes the "next" pointer.
  376. for (int i = _nodeCount; i < _nodeCapacity - 1; ++i)
  377. {
  378. _nodes[i].ParentOrNext = i + 1;
  379. }
  380. _nodes[_nodeCapacity - 1].ParentOrNext = NullNode;
  381. _freeList = _nodeCount;
  382. }
  383. // Peel a node off the free list.
  384. int nodeId = _freeList;
  385. _freeList = _nodes[nodeId].ParentOrNext;
  386. _nodes[nodeId].ParentOrNext = NullNode;
  387. _nodes[nodeId].Child1 = NullNode;
  388. _nodes[nodeId].Child2 = NullNode;
  389. _nodes[nodeId].LeafCount = 0;
  390. ++_nodeCount;
  391. return nodeId;
  392. }
  393. private void FreeNode(int nodeId)
  394. {
  395. Debug.Assert(0 <= nodeId && nodeId < _nodeCapacity);
  396. Debug.Assert(0 < _nodeCount);
  397. _nodes[nodeId].ParentOrNext = _freeList;
  398. _freeList = nodeId;
  399. --_nodeCount;
  400. }
  401. private void InsertLeaf(int leaf)
  402. {
  403. ++_insertionCount;
  404. if (_root == NullNode)
  405. {
  406. _root = leaf;
  407. _nodes[_root].ParentOrNext = NullNode;
  408. return;
  409. }
  410. // Find the best sibling for this node
  411. AABB leafAABB = _nodes[leaf].AABB;
  412. int sibling = _root;
  413. while (_nodes[sibling].IsLeaf() == false)
  414. {
  415. int child1 = _nodes[sibling].Child1;
  416. int child2 = _nodes[sibling].Child2;
  417. // Expand the node's AABB.
  418. _nodes[sibling].AABB.Combine(ref leafAABB);
  419. _nodes[sibling].LeafCount += 1;
  420. float siblingArea = _nodes[sibling].AABB.Perimeter;
  421. AABB parentAABB = new AABB();
  422. parentAABB.Combine(ref _nodes[sibling].AABB, ref leafAABB);
  423. float parentArea = parentAABB.Perimeter;
  424. float cost1 = 2.0f * parentArea;
  425. float inheritanceCost = 2.0f * (parentArea - siblingArea);
  426. float cost2;
  427. if (_nodes[child1].IsLeaf())
  428. {
  429. AABB aabb = new AABB();
  430. aabb.Combine(ref leafAABB, ref _nodes[child1].AABB);
  431. cost2 = aabb.Perimeter + inheritanceCost;
  432. }
  433. else
  434. {
  435. AABB aabb = new AABB();
  436. aabb.Combine(ref leafAABB, ref _nodes[child1].AABB);
  437. float oldArea = _nodes[child1].AABB.Perimeter;
  438. float newArea = aabb.Perimeter;
  439. cost2 = (newArea - oldArea) + inheritanceCost;
  440. }
  441. float cost3;
  442. if (_nodes[child2].IsLeaf())
  443. {
  444. AABB aabb = new AABB();
  445. aabb.Combine(ref leafAABB, ref _nodes[child2].AABB);
  446. cost3 = aabb.Perimeter + inheritanceCost;
  447. }
  448. else
  449. {
  450. AABB aabb = new AABB();
  451. aabb.Combine(ref leafAABB, ref _nodes[child2].AABB);
  452. float oldArea = _nodes[child2].AABB.Perimeter;
  453. float newArea = aabb.Perimeter;
  454. cost3 = newArea - oldArea + inheritanceCost;
  455. }
  456. // Descend according to the minimum cost.
  457. if (cost1 < cost2 && cost1 < cost3)
  458. {
  459. break;
  460. }
  461. // Expand the node's AABB to account for the new leaf.
  462. _nodes[sibling].AABB.Combine(ref leafAABB);
  463. // Descend
  464. if (cost2 < cost3)
  465. {
  466. sibling = child1;
  467. }
  468. else
  469. {
  470. sibling = child2;
  471. }
  472. }
  473. // Create a new parent for the siblings.
  474. int oldParent = _nodes[sibling].ParentOrNext;
  475. int newParent = AllocateNode();
  476. _nodes[newParent].ParentOrNext = oldParent;
  477. _nodes[newParent].UserData = default(T);
  478. _nodes[newParent].AABB.Combine(ref leafAABB, ref _nodes[sibling].AABB);
  479. _nodes[newParent].LeafCount = _nodes[sibling].LeafCount + 1;
  480. if (oldParent != NullNode)
  481. {
  482. // The sibling was not the root.
  483. if (_nodes[oldParent].Child1 == sibling)
  484. {
  485. _nodes[oldParent].Child1 = newParent;
  486. }
  487. else
  488. {
  489. _nodes[oldParent].Child2 = newParent;
  490. }
  491. _nodes[newParent].Child1 = sibling;
  492. _nodes[newParent].Child2 = leaf;
  493. _nodes[sibling].ParentOrNext = newParent;
  494. _nodes[leaf].ParentOrNext = newParent;
  495. }
  496. else
  497. {
  498. // The sibling was the root.
  499. _nodes[newParent].Child1 = sibling;
  500. _nodes[newParent].Child2 = leaf;
  501. _nodes[sibling].ParentOrNext = newParent;
  502. _nodes[leaf].ParentOrNext = newParent;
  503. _root = newParent;
  504. }
  505. }
  506. private void RemoveLeaf(int leaf)
  507. {
  508. if (leaf == _root)
  509. {
  510. _root = NullNode;
  511. return;
  512. }
  513. int parent = _nodes[leaf].ParentOrNext;
  514. int grandParent = _nodes[parent].ParentOrNext;
  515. int sibling;
  516. if (_nodes[parent].Child1 == leaf)
  517. {
  518. sibling = _nodes[parent].Child2;
  519. }
  520. else
  521. {
  522. sibling = _nodes[parent].Child1;
  523. }
  524. if (grandParent != NullNode)
  525. {
  526. // Destroy parent and connect sibling to grandParent.
  527. if (_nodes[grandParent].Child1 == parent)
  528. {
  529. _nodes[grandParent].Child1 = sibling;
  530. }
  531. else
  532. {
  533. _nodes[grandParent].Child2 = sibling;
  534. }
  535. _nodes[sibling].ParentOrNext = grandParent;
  536. FreeNode(parent);
  537. // Adjust ancestor bounds.
  538. parent = grandParent;
  539. while (parent != NullNode)
  540. {
  541. _nodes[parent].AABB.Combine(ref _nodes[_nodes[parent].Child1].AABB,
  542. ref _nodes[_nodes[parent].Child2].AABB);
  543. Debug.Assert(_nodes[parent].LeafCount > 0);
  544. _nodes[parent].LeafCount -= 1;
  545. parent = _nodes[parent].ParentOrNext;
  546. }
  547. }
  548. else
  549. {
  550. _root = sibling;
  551. _nodes[sibling].ParentOrNext = NullNode;
  552. FreeNode(parent);
  553. }
  554. }
  555. private int ComputeHeight(int nodeId)
  556. {
  557. if (nodeId == NullNode)
  558. {
  559. return 0;
  560. }
  561. Debug.Assert(0 <= nodeId && nodeId < _nodeCapacity);
  562. DynamicTreeNode<T> node = _nodes[nodeId];
  563. int height1 = ComputeHeight(node.Child1);
  564. int height2 = ComputeHeight(node.Child2);
  565. return 1 + Math.Max(height1, height2);
  566. }
  567. }
  568. }