Encapsulate a public property (Parents).
Added xml-comments (to fix some compilation warnings)
This commit is contained in:
Andreas Torebring
2023-08-06 19:33:17 +02:00
parent a5db880e42
commit 10a55d34f0
3 changed files with 82 additions and 60 deletions
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Microsoft.Xna.Framework;
namespace MonoGame.Extended.Collisions
@@ -12,8 +11,7 @@ namespace MonoGame.Extended.Collisions
/// </summary>
public class CollisionComponent : SimpleGameComponent
{
private readonly Dictionary<ICollisionActor, QuadtreeData> _targetDataDictionary =
new Dictionary<ICollisionActor, QuadtreeData>();
private readonly Dictionary<ICollisionActor, QuadtreeData> _targetDataDictionary = new();
private readonly Quadtree _collisionTree;
@@ -47,11 +45,11 @@ namespace MonoGame.Extended.Collisions
// Generate list of collision Infos
foreach (var other in collisions)
{
var collisionInfo = new CollisionEventArgs()
{
Other = other.Target,
PenetrationVector = CalculatePenetrationVector(value.Bounds, other.Bounds)
};
var collisionInfo = new CollisionEventArgs
{
Other = other.Target,
PenetrationVector = CalculatePenetrationVector(value.Bounds, other.Bounds)
};
target.OnCollision(collisionInfo);
}
@@ -74,9 +74,9 @@ namespace MonoGame.Extended.Collisions
}
}
}
for (var i = 0; i < dirtyItems.Count; i++)
foreach (var quadtreeData in dirtyItems)
{
dirtyItems[i].MarkClean();
quadtreeData.MarkClean();
}
return objectCount;
}
@@ -87,8 +87,8 @@ namespace MonoGame.Extended.Collisions
/// <param name="data">Data being inserted.</param>
public void Insert(QuadtreeData data)
{
var actorBounds = data.Target.Bounds;
var actorBounds = data.Bounds;
// Object doesn't fit into this node.
if (!NodeBounds.Intersects(actorBounds))
{
@@ -126,7 +126,7 @@ namespace MonoGame.Extended.Collisions
}
else
{
throw new InvalidOperationException($"Cannot remove from a non leaf {nameof(Quadtree)}");
throw new InvalidOperationException($"Cannot remove from a non leaf {nameof(Quadtree)}");
}
}
@@ -135,49 +135,51 @@ namespace MonoGame.Extended.Collisions
/// </summary>
public void Shake()
{
if (!IsLeaf)
if (IsLeaf)
{
List<QuadtreeData> dirtyItems = new List<QuadtreeData>();
return;
}
var numObjects = NumTargets();
if (numObjects == 0)
List<QuadtreeData> dirtyItems = new List<QuadtreeData>();
var numObjects = NumTargets();
if (numObjects == 0)
{
Children.Clear();
}
else if (numObjects < MaxObjectsPerNode)
{
var process = new Queue<Quadtree>();
process.Enqueue(this);
while (process.Count > 0)
{
Children.Clear();
}
else if (numObjects < MaxObjectsPerNode)
{
var process = new Queue<Quadtree>();
process.Enqueue(this);
while (process.Count > 0)
var processing = process.Dequeue();
if (!processing.IsLeaf)
{
var processing = process.Dequeue();
if (!processing.IsLeaf)
foreach (var subTree in processing.Children)
{
foreach (var subTree in processing.Children)
{
process.Enqueue(subTree);
}
process.Enqueue(subTree);
}
else
}
else
{
foreach (var data in processing.Contents)
{
foreach (var data in processing.Contents)
if (data.Dirty == false)
{
if (data.Dirty == false)
{
AddToLeaf(data);
data.MarkDirty();
dirtyItems.Add(data);
}
AddToLeaf(data);
data.MarkDirty();
dirtyItems.Add(data);
}
}
}
Children.Clear();
}
Children.Clear();
}
for (var i = 0; i < dirtyItems.Count; i++)
{
dirtyItems[i].MarkClean();
}
foreach (var quadtreeData in dirtyItems)
{
quadtreeData.MarkClean();
}
}
@@ -241,16 +243,16 @@ namespace MonoGame.Extended.Collisions
{
var recursiveResult = new List<QuadtreeData>();
QueryWithoutReset(area, recursiveResult);
for (var i = 0; i < recursiveResult.Count; i++)
foreach (var quadtreeData in recursiveResult)
{
recursiveResult[i].MarkClean();
quadtreeData.MarkClean();
}
return recursiveResult;
}
private void QueryWithoutReset(IShapeF area, List<QuadtreeData> recursiveResult)
{
if (!NodeBounds.Intersects(area))
if (!NodeBounds.Intersects(area))
return;
if (IsLeaf)
@@ -273,4 +275,4 @@ namespace MonoGame.Extended.Collisions
}
}
}
}
}
@@ -9,37 +9,58 @@ namespace MonoGame.Extended.Collisions;
/// </summary>
public class QuadtreeData
{
private readonly ICollisionActor _target;
private readonly HashSet<Quadtree> _parents = new();
/// <summary>
/// Initialize a new instance of QuadTreeData.
/// </summary>
/// <param name="target"></param>
public QuadtreeData(ICollisionActor target)
{
Target = target;
_target = target;
}
/// <summary>
/// Remove a parent node.
/// </summary>
/// <param name="parent"></param>
public void RemoveParent(Quadtree parent)
{
Parents.Remove(parent);
_parents.Remove(parent);
}
/// <summary>
/// Add a parent node.
/// </summary>
/// <param name="parent"></param>
public void AddParent(Quadtree parent)
{
Parents.Add(parent);
_parents.Add(parent);
}
/// <summary>
/// Remove all parent nodes from this node.
/// </summary>
public void RemoveFromAllParents()
{
foreach (Quadtree parent in Parents.ToList())
foreach (var parent in _parents.ToList())
{
parent.Remove(this);
}
Parents.Clear();
_parents.Clear();
}
public HashSet<Quadtree> Parents = new HashSet<Quadtree>();
/// <summary>
/// Gets the bounding box for collision detection.
/// </summary>
public IShapeF Bounds => _target.Bounds;
/// <summary>
/// Gets or sets the Target for collision.
/// Gets the collision actor target.
/// </summary>
public ICollisionActor Target { get; }
public ICollisionActor Target => _target;
/// <summary>
/// Gets or sets whether Target has had its collision handled this
@@ -47,18 +68,19 @@ public class QuadtreeData
/// </summary>
public bool Dirty { get; private set; }
/// <summary>
/// Mark node as dirty.
/// </summary>
public void MarkDirty()
{
Dirty = true;
}
/// <summary>
/// Mark node as clean, i.e. not dirty.
/// </summary>
public void MarkClean()
{
Dirty = false;
}
/// <summary>
/// Gets or sets the bounding box for collision detection.
/// </summary>
public IShapeF Bounds => Target.Bounds;
}