int CheckNeedBorder(TerrainChunk chunk, int x, int z) { TerrainChunk other = null; var chunkIdx = new ChunkIdx(chunk.chunkIdx.X + x, chunk.chunkIdx.Z + z); visibleChunk.TryGetValue(chunkIdx, out other); return(other != null && other.targetLod == chunk.targetLod + 1 ? 1 : 0); }
void UpdateTerrainChunk() { for (int i = -ViewDist; i <= 2 * ViewDist; ++i) { for (int j = -ViewDist; j <= 2 * ViewDist; ++j) { if (IsChunkVisible(i, j)) { TerrainChunk chunk = null; var chunkIdx = new ChunkIdx(currentIdx.X + i, currentIdx.Z + j); visibleChunk.TryGetValue(chunkIdx, out chunk); if (chunk == null) { chunk = new TerrainChunk(chunkIdx, ChunkSize, TerrainMaterial); } chunk.UpdateLod(); visibleChunk[chunkIdx] = chunk; } } } for (int i = -ViewDist; i <= 2 * ViewDist; ++i) { for (int j = -ViewDist; j <= 2 * ViewDist; ++j) { if (IsChunkVisible(i, j)) { TerrainChunk chunk = null; var chunkIdx = new ChunkIdx(currentIdx.X + i, currentIdx.Z + j); visibleChunk.TryGetValue(chunkIdx, out chunk); chunk.borderInfo = CheckNeedBorder(chunk, -1, 0) + (CheckNeedBorder(chunk, 0, 1) << 1) + (CheckNeedBorder(chunk, 1, 0) << 2) + (CheckNeedBorder(chunk, 0, -1) << 3); chunk.UpdateChunk(); } } } var outsideChunkds = visibleChunk.Keys.Where((chunkIdx) => !IsChunkVisible(chunkIdx.X - currentIdx.X, chunkIdx.Z - currentIdx.Z)).ToList(); foreach (var chunkIdx in outsideChunkds) { var chunk = visibleChunk[chunkIdx]; chunk.Destroy(); visibleChunk.Remove(chunkIdx); } }
// Update is called once per frame void Update() { var pos = Viewer.position; var x = Mathf.FloorToInt(pos.x / ChunkSize); var z = Mathf.FloorToInt(pos.z / ChunkSize); if (currentIdx == null || currentIdx.X != x || currentIdx.Z != z) { currentIdx = new ChunkIdx(x, z); UpdateTerrainChunk(); } }
public TerrainChunk(ChunkIdx idx, float chunkSize, Material material) { chunkIdx = idx; center = new Vector2(chunkIdx.X * chunkSize, chunkIdx.Z * chunkSize); obj = new GameObject(chunkIdx.ToString()); meshFilter = obj.AddComponent <MeshFilter>(); meshRenderer = obj.AddComponent <MeshRenderer>(); meshCollider = obj.AddComponent <MeshCollider>(); previousLod = -1; meshRenderer.material = material; obj.transform.position = new Vector3(center.x, 0, center.y); meshData = new LodMesh[MAX_LOD + 1]; for (int i = 0; i < MAX_LOD + 1; ++i) { meshData[i] = new LodMesh(i, UpdateChunk); } generator.RequestMapData(center, OnReceivedMapData); }