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 AddCubeSurface(MeshTool.BlockSurface surface, int normalIndex, BlockTypeFunBase blockFun) { int startVericesNum = vertices.Count; //三角形 for (int t = 0; t < 6; t++) { triangles.Add(startVericesNum + indices[t]); } //顶点 for (int p = 0; p < 4; p++) { vertices.Add(surface.pos + MeshTool.VertexOffset[normalIndex, p]); normals.Add(MeshTool.NormalDefine[normalIndex]); tangents.Add(new Vector4(surface.raytraceAo[0], surface.raytraceAo[1], surface.raytraceAo[2], surface.raytraceAo[3])); colors.Add(blockFun.getFaceColor(surface.type, (Block.BlockFaceIndex)normalIndex)); } //uv Rect rect = blockFun.getTextureUV(surface.type, (Block.BlockFaceIndex)normalIndex); uv.Add(new Vector2(rect.xMax, rect.yMin)); uv.Add(new Vector2(rect.xMin, rect.yMin)); uv.Add(new Vector2(rect.xMin, rect.yMax)); uv.Add(new Vector2(rect.xMax, rect.yMax)); //uv2 uv2.Add(new Vector2(0, 0)); uv2.Add(new Vector2(0, 1)); uv2.Add(new Vector2(1, 1)); uv2.Add(new Vector2(1, 0)); }
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 void create(int sizeX, int sizeY, int sizeZ, BlockTypeFunBase blockTypeFun) { this.sizeX = sizeX; this.sizeY = sizeY; this.sizeZ = sizeZ; this.blockTypeFun = blockTypeFun; blocks = new short[sizeX, sizeY, sizeZ]; //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)); // } // } // } // } //}); }
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)); } } } } }); }
public bool[] getEntityArray(BlockTypeFunBase blockType) { bool[] data = new bool[Const.ChunkSize * Const.ChunkSize * Const.ChunkSize]; for (int i = 0; i < blocks.Length; i++) { int x = i % Const.ChunkSize; int y = (i / Const.ChunkSize) % Const.ChunkSize; int z = i / (Const.ChunkSize * Const.ChunkSize); data[i] = blockType.isOpacity(blocks[x, y, z]); } return(data); }
public BlockChunk(BlockTypeFunBase fun) { for (int i = 0; i < 27; i++) { adjacencyChunks[i] = defaultChunk; } adjacencyChunks[13] = this; for (int i = 0; i < 6; i++) { surfaceList[i] = new List <VecInt3>(); } this.blockTypeFun = fun; }
public void AddSurface(MeshTool.BlockSurface surface, int normalIndex, BlockTypeFunBase blockFun) { if (surface.type >= (short)Game.BlockType.StairLeft && surface.type <= (short)Game.BlockType.StairFront) { string[] names = { "stair0", "stair1", "stair4", "stair5" }; SimpleModel model = SimpleModelFactory.GetModel(names[surface.type - (short)Game.BlockType.StairLeft]); for (int i = 0; i < model.quads[normalIndex].Count; i++) { SimpleModel.Quad quad = model.quads[normalIndex][i]; AddSubSurface(surface, normalIndex, blockFun, quad.rect, quad.depth); } } else { AddCubeSurface(surface, normalIndex, blockFun); } }
private void AddSubSurface(MeshTool.BlockSurface surface, int normalIndex, BlockTypeFunBase blockFun, Rect rect, float depth) { int startVericesNum = vertices.Count; //三角形 for (int t = 0; t < 6; t++) { triangles.Add(startVericesNum + indices[t]); } //顶点 Vector3[] vs = GetSubSurfaceVertex(normalIndex, rect, depth); for (int p = 0; p < 4; p++) { Vector3 pos = surface.pos + vs[p]; vertices.Add(pos); normals.Add(MeshTool.NormalDefine[normalIndex]); //tangents.Add(new Vector4(surface.raytraceAo[0], surface.raytraceAo[1], surface.raytraceAo[2], surface.raytraceAo[3])); Color color = blockFun.getFaceColor(surface.type, (Block.BlockFaceIndex)normalIndex); //color *= ((vs[p] - Vector3.one * 0.5f).magnitude); //color.a = surface.raytraceAo[p]; color.a = (surface.extendAo[p] * 0.5f + 0.5f) * surface.raytraceAo[p]; colors.Add(color); } //uv Rect uvRect = blockFun.getTextureUV(surface.type, (Block.BlockFaceIndex)normalIndex); uvRect = GetSubRect(uvRect, rect); uv.Add(new Vector2(uvRect.xMax, uvRect.yMin)); uv.Add(new Vector2(uvRect.xMin, uvRect.yMin)); uv.Add(new Vector2(uvRect.xMin, uvRect.yMax)); uv.Add(new Vector2(uvRect.xMax, uvRect.yMax)); //uv2 uv2.Add(new Vector2(rect.xMin, rect.yMin)); uv2.Add(new Vector2(rect.xMax, rect.yMin)); uv2.Add(new Vector2(rect.xMax, rect.yMax)); uv2.Add(new Vector2(rect.xMin, rect.yMax)); }
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 Mesh createMesh2(List <BlockSurface> surfacePoints, int normalIndex, BlockTypeFunBase blockFun, ChunkMeshInfoBase chunkMeshInfo) { if (surfacePoints.Count > 0) { ChunkMeshInfoBase meshInfo = new ChunkMeshInfo(surfacePoints.Count); for (int i = 0; i < surfacePoints.Count; i++) { BlockSurface surface = surfacePoints[i]; meshInfo.AddSurface(surface, normalIndex, blockFun); } Mesh mesh = new Mesh(); mesh.vertices = meshInfo.vertices.ToArray(); mesh.triangles = meshInfo.triangles.ToArray(); mesh.normals = meshInfo.normals.ToArray(); mesh.tangents = meshInfo.tangents.ToArray(); mesh.uv = meshInfo.uv.ToArray(); mesh.uv2 = meshInfo.uv2.ToArray(); mesh.colors = meshInfo.colors.ToArray(); return(mesh); } return(null); }
public static Mesh createMesh(List <BlockSurface> surfacePoints, int normalIndex, Texture2D aoTexture, BlockTypeFunBase blockFun) { if (surfacePoints.Count > 0) { Vector3[] vertices = new Vector3[surfacePoints.Count * 4]; for (int i = 0; i < surfacePoints.Count; i++) { for (int p = 0; p < 4; p++) { vertices[i * 4 + p] = surfacePoints[i].pos + VertexOffset[normalIndex, p]; } } int[] triangles = new int[surfacePoints.Count * 6]; for (int i = 0; i < surfacePoints.Count; i++) { triangles[i * 6 + 0] = i * 4 + 0; triangles[i * 6 + 1] = i * 4 + 1; triangles[i * 6 + 2] = i * 4 + 2; triangles[i * 6 + 3] = i * 4 + 0; triangles[i * 6 + 4] = i * 4 + 2; triangles[i * 6 + 5] = i * 4 + 3; } Vector3[] normals = new Vector3[vertices.Length]; for (int i = 0; i < normals.Length; i++) { normals[i] = NormalDefine[normalIndex]; } Vector4[] tangents = new Vector4[surfacePoints.Count * 4]; if (aoTexture) { Color[] aoColors = aoTexture.GetPixels(); for (int i = 0; i < surfacePoints.Count; i++) { for (int v = 0; v < 4; v++) { tangents[i * 4 + v] = new Vector4(aoColors[i * 4 + 0].a, aoColors[i * 4 + 1].a, aoColors[i * 4 + 2].a, aoColors[i * 4 + 3].a); } } } Vector2[] uv = new Vector2[surfacePoints.Count * 4]; for (int i = 0; i < surfacePoints.Count; i++) { Rect rect = blockFun.getTextureUV(surfacePoints[i].type, (Block.BlockFaceIndex)normalIndex); uv[i * 4 + 0] = new Vector2(rect.xMax, rect.yMin); uv[i * 4 + 1] = new Vector2(rect.xMin, rect.yMin); uv[i * 4 + 2] = new Vector2(rect.xMin, rect.yMax); uv[i * 4 + 3] = new Vector2(rect.xMax, rect.yMax); } Vector2[] uv2 = new Vector2[surfacePoints.Count * 4]; for (int i = 0; i < surfacePoints.Count; i++) { uv2[i * 4 + 0] = new Vector2(0, 0); uv2[i * 4 + 1] = new Vector2(0, 1); uv2[i * 4 + 2] = new Vector2(1, 1); uv2[i * 4 + 3] = new Vector2(1, 0); } Color[] colors = new Color[surfacePoints.Count * 4]; for (int i = 0; i < surfacePoints.Count; i++) { for (int v = 0; v < 4; v++) { colors[i * 4 + v] = blockFun.getFaceColor(surfacePoints[i].type, (Block.BlockFaceIndex)normalIndex); } } Mesh mesh = new Mesh(); mesh.vertices = vertices; mesh.triangles = triangles; mesh.normals = normals; mesh.tangents = tangents; mesh.uv = uv; mesh.uv2 = uv2; mesh.colors = colors; return(mesh); } return(null); }
public abstract void AddSurface(MeshTool.BlockSurface surface, int normalIndex, BlockTypeFunBase blockFun);
public List <VecInt3>[] calcSurfaceList() { BlockTypeFunBase fun = blockTypeFun; if (isSurfaceDirty) { isSurfaceDirty = false; surfaceList = new List <VecInt3> [6]; for (int f = 0; f < 6; f++) { surfaceList[f] = new List <VecInt3>(); } for (int z = 0; z < Const.ChunkSize; z++) { for (int y = 0; y < Const.ChunkSize; y++) { bool bOldIsEntity = fun.isOpacity(getBlockSmart(-1, y, z)); for (int x = 0; x < Const.ChunkSize; x++) { bool bCurIsEntity = fun.isOpacity(getBlock(x, y, z)); if (bCurIsEntity && !bOldIsEntity) { surfaceList[(int)Face.FNI_x0].Add(new VecInt3(x, y, z)); } else if (bOldIsEntity && (!bCurIsEntity) && x >= 1) { surfaceList[(int)Face.FNI_x1].Add(new VecInt3(x - 1, y, z)); } bOldIsEntity = bCurIsEntity; } if (bOldIsEntity && !fun.isOpacity(getBlockSmart(Const.ChunkSize, y, z))) { surfaceList[(int)Face.FNI_x1].Add(new VecInt3(Const.ChunkSize - 1, y, z)); } } } for (int z = 0; z < Const.ChunkSize; z++) { for (int x = 0; x < Const.ChunkSize; x++) { bool bOldIsEntity = fun.isOpacity(getBlockSmart(x, -1, z)); for (int y = 0; y < Const.ChunkSize; y++) { bool bCurIsEntity = fun.isOpacity(getBlock(x, y, z)); if (bCurIsEntity && !bOldIsEntity) { surfaceList[(int)Face.FNI_y0].Add(new VecInt3(x, y, z)); } else if (bOldIsEntity && (!bCurIsEntity) && y >= 1) { surfaceList[(int)Face.FNI_y1].Add(new VecInt3(x, y - 1, z)); } bOldIsEntity = bCurIsEntity; } if (bOldIsEntity && !fun.isOpacity(getBlockSmart(x, Const.ChunkSize, z))) { surfaceList[(int)Face.FNI_y1].Add(new VecInt3(x, Const.ChunkSize - 1, z)); } } } for (int x = 0; x < Const.ChunkSize; x++) { for (int y = 0; y < Const.ChunkSize; y++) { bool bOldIsEntity = fun.isOpacity(getBlockSmart(x, y, -1)); for (int z = 0; z < Const.ChunkSize; z++) { bool bCurIsEntity = fun.isOpacity(getBlock(x, y, z)); if (bCurIsEntity && !bOldIsEntity) { surfaceList[(int)Face.FNI_z0].Add(new VecInt3(x, y, z)); } else if (bOldIsEntity && (!bCurIsEntity) && z >= 1) { surfaceList[(int)Face.FNI_z1].Add(new VecInt3(x, y, z - 1)); } bOldIsEntity = bCurIsEntity; } if (bOldIsEntity && !fun.isOpacity(getBlockSmart(x, y, Const.ChunkSize))) { surfaceList[(int)Face.FNI_z1].Add(new VecInt3(x, y, Const.ChunkSize - 1)); } } } } return(surfaceList); }