Esempio n. 1
0
        public BlockStorage(IBlockPalette globalPalette, byte bitsPerBlock = MinBitsPerBlock)
        {
            _globalPalette = globalPalette;
            BlockPalette   = _globalPalette;

            UpdatePalette(bitsPerBlock);
        }
        public LinearBlockPalette(IBlockPalette globalPalette, byte bitsPerBlock)
        {
            _globalPalette = globalPalette;

            BitsPerBlock         = bitsPerBlock;
            _globalBlockStateIds = new int[1 << BitsPerBlock];

            // store "air"
            _position = 1;
            _globalBlockStateIds[0] = 0;
        }
        // TODO: dont allow public constructor, use a chunk manager/provider instead

        public LocalChunk(IChunkColumn parent, int y, IBlockPalette blockPalette, BlockState airBlock)
        {
            // TODO: validate Y through a chunk manager or something
            Y = y;

            Column       = parent ?? throw new ArgumentNullException(nameof(parent));
            BlockPalette = blockPalette ?? throw new ArgumentNullException(nameof(blockPalette));
            AirBlock     = airBlock;

            // TODO: pool storage arrays
            _blocks = BitArray32.AllocateUninitialized(BlockCount, BlockPalette.BitsPerBlock);
        }
Esempio n. 4
0
        public IChunk RenderChunk(ChunkPosition position, IBlockPalette globalBlockPalette)
        {
            var clientChunk = new Chunk(globalBlockPalette);

            var worldContexts = _client.World.WorldContexts;

            foreach (var worldContext in worldContexts)
            {
                var chunkManager = worldContext.ChunkManager;
                if (!chunkManager.CanGenerate(position) && !chunkManager.IsLoaded(position))
                {
                    Logger.Warn("Skipped chunk at {0}", position);
                    continue;
                }

                var worldChunk = chunkManager.GenerateChunk(position);
                for (var i = 0; i < Minecraft.Units.Chunk.SectionCount; i++)
                {
                    if (!worldChunk.HasSection(i))
                    {
                        continue;
                    }

                    var worldSection      = worldChunk[i];
                    var worldBlockStorage = worldSection.BlockStorage;
                    if (worldBlockStorage.BlockCount == 0)
                    {
                        continue;
                    }

                    var clientSection      = clientChunk.CreateSection(i);
                    var clientBlockStorage = clientSection.BlockStorage;

                    for (var x = 0; x < Minecraft.Units.Chunk.Size; x++)
                    {
                        for (var z = 0; z < Minecraft.Units.Chunk.Size; z++)
                        {
                            for (var y = 0; y < Minecraft.Units.Chunk.SectionHeight; y++)
                            {
                                var worldBlock = worldBlockStorage.GetBlock(x, y, z);
                                if (worldBlock != null)
                                {
                                    clientBlockStorage.SetBlock(x, y, z, worldBlock);
                                }
                            }
                        }
                    }
                }
            }

            return(clientChunk);
        }
        public ChunkSection(Chunk parent, int sectionY, BlockState airBlock, IBlockPalette blockPalette)
        {
            if (sectionY < 0 || sectionY > Chunk.SectionCount)
            {
                throw new ArgumentOutOfRangeException(nameof(sectionY));
            }
            SectionY = sectionY;

            Parent       = parent ?? throw new ArgumentNullException(nameof(parent));
            AirBlock     = airBlock ?? throw new ArgumentNullException(nameof(airBlock));
            BlockPalette = blockPalette ?? throw new ArgumentNullException(nameof(blockPalette));

            _blocks = new BlockState[BlockCount];
            FillBlock(airBlock);
        }
        public static int GetChunkSectionDataLength(ChunkSection section)
        {
            if (section == null)
            {
                throw new ArgumentNullException(nameof(section));
            }

            IBlockPalette palette = section.BlockPalette;

            int length = 0;

            length += sizeof(short);
            length += sizeof(byte);
            length += palette.GetEncodedSize();

            int longCount = GetUnderlyingDataLength(UnderlyingDataSize, palette.BitsPerBlock);

            length += VarInt.GetEncodedSize(longCount);
            length += longCount * sizeof(ulong);

            return(length);
        }
Esempio n. 7
0
 public ChunkSection(IBlockPalette globalPalette)
 {
     BlockStorage = new BlockStorage(globalPalette);
 }
Esempio n. 8
0
 public Chunk(IBlockPalette globalPalette)
 {
     _globalPalette = globalPalette;
 }
Esempio n. 9
0
 public WorldContext(World world, IUidGenerator uidGenerator, IBlockPalette globalPalette)
 {
     _world        = world;
     ChunkManager  = new ChunkManager(globalPalette);
     EntityManager = new EntityManager(this, uidGenerator);
 }
Esempio n. 10
0
        public Chunk(Dimension dimension, ChunkPosition position, BlockState airBlock, IBlockPalette blockPalette)
        {
            Dimension = dimension ?? throw new ArgumentNullException(nameof(dimension));
            Position  = position;

            _sections = new ChunkSection?[SectionCount];
            for (int y = 0; y < _sections.Length; y++)
            {
                _sections[y] = new ChunkSection(this, y, airBlock, blockPalette);
            }
        }
Esempio n. 11
0
 public WorldManager(IBlockRegistry blockRegistry)
 {
     BlockRegistry  = blockRegistry;
     _globalPalette = new GlobalBlockPalette(blockRegistry);
 }
Esempio n. 12
0
 public World(IUidGenerator uidGenerator, IBlockPalette globalPalette) : base(null, uidGenerator, globalPalette)
 {
     _uidGenerator  = uidGenerator;
     _globalPalette = globalPalette;
 }
        public static void WriteBlocks(NetBinaryWriter writer, ReadOnlySpan <BlockState> blocks, IBlockPalette palette)
        {
            if (palette == null)
            {
                throw new ArgumentNullException(nameof(palette));
            }

            // Creating these struct abstractions allow the JIT to inline IdForBlock
            // which yields almost 2x performance. These savings measure up quickly as
            // the function is called millions of times when loading chunks.

            if (palette is DirectBlockPalette directPalette)
            {
                WriteBlocks(writer, blocks, new DirectBlockPaletteWrapper(directPalette));
            }
            else if (palette is IndirectBlockPalette indirectPalette)
            {
                WriteBlocks(writer, blocks, new IndirectBlockPaletteWrapper(indirectPalette));
            }
            else
            {
                WriteBlocks(writer, blocks, palette);
            }
        }
Esempio n. 14
0
 public ChunkManager(IBlockPalette globalPalette)
 {
     _globalPalette = globalPalette;
 }