예제 #1
0
파일: MeshTool.cs 프로젝트: wachel/block
        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);
        }
예제 #2
0
        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));
        }
예제 #3
0
파일: MeshTool.cs 프로젝트: wachel/block
        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);
        }
예제 #4
0
        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));
            //                }
            //            }
            //        }
            //    }
            //});
        }
예제 #5
0
 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));
                     }
                 }
             }
         }
     });
 }
예제 #6
0
 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);
 }
예제 #7
0
 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;
 }
예제 #8
0
 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);
     }
 }
예제 #9
0
        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));
        }
예제 #10
0
파일: MeshTool.cs 프로젝트: wachel/block
        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);
        }
예제 #11
0
파일: MeshTool.cs 프로젝트: wachel/block
        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);
        }
예제 #12
0
파일: MeshTool.cs 프로젝트: wachel/block
        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);
        }
예제 #13
0
 public abstract void AddSurface(MeshTool.BlockSurface surface, int normalIndex, BlockTypeFunBase blockFun);
예제 #14
0
        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);
        }