// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT using System; using ClassicalSharp.GraphicsAPI; using OpenTK; namespace ClassicalSharp.Renderers { public static class ChunkSorter { public static void UpdateSortOrder(Game game, ChunkUpdater updater) { Vector3 cameraPos = game.CurrentCameraPos; Vector3I newChunkPos = Vector3I.Floor(cameraPos); newChunkPos.X = (newChunkPos.X & ~0x0F) + 8; newChunkPos.Y = (newChunkPos.Y & ~0x0F) + 8; newChunkPos.Z = (newChunkPos.Z & ~0x0F) + 8; if (newChunkPos == updater.chunkPos) return; ChunkInfo[] chunks = game.MapRenderer.chunks; int[] distances = updater.distances; Vector3I pPos = newChunkPos; updater.chunkPos = pPos; for (int i = 0; i < chunks.Length; i++) { ChunkInfo info = chunks[i]; distances[i] = Utils.DistanceSquared(info.CentreX, info.CentreY, info.CentreZ, pPos.X, pPos.Y, pPos.Z); int dX1 = (info.CentreX - 8) - pPos.X, dX2 = (info.CentreX + 8) - pPos.X; int dY1 = (info.CentreY - 8) - pPos.Y, dY2 = (info.CentreY + 8) - pPos.Y; int dZ1 = (info.CentreZ - 8) - pPos.Z, dZ2 = (info.CentreZ + 8) - pPos.Z; // Back face culling: make sure that the chunk is definitely entirely back facing. info.DrawLeft = !(dX1 <= 0 && dX2 <= 0); info.DrawRight = !(dX1 >= 0 && dX2 >= 0); info.DrawFront = !(dZ1 <= 0 && dZ2 <= 0); info.DrawBack = !(dZ1 >= 0 && dZ2 >= 0); info.DrawBottom = !(dY1 <= 0 && dY2 <= 0); info.DrawTop = !(dY1 >= 0 && dY2 >= 0); } // NOTE: Over 5x faster compared to normal comparison of IComparer.Compare if (distances.Length > 1) QuickSort(distances, chunks, 0, chunks.Length - 1); updater.ResetUsedFlags(); //SimpleOcclusionCulling(); } static void QuickSort(int[] keys, ChunkInfo[] values, int left, int right) { while (left < right) { int i = left, j = right; int pivot = keys[(i + j) / 2]; // partition the list while (i <= j) { while (pivot > keys[i]) i++; while (pivot < keys[j]) j--; if (i <= j) { int key = keys[i]; keys[i] = keys[j]; keys[j] = key; ChunkInfo value = values[i]; values[i] = values[j]; values[j] = value; i++; j--; } } // recurse into the smaller subset if (j - left <= right - i) { if (left < j) QuickSort(keys, values, left, j); left = i; } else { if (i < right) QuickSort(keys, values, i, right); right = j; } } } } }