mirror of
https://github.com/AlexMacocian/MonoGame.Extended.git
synced 2026-07-15 15:09:29 +00:00
Add interface for space splitting and impls
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user