QuadTreeSpace.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. namespace MonoGame.Extended.Collisions.QuadTree;
  4. public class QuadTreeSpace: ISpaceAlgorithm
  5. {
  6. private readonly QuadTree _collisionTree;
  7. private readonly List<ICollisionActor> _actors = new();
  8. private readonly Dictionary<ICollisionActor, QuadtreeData> _targetDataDictionary = new();
  9. public QuadTreeSpace(RectangleF boundary)
  10. {
  11. _collisionTree = new QuadTree(boundary);
  12. }
  13. /// <summary>
  14. /// Inserts the target into the collision tree.
  15. /// The target will have its OnCollision called when collisions occur.
  16. /// </summary>
  17. /// <param name="target">Target to insert.</param>
  18. public void Insert(ICollisionActor target)
  19. {
  20. if (!_targetDataDictionary.ContainsKey(target))
  21. {
  22. var data = new QuadtreeData(target);
  23. _targetDataDictionary.Add(target, data);
  24. _collisionTree.Insert(data);
  25. _actors.Add(target);
  26. }
  27. }
  28. /// <summary>
  29. /// Removes the target from the collision tree.
  30. /// </summary>
  31. /// <param name="target">Target to remove.</param>
  32. public bool Remove(ICollisionActor target)
  33. {
  34. if (_targetDataDictionary.ContainsKey(target))
  35. {
  36. var data = _targetDataDictionary[target];
  37. data.RemoveFromAllParents();
  38. _targetDataDictionary.Remove(target);
  39. _collisionTree.Shake();
  40. _actors.Remove(target);
  41. return true;
  42. }
  43. return false;
  44. }
  45. /// <summary>
  46. /// Restructure a inner collection, if layer is dynamic, because actors can change own position
  47. /// </summary>
  48. public void Reset()
  49. {
  50. _collisionTree.ClearAll();
  51. foreach (var value in _targetDataDictionary.Values)
  52. {
  53. _collisionTree.Insert(value);
  54. }
  55. _collisionTree.Shake();
  56. }
  57. /// <summary>
  58. /// foreach support
  59. /// </summary>
  60. /// <returns></returns>
  61. public List<ICollisionActor>.Enumerator GetEnumerator() => _actors.GetEnumerator();
  62. /// <inheritdoc cref="QuadTree.Query"/>
  63. public IEnumerable<ICollisionActor> Query(RectangleF boundsBoundingRectangle)
  64. {
  65. return _collisionTree.Query(ref boundsBoundingRectangle).Select(x => x.Target);
  66. }
  67. }