public static bool[, ,] GetVisibleBlocks(BlockChunk chunk, BlockTypeFunBase blockFun) { bool[, ,] blocks = new bool[Const.ChunkSize, Const.ChunkSize, Const.ChunkSize]; for (int normalIndex = 0; normalIndex < 6; normalIndex++) { int stepX = normalIndex == 0 ? -1 : (normalIndex == 1 ? 1 : 0); int stepY = normalIndex == 2 ? -1 : (normalIndex == 3 ? 1 : 0); int stepZ = normalIndex == 4 ? -1 : (normalIndex == 5 ? 1 : 0); for (int x = 0; x < Const.ChunkSize; x++) { for (int y = 0; y < Const.ChunkSize; y++) { for (int z = 0; z < Const.ChunkSize; z++) { int nextX = x + stepX; int nextY = y + stepY; int nextZ = z + stepZ; short block = chunk.getBlock(x, y, z); if (block != 0) { bool isCurrentVisible = blockFun.isCollider(block); short nextBlock = chunk.getBlock(nextX, nextY, nextZ); bool isNextOpacity = blockFun.isCollider(nextBlock); if (isCurrentVisible && !isNextOpacity) { blocks[x, y, z] = true; } } } } } } return(blocks); }
public static List <BlockSurface> getChunkSurface(BlockChunk chunk, BlockTypeFunBase blockFun, int normalIndex) { int stepX = normalIndex == 0 ? -1 : (normalIndex == 1 ? 1 : 0); int stepY = normalIndex == 2 ? -1 : (normalIndex == 3 ? 1 : 0); int stepZ = normalIndex == 4 ? -1 : (normalIndex == 5 ? 1 : 0); List <BlockSurface> surfacePoints = new List <BlockSurface>(); for (int x = 0; x < Const.ChunkSize; x++) { for (int y = 0; y < Const.ChunkSize; y++) { for (int z = 0; z < Const.ChunkSize; z++) { int nextX = x + stepX; int nextY = y + stepY; int nextZ = z + stepZ; short block = chunk.getBlock(x, y, z); bool isCurrentVisible = blockFun.isVisible(block); bool isNextOpacity = blockFun.isOpacity(chunk.getBlockSmart(nextX, nextY, nextZ)); if (isCurrentVisible && !isNextOpacity) { BlockSurface surface = new BlockSurface(new Vector3(x, y, z), block, new float[4], new float[4]); for (int v = 0; v < 4; v++) { surface.smallAo[v] = getVertexSmallAo(chunk, blockFun, x, y, z, normalIndex, v); } surfacePoints.Add(surface); } } } } return(surfacePoints); }
public void create(int chunkNumX, int chunkNumY, int chunkNumZ, BlockTypeFunBase blockTypeFun) { this.chunkNumX = chunkNumX; this.chunkNumY = chunkNumY; this.chunkNumZ = chunkNumZ; this.blockTypeFun = blockTypeFun; Array.Resize(ref chunks, chunkNumX * chunkNumY * chunkNumZ); for (int i = 0; i < chunks.Length; i++) { chunks[i] = new BlockChunk(blockTypeFun); } forEachChunk((chunk, i, j, k) => { for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { for (int z = -1; z <= 1; z++) { // int index = (z+1)*9+(y+1)*3+x+1; if (i + x >= 0 && i + x < chunkNumX && j + y >= 0 && j + y < chunkNumY && k + z >= 0 && k + z < chunkNumZ) { chunk.setAdjacencyChunk(x, y, z, getChunk(i + x, j + y, k + z)); } } } } }); }
static BlockChunk createDefaultChunk() { BlockChunk rlt = new BlockChunk(null); for (int i = 0; i < Const.ChunkSize; i++) { for (int j = 0; j < Const.ChunkSize; j++) { for (int k = 0; k < Const.ChunkSize; k++) { rlt.setBlock(i, j, k, (short)BlockTypeEnum.Out); } } } return(rlt); }
private static float getVertexSmallAo(BlockChunk blocks, BlockTypeFunBase blockFun, int x, int y, int z, int faceIndex, int vertixIndex) { float rlt = 1.0f; int offset0X = Const.VertexAdjacencyOffset[faceIndex, vertixIndex, 0, 0]; int offset0Y = Const.VertexAdjacencyOffset[faceIndex, vertixIndex, 0, 1]; int offset0Z = Const.VertexAdjacencyOffset[faceIndex, vertixIndex, 0, 2]; bool bBlock0 = blockFun.isOpacity(blocks.getBlockSmart(x + offset0X, y + offset0Y, z + offset0Z)); int offset1X = Const.VertexAdjacencyOffset[faceIndex, vertixIndex, 1, 0]; int offset1Y = Const.VertexAdjacencyOffset[faceIndex, vertixIndex, 1, 1]; int offset1Z = Const.VertexAdjacencyOffset[faceIndex, vertixIndex, 1, 2]; bool bBlock1 = blockFun.isOpacity(blocks.getBlockSmart(x + offset1X, y + offset1Y, z + offset1Z)); int offset2X = Const.VertexAdjacencyOffset[faceIndex, vertixIndex, 2, 0]; int offset2Y = Const.VertexAdjacencyOffset[faceIndex, vertixIndex, 2, 1]; int offset2Z = Const.VertexAdjacencyOffset[faceIndex, vertixIndex, 2, 2]; bool bBlock2 = blockFun.isOpacity(blocks.getBlockSmart(x + offset2X, y + offset2Y, z + offset2Z)); if (bBlock0 && bBlock2) //如果两个共边对角块都是实体,则共点对角块存不存在已经无所谓,说明是三面内角 { rlt *= 0.7f; } else if ((bBlock0 && bBlock1) || (bBlock1 && bBlock2)) //如果有一个共边对角块和一个共点对角块,则说明是阶梯的内角 { rlt *= 0.8f; } else if (bBlock0 || bBlock1 || bBlock2) { rlt *= 0.8f; } else { rlt *= 1.0f; } return(rlt); }
public static void calcChunkLight(BlockChunk chunk, int cx, int cy, int cz, RayCastManager rayTraceManager, Vector3[][] rays, Vector3 sunDir) { //List<VecInt3>[] surfaces = chunk.calcSurfaceList(); //for (int f = 0; f < 6; f++) { // List<VecInt3> surs = surfaces[f]; // for (int i = 0; i < surs.Count; i++) { // VecInt3 surface = surs[i]; // int gx = cx * Const.ChunkSize + surface.x; // int gy = cy * Const.ChunkSize + surface.y; // int gz = cz * Const.ChunkSize + surface.z; // Vector3 faceNormal = Const.getFaceNormal(f); // float faceLightFactor = Vector3.Dot(faceNormal, -sunDir); // Vector3 startPos = (new Vector3(gx, gy, gz) + Vector3.one * 0.5f + faceNormal * 0.51f) * Const.BlockSize; // // float directionLight = 0; // float aoLight = 0; // float aoLenght = 8.0f; // if(faceLightFactor > 0){ // RayCastRestult rlt = rayTraceManager.rayCast(startPos, -sunDir, 30); // directionLight += rlt.bHit ? 0 : faceLightFactor; // } // for (int r = 0; r < rays[f].Length; r++) { // RayCastRestult rlt = rayTraceManager.rayCast(startPos, rays[f][r], aoLenght); // if (rlt.bHit && rlt.hitLength < aoLenght) { // float a = ((rlt.hitLength) / aoLenght); // aoLight += (a / rays[f].Length); // } // else { // aoLight += 1.0f / rays[f].Length; // } // } // float brightness = directionLight * 0.35f + aoLight * 0.45f + 0.2f; // brightness = Mathf.Clamp(brightness, 0, 1); // chunk.setBrightness(surface.x, surface.y, surface.z, f, (Byte)(brightness * Const.MaxBrightness)); // } //} }
public void setAdjacencyChunk(int x, int y, int z, BlockChunk chunk) { adjacencyChunks[(z + 1) * 9 + (y + 1) * 3 + (x + 1)] = chunk; }