Exemplo n.º 1
0
        static void GrowMemory(ref WorldAllocator storage, int newElementCapacity)
        {
            if (storage.elementAllocationCapacity < 0)
            {
                throw new InvalidOperationException();
            }

            long extraBytes = UnsafeUtility.SizeOf <RLEElement>() * (newElementCapacity - storage.elementAllocationCapacity);

            long newBytes = UnsafeUtility.SizeOf <RLEColumn>() * (long)storage.columnCount;

            newBytes += UnsafeUtility.SizeOf <RLEElement>() * (long)newElementCapacity;
            void *newPointer = UnsafeUtility.Malloc(newBytes, UnsafeUtility.AlignOf <RLEColumn>(), Allocator.Persistent);

            if (storage.pointer == null)
            {
                UnsafeUtility.MemClear(newPointer, newBytes);
            }
            else
            {
                UnsafeUtility.MemCpy(newPointer, storage.pointer, newBytes - extraBytes);
                UnsafeUtility.MemClear((byte *)newPointer + newBytes - extraBytes, extraBytes);
                UnsafeUtility.Free(storage.pointer, Allocator.Persistent);
            }

            storage.pointer = newPointer;
            storage.elementAllocationCapacity = newElementCapacity;
            storage.elementsStart             = storage.GetColumnPointer(storage.columnCount);
        }
Exemplo n.º 2
0
 public unsafe World(int3 dimensions, int lod, void *data) : this()
 {
     this.lod        = lod;
     this.dimensions = dimensions;
     indexingMulX    = dimensions.z >> lod;
     dimensionMaskXZ = dimensions.xz - 1;
     Storage         = WorldAllocator.Allocate(ColumnCount, data);
 }
Exemplo n.º 3
0
        public static WorldAllocator Allocate(int columnCount)
        {
            WorldAllocator storage = new WorldAllocator();

            storage.columnCount    = columnCount;
            storage.allocationLock = new System.Threading.SpinLock(false);
            GrowMemory(ref storage, columnCount * 4);
            return(storage);
        }
Exemplo n.º 4
0
        public static WorldAllocator Allocate(int columnCount, void *data)
        {
            WorldAllocator storage = new WorldAllocator();

            storage.columnCount               = columnCount;
            storage.allocationLock            = new System.Threading.SpinLock(false);
            storage.pointer                   = data;
            storage.elementsStart             = storage.GetColumnPointer(storage.columnCount);
            storage.elementAllocationCapacity = -1;
            return(storage);
        }
Exemplo n.º 5
0
    // downsample a grid of columns into one column
    public RLEColumn DownSampleColumn(int xStart, int zStart, RLEElement[] buffer, int extraLods, ref WorldBuilder.RLEColumnBuilder columnBuilder, ref int totalVoxels, ref WorldAllocator newStorage)
    {
        // lod 0 = 0, 1
        // lod 1 = 0, 2
        int stepSize        = 1 << lod;
        int steps           = 1 << extraLods;
        int nextVoxelCountY = (dimensions.y >> (lod + extraLods)) - 1;

        columnBuilder.Clear();

        for (int ix = 0; ix < steps; ix++)
        {
            int x = xStart + ix * stepSize;
            for (int iz = 0; iz < steps; iz++)
            {
                int z = zStart + iz * stepSize;
                DownSamplePartial(x, z, extraLods, ref columnBuilder);
            }
        }

        return(columnBuilder.ToFinalColumn(1 << (lod + extraLods), (short)(nextVoxelCountY), buffer, ref totalVoxels, ref newStorage));
    }
Exemplo n.º 6
0
 public RLEElement *ToPointer(ref WorldAllocator storage)
 {
     return(storage.GetElementPointer(this));
 }
Exemplo n.º 7
0
 public RLEElement GetIndex(ref WorldAllocator storage, int idx)
 {
     return(ElementGuardStart(ref storage)[idx + 1]);
 }
Exemplo n.º 8
0
        public RLEColumn(RLEElement[] buffer, int runCount, int solidCount, int voxelScale, ref WorldAllocator allocator)
        {
            this = default;
            if (runCount <= 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            this.runCount = (ushort)runCount;

            int allocationElementCount = runCount + solidCount + 2;

            storagePointer = allocator.AllocateElements(allocationElementCount);

            RLEElement *startPointer = ElementGuardStart(ref allocator);

            // initialize element guards
            startPointer[0] = new RLEElement(0, 0);
            for (int i = 0; i < runCount; i++)
            {
                startPointer[i + 1] = buffer[i];
            }
            startPointer[runCount + 1] = new RLEElement(0, 0);

            int worldMin = int.MaxValue;
            int worldMax = int.MinValue;

            int elementBoundsMin = 0;
            int elementBoundsMax = 0;

            for (int i = runCount - 1; i >= 0; i--)
            {
                RLEElement element = buffer[i];
                elementBoundsMin = elementBoundsMax;
                elementBoundsMax = elementBoundsMin + element.Length;
                if (element.IsAir)
                {
                    continue;
                }
                worldMin = Mathf.Min(worldMin, elementBoundsMin);
                worldMax = Mathf.Max(worldMax, elementBoundsMax);
            }

            if (worldMin == int.MaxValue)
            {
                throw new InvalidOperationException("only air elements in the RLE");
            }

            this.worldMin = (ushort)(worldMin * voxelScale);
            this.worldMax = (ushort)(worldMax * voxelScale);
        }
Exemplo n.º 9
0
 public ColorARGB32 *ColorPointer(ref WorldAllocator storage)
 {
     return((ColorARGB32 *)storagePointer.ToPointer(ref storage) + runCount + 2);
 }
Exemplo n.º 10
0
 public RLEElement *ElementGuardEnd(ref WorldAllocator storage)
 {
     return(storagePointer.ToPointer(ref storage) + runCount + 1);
 }
Exemplo n.º 11
0
 public RLEElement *ElementGuardStart(ref WorldAllocator storage)
 {
     return(storagePointer.ToPointer(ref storage));
 }