mirror of
				https://github.com/ClassiCube/ClassiCube.git
				synced 2025-10-30 18:13:56 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			77 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| // Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
 | |
| 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<ChunkInfo>.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;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| } | 
