public Chunk NBTDeserialize(CompoundTag tag) { CompoundTag level = (CompoundTag)tag["Level"]; int x = level.GetInt("xPos"); int z = level.GetInt("zPos"); SubChunk[] subChunks = ArrayUtils.CreateArray <SubChunk>(16); ListTag sections = level.GetList("Sections"); for (int i = 0; i < sections.Count; ++i) { CompoundTag section = ((CompoundTag)sections[i]); SubChunk subChunk = new SubChunk(); byte y = section.GetByte("Y"); subChunk.BlockDatas = section.GetByteArray("Blocks"); subChunk.MetaDatas = new NibbleArray(section.GetByteArray("Data")); subChunk.SkyLights = new NibbleArray(section.GetByteArray("SkyLight")); subChunk.BlockLigths = new NibbleArray(section.GetByteArray("BlockLight")); subChunks[y] = subChunk; } byte[] biomes = level.GetByteArray("Biomes"); short[] cast = new short[256]; int[] heightMap = level.GetIntArray("HeightMap"); heightMap.CopyTo(cast, 0); Chunk chunk = new Chunk(x, z, subChunks, biomes, cast, level.GetList("Entities"), level.GetList("TileEntities")); chunk.LastUpdate = level.GetLong("LastUpdate"); chunk.InhabitedTime = level.GetLong("InhabitedTime"); chunk.LightPopulated = level.GetByte("LightPopulated") == 1; chunk.TerrainPopulated = level.GetByte("TerrainPopulated") == 1; return(chunk); }
public override ChunkMesh Draw(SubChunk chunk, int x, int y, int z, ChunkMesh data) { Shape shape = GetShape(); if (!chunk.getBlock(x, y + 1, z).isSolid(WorldTypes.Direction.down, BlockBin.Air)) { data = FaceDataUp(data, x, y, z, shape); } if (!chunk.getBlock(x, y - 1, z).isSolid(WorldTypes.Direction.up, BlockBin.Air)) { data = FaceDataDown(data, x, y, z, shape); } if (!chunk.getBlock(x, y, z - 1).isSolid(WorldTypes.Direction.north, BlockBin.Air)) { data = FaceDataSouth(data, x, y, z, shape); } if (!chunk.getBlock(x, y, z + 1).isSolid(WorldTypes.Direction.south, BlockBin.Air)) { data = FaceDataNorth(data, x, y, z, shape); } if (!chunk.getBlock(x - 1, y, z).isSolid(WorldTypes.Direction.east, BlockBin.Air)) { data = FaceDataWest(data, x, y, z, shape); } if (!chunk.getBlock(x + 1, y, z).isSolid(WorldTypes.Direction.west, BlockBin.Air)) { data = FaceDataEast(data, x, y, z, shape); } return(data); }
public override void GenerationBasicTerrain(Chunk chunk) { if (this.flatOption != null) { BlockLayers layers = this.flatOption.blockLayers; for (int i = 0; i < 16; ++i) //X { for (int j = 0; j < 16; ++j) //Z { int y = 0; for (int c = 0; c < layers.layers.Count; ++c) { BlockLayer layer = layers.layers[c]; for (int k = 0; k < layer.height; ++k)//Y { if (World.MAX_HEIGHT == y) { Logger.Warn("World MaxHeight 256"); break; } chunk.SetBlock(i, y, j, (byte)layer.block.ID); chunk.SetMetadata(i, y, j, (byte)layer.block.Damage); chunk.SetBiome(i, j, BiomeIDs.Plains); y++; } } } } } else { SubChunk flat = new SubChunk(); for (int i = 0; i < 16; ++i) //X { for (int j = 0; j < 16; ++j) //Z { for (int k = 0; k < 16; ++k) //Y { if (k == 0) { flat.SetBlock(i, k, j, 7); } else if (k == 1 || k == 2) { flat.SetBlock(i, k, j, 3); } else if (k == 3) { flat.SetBlock(i, k, j, 2); } } } } chunk.SubChunks[0] = flat; } }
public SubChunk getChunkAtIndex(int index) { SubChunk subB = null; foreach (SubChunk sub in subChunk) { if (sub.index == index) { subB = sub; } } return(subB); }
public override Chunk DeserializeChunk(CompoundTag tag) { CompoundTag level = tag.GetCompound("").GetCompound("Level"); int x = level.GetInt("xPos"); int z = level.GetInt("zPos"); byte[] biomes = level.GetByteArray("Biomes"); short[] cast = new short[256]; int[] heightMap = level.GetIntArray("HeightMap"); for (int i = 0; i < 256; ++i) { cast[i] = (short)heightMap[i]; } ListTag sections = level.GetList("Sections"); SubChunk[] subChunks = new SubChunk[16]; for (int i = 0; i < sections.Count; ++i) { CompoundTag section = (CompoundTag)sections[i]; SubChunk subChunk = new SubChunk(); byte y = section.GetByte("Y"); byte[] bytes = section.GetByteArray("Blocks"); int[] blocks = new int[4096]; for (int j = 0; j < 4096; ++j) { blocks[j] = bytes[j]; } subChunk.BlockDatas = blocks; subChunk.MetaDatas = new NibbleArray(section.GetByteArray("Data")); subChunk.BlockLight = section.GetByteArray("BlockLight"); subChunk.SkyLight = section.GetByteArray("SkyLight"); subChunks[y] = subChunk; } Chunk chunk = new Chunk(x, z, subChunks, level.GetList("Entities"), level.GetList("TileEntities")) { LastUpdate = level.GetLong("LastUpdate"), LightPopulated = level.GetByte("LightPopulated"), TerrainPopulated = level.GetByte("TerrainPopulated"), V = level.GetByte("V"), InhabitedTime = level.GetLong("InhabitedTime"), Biomes = biomes, HeightMap = cast }; return(chunk); }
public void ChunkSetup() { this.Name = Position.ToString(); // Filling all subchunks for (int sc = 0; sc < SUBCHUNK_COUNT; sc++) { m_SubChunks[sc] = new SubChunk(); m_SubChunks[sc].SubChunkId = sc; m_SubChunks[sc].Fill(true); m_SubChunks[sc].Chunk = this; } isSetup = true; }
public override ChunkMesh Draw(SubChunk chunk, int x, int y, int z, ChunkMesh data) { Shape shape = GetShape(); data = FaceDataSouth(data, x, y, z, shape); data = FaceDataNorth(data, x, y, z, shape); data = FaceDataWest(data, x, y, z, shape); data = FaceDataEast(data, x, y, z, shape); return(data); }
public T CreateSubChunk <T> (float x, float y, float z, SubChunk sub, Chunk chunk) where T : SubChunk { Vector3 position = new Vector3(x, y, z); T newSubChunk = (T)sub.GetPooledInstance <T> (); newSubChunk.transform.position = position; newSubChunk.transform.rotation = Quaternion.Euler(Vector3.zero); newSubChunk.parentChunk = chunk; newSubChunk.transform.parent = chunk.transform; newSubChunk.chunkWidth = chunk.chunkWidth; newSubChunk.chunkHeight = chunk.chunkHeight; newSubChunk.chunkDepth = chunk.chunkDepth; newSubChunk.poolStart(); return(newSubChunk); }
public void ArrayUtilsTests_CreateArrayTest() { SubChunk c = new SubChunk(); SubChunk[] c1 = ArrayUtils.CreateArray(10, c); SubChunk[] c2 = ArrayUtils.CreateArray <SubChunk>(10); for (int i = 0; i < 10; ++i) { Console.WriteLine(c1[i]); } Console.WriteLine(); for (int j = 0; j < 10; ++j) { Console.WriteLine(c2[j]); } }
public Block GetBlock(int x, int y, int z) { if (inRange(x, y, z)) { SubChunk t = getChunkAtPosition(x, y, z); if (t != null) { return(BlockBin.GetBlock(t.getBlockNum(x, y, z))); } else { return(BlockBin.Air); } } else { //return BlockBin.Air; return(world.GetBlock(x, y, z, this)); } }
public void RoundtripTest() { var provider = new LevelDbProvider(null); var flatGenerator = new SuperflatGenerator(Dimension.Overworld); flatGenerator.Initialize(null); SubChunk chunk = flatGenerator.GenerateChunkColumn(new ChunkCoordinates())[0]; using var stream = new MemoryStream(); provider.Write(chunk, stream); byte[] output = stream.ToArray(); var parsedChunk = new SubChunk(); provider.ParseSection(parsedChunk, output); // Assert CollectionAssert.AreEqual(chunk.Blocks, parsedChunk.Blocks); CollectionAssert.AreEqual(chunk.LoggedBlocks, parsedChunk.LoggedBlocks); CollectionAssert.AreEqual(chunk.RuntimeIds, parsedChunk.RuntimeIds); }
void GenerateSubChunks() { for (int i = 0; i < subChunkCount; i++) { float y = i * subChunkSize.y; Vector3 scPos = new Vector3(pos.x, y, pos.z); GameObject subChunk = new GameObject(); subChunk.name = $"SubChunk @{scPos}"; subChunk.transform.position = scPos; subChunk.transform.parent = transform; SubChunk sc = subChunk.AddComponent <SubChunk>(); sc.position = scPos; sc.SetSize(subChunkSize); sc.SetMeshFilter(subChunk.AddComponent <MeshFilter>()); MeshRenderer mr = subChunk.AddComponent <MeshRenderer>(); mr.material = chunkMaterial; sc.SetMeshCollider(subChunk.AddComponent <MeshCollider>()); meshGenerator.RequestGeneration(sc); subChunks[i] = sc; } }
public override ChunkMesh Draw(SubChunk chunk, int x, int y, int z, ChunkMesh data) { return(data); }
public void RequestGeneration(SubChunk chunk) { generationRequests.Enqueue(chunk); }
public void CoordinateCoversions() { int cellIndexX = 0; int cellIndexY = 0; for (int chX = 0; chX < ChunksX; chX++) { for (int chY = 0; chY < ChunksY; chY++) { Chunk chunk = world.GetChunkAtPosition(cellIndexX, cellIndexY); Assert.True(chunk.ChunkXIndex == chX); Assert.True(chunk.ChunkYIndex == chY); Assert.True(chunk.ChunkX == chX * world.CellsPerChunkWidth); Assert.True(chunk.ChunkY == chY * world.CellsPerChunkHeight); for (int schX = 0; schX < SubChunksX; schX++) { for (int schY = 0; schY < SubChunksY; schY++) { SubChunk subchunk = world.GetSubChunkAtPosition(cellIndexX, cellIndexY); Assert.True(subchunk.SubChunkXIndex == schX); Assert.True(subchunk.SubChunkYIndex == schY); Assert.True(subchunk.SubChunkX == chX * world.CellsPerChunkWidth + schX * world.CellsPerSubChunkWidth); Assert.True(subchunk.SubChunkY == chY * world.CellsPerChunkHeight + schY * world.CellsPerSubChunkHeight); for (int cX = 0; cX < CellsX; cX++) { for (int cY = 0; cY < CellsY; cY++) { Cell cell = world.GetCellAtPosition(cellIndexX, cellIndexY); Assert.True(cell.CellXLocal == cX); Assert.True(cell.CellYLocal == cY); Assert.True(cell.CellX == cellIndexX); Assert.True(cell.CellY == cellIndexY); cellIndexY++; } cellIndexY -= CellsY; cellIndexX++; } cellIndexX -= CellsX; cellIndexY += CellsY; } cellIndexX += CellsX; cellIndexY -= CellsY * SubChunksY; } cellIndexX -= CellsX * SubChunksX; cellIndexY += CellsY * SubChunksY; } cellIndexX += CellsX * SubChunksX; cellIndexY = 0; } for (int x = 0; x < world.TotalWorldWidthCells; x++) { for (int y = 0; y < world.TotalWorldHeightCells; y++) { Cell cell = world.GetCellAtPosition(x, y); if (cell.Adjacency.TL != null) { Assert.True(cell.Adjacency.TL.CellX == x - 1); Assert.True(cell.Adjacency.TL.CellY == y - 1); } if (cell.Adjacency.TM != null) { Assert.True(cell.Adjacency.TM.CellX == x); Assert.True(cell.Adjacency.TM.CellY == y - 1); } if (cell.Adjacency.TR != null) { Assert.True(cell.Adjacency.TR.CellX == x + 1); Assert.True(cell.Adjacency.TR.CellY == y - 1); } if (cell.Adjacency.ML != null) { Assert.True(cell.Adjacency.ML.CellX == x - 1); Assert.True(cell.Adjacency.ML.CellY == y); } if (cell.Adjacency.MM != null) { Assert.True(cell.Adjacency.MM.CellX == x); Assert.True(cell.Adjacency.MM.CellY == y); } if (cell.Adjacency.MR != null) { Assert.True(cell.Adjacency.MR.CellX == x + 1); Assert.True(cell.Adjacency.MR.CellY == y); } if (cell.Adjacency.BL != null) { Assert.True(cell.Adjacency.BL.CellX == x - 1); Assert.True(cell.Adjacency.BL.CellY == y + 1); } if (cell.Adjacency.BM != null) { Assert.True(cell.Adjacency.BM.CellX == x); Assert.True(cell.Adjacency.BM.CellY == y + 1); } if (cell.Adjacency.BR != null) { Assert.True(cell.Adjacency.BR.CellX == x + 1); Assert.True(cell.Adjacency.BR.CellY == y + 1); } } } }
// Creates a cube using an array. public static ArrayMesh Render(SubChunk chunk) { var arrayMesh = new ArrayMesh(); // Array containing other arrays. // OpenGL array buffer. var arrays = new Godot.Collections.Array(); arrays.Resize((int)ArrayMesh.ArrayType.Max); // Reset data. Vertices = new Vector3[9999]; Normals = new Vector3[9999]; Colors = new Color[9999]; vertexIdx = 0; if (chunk.isEmpty()) { return(null); } // If sub-chunk is completely surrounded. dont render. if (!chunk.RenderBottom && !chunk.RenderTop && !chunk.RenderLeft && !chunk.RenderRight && !chunk.RenderFront && !chunk.RenderBack) { return(null); } // 16 x 16 x 16 = 4096 blocks. for (int x = 0; x < Chunk.CHUNK_SIZE; x++) { for (int z = 0; z < Chunk.CHUNK_SIZE; z++) { for (int y = 0; y < Chunk.CHUNK_SIZE; y++) { // No cube if not active. if (chunk.GetBlock(x, y, z) == -1) { continue; } // Create cube. CreateBlock(new Vector3(x, y, z), chunk); } } } System.Array.Resize(ref Vertices, vertexIdx); System.Array.Resize(ref Normals, vertexIdx); System.Array.Resize(ref Colors, vertexIdx); // Fill the array with the others arrays. arrays[0] = Vertices; arrays[1] = Normals; arrays[3] = Colors; if (Vertices.Length == 0) { return(null); } // Create surface from arrays. arrayMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays); ApplyMaterial(arrayMesh); // Done. return(arrayMesh); }
private static void CreateBlock(Vector3 position, SubChunk chunk) { // subChunk index in the Chunk itself. [0, 15] int subChunkId = chunk.SubChunkId; // Position as integer. int x = (int)position.x; int y = (int)position.y; int z = (int)position.z; // False if there is a block next to those faces. bool left, right, top, bottom, front, back; top = y != 15 ? chunk.GetBlock(x, y + 1, z) == -1 : true; bottom = y != 0 ? chunk.GetBlock(x, y - 1, z) == -1 : true; left = x != 0 ? chunk.GetBlock(x - 1, y, z) == -1 : true; right = x != 15 ? chunk.GetBlock(x + 1, y, z) == -1 : true; front = z != 15 ? chunk.GetBlock(x, y, z + 1) == -1 : true; back = z != 0 ? chunk.GetBlock(x, y, z - 1) == -1 : true; // If the block is completly surrounded(not seen). if (left && right && top && bottom && front && back) { return; } // Should draw faces? except chunk borders. bool leftChunk = true; bool rightChunk = true; bool backChunk = true; bool frontChunk = true; if (x == 0) { leftChunk = chunk.Chunk.ChunkLeft.GetSubChunk(subChunkId).GetBlock(15, y, z) == -1; } if (x == 15) { rightChunk = chunk.Chunk.ChunkRight.GetSubChunk(subChunkId).GetBlock(0, y, z) == -1; } if (z == 0) { backChunk = chunk.Chunk.ChunkBack.GetSubChunk(subChunkId).GetBlock(x, y, 15) == -1; } if (z == 15) { frontChunk = chunk.Chunk.ChunkFront.GetSubChunk(subChunkId).GetBlock(x, y, 0) == -1; } // Check if there is a block in the above subchunk. // Dont check if the subchunk is the bottom or top one. bool topChunk = true; bool bottomChunk = true; if (subChunkId != 15) { SubChunk topSubChunk = chunk.Chunk.GetSubChunk(subChunkId + 1); if (topSubChunk.isFull()) { topChunk = true; } else { topChunk = topSubChunk.GetBlock(x, 0, z) == -1; } } if (subChunkId != 0) { SubChunk botSubChunk = chunk.Chunk.GetSubChunk(subChunkId - 1); if (botSubChunk.isFull()) { bottomChunk = false; } else { bottomChunk = botSubChunk.GetBlock(x, 15, z) == -1; } } // False if should not render chunk border faces. bool topBorder = y == 15 ? chunk.RenderTop && topChunk : top; bool bottomBorder = y == 0 ? chunk.RenderBottom && bottomChunk : bottom; bool leftBorder = x == 0 ? chunk.RenderLeft && leftChunk : left; bool rightBorder = x == 15 ? chunk.RenderRight && rightChunk : right; bool frontBorder = z == 15 ? chunk.RenderFront && frontChunk : front; bool backBorder = z == 0 ? chunk.RenderBack && backChunk : back; // Display the chunk in green if chunk is surrounded. int gx = (int)(chunk.Chunk.Position.x * 16) + x; int gz = (int)(chunk.Chunk.Position.y * 16) + z; CurrentColor = BlockPalette.GetColor((BLOCK_TYPE)chunk.GetBlock(x, y, z), gx, gz); // Represent each faces of a cube and if it should place // each faces. Placed in the same order in CUBE_FACES enum. bool[] lutFaces = { topBorder, bottomBorder, leftBorder, rightBorder, frontBorder, backBorder }; for (int i = 0; i < 6; i++) { if (lutFaces[i] == true) { CreateFace(i, position); } } }