84 lines
1.8 KiB
C#
84 lines
1.8 KiB
C#
using System;
|
|
|
|
namespace UnityEngine.ProBuilder.KdTree
|
|
{
|
|
interface INearestNeighbourList<TItem, TDistance>
|
|
{
|
|
bool Add(TItem item, TDistance distance);
|
|
TItem GetFurtherest();
|
|
TItem RemoveFurtherest();
|
|
|
|
int MaxCapacity { get; }
|
|
int Count { get; }
|
|
}
|
|
|
|
class NearestNeighbourList<TItem, TDistance> : INearestNeighbourList<TItem, TDistance>
|
|
{
|
|
public NearestNeighbourList(int maxCapacity, ITypeMath<TDistance> distanceMath)
|
|
{
|
|
this.maxCapacity = maxCapacity;
|
|
this.distanceMath = distanceMath;
|
|
|
|
queue = new PriorityQueue<TItem, TDistance>(maxCapacity, distanceMath);
|
|
}
|
|
|
|
private PriorityQueue<TItem, TDistance> queue;
|
|
|
|
private ITypeMath<TDistance> distanceMath;
|
|
|
|
private int maxCapacity;
|
|
public int MaxCapacity { get { return maxCapacity; } }
|
|
|
|
public int Count { get { return queue.Count; } }
|
|
|
|
public bool Add(TItem item, TDistance distance)
|
|
{
|
|
if (queue.Count >= maxCapacity)
|
|
{
|
|
// If the distance of this item is less than the distance of the last item
|
|
// in our neighbour list then pop that neighbour off and push this one on
|
|
// otherwise don't even bother adding this item
|
|
if (distanceMath.Compare(distance, queue.GetHighestPriority()) < 0)
|
|
{
|
|
queue.Dequeue();
|
|
queue.Enqueue(item, distance);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
queue.Enqueue(item, distance);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public TItem GetFurtherest()
|
|
{
|
|
if (Count == 0)
|
|
throw new Exception("List is empty");
|
|
else
|
|
return queue.GetHighest();
|
|
}
|
|
|
|
public TDistance GetFurtherestDistance()
|
|
{
|
|
if (Count == 0)
|
|
throw new Exception("List is empty");
|
|
else
|
|
return queue.GetHighestPriority();
|
|
}
|
|
|
|
public TItem RemoveFurtherest()
|
|
{
|
|
return queue.Dequeue();
|
|
}
|
|
|
|
public bool IsCapacityReached
|
|
{
|
|
get { return Count == MaxCapacity; }
|
|
}
|
|
}
|
|
}
|