public bool Set(Boxl bounds, Point3l point, T value) { if (value.Equals(Value) && (Children == null || bounds.Size == Size3i.Unit)) { return(false); } else if (bounds.Size == Size3i.Unit) { Value = value; return(true); } else { Split(); var center = bounds.Center; int index = 0; index |= point.X < center.X ? 0 : 1; index |= point.Y < center.Y ? 0 : 2; index |= point.Z < center.Z ? 0 : 4; bool sparse = Children[index].Set(Subbounds(index, bounds, bounds.Size / 2), point, value); if (sparse) { return(Sparsen()); } return(false); } }
public CompressedVoxelVolume <T> GetUncompressedChunk(Point3l point) { var page = GetPage(point); DecompressPage(page); return(page.Voxels); }
public void Set(Point3l point, T value) { Contract.Requires(Box.Contains(Bounds, point)); long xz = Morton.Encode(point.X - Bounds.X, point.Z - Bounds.Z); Volume[(point.Y - Bounds.Y) + xz * Bounds.Height] = value; }
// Volume is stored in columns (y is up/down), this makes traversals down columns fast. // After that x and z are in morton order. public T Get(Point3l point) { Contract.Requires(Box.Contains(Bounds, point)); long xz = Morton.Encode(point.X - Bounds.X, point.Z - Bounds.Z); return(Volume[(point.Y - Bounds.Y) + xz * Bounds.Height]); }
public T Get(Point3l point) { Contract.Requires(IsUncompressed); point = new Point3l(point.X - Bounds.X, point.Y - Bounds.Y, point.Z - Bounds.Z); long index = point.Y + point.X * Bounds.Height + point.Z * Bounds.Height * Bounds.Width; return(Uncompressed[index]); }
public void Set(Point3l point, T value) { Contract.Requires(IsUncompressed); point = new Point3l(point.X - Bounds.X, point.Y - Bounds.Y, point.Z - Bounds.Z); long index = point.Y + point.X * Bounds.Height + point.Z * Bounds.Height * Bounds.Width; Uncompressed[index] = value; Compressed.Clear(); }
public T this[Point3l point] { get { return(Get(point)); } set { Set(point, value); } }
public T this[Point3l point] { get { Contract.Requires(Box.Contains(Bounds, point)); return(Get(point)); } set { Contract.Requires(Box.Contains(Bounds, point)); Set(point, value); } }
Page GetPage(Point3l point) { Point3l chunk = new Point3l( Functions.Divide(point.X, PageSize.Width) * PageSize.Width, Functions.Divide(point.Y, PageSize.Height) * PageSize.Height, Functions.Divide(point.Z, PageSize.Depth) * PageSize.Depth); if (LastChunk == chunk) { return(LastPage); } LastChunk = chunk; Page page; if (Pages.TryGetValue(chunk, out page)) { page.Timestamp = Timestamp++; } else { if (Pages.Count == Capacity) { var enumerator = Pages.GetEnumerator(); if (enumerator.MoveNext()) { KeyValuePair <Point3l, Page> evict = enumerator.Current; while (enumerator.MoveNext()) { if (enumerator.Current.Value.Timestamp < evict.Value.Timestamp) { evict = enumerator.Current; } } DataOverflow(evict.Value.Voxels); Pages.Remove(evict.Key); } } page = new Page(new CompressedVoxelVolume <T>(new Boxl(chunk, PageSize)), Timestamp++); Pages.Add(chunk, page); DecompressPage(page); DataRequired(page.Voxels); } LastPage = page; return(page); }
public T Get(Boxl bounds, Point3l point) { if (Children == null) { return(Value); } else { var center = bounds.Center; int index = 0; index |= point.X < center.X ? 0 : 1; index |= point.Y < center.Y ? 0 : 2; index |= point.Z < center.Z ? 0 : 4; return(Children[index].Get(Subbounds(index, bounds, bounds.Size / 2), point)); } }
public IEnumerable<Tuple<Point3l, Point3l>> Trace(Point3l start, Point3l end) { var x0 = start.X / GridSize.Width; var y0 = start.Y / GridSize.Height; var z0 = start.Z / GridSize.Depth; var x1 = end.X / GridSize.Width; var y1 = end.Y / GridSize.Height; var z1 = end.Z / GridSize.Depth; var dir = new Vector3l(end.X - start.X, end.Y - start.Y, end.Z - start.Z); var dx = Math.Sign(dir.X); var dy = Math.Sign(dir.Y); var dz = Math.Sign(dir.Z); var deltax = (double)GridSize.Width / Math.Abs(dir.X); var deltay = (double)GridSize.Height / Math.Abs(dir.Y); var deltaz = (double)GridSize.Depth / Math.Abs(dir.Z); var minx = x0 * GridSize.Width; var maxx = minx + GridSize.Width; var miny = y0 * GridSize.Height; var maxy = miny + GridSize.Height; var minz = z0 * GridSize.Depth; var maxz = minz + GridSize.Depth; var distx = ((dx >= 0) ? (maxx - start.X) : (start.X - minx)) / (double)GridSize.Width; var disty = ((dy >= 0) ? (maxy - start.Y) : (start.Y - miny)) / (double)GridSize.Height; var distz = ((dz >= 0) ? (maxz - start.Z) : (start.Z - minz)) / (double)GridSize.Depth; var tx = distx * deltax; var ty = disty * deltay; var tz = distz * deltaz; var prev = new Point3l(x0, y0, z0); var hit = start; while (true) { var grid = new Point3l(x0, y0, z0); yield return Tuple.Create(grid, hit); prev = grid; if (tx <= ty && tx <= tz) { if (x0 == x1) break; hit = new Point3l( start.X + (long)(dir.X * tx), start.Y + (long)(dir.Y * tx), start.Z + (long)(dir.Z * tz)); tx += deltax; x0 += dx; } else if(ty <= tz) { if (y0 == y1) break; hit = new Point3l( start.X + (long)(dir.X * tx), start.Y + (long)(dir.Y * tx), start.Z + (long)(dir.Z * tz)); ty += deltay; y0 += dy; } else { if (z0 == z1) break; hit = new Point3l( start.X + (long)(dir.X * tx), start.Y + (long)(dir.Y * tx), start.Z + (long)(dir.Z * tz)); tz += deltaz; z0 += dz; } } }
public void Set(Point3l point, T value) { var chunk = GetUncompressedChunk(point); chunk[point] = value; }
public T Get(Point3l point) { var chunk = GetUncompressedChunk(point); return(chunk[point]); }
public void Set(Point3l point, T value) { Contract.Requires(Box.Contains(Bounds, point)); Root.Set(Bounds, point, value); }
public T Get(Point3l point) { Contract.Requires(Box.Contains(Bounds, point)); return(Root.Get(Bounds, point)); }
public IEnumerable <Tuple <Point3l, Point3l> > Trace(Point3l start, Point3l end) { var x0 = start.X / GridSize.Width; var y0 = start.Y / GridSize.Height; var z0 = start.Z / GridSize.Depth; var x1 = end.X / GridSize.Width; var y1 = end.Y / GridSize.Height; var z1 = end.Z / GridSize.Depth; var dir = new Vector3l(end.X - start.X, end.Y - start.Y, end.Z - start.Z); var dx = Math.Sign(dir.X); var dy = Math.Sign(dir.Y); var dz = Math.Sign(dir.Z); var deltax = (double)GridSize.Width / Math.Abs(dir.X); var deltay = (double)GridSize.Height / Math.Abs(dir.Y); var deltaz = (double)GridSize.Depth / Math.Abs(dir.Z); var minx = x0 * GridSize.Width; var maxx = minx + GridSize.Width; var miny = y0 * GridSize.Height; var maxy = miny + GridSize.Height; var minz = z0 * GridSize.Depth; var maxz = minz + GridSize.Depth; var distx = ((dx >= 0) ? (maxx - start.X) : (start.X - minx)) / (double)GridSize.Width; var disty = ((dy >= 0) ? (maxy - start.Y) : (start.Y - miny)) / (double)GridSize.Height; var distz = ((dz >= 0) ? (maxz - start.Z) : (start.Z - minz)) / (double)GridSize.Depth; var tx = distx * deltax; var ty = disty * deltay; var tz = distz * deltaz; var prev = new Point3l(x0, y0, z0); var hit = start; while (true) { var grid = new Point3l(x0, y0, z0); yield return(Tuple.Create(grid, hit)); prev = grid; if (tx <= ty && tx <= tz) { if (x0 == x1) { break; } hit = new Point3l( start.X + (long)(dir.X * tx), start.Y + (long)(dir.Y * tx), start.Z + (long)(dir.Z * tz)); tx += deltax; x0 += dx; } else if (ty <= tz) { if (y0 == y1) { break; } hit = new Point3l( start.X + (long)(dir.X * tx), start.Y + (long)(dir.Y * tx), start.Z + (long)(dir.Z * tz)); ty += deltay; y0 += dy; } else { if (z0 == z1) { break; } hit = new Point3l( start.X + (long)(dir.X * tx), start.Y + (long)(dir.Y * tx), start.Z + (long)(dir.Z * tz)); tz += deltaz; z0 += dz; } } }