protected override void UpdateSingleThreaded()
{
overlapCandidatesX.Clear();
overlapCandidatesY.Clear();
Overlaps.Clear();
//Sort along x axis using insertion sort; the list will be nearly sorted, so very few swaps are necessary.
for (int i = 1; i < entriesX.Count; i++)
{
var entry = entriesX.Elements[i];
for (int j = i - 1; j >= 0; j--)
{
if (entry.boundingBox.Min.X < entriesX.Elements[j].boundingBox.Min.X)
{
entriesX.Elements[j + 1] = entriesX.Elements[j];
entriesX.Elements[j] = entry;
}
else
break;
}
}
//Sort along y axis using insertion sort; the list will be nearly sorted, so very few swaps are necessary.
for (int i = 1; i < entriesY.Count; i++)
{
var entry = entriesY.Elements[i];
for (int j = i - 1; j >= 0; j--)
{
if (entry.boundingBox.Min.Y < entriesY.Elements[j].boundingBox.Min.Y)
{
entriesY.Elements[j + 1] = entriesY.Elements[j];
entriesY.Elements[j] = entry;
}
else
break;
}
}
//Sort along z axis using insertion sort; the list will be nearly sorted, so very few swaps are necessary.
for (int i = 1; i < entriesZ.Count; i++)
{
var entry = entriesZ.Elements[i];
for (int j = i - 1; j >= 0; j--)
{
if (entry.boundingBox.Min.Z < entriesZ.Elements[j].boundingBox.Min.Z)
{
entriesZ.Elements[j + 1] = entriesZ.Elements[j];
entriesZ.Elements[j] = entry;
}
else
break;
}
}
//Hash-set based sweeping is way too slow. 3D sap is really best suited to an incremental approach.
//Sweep the list looking for overlaps.
//Sweep the X axis first; in this phase, add overlaps to the hash set if they exist.
for (int i = 0; i < entriesX.Count; i++)
{
BoundingBox a = entriesX.Elements[i].boundingBox;
for (int j = i + 1; j < entriesX.Count && a.Max.X > entriesX.Elements[j].boundingBox.Min.X; j++)
{
overlapCandidatesX.Add(new BroadPhaseOverlap(entriesX.Elements[i], entriesX.Elements[j]));
}
}
//Sweep the Y axis second; same thing
for (int i = 0; i < entriesY.Count; i++)
{
BoundingBox a = entriesY.Elements[i].boundingBox;
for (int j = i + 1; j < entriesY.Count && a.Max.Y > entriesY.Elements[j].boundingBox.Min.Y; j++)
{
overlapCandidatesY.Add(new BroadPhaseOverlap(entriesY.Elements[i], entriesY.Elements[j]));
}
}
//Sweep the Z axis last
for (int i = 0; i < entriesZ.Count; i++)
{
BoundingBox a = entriesZ.Elements[i].boundingBox;
for (int j = i + 1; j < entriesZ.Count && a.Max.Z > entriesZ.Elements[j].boundingBox.Min.Z; j++)
{
var overlap = new BroadPhaseOverlap(entriesZ.Elements[i], entriesZ.Elements[j]);
if (overlapCandidatesX.Contains(overlap) && overlapCandidatesY.Contains(overlap))
TryToAddOverlap(entriesZ.Elements[i], entriesZ.Elements[j]);
}
}
}