/// <summary> /// Iterates over the a rectangular box of ChunkPos values around a given center, starting with the center and working outwards. /// </summary> /// <param name="center">The center position of the chunks to iterate.</param> /// <param name="radiusXZ">The "radius" of the box in X and Z coordinates.</param> /// <param name="radiusY">The "radius" of the box in Y coordinates.</param> /// <param name="action">The action to call for each ChunkPos.</param> public static void IterateOutwards(ChunkPos center, int radiusXZ, int radiusY, Action<ChunkPos> action) { var radius = Math.Max(radiusXZ, radiusY); for (var r = 0; r <= radius; ++r) { /* Only send the ChunkPos values with exact distance r from the center. */ var ry = Math.Min(r, radiusY); for (var y = -ry; y <= ry; ++y) { if (y == -r || y == r) { var rxz = Math.Min(r, radiusXZ); for (var x = -rxz; x <= rxz; ++x) { for (var z = -rxz; z <= rxz; ++z) { action(new ChunkPos(center.X + x, center.Y + y, center.Z + z)); } } } else if (r <= radiusXZ) { for (var i = 0; i <= 2 * r; ++i) { action(new ChunkPos(center.X - r + i, center.Y + y, center.Z - r)); action(new ChunkPos(center.X + r, center.Y + y, center.Z - r + i)); action(new ChunkPos(center.X + r - i, center.Y + y, center.Z + r)); action(new ChunkPos(center.X - r, center.Y + y, center.Z + r - i)); } } } } }
public Chunk GetChunk(ChunkPos chunkPos) { lock (_mutex) { Chunk chunk; if (!_chunkMap.TryGetValue(chunkPos, out chunk)) { chunk = new Chunk(this, chunkPos); _chunkMap[chunkPos] = chunk; Task.Run(() => LoadOrGenerate(chunk)); } return chunk; } }
/// <summary> /// Iterates over the a rectangular box of ChunkPos values around a given center, starting with the center and working outwards. /// </summary> /// <param name="center">The center position of the chunks to iterate.</param> /// <param name="radiusXZ">The "radius" of the box in X and Z coordinates.</param> /// <param name="radiusY">The "radius" of the box in Y coordinates.</param> /// <param name="action">The action to call for each ChunkPos.</param> public static void IterateOutwards(ChunkPos center, int radiusXZ, int radiusY, Action <ChunkPos> action) { var radius = Math.Max(radiusXZ, radiusY); for (var r = 0; r <= radius; ++r) { /* Only send the ChunkPos values with exact distance r from the center. */ var ry = Math.Min(r, radiusY); for (var y = -ry; y <= ry; ++y) { if (y == -r || y == r) { var rxz = Math.Min(r, radiusXZ); for (var x = -rxz; x <= rxz; ++x) { for (var z = -rxz; z <= rxz; ++z) { action(new ChunkPos(center.X + x, center.Y + y, center.Z + z)); } } } else if (r <= radiusXZ) { for (var i = 0; i <= 2 * r; ++i) { action(new ChunkPos(center.X - r + i, center.Y + y, center.Z - r)); action(new ChunkPos(center.X + r, center.Y + y, center.Z - r + i)); action(new ChunkPos(center.X + r - i, center.Y + y, center.Z + r)); action(new ChunkPos(center.X - r, center.Y + y, center.Z + r - i)); } } } } }
private bool IsInViewingFrustum(GameClient gameClient, EntityOffset offset, ChunkPos chunkPos) { /* Check if the bounding sphere of the chunk is in the viewing frustum. */ var df = (double)GeometryConstants.ChunkSize; // Determine the chunk center relative to the viewer. double dx = (chunkPos.X + 0.5) * df - offset.X; double dy = (chunkPos.Y + 0.5) * df - offset.Y; double dz = (chunkPos.Z + 0.5) * df - offset.Z; double t0, t1; // Perform mouselook rotation double ha = gameClient.PositionData.Placement.Orientation.Horizontal; double hc = Math.Cos(ha), hs = Math.Sin(ha); t0 = dx * hc - dz * hs; t1 = dz * hc + dx * hs; dx = t0; dz = t1; double va = -gameClient.PositionData.Placement.Orientation.Vertical; double vc = Math.Cos(va), vs = Math.Sin(va); t0 = dz * vc - dy * vs; t1 = dy * vc + dz * vs; dz = t0; dy = t1; // Check if the chunk is behind the viewer. if (dz > ChunkRadius && dz > ChunkRadius) return false; /* TODO: We can discard even more chunks by taking the left, right, top and bottom planes into account. */ return true; }
public Chunk PeekChunk(ChunkPos chunkPos) { Chunk chunk; _chunkMap.TryGetValue(chunkPos, out chunk); return chunk; }
public Chunk(World world, ChunkPos chunkPos) { World = world; Pos = chunkPos; }