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