public unsafe void SaveChunk(BlockTerrain.Chunk chunk) { if (!chunk.isEdited) { return; } lock (locker) { Point2 p = new Point2(chunk.chunkx, chunk.chunky); long value; if (chunkOffsets.TryGetValue(p, out value)) { stream.Seek(value, SeekOrigin.Begin); WriteChunkHeader(stream, chunk.chunkx, chunk.chunky); fixed(byte *bptr = &buffer[0]) { int *iptr = (int *)bptr; for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { int index = BlockTerrain.GetCellIndex(15 - x, 0, y); int h = 0; while (h < 128) { *iptr = chunk.GetCellValue(index); iptr++; h++; index++; } } } } stream.Write(buffer, 0, 131072); fixed(byte *bptr = &buffer[0]) { int *iptr = (int *)bptr; for (int x = 0; x < 16; x++) { int index = BlockTerrain.GetShiftIndex(15 - x, 0); int h = 0; while (h < 16) { *iptr = chunk.GetShiftValue(index); iptr++; h++; index++; } } } stream.Write(buffer, 0, 1024); } } }
public void GenerateSuperFlatTerrain(BlockTerrain.Chunk chunk) { GameInfo info = WorldManager.Project.GameInfo; int startx = chunk.chunkx << 4; int startz = chunk.chunkx << 4; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 128; y++) { if (y < info.TerrainLevel) { if (y <= 1) { chunk.SetCellValue(x, y, z, 1); } else if (startx + x >= 200 || startz + z >= 200) { chunk.SetCellValue(x, y, z, info.TerrainOceanBlockIndex); } else { chunk.SetCellValue(x, y, z, info.TerrainBlockIndex); } } } } } }
// Use this for initialization void Start() { BlockTerrain.Chunk chunk = new BlockTerrain.Chunk(16, 128, 16); MeshGenerator g = new MeshGenerator(); Stopwatch stopwatch = new Stopwatch(); int count = BlocksData.Blocks.Length; for (int i = 0; i < count; i++) { if (BlocksData.IsTransparent[i]) { try { stopwatch.Reset(); stopwatch.Start(); for (int k = 0; k < 50; k++) { BlocksData.NormalBlocks[i].GenerateTerrain(1, 1, 1, i, chunk, g); } stopwatch.Stop(); UnityEngine.Debug.LogFormat("tested block: {0}; time: {1}ms", BlocksData.Blocks[i].Name, stopwatch.ElapsedMilliseconds); } catch (System.Exception e) { UnityEngine.Debug.LogException(e); } } } }
public void GenerateTerrain(int x, int y, int z, int value, int face, BlockTerrain.Chunk chunk, ref CellFace data) { int?color = GetColor(BlockTerrain.GetData(value)); data.TextureSlot = color.HasValue ? BlocksData.paintedTextures[TextureSlot] : TextureSlot; data.Color = BlocksData.ColorFromInt(color); }
public void UpdateChunk(int index) { BlockTerrain.ChunkStatics statics = Terrain.chunkStats.Get(index); if (statics.needsToBeCreated && !statics.needsToBeDestroyed) { BlockTerrain.Chunk chunk = Terrain.GetChunk(index); InstantiateChunk(chunk); //if (chunk.XminusOne != null && chunk.XminusOne.Statics(Terrain).IsNormal) //{ // QuqueChunkUpdate(chunk.XminusOne.index, 3); //} //if (chunk.XplusOne != null && chunk.XplusOne.Statics(Terrain).IsNormal) //{ // QuqueChunkUpdate(chunk.XplusOne.index, 3); //} //if (chunk.YminusOne != null && chunk.YminusOne.Statics(Terrain).IsNormal) //{ // QuqueChunkUpdate(chunk.YminusOne.index, 3); //} //if (chunk.YplusOne != null && chunk.YplusOne.Statics(Terrain).IsNormal) //{ // QuqueChunkUpdate(chunk.YplusOne.index, 3); //} statics.needsToBeCreated = false; } else if (statics.needsToBeDestroyed) { chunkRenderer.RemoveChunk(index); //chunkInstanceManager.UnloadChunkInstance(Terrain.chunkInstances[index]); statics.needsToBeDestroyed = false; } ChunkInstance instance; switch (statics.state) { case 3: instance = Terrain.chunkInstances[index]; instance.UpdateMesh(0); instance.UpdateMesh(1); //chunkInstanceManager.UpdateChunkInstance(instance); break; case 1: instance = Terrain.chunkInstances[index]; instance.UpdateMesh(0); //chunkInstanceManager.UpdateChunkInstance(instance); break; case 2: instance = Terrain.chunkInstances[index]; instance.UpdateMesh(1); //chunkInstanceManager.UpdateChunkInstance(instance); break; } statics.state = 0; }
public void GenerateAllBlocks(BlockTerrain.Chunk chunk) { #if GREEDY_MESHING GenerateChunkMesh(chunk); GenerateNormalBlocks(chunk); #else GenerateCubeBlocks(chunk); #endif }
// public void SaveChunkEntries () // { // Point2[] entries = new Point2[chunkOffsets.Count]; // foreach (KeyValuePair<Point2, long> p in chunkOffsets) { // entries [(int)((p.Value - 786444L) / 132112L)] = p.Key; // } // // stream.Seek (0, SeekOrigin.Begin); // for (int i = 0; i < entries.Length; i++) { // WriteChunkEntry (stream, -entries [i].X, entries [i].Y, i); // } // } public unsafe void ReadChunk(int chunkx, int chunky, BlockTerrain.Chunk chunk) { lock (locker) { Point2 p = new Point2(chunkx, chunky); long value; if (chunkOffsets.TryGetValue(p, out value)) { stream.Seek(value, SeekOrigin.Begin); ReadChunkHeader(stream); stream.Read(buffer, 0, 131072); fixed(byte *bptr = &buffer[0]) { int *iptr = (int *)bptr; for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { int index = BlockTerrain.GetCellIndex(15 - x, 0, y); int h = 0; while (h < 128) { chunk.SetCellValue(index, *iptr); iptr++; h++; index++; } } } } stream.Read(buffer, 0, 1024); fixed(byte *bptr = &buffer[0]) { int *iptr = (int *)bptr; for (int x = 0; x < 16; x++) { int index = BlockTerrain.GetShiftIndex(15 - x, 0); int h = 0; while (h < 16) { chunk.SetShiftValue(index, *iptr); iptr++; h++; index++; } } } } } }
public void InstantiateChunk(BlockTerrain.Chunk c) { int index = Terrain.GetChunkIndex(c.chunkx, c.chunky); ChunkInstance instance = Terrain.chunkInstances[index]; instance.UpdateAll(c); instance.UpdateMesh(0); instance.UpdateMesh(1); chunkRenderer.AddChunk(index); //chunkInstanceManager.LoadChunkInstance(instance); }
public void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g) { Vector3 v000 = new Vector3(x, y, z); Vector3 v001 = new Vector3(x, y, z + 1.0f); Vector3 v010 = new Vector3(x, y + 1.0f, z); Vector3 v011 = new Vector3(x, y + 1.0f, z + 1.0f); Vector3 v100 = new Vector3(x + 1.0f, y, z); Vector3 v101 = new Vector3(x + 1.0f, y, z + 1.0f); Vector3 v110 = new Vector3(x + 1.0f, y + 1.0f, z); Vector3 v111 = new Vector3(x + 1.0f, y + 1.0f, z + 1.0f); GreedyTerrainMesh terrainMesh = g.AlphaTest; int texSlot = TextureSlot; Color color = map.Lookup(chunk.GetShiftValue(x, z)); int content = chunk.GetCellContent(x - 1, y, z); if (content != BlockTerrain.NULL_BLOCK_CONTENT && content != Index && BlocksData.IsTransparent[content]) { terrainMesh.NormalQuad(v001, v011, v010, v000, texSlot, color); } content = chunk.GetCellContent(x, y - 1, z); if (content != BlockTerrain.NULL_BLOCK_CONTENT && content != Index && BlocksData.IsTransparent[content]) { terrainMesh.NormalQuad(v000, v100, v101, v001, texSlot, color); } content = chunk.GetCellContent(x, y, z - 1); if (content != BlockTerrain.NULL_BLOCK_CONTENT && content != Index && BlocksData.IsTransparent[content]) { terrainMesh.NormalQuad(v000, v010, v110, v100, texSlot, color); } content = chunk.GetCellContent(x + 1, y, z); if (content != BlockTerrain.NULL_BLOCK_CONTENT && content != Index && BlocksData.IsTransparent[content]) { terrainMesh.NormalQuad(v100, v110, v111, v101, texSlot, color); } content = chunk.GetCellContent(x, y + 1, z); if (content != BlockTerrain.NULL_BLOCK_CONTENT && content != Index && BlocksData.IsTransparent[content]) { terrainMesh.NormalQuad(v111, v110, v010, v011, texSlot, color); } content = chunk.GetCellContent(x, y, z + 1); if (content != BlockTerrain.NULL_BLOCK_CONTENT && content != Index && BlocksData.IsTransparent[content]) { terrainMesh.NormalQuad(v101, v111, v011, v001, texSlot, color); } }
public void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g) { int d = BlockTerrain.GetData(value); if (furnitureManager.isTransparent[GetDesignIndex(d)]) { g.AlphaTest.Mesh(x, y, z, furnitureManager.GetFurniture(GetDesignIndex(d), GetRotation(d))); } else { g.Terrain.Mesh(x, y, z, furnitureManager.GetFurniture(GetDesignIndex(d), GetRotation(d))); } }
public void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g) { int?color = GetColor(BlockTerrain.GetData(value)); if (color.HasValue) { g.Terrain.Mesh(x, y, z, paintedBlockMeshes[GetVariant(BlockTerrain.GetData(value))], BlocksData.DEFAULT_COLORS[color.Value]); } else { g.Terrain.Mesh(x, y, z, blockMeshes[GetVariant(BlockTerrain.GetData(value))], Color.white); } }
public void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g) { int data = BlockTerrain.GetData(value); int?i = GetColor(data); GreedyTerrainMesh terrainMesh = useAlphaTest ? g.AlphaTest : g.Terrain; if (i.HasValue) { terrainMesh.Mesh(x, y, z, paintedBlockMeshes[GetVariant(data)], BlocksData.DEFAULT_COLORS[i.Value]); } else { terrainMesh.Mesh(x, y, z, blockMeshes[GetVariant(data)], unpaintedColor); } }
public void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g) { switch (GetFace(BlockTerrain.GetData(value))) { case 1: g.AlphaTest.TwoSidedQuad( new Vector3(x, y, z), new Vector3(x, y + 1.0f, z), new Vector3(x, y + 1.0f, z + 1.0f), new Vector3(x, y, z + 1.0f), TextureSlot, map.Lookup(chunk.GetShiftValue(x, z)) ); break; case 0: g.AlphaTest.TwoSidedQuad( new Vector3(x, y, z + 1.0f), new Vector3(x, y + 1.0f, z + 1.0f), new Vector3(x + 1.0f, y + 1.0f, z + 1.0f), new Vector3(x + 1.0f, y, z + 1.0f), TextureSlot, map.Lookup(chunk.GetShiftValue(x, z)) ); break; case 3: g.AlphaTest.TwoSidedQuad( new Vector3(x + 1.0f, y, z + 1.0f), new Vector3(x + 1.0f, y + 1.0f, z + 1.0f), new Vector3(x + 1.0f, y + 1.0f, z), new Vector3(x + 1.0f, y, z), TextureSlot, map.Lookup(chunk.GetShiftValue(x, z)) ); break; case 2: g.AlphaTest.TwoSidedQuad( new Vector3(x + 1.0f, y, z), new Vector3(x + 1.0f, y + 1.0f, z), new Vector3(x, y + 1.0f, z), new Vector3(x, y, z), TextureSlot, map.Lookup(chunk.GetShiftValue(x, z)) ); break; default: throw new UnityException("undefined face: " + GetFace(BlockTerrain.GetData(value))); } }
public void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g) { int textureSlot = GetIsSmall(BlockTerrain.GetData(value)) ? 84 : 85; Color color = GrassBlock.map.Lookup(chunk.GetShiftValue(x, z)); g.AlphaTest.TwoSidedQuad(new Vector3(x, y, z), new Vector3(x + 1.0f, y, z + 1.0f), new Vector3(x + 1.0f, y + 1.0f, z + 1.0f), new Vector3(x, y + 1.0f, z), textureSlot, color); g.AlphaTest.TwoSidedQuad(new Vector3(x, y, z + 1.0f), new Vector3(x + 1.0f, y, z), new Vector3(x + 1.0f, y + 1.0f, z), new Vector3(x, y + 1.0f, z + 1.0f), textureSlot, color); }
public void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g) { int textureSlot = TextureSlot; Color color = Color.white; g.AlphaTest.TwoSidedQuad(new Vector3(x, y, z), new Vector3(x + 1.0f, y, z + 1.0f), new Vector3(x + 1.0f, y + 1.0f, z + 1.0f), new Vector3(x, y + 1.0f, z), textureSlot, color); g.AlphaTest.TwoSidedQuad(new Vector3(x, y, z + 1.0f), new Vector3(x + 1.0f, y, z), new Vector3(x + 1.0f, y + 1.0f, z), new Vector3(x, y + 1.0f, z + 1.0f), textureSlot, color); }
public void ChangeCell(int x, int y, int z, int newValue) { int index = Terrain.GetChunkIndex(x >> 4, z >> 4); BlockTerrain.Chunk c = Terrain.GetChunk(index); BlockTerrain.ChunkStatics state = Terrain.chunkStats.Get(index); if (c != null) { int cx = x & 15; int cz = z & 15; int content = c.GetCellContent(cx, y, cz); if (content != 0) { state.state = 3; } content = BlockTerrain.GetContent(newValue); if (content != 0) { state.state = 3; } c.SetCellValue(cx, y, cz, newValue); c.isEdited = true; if (cx == 0 && c.XminusOne != null) { QuqueChunkUpdate(c.XminusOne.index, 3); } else if (cx == 15 && c.XplusOne != null) { QuqueChunkUpdate(c.XplusOne.index, 3); } if (cz == 0 && c.YminusOne != null) { QuqueChunkUpdate(c.YminusOne.index, 3); } else if (cz == 15 && c.YplusOne != null) { QuqueChunkUpdate(c.YplusOne.index, 3); } QuqueChunkUpdate(c.index); } }
public void GenerateTerrain(int x, int y, int z, int value, int face, BlockTerrain.Chunk chunk, ref CellFace data) { switch (face) { case CellFace.TOP: data.TextureSlot = 0; data.Color = map.Lookup(chunk.GetShiftValue(x, z)); break; case CellFace.BOTTOM: data.TextureSlot = 2; data.Color = Color.white; break; default: data.TextureSlot = 3; data.Color = Color.white; break; } }
public void GenerateNormalBlocks(BlockTerrain.Chunk chunk) { bool[] isTransparent = BlocksData.IsTransparent; INormalBlock[] normalBlocks = BlocksData.NormalBlocks; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 128; y++) { int value = chunk.GetCellValue(x, y, z); int content = BlockTerrain.GetContent(value); if (isTransparent[content]) { normalBlocks[content].GenerateTerrain(x, y, z, value, chunk, this); } } } } }
public void GenerateCubeBlocks(BlockTerrain.Chunk chunk) { bool[] isTransparent = BlocksData.IsTransparent; IStandardCubeBlock[] cubeBlocks = BlocksData.StandardCubeBlocks; INormalBlock[] normalBlocks = BlocksData.NormalBlocks; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 128; y++) { int value = chunk.GetCellValue(x, y, z); int content = BlockTerrain.GetContent(value); if (isTransparent[content]) { normalBlocks[content].GenerateTerrain(x, y, z, value, chunk, this); } else { Vector3 v000 = new Vector3(x, y, z); Vector3 v001 = new Vector3(x, y, z + 1.0f); Vector3 v010 = new Vector3(x, y + 1.0f, z); Vector3 v011 = new Vector3(x, y + 1.0f, z + 1.0f); Vector3 v100 = new Vector3(x + 1.0f, y, z); Vector3 v101 = new Vector3(x + 1.0f, y, z + 1.0f); Vector3 v110 = new Vector3(x + 1.0f, y + 1.0f, z); Vector3 v111 = new Vector3(x + 1.0f, y + 1.0f, z + 1.0f); var cellFace = new CellFace(); var block = cubeBlocks[content]; int neighbor = chunk.GetCellContent(x - 1, y, z); if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor]) { block.GenerateTerrain(x, y, z, value, CellFace.BACK, chunk, ref cellFace); Terrain.NormalQuad(v000, v001, v011, v010, cellFace.TextureSlot, cellFace.Color); } neighbor = chunk.GetCellContent(x, y - 1, z); if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor]) { block.GenerateTerrain(x, y, z, value, CellFace.BOTTOM, chunk, ref cellFace); Terrain.NormalQuad(v001, v000, v100, v101, cellFace.TextureSlot, cellFace.Color); } neighbor = chunk.GetCellContent(x, y, z - 1); if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor]) { block.GenerateTerrain(x, y, z, value, CellFace.LEFT, chunk, ref cellFace); Terrain.NormalQuad(v100, v000, v010, v110, cellFace.TextureSlot, cellFace.Color); } neighbor = chunk.GetCellContent(x + 1, y, z); if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor]) { block.GenerateTerrain(x, y, z, value, CellFace.FRONT, chunk, ref cellFace); Terrain.NormalQuad(v101, v100, v110, v111, cellFace.TextureSlot, cellFace.Color); } neighbor = chunk.GetCellContent(x, y + 1, z); if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor]) { block.GenerateTerrain(x, y, z, value, CellFace.TOP, chunk, ref cellFace); Terrain.NormalQuad(v011, v111, v110, v010, cellFace.TextureSlot, cellFace.Color); } neighbor = chunk.GetCellContent(x, y, z + 1); if (neighbor != BlockTerrain.NULL_BLOCK_CONTENT && BlocksData.IsTransparent[neighbor]) { block.GenerateTerrain(x, y, z, value, CellFace.RIGHT, chunk, ref cellFace); Terrain.NormalQuad(v001, v101, v111, v011, cellFace.TextureSlot, cellFace.Color); } } } } } }
public void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g) { g.AlphaTest.Mesh(x, y, z, meshes[BlockTerrain.GetData(value)], Color.white); }
public void GenerateFluidTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, GreedyTerrainMesh terrainMesh, Color topColor, Color sideColor) { float height1, height2, height3, height4; int data = BlockTerrain.GetData(value); if (GetIsTop(data)) { int cellValueFast = chunk.GetCellValue(x - 1, y, z - 1); int cellValueFast2 = chunk.GetCellValue(x, y, z - 1); int cellValueFast3 = chunk.GetCellValue(x + 1, y, z - 1); int cellValueFast4 = chunk.GetCellValue(x - 1, y, z); int cellValueFast5 = chunk.GetCellValue(x + 1, y, z); int cellValueFast6 = chunk.GetCellValue(x - 1, y, z + 1); int cellValueFast7 = chunk.GetCellValue(x, y, z + 1); int cellValueFast8 = chunk.GetCellValue(x + 1, y, z + 1); float h = CalculateNeighborHeight(cellValueFast); float num = CalculateNeighborHeight(cellValueFast2); float h2 = CalculateNeighborHeight(cellValueFast3); float num2 = CalculateNeighborHeight(cellValueFast4); float num3 = CalculateNeighborHeight(cellValueFast5); float h3 = CalculateNeighborHeight(cellValueFast6); float num4 = CalculateNeighborHeight(cellValueFast7); float h4 = CalculateNeighborHeight(cellValueFast8); float levelHeight = GetLevelHeight(GetLevel(data)); height1 = CalculateFluidVertexHeight(h, num, num2, levelHeight); height2 = CalculateFluidVertexHeight(num, h2, levelHeight, num3); height3 = CalculateFluidVertexHeight(levelHeight, num3, num4, h4); height4 = CalculateFluidVertexHeight(num2, levelHeight, h3, num4); } else { height1 = 1f; height2 = 1f; height3 = 1f; height4 = 1f; } Vector3 v000 = new Vector3(x, y, z); Vector3 v001 = new Vector3(x, y, z + 1f); Vector3 v010 = new Vector3(x, y + height1, z); Vector3 v011 = new Vector3(x, y + height4, z + 1f); Vector3 v100 = new Vector3(x + 1.0f, y, z); Vector3 v101 = new Vector3(x + 1.0f, y, z + 1f); Vector3 v110 = new Vector3(x + 1.0f, y + height2, z); Vector3 v111 = new Vector3(x + 1.0f, y + height3, z + 1f); int v = chunk.GetCellValue(x - 1, y, z); if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index) { terrainMesh.NormalQuad(v001, v011, v010, v000, TextureSlot, sideColor); } v = chunk.GetCellValue(x, y - 1, z); if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index) { terrainMesh.NormalQuad(v000, v100, v101, v001, TextureSlot, sideColor); } v = chunk.GetCellValue(x, y, z - 1); if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index) { terrainMesh.NormalQuad(v000, v010, v110, v100, TextureSlot, sideColor); } v = chunk.GetCellValue(x + 1, y, z); if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index) { terrainMesh.NormalQuad(v100, v110, v111, v101, TextureSlot, sideColor); } v = chunk.GetCellValue(x, y + 1, z); if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index) { terrainMesh.NormalQuad(v111, v110, v010, v011, TextureSlot, topColor); } v = chunk.GetCellValue(x, y, z + 1); if (v != BlockTerrain.NULL_BLOCK_VALUE && BlockTerrain.GetContent(v) != Index) { terrainMesh.NormalQuad(v101, v111, v011, v001, TextureSlot, sideColor); } }
public void GenerateTerrain(int x, int y, int z, int value, int face, BlockTerrain.Chunk chunk, ref CellFace data) { data.TextureSlot = face == CellFace.TOP || face == CellFace.BOTTOM ? 21 : TextureSlot; data.Color = Color.white; }
public override void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g) { GenerateFluidTerrain(x, y, z, value, chunk, g.Terrain, Color.white, Color.white); }
public override void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g) { Color color = map.Lookup(chunk.GetShiftValue(x, z)); GenerateFluidTerrain(x, y, z, value, chunk, g.AlphaTest, color, color); }
public void GenerateChunkMesh(BlockTerrain.Chunk chunk) { bool[] isTrans = BlocksData.IsTransparent; IStandardCubeBlock[] blocks = BlocksData.StandardCubeBlocks; CellFace[] mask; int u, v, n, w, h, j, i, l, k; int[] off; int[] x; int[] dim = new int[] { 16, 128, 16 }; for (int d = 0; d < 3; d++) { off = new int[] { 0, 0, 0 }; x = new int[] { 0, 0, 0 }; u = (d + 1) % 3; v = (d + 2) % 3; off[d] = 1; //face = d; mask = new CellFace[dim[u] * dim[v]]; for (x[d] = -1; x[d] < dim[d];) { //Debug.LogFormat("x[d]: {0}", x[d]); for (n = 0; n < mask.Length; n++) { mask[n].TextureSlot = -1; } n = 0; for (x[v] = 0; x[v] < dim[v]; x[v]++) { for (x[u] = 0; x[u] < dim[u]; x[u]++) { int va = chunk.GetCellValue(x[0], x[1], x[2]); int vb = chunk.GetCellValue(x[0] + off[0], x[1] + off[1], x[2] + off[2]); if (va == BlockTerrain.NULL_BLOCK_VALUE || vb == BlockTerrain.NULL_BLOCK_VALUE) { break; } int ca = BlockTerrain.GetContent(va); int cb = BlockTerrain.GetContent(vb); //Debug.LogFormat("{0} and {1}: {2}, {3}", new Point3(x[0], x[1], x[2]), new Point3(x[0] + off[0], x[1] + off[1], x[2] + off[2]), a.Name, b.Name); if (isTrans[ca]) { if (!isTrans[cb] && (((x[0] + off[0])) & 16) == 0) { mask[n].IsOpposite = true; blocks[cb].GenerateTerrain(x[0] + off[0], x[1] + off[1], x[2] + off[2], vb, CellFace.opposite[d], chunk, ref mask[n]); } } else { if (isTrans[cb]) { mask[n].IsOpposite = false; blocks[ca].GenerateTerrain(x[0], x[1], x[2], va, d, chunk, ref mask[n]); } } n++; } } ++x[d]; n = 0; for (j = 0; j < dim[v]; j++) { for (i = 0; i < dim[u];) { if (mask[n].TextureSlot != -1) { for (w = 1; i + w < dim[u] && mask[w + n] == mask[n]; w++) { } for (h = 1; h + j < dim[v]; h++) { for (k = 0; k < w; k++) { if (mask[n + k + h * dim[u]] != mask[n]) { goto Done; } } } Done: //Debug.LogFormat("quard: {0}, {1}, {2}, {3}; {4}", j, i, h, w, x[d]); x[u] = i; x[v] = j; int[] du = new int[] { 0, 0, 0 }; int[] dv = new int[] { 0, 0, 0 }; du[u] = w; dv[v] = h; int textureSlot = mask[n].TextureSlot; if (!mask[n].IsOpposite) { Terrain.Quad( new Vector3(x[0], x[1], x[2]), new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]), new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]), new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]), textureSlot, mask[n].Color ); } else { Terrain.Quad( new Vector3(x[0], x[1], x[2]), new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]), new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]), new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]), textureSlot, mask[n].Color ); } for (l = 0; l < h; l++) { for (k = 0; k < w; k++) { mask[n + k + l * dim[u]].TextureSlot = -1; } } i += w; n += w; } else { i++; n++; } } } } } }
public abstract void GenerateTerrain(int x, int y, int z, int value, BlockTerrain.Chunk chunk, MeshGenerator g);
public void UpdateAll(BlockTerrain.Chunk chunk) { chunkData = chunk; transform = Matrix4x4.Translate(new Vector3(chunk.chunkx << 4, 0, chunk.chunky << 4)); }
void ChunkUpdateWork() { Debug.Log("starting terrain updating thread"); while (threadRunning) { chunkUpdateWorking = true; try { if (chunkQueue.TerrainCount != 0) { int count = chunkQueue.TerrainCount; for (int i = 0; i < count; i++) { int index = chunkQueue.PopTerrain(); BlockTerrain.Chunk chunk = Terrain.GetChunk(index); if (chunk == null) { continue; } if (Terrain.chunkStats.Get(index).needsToBeCreated) { terrainReader.ReadChunk(chunk.chunkx, chunk.chunky, chunk); } //stopwatch.Reset(); //stopwatch.Start(); //terrainGenerator.GenerateChunkMesh(chunk); //stopwatch.Stop(); //Debug.Log("building terrain time: " + stopwatch.ElapsedMilliseconds); //stopwatch.Reset(); //stopwatch.Start(); //terrainGenerator.GenerateNormalBlocks(chunk); //stopwatch.Stop(); //Debug.Log("building normal blocks time: " + stopwatch.ElapsedMilliseconds); terrainMeshGenerator.GenerateAllBlocks(chunk); terrainMeshGenerator.Terrain.PushToMesh(out chunk.mesh[0]); terrainMeshGenerator.AlphaTest.PushToMesh(out chunk.mesh[1]); //switch (Terrain.chunkStats.Get(index).state) //{ // case 3: // terrainGenerator.GenerateChunkMesh(chunk); // terrainGenerator.GenerateNormalBlocks(chunk); // terrainGenerator.Terrain.PushToMesh(out chunk.mesh[0]); // terrainGenerator.AlphaTest.PushToMesh(out chunk.mesh[1]); // break; // case 1: // terrainGenerator.GenerateChunkMesh(chunk); // terrainGenerator.Terrain.PushToMesh(out chunk.mesh[0]); // break; // case 2: // terrainGenerator.GenerateNormalBlocks(chunk); // terrainGenerator.AlphaTest.PushToMesh(out chunk.mesh[1]); // break; //} chunkQueue.AddMain(index); } } else if (needTerrainUpdate) { UpdateTerrain(centerChunk.X, centerChunk.Y); } } catch (System.Exception e) { Debug.LogException(e); } finally { chunkUpdateWorking = false; } } Debug.Log("chunk loading thread closed"); }