Add interface for space splitting and impls

This commit is contained in:
Gandifil
2023-11-22 23:22:40 +03:00
parent f0d558c8be
commit 01abb187cc
2 changed files with 95 additions and 0 deletions
@@ -0,0 +1,19 @@
using System.Collections.Generic;
namespace MonoGame.Extended.Collisions;
public interface ISpaceAlgorithm
{
void Insert(ICollisionActor actor);
bool Remove(ICollisionActor actor);
IEnumerable<ICollisionActor> Query(RectangleF boundsBoundingRectangle);
List<ICollisionActor>.Enumerator GetEnumerator();
/// <summary>
/// Restructure a space with new positions
/// </summary>
void Reset();
}
@@ -0,0 +1,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);
}
}