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); }
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()); }
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)); }
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); }