예제 #1
0
            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);
                }
            }
예제 #2
0
        public CompressedVoxelVolume <T> GetUncompressedChunk(Point3l point)
        {
            var page = GetPage(point);

            DecompressPage(page);
            return(page.Voxels);
        }
예제 #3
0
        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;
        }
예제 #4
0
        // 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]);
        }
예제 #5
0
        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]);
        }
예제 #6
0
        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();
        }
예제 #7
0
 public T this[Point3l point]
 {
     get
     {
         return(Get(point));
     }
     set
     {
         Set(point, value);
     }
 }
예제 #8
0
 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);
     }
 }
예제 #9
0
        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);
        }
예제 #10
0
            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));
                }
            }
예제 #11
0
파일: Raytracer.cs 프로젝트: Frassle/Ibasa
        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;
                }
            }
        }
예제 #12
0
        public void Set(Point3l point, T value)
        {
            var chunk = GetUncompressedChunk(point);

            chunk[point] = value;
        }
예제 #13
0
        public T Get(Point3l point)
        {
            var chunk = GetUncompressedChunk(point);

            return(chunk[point]);
        }
예제 #14
0
 public void Set(Point3l point, T value)
 {
     Contract.Requires(Box.Contains(Bounds, point));
     Root.Set(Bounds, point, value);
 }
예제 #15
0
 public T Get(Point3l point)
 {
     Contract.Requires(Box.Contains(Bounds, point));
     return(Root.Get(Bounds, point));
 }
예제 #16
0
파일: Raytracer.cs 프로젝트: bonomali/Ibasa
        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;
                }
            }
        }