private void Update() { //if (Time.time - lastClear > 1000) { Debug.ClearDeveloperConsole(); // lastClear = Time.time; //} GetChunkCoordFromVector3(playerChunkCoord); // Only update the chunks if the player has moved from the chunk they were previously on. //if (!playerChunkCoord.Equals(playerLastChunkCoord)) // CheckViewDistance(); tmpTimeDelta += Time.deltaTime; //Debug.Log(string.Format("Tick CountLands::{0} GridSize^2::{1}", CountLands, landPoolsSize)); if (CountLands < landPoolsSize)// initilise map { if (tmpTimeDelta > -0.1) { tmpTimeDelta = 0; ChunkCoord pos = PreferedLocArray[0]; PreferedLocArray.RemoveAt(0); Chunk newChunk = new Chunk(pos); if (!settings.enableThreading) { activeChunks.Add(pos); newChunk.PullChunkDataAndUpdateChunk(); } else { lock (threadingChunks) { pos.chunk = newChunk; threadingChunks.Add(pos); } } BoxDebug.DrawBox(new Vector3(pos.x * VoxelData.TileWidthUU, 40, pos.z * VoxelData.TileWidthUU), new Vector3(VoxelData.TileWidthUU, 10, VoxelData.TileWidthUU), Color.red, init_show_time); chunkPools.Add(newChunk); chunkDict.Add(pos, newChunk); CountLands++; } } else // Lazily check and invalidate chunks. { if (tmpTimeDelta > -0.125) { lock (unthreadingChunks){ int size = unthreadingChunks.Count; if (size > 0) { for (int i = 0; i < size; i++) { chunkDict.Remove(unthreadingChunks[i]); } unthreadingChunks.Clear(); } } tmpTimeDelta = 0; CalculatePositionMap(false); if (!settings.enableThreading) { //if (!applyingModifications) // ApplyModifications(); //if (chunksToUpdate.Count > 0) // UpdateChunks(); } } } lock (this) { while (chunksToDraw.Count > 0) { chunksToDraw.Dequeue().AssignMesh(); } } if (Input.GetKeyDown(KeyCode.F3)) { debugScreen.SetActive(!debugScreen.activeSelf); } if (Input.GetKeyDown(KeyCode.F1)) { SaveSystem.SaveWorld(worldData); } }
/** Calculate positions to update. * A grid system that starts at player's position, and flip-expand again and again to reach maximum size. * The grid system was first wirten for UE4's landscape. https://www.youtube.com/watch?v=xvZg9IgXLLE&t=8s * ... now It's used to initialise and update the voxel map. */ public void CalculatePositionMap(bool init) { CC = 0; if (init) { PreferedLocations.Clear(); PreferedLocArray.Clear(); } rCurrentCoord.Set(0, 0); float relativeX = player.position.x - baseLocation.x; float relativeZ = player.position.z - baseLocation.z; rStartCoord.x = Mathf.FloorToInt(relativeX / VoxelData.ChunkWidth); rStartCoord.z = Mathf.FloorToInt(relativeZ / VoxelData.ChunkWidth); int NormalizdRelativeX = rStartCoord.x * VoxelData.ChunkWidth; int NormalizdRelativeZ = rStartCoord.z * VoxelData.ChunkWidth; R0x = NormalizdRelativeX + baseLocation.x; R0z = NormalizdRelativeZ + baseLocation.z; R0y = baseLocation.y; if (init) { BoxDebug.DrawBox(new Vector3(R0x, R0y, R0z), new Vector3(VoxelData.TileWidthUU, 10, VoxelData.TileWidthUU), Color.black, init_show_time); PreferedLocArray.Add(new ChunkCoord(rStartCoord.x, rStartCoord.z)); } int square_case = 0; if (relativeX >= NormalizdRelativeX + VoxelData.HalfTileWidth) { square_case = 1; } if (relativeZ >= NormalizdRelativeZ + VoxelData.HalfTileWidth) { square_case += 2; } minX = rStartCoord.x - settings.GridSize / 2; maxX = rStartCoord.x + settings.GridSize / 2; minZ = rStartCoord.z - settings.GridSize / 2; maxZ = rStartCoord.z + settings.GridSize / 2; Chunk chunkToReposition = null; if (!init) { // Caculate map extensions. //Debug.Log(string.Format("MinMax: minX={0}, maxX={1}, minZ={2}, maxZ={3}", minX, maxX, minZ, maxZ)); if (settings.GridSize % 2 == 0) { if ((square_case & 1) != 0) { minX++; } else { maxX--; } if ((square_case & 2) != 0) { minZ++; } else { maxZ--; } } for (int i = 0; i < landPoolsSize; i++) { Chunk c = chunkPools[i]; ChunkCoord pos = c.coord; if (pos.x < minX || pos.x > maxX || pos.z < minZ || pos.z > maxZ) { chunkToReposition = c; break; } } if (!chunkDict.ContainsKey(rStartCoord)) // check coord not occupied //Debug.Log("start not occupied!!!"); { if (chunkToReposition != null) { RepositionChunk(chunkToReposition, new ChunkCoord(rStartCoord)); } return; } } bool cornerflipped = square_case == 3 || square_case == 2; bool typeA = square_case == 0 || square_case == 3; GridSizeCurrent = 1; rcx = rcz = 0; while (GridSizeCurrent < settings.GridSize) { if (typeA) { if (!cornerflipped) { rcx--; rcz--; } } else { if (cornerflipped) { rcx--; } else { rcz--; } } rCurrentStillx = rcx; if (typeA == cornerflipped) { rCurrentStillx += GridSizeCurrent; } //if(GridSizeCurrent==3) //rCurrentStillx-=1; stillx = rCurrentStillx * VoxelData.ChunkWidth + R0x; rCurrentStillz = rcz; if (cornerflipped) { rCurrentStillz += GridSizeCurrent; } stillz = rCurrentStillz * VoxelData.ChunkWidth + R0z; // Expand X. for (int i = 0; i <= GridSizeCurrent; i++) { rCurrentCoord.x = rcx + i; MT_TmpCoord.Set(rStartCoord.x + rCurrentCoord.x, rStartCoord.z + rCurrentStillz); if (init) { Vector3 pos = new Vector3(R0x + rCurrentCoord.x * VoxelData.TileWidthUU, R0y, stillz); BoxDebug.DrawBox(pos + new Vector3(0, 60, 0), new Vector3(VoxelData.TileWidthUU, 10, VoxelData.TileWidthUU), Color.white, init_show_time); PreferedLocArray.Add(new ChunkCoord(MT_TmpCoord)); } else if (!chunkDict.ContainsKey(MT_TmpCoord)) // check coord not occupied { if (chunkToReposition != null) { RepositionChunk(chunkToReposition, new ChunkCoord(MT_TmpCoord)); } return; } } // Expand Z. int ZIndexOffset = cornerflipped?1:0; for (int i = 1; i <= GridSizeCurrent; i++) { rCurrentCoord.z = rcz + i - ZIndexOffset; MT_TmpCoord.Set(rStartCoord.x + rCurrentStillx, rStartCoord.z + rCurrentCoord.z); if (init) { Vector3 pos = new Vector3(stillx, R0y, R0z + rCurrentCoord.z * VoxelData.TileWidthUU); BoxDebug.DrawBox(pos + new Vector3(0, 60, 0), new Vector3(VoxelData.TileWidthUU, 10, VoxelData.TileWidthUU), Color.red, init_show_time); PreferedLocArray.Add(new ChunkCoord(MT_TmpCoord)); } else if (!chunkDict.ContainsKey(MT_TmpCoord)) // check coord not occupied { if (chunkToReposition != null) { RepositionChunk(chunkToReposition, new ChunkCoord(MT_TmpCoord)); } return; } } GridSizeCurrent++; cornerflipped = !cornerflipped; } //Debug.Log(string.Format("PreferedLocArray::{0} GridSize^2::{1}", PreferedLocArray.Count, landPoolsSize)); }