Beispiel #1
0
        public bool ConsumeChanges()
        {
            ChunkBlocks blocks = Chunk.Blocks;

            if (!Features.useDifferentialSerialization)
            {
                return(true);
            }

            if (Features.useDifferentialSerialization_ForceSaveHeaders)
            {
                if (blocks.modifiedBlocks.Count <= 0)
                {
                    return(true);
                }
            }
            else
            {
                if (blocks.modifiedBlocks.Count <= 0)
                {
                    return(false);
                }
            }

            Dictionary <BlockPos, BlockData> blocksDictionary = new Dictionary <BlockPos, BlockData>();

            // Create a map of modified blocks and their positions
            // TODO: Depending on the amount of changes this could become a performance bottleneck
            for (int i = 0; i < blocks.modifiedBlocks.Count; i++)
            {
                BlockPos pos = blocks.modifiedBlocks[i];
                // Remove any existing blocks in the dictionary. They come from the existing save and are overwritten
                blocksDictionary.Remove(pos);
                blocksDictionary.Add(pos, blocks.Get(Helpers.GetChunkIndex1DFrom3D(pos.x, pos.y, pos.z)));
            }

            int cnt = blocksDictionary.Keys.Count;

            if (cnt > 0)
            {
                blocksModified    = new BlockData[cnt];
                positionsModified = new BlockPos[cnt];

                int index = 0;
                foreach (KeyValuePair <BlockPos, BlockData> pair in blocksDictionary)
                {
                    blocksModified[index]    = pair.Value;
                    positionsModified[index] = pair.Key;
                    ++index;
                }
            }

            return(true);
        }
Beispiel #2
0
        public Rect GetTexture(Chunk chunk, ref Vector3Int localPos, Direction direction)
        {
            if (uvs.Count == 1)
            {
                return(uvs[0]);
            }

            if (textureType == TextureConfigType.Connected)
            {
                ChunkBlocks blocks        = chunk.Blocks;
                int         localPosIndex = Helpers.GetChunkIndex1DFrom3D(localPos.x, localPos.y, localPos.z);
                ushort      blockType     = blocks.Get(localPosIndex).Type;

                // Side blocks
                bool n_, _e, s_, _w;
                // Corner blocks
                bool nw, ne, se, sw;

                int index1, index2, index3;
                int sizeWithPadding     = chunk.SideSize + Env.CHUNK_PADDING_2;
                int sizeWithPaddingPow2 = sizeWithPadding * sizeWithPadding;

                switch (direction)
                {
                case Direction.up:
                    index1 = localPosIndex + sizeWithPaddingPow2;       // + (0,1,0)
                    index2 = index1 - sizeWithPadding;                  // - (0,0,1)
                    index3 = index1 + sizeWithPadding;                  // + (0,0,1)

                    sw = blocks.Get(index2 - 1).Type == blockType;      // -1,1,-1
                    s_ = blocks.Get(index2).Type == blockType;          //  0,1,-1
                    se = blocks.Get(index2 + 1).Type == blockType;      //  1,1,-1
                    _w = blocks.Get(index1 - 1).Type == blockType;      // -1,1, 0
                    _e = blocks.Get(index1 + 1).Type == blockType;      //  1,1, 0
                    nw = blocks.Get(index3 - 1).Type == blockType;      // -1,1, 1
                    n_ = blocks.Get(index3).Type == blockType;          //  0,1, 1
                    ne = blocks.Get(index3 + 1).Type == blockType;      //  1,1, 1
                    break;

                case Direction.down:
                    index1 = localPosIndex - sizeWithPaddingPow2;      // - (0,1,0)
                    index2 = index1 - sizeWithPadding;                 // - (0,0,1)
                    index3 = index1 + sizeWithPadding;                 // + (0,0,1)

                    sw = blocks.Get(index2 - 1).Type == blockType;     // -1,-1,-1
                    s_ = blocks.Get(index2).Type == blockType;         //  0,-1,-1
                    se = blocks.Get(index2 + 1).Type == blockType;     //  1,-1,-1
                    _w = blocks.Get(index1 - 1).Type == blockType;     // -1,-1, 0
                    _e = blocks.Get(index1 + 1).Type == blockType;     //  1,-1, 0
                    nw = blocks.Get(index3 - 1).Type == blockType;     // -1,-1, 1
                    n_ = blocks.Get(index3).Type == blockType;         //  0,-1, 1
                    ne = blocks.Get(index3 + 1).Type == blockType;     //  1,-1, 1
                    break;

                case Direction.north:
                    index1 = localPosIndex + sizeWithPadding;       // + (0,0,1)
                    index2 = index1 - sizeWithPaddingPow2;          // - (0,1,0)
                    index3 = index1 + sizeWithPaddingPow2;          // + (0,1,0)

                    sw = blocks.Get(index2 - 1).Type == blockType;  // -1,-1,1
                    se = blocks.Get(index2 + 1).Type == blockType;  //  1,-1,1
                    _w = blocks.Get(index1 - 1).Type == blockType;  // -1, 0,1
                    _e = blocks.Get(index1 + 1).Type == blockType;  //  1, 0,1
                    nw = blocks.Get(index3 - 1).Type == blockType;  // -1, 1,1
                    s_ = blocks.Get(index2).Type == blockType;      //  0,-1,1
                    n_ = blocks.Get(index3).Type == blockType;      //  0, 1,1
                    ne = blocks.Get(index3 + 1).Type == blockType;  //  1, 1,1
                    break;

                case Direction.south:
                    index1 = localPosIndex - sizeWithPadding;       // - (0,0,1)
                    index2 = index1 - sizeWithPaddingPow2;          // - (0,1,0)
                    index3 = index1 + sizeWithPaddingPow2;          // + (0,1,0)

                    sw = blocks.Get(index2 - 1).Type == blockType;  // -1,-1,-1
                    se = blocks.Get(index2 + 1).Type == blockType;  //  1,-1,-1
                    _w = blocks.Get(index1 - 1).Type == blockType;  // -1, 0,-1
                    _e = blocks.Get(index1 + 1).Type == blockType;  //  1, 0,-1
                    nw = blocks.Get(index3 - 1).Type == blockType;  // -1, 1,-1
                    s_ = blocks.Get(index2).Type == blockType;      //  0,-1,-1
                    n_ = blocks.Get(index3).Type == blockType;      //  0, 1,-1
                    ne = blocks.Get(index3 + 1).Type == blockType;  //  1, 1,-1
                    break;

                case Direction.east:
                    index1 = localPosIndex + 1;                                  // + (1,0,0)
                    index2 = index1 - sizeWithPaddingPow2;                       // - (0,1,0)
                    index3 = index1 + sizeWithPaddingPow2;                       // + (0,1,0)

                    sw = blocks.Get(index2 - sizeWithPadding).Type == blockType; // 1,-1,-1
                    s_ = blocks.Get(index2).Type == blockType;                   // 1,-1, 0
                    se = blocks.Get(index2 + sizeWithPadding).Type == blockType; // 1,-1, 1
                    _w = blocks.Get(index1 - sizeWithPadding).Type == blockType; // 1, 0,-1
                    _e = blocks.Get(index1 + sizeWithPadding).Type == blockType; // 1, 0, 1
                    nw = blocks.Get(index3 - sizeWithPadding).Type == blockType; // 1, 1,-1
                    n_ = blocks.Get(index3).Type == blockType;                   // 1, 1, 0
                    ne = blocks.Get(index3 + sizeWithPadding).Type == blockType; // 1, 1, 1
                    break;

                default:                                                         //case Direction.west:
                    index1 = localPosIndex - 1;                                  // - (1,0,0)
                    index2 = index1 - sizeWithPaddingPow2;                       // - (0,1,0)
                    index3 = index1 + sizeWithPaddingPow2;                       // + (0,1,0)

                    sw = blocks.Get(index2 - sizeWithPadding).Type == blockType; // -1,-1,-1
                    s_ = blocks.Get(index2).Type == blockType;                   // -1,-1, 0
                    se = blocks.Get(index2 + sizeWithPadding).Type == blockType; // -1,-1, 1
                    _w = blocks.Get(index1 - sizeWithPadding).Type == blockType; // -1, 0,-1
                    _e = blocks.Get(index1 + sizeWithPadding).Type == blockType; // -1, 0, 1
                    nw = blocks.Get(index3 - sizeWithPadding).Type == blockType; // -1, 1,-1
                    n_ = blocks.Get(index3).Type == blockType;                   // -1, 1, 0
                    ne = blocks.Get(index3 + sizeWithPadding).Type == blockType; // -1, 1, 1
                    break;
                }

                int uvIndex = ConnectedTextures.GetTexture(n_, _e, s_, _w, nw, ne, se, sw);
                return(uvs[uvIndex]);
            }

            if (uvs.Count > 1)
            {
                int hash = localPos.GetHashCode();
                if (hash < 0)
                {
                    hash *= -1;
                }

                float randomNumber = (hash % 100) / 100f;
                randomNumber *= uvs.Count;

                return(uvs[(int)randomNumber]);
            }

            Debug.LogError("There were no textures for " + textureName);
            return(new Rect());
        }
Beispiel #3
0
        public static BlockLightData CalculateColors(Chunk chunk, int localPosIndex, Direction direction)
        {
            // With AO turned off, do not generate any fancy data
            if (!chunk.World.config.AddAOToMesh)
            {
                return(new BlockLightData());
            }

            // Side blocks
            bool n_Solid, _eSolid, s_Solid, _wSolid;
            // Corner blocks
            bool nwSolid, neSolid, seSolid, swSolid;

            ChunkBlocks blocks = chunk.Blocks;
            int         index1, index2, index3;

            int sizeWithPadding     = chunk.SideSize + Env.CHUNK_PADDING_2;
            int sizeWithPaddingPow2 = sizeWithPadding * sizeWithPadding;

            switch (direction)
            {
            case Direction.up:
                index1 = localPosIndex + sizeWithPaddingPow2; // + (0,1,0)
                index2 = index1 - sizeWithPadding;            // - (0,0,1)
                index3 = index1 + sizeWithPadding;            // + (0,0,1)

                swSolid = blocks.Get(index2 - 1).Solid;       // -1,1,-1
                s_Solid = blocks.Get(index2).Solid;           //  0,1,-1
                seSolid = blocks.Get(index2 + 1).Solid;       //  1,1,-1
                _wSolid = blocks.Get(index1 - 1).Solid;       // -1,1, 0
                _eSolid = blocks.Get(index1 + 1).Solid;       //  1,1, 0
                nwSolid = blocks.Get(index3 - 1).Solid;       // -1,1, 1
                n_Solid = blocks.Get(index3).Solid;           //  0,1, 1
                neSolid = blocks.Get(index3 + 1).Solid;       //  1,1, 1
                break;

            case Direction.down:
                index1 = localPosIndex - sizeWithPaddingPow2; // - (0,1,0)
                index2 = index1 - sizeWithPadding;            // - (0,0,1)
                index3 = index1 + sizeWithPadding;            // + (0,0,1)

                swSolid = blocks.Get(index2 - 1).Solid;       // -1,-1,-1
                s_Solid = blocks.Get(index2).Solid;           //  0,-1,-1
                seSolid = blocks.Get(index2 + 1).Solid;       //  1,-1,-1
                _wSolid = blocks.Get(index1 - 1).Solid;       // -1,-1, 0
                _eSolid = blocks.Get(index1 + 1).Solid;       //  1,-1, 0
                nwSolid = blocks.Get(index3 - 1).Solid;       // -1,-1, 1
                n_Solid = blocks.Get(index3).Solid;           //  0,-1, 1
                neSolid = blocks.Get(index3 + 1).Solid;       //  1,-1, 1
                break;

            case Direction.north:
                index1 = localPosIndex + sizeWithPadding;   // + (0,0,1)
                index2 = index1 - sizeWithPaddingPow2;      // - (0,1,0)
                index3 = index1 + sizeWithPaddingPow2;      // + (0,1,0)

                swSolid = blocks.Get(index2 - 1).Solid;     // -1,-1,1
                seSolid = blocks.Get(index2 + 1).Solid;     //  1,-1,1
                _wSolid = blocks.Get(index1 - 1).Solid;     // -1, 0,1
                _eSolid = blocks.Get(index1 + 1).Solid;     //  1, 0,1
                nwSolid = blocks.Get(index3 - 1).Solid;     // -1, 1,1
                s_Solid = blocks.Get(index2).Solid;         //  0,-1,1
                n_Solid = blocks.Get(index3).Solid;         //  0, 1,1
                neSolid = blocks.Get(index3 + 1).Solid;     //  1, 1,1
                break;

            case Direction.south:
                index1 = localPosIndex - sizeWithPadding;   // - (0,0,1)
                index2 = index1 - sizeWithPaddingPow2;      // - (0,1,0)
                index3 = index1 + sizeWithPaddingPow2;      // + (0,1,0)

                swSolid = blocks.Get(index2 - 1).Solid;     // -1,-1,-1
                seSolid = blocks.Get(index2 + 1).Solid;     //  1,-1,-1
                _wSolid = blocks.Get(index1 - 1).Solid;     // -1, 0,-1
                _eSolid = blocks.Get(index1 + 1).Solid;     //  1, 0,-1
                nwSolid = blocks.Get(index3 - 1).Solid;     // -1, 1,-1
                s_Solid = blocks.Get(index2).Solid;         //  0,-1,-1
                n_Solid = blocks.Get(index3).Solid;         //  0, 1,-1
                neSolid = blocks.Get(index3 + 1).Solid;     //  1, 1,-1
                break;

            case Direction.east:
                index1 = localPosIndex + 1;                           // + (1,0,0)
                index2 = index1 - sizeWithPaddingPow2;                // - (0,1,0)
                index3 = index1 + sizeWithPaddingPow2;                // + (0,1,0)

                swSolid = blocks.Get(index2 - sizeWithPadding).Solid; // 1,-1,-1
                s_Solid = blocks.Get(index2).Solid;                   // 1,-1, 0
                seSolid = blocks.Get(index2 + sizeWithPadding).Solid; // 1,-1, 1
                _wSolid = blocks.Get(index1 - sizeWithPadding).Solid; // 1, 0,-1
                _eSolid = blocks.Get(index1 + sizeWithPadding).Solid; // 1, 0, 1
                nwSolid = blocks.Get(index3 - sizeWithPadding).Solid; // 1, 1,-1
                n_Solid = blocks.Get(index3).Solid;                   // 1, 1, 0
                neSolid = blocks.Get(index3 + sizeWithPadding).Solid; // 1, 1, 1
                break;

            default:                                                  //case Direction.west:
                index1 = localPosIndex - 1;                           // - (1,0,0)
                index2 = index1 - sizeWithPaddingPow2;                // - (0,1,0)
                index3 = index1 + sizeWithPaddingPow2;                // + (0,1,0)

                swSolid = blocks.Get(index2 - sizeWithPadding).Solid; // -1,-1,-1
                s_Solid = blocks.Get(index2).Solid;                   // -1,-1, 0
                seSolid = blocks.Get(index2 + sizeWithPadding).Solid; // -1,-1, 1
                _wSolid = blocks.Get(index1 - sizeWithPadding).Solid; // -1, 0,-1
                _eSolid = blocks.Get(index1 + sizeWithPadding).Solid; // -1, 0, 1
                nwSolid = blocks.Get(index3 - sizeWithPadding).Solid; // -1, 1,-1
                n_Solid = blocks.Get(index3).Solid;                   // -1, 1, 0
                neSolid = blocks.Get(index3 + sizeWithPadding).Solid; // -1, 1, 1
                break;
            }

            return(new BlockLightData(nwSolid, n_Solid, neSolid, _eSolid, seSolid, s_Solid, swSolid, _wSolid));
        }
Beispiel #4
0
        public bool DoCompression()
        {
            if (Features.useDifferentialSerialization)
            {
                BlockProvider provider      = Chunk.World.blockProvider;
                int           blockPosSize  = StructSerialization.TSSize <BlockPos> .ValueSize;
                int           blockDataSize = StructSerialization.TSSize <BlockData> .ValueSize;

                int posLenBytes = blocksModified.Length * blockPosSize;
                int blkLenBytes = blocksModified.Length * blockDataSize;
                positionsBytes = new byte[posLenBytes];
                blocksBytes    = new byte[blkLenBytes];

                unsafe
                {
                    // Pack positions to a byte array
                    fixed(byte *pDst = positionsBytes)
                    {
                        for (int i = 0, j = 0; i < blocksModified.Length; i++, j += blockPosSize)
                        {
                            *(BlockPos *)&pDst[j] = positionsModified[i];
                        }
                    }

                    // Pack block data to a byte array
                    fixed(BlockData *pBD = blocksModified)
                    fixed(byte *pDst = blocksBytes)
                    {
                        for (int i = 0, j = 0; i < blocksModified.Length; i++, j += blockDataSize)
                        {
                            BlockData *bd = &pBD[i];
                            // Convert block types from internal optimized version into global types
                            ushort typeInConfig = provider.GetConfig(bd->Type).TypeInConfig;

                            *(BlockData *)&pDst[j] = new BlockData(typeInConfig, bd->Solid);
                        }
                    }
                }
            }
            else
            {
                LocalPools    pools    = Globals.WorkPool.GetPool(Chunk.ThreadID);
                BlockProvider provider = Chunk.World.blockProvider;

                int blockDataSize     = StructSerialization.TSSize <BlockData> .ValueSize;
                int requestedByteSize = Env.CHUNK_SIZE_POW_3 * blockDataSize;

                // Pop large enough buffers from the pool
                byte[] tmp             = pools.byteArrayPool.Pop(requestedByteSize);
                byte[] bytesCompressed = pools.byteArrayPool.Pop(requestedByteSize);
                {
                    ChunkBlocks blocks = Chunk.Blocks;
                    int         i      = 0;

                    int index   = Helpers.ZERO_CHUNK_INDEX;
                    int yOffset = Env.CHUNK_SIZE_WITH_PADDING_POW_2 - Env.CHUNK_SIZE * Env.CHUNK_SIZE_WITH_PADDING;
                    int zOffset = Env.CHUNK_SIZE_WITH_PADDING - Env.CHUNK_SIZE;

                    for (int y = 0; y < Env.CHUNK_SIZE; ++y, index += yOffset)
                    {
                        for (int z = 0; z < Env.CHUNK_SIZE; ++z, index += zOffset)
                        {
                            for (int x = 0; x < Env.CHUNK_SIZE; ++x, i += blockDataSize, ++index)
                            {
                                BlockData bd = blocks.Get(index);

                                // Convert block types from internal optimized version into global types
                                ushort typeInConfig = provider.GetConfig(bd.Type).TypeInConfig;

                                // Write updated block data to destination buffer
                                unsafe
                                {
                                    fixed(byte *pDst = tmp)
                                    {
                                        *(BlockData *)&pDst[i] = new BlockData(typeInConfig, bd.Solid);
                                    }
                                }
                            }
                        }
                    }

                    // Compress bytes
                    int blkLenBytes = CLZF2.lzf_compress(tmp, requestedByteSize, ref bytesCompressed);
                    blocksBytes = new byte[blkLenBytes];

                    // Copy data from a temporary buffer to block buffer
                    Array.Copy(bytesCompressed, 0, blocksBytes, 0, blkLenBytes);
                }

                // Return our temporary buffer back to the pool
                pools.byteArrayPool.Push(bytesCompressed);
                pools.byteArrayPool.Push(tmp);
            }

            return(true);
        }