Rasagar/Library/PackageCache/com.unity.probuilder/External/KdTree/KdTreeLib/NearestNeighbourList.cs
2024-08-26 23:07:20 +03:00

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; }
}
}
}