Пример #1
0
    // On random Update spread grass to any nearby dirt blocks on the surface
    public override void RandomUpdate(Chunk chunk, Vector3Int localPos, Vector3Int globalPos)
    {
        ChunkBlocks blocks  = chunk.blocks;
        WorldBlocks blocksW = chunk.world.blocks;

        int minX = localPos.x <= 0 ? 0 : 1;
        int maxX = localPos.x >= Env.ChunkMask ? 0 : 1;
        int minY = localPos.y <= 0 ? 0 : 1;
        int maxY = localPos.y >= Env.ChunkMask ? 0 : 1;
        int minZ = localPos.z <= 0 ? 0 : 1;
        int maxZ = localPos.z >= Env.ChunkMask ? 0 : 1;

        for (int x = -minX; x <= maxX; x++)
        {
            for (int y = -minY; y <= maxY; y++)
            {
                for (int z = -minZ; z <= maxZ; z++)
                {
                    Vector3Int newPos = localPos.Add(x, y, z);
                    if (blocks.Get(newPos).Equals(dirt) &&
                        blocksW.Get(globalPos.Add(x, y + 1, z)).Equals(air))
                    {
                        blocks.Modify(newPos, grass, true);
                    }
                }
            }
        }
    }
Пример #2
0
    public override void BuildBlock(Chunk chunk, Vector3Int localPos, Vector3Int globalPos)
    {
        WorldBlocks blocks = chunk.world.blocks;

        for (int d = 0; d < 6; d++)
        {
            Direction dir           = DirectionUtils.Get(d);
            Block     adjacentBlock = blocks.GetBlock(globalPos.Add(dir));
            if (CanBuildFaceWith(adjacentBlock, dir))
            {
                BuildFace(chunk, localPos, globalPos, dir);
            }
        }
    }
Пример #3
0
    public override void BuildBlock(Chunk chunk, Vector3Int localPos, Vector3Int globalPos)
    {
        Rect texture;
        RenderGeometryBatcher batcher = chunk.GeometryHandler.Batcher;
        WorldBlocks           blocks  = chunk.world.blocks;

        for (int d = 0; d < 6; d++)
        {
            Direction dir = DirectionUtils.Get(d);
            if (!connectedMeshConfig.directionalTris.ContainsKey(dir))
            {
                continue;
            }

            if (connectedMeshConfig.connectsToSolid && blocks.GetBlock(globalPos + dir).IsSolid(DirectionUtils.Opposite(dir)))
            {
                texture = connectedMeshConfig.texture.GetTexture(chunk, localPos, globalPos, dir);
                batcher.AddMeshData(connectedMeshConfig.directionalTris[dir], connectedMeshConfig.directionalVerts[dir], texture, localPos);
            }
            else if (connectedMeshConfig.connectsToTypes.Length != 0)
            {
                int neighborType = blocks.Get(globalPos.Add(dir)).Type;
                for (int i = 0; i < connectedMeshConfig.connectsToTypes.Length; i++)
                {
                    if (neighborType == connectedMeshConfig.connectsToTypes[i])
                    {
                        texture = connectedMeshConfig.texture.GetTexture(chunk, localPos, globalPos, dir);
                        batcher.AddMeshData(connectedMeshConfig.directionalTris[dir], connectedMeshConfig.directionalVerts[dir], texture, localPos);
                        break;
                    }
                }
            }
        }

        texture = customMeshConfig.texture.GetTexture(chunk, localPos, globalPos, Direction.down);
        batcher.AddMeshData(customMeshConfig.tris, customMeshConfig.verts, texture, localPos);
    }
Пример #4
0
 public override void Init(World world)
 {
     blocks = world.blocks;
     leaves = new BlockData(world.blockProvider.GetBlock("leaves").type);
     log    = new BlockData(world.blockProvider.GetBlock("log").type);
 }
Пример #5
0
        public void Build(Chunk chunk, int minX, int maxX, int minY, int maxY, int minZ, int maxZ)
        {
            WorldBlocks blocks = chunk.world.blocks;

            const int stepSize = 1;
            const int width    = Env.ChunkSize;

            int[] mins  = { minX, minY, minZ };
            int[] maxes = { maxX, maxY, maxZ };

            int[] x = { 0, 0, 0 }; // Relative position of a block
            int[] q = { 0, 0, 0 };
            // Direction in which we compare neighbors when building mask (q[d] is our current direction)
            int[] du = { 0, 0, 0 }; // Width in a given dimension (du[u] is our current dimension)
            int[] dv = { 0, 0, 0 }; // Height in a given dimension (dv[v] is our current dimension)

            bool[]    mask = chunk.pools.PopBoolArray(width * width);
            Vector3[] vecs = chunk.pools.PopVector3Array(4);

            // Iterate over 3 dimensions. Once for front faces, once for back faces
            for (int dd = 0; dd < 2 * 3; dd++)
            {
                int d = dd % 3;
                int u = (d + 1) % 3;
                int v = (d + 2) % 3;

                x[0] = 0;
                x[1] = 0;
                x[2] = 0;

                q[0] = 0;
                q[1] = 0;
                q[2] = 0;
                q[d] = stepSize;

                // Determine which side we're meshing
                Direction dir = Direction.west;
                switch (dd)
                {
                // Back faces
                //case 0: dir = Direction.west; break;
                case 1: dir = Direction.down; break;

                case 2: dir = Direction.south; break;

                // Front faces
                case 3: dir = Direction.east; break;

                case 4: dir = Direction.up; break;

                case 5: dir = Direction.north; break;
                }
                bool backFace = DirectionUtils.Backface(dir);

                // Move through the dimension from front to back
                for (x[d] = mins[d] - 1; x[d] <= maxes[d];)
                {
                    // Compute the mask
                    int n = 0;

                    for (x[v] = 0; x[v] < mins[v]; x[v]++)
                    {
                        for (x[u] = 0; x[u] < width; x[u]++)
                        {
                            mask[n++] = false;
                        }
                    }

                    for (x[v] = mins[v]; x[v] <= maxes[v]; x[v]++)
                    {
                        for (x[u] = 0; x[u] < mins[u]; x[u]++)
                        {
                            mask[n++] = false;
                        }

                        for (x[u] = mins[u]; x[u] <= maxes[u]; x[u]++)
                        {
                            int realX = chunk.pos.x + x[0];
                            int realY = chunk.pos.y + x[1];
                            int realZ = chunk.pos.z + x[2];

                            bool voxelFace0 = blocks.GetBlock(new Vector3Int(realX, realY, realZ)).canBeWalkedOn;
                            bool voxelFace1 = blocks.GetBlock(new Vector3Int(realX + q[0], realY + q[1], realZ + q[2])).canBeWalkedOn;

                            mask[n++] = (!voxelFace0 || !voxelFace1) && (backFace ? voxelFace1 : voxelFace0);
                        }

                        for (x[u] = maxes[u] + 1; x[u] < width; x[u]++)
                        {
                            mask[n++] = false;
                        }
                    }

                    for (x[v] = maxes[v] + 1; x[v] < width; x[v]++)
                    {
                        for (x[u] = 0; x[u] < width; x[u]++)
                        {
                            mask[n++] = false;
                        }
                    }

                    x[d]++;
                    n = 0;

                    // Build faces from the mask if it's possible
                    int j;
                    for (j = 0; j < width; j++)
                    {
                        int i;
                        for (i = 0; i < width;)
                        {
                            if (mask[n] == false)
                            {
                                i++;
                                n++;
                                continue;
                            }

                            bool type = mask[n];

                            // Compute width
                            int w;
                            for (w = 1; i + w < width && mask[n + w] == type; w++)
                            {
                            }

                            // Compute height
                            bool done = false;
                            int  k;
                            int  h;
                            for (h = 1; j + h < width; h++)
                            {
                                for (k = 0; k < w; k++)
                                {
                                    if (mask[n + k + h * width] == false ||
                                        mask[n + k + h * width] != type)
                                    {
                                        done = true;
                                        break;
                                    }
                                }

                                if (done)
                                {
                                    break;
                                }
                            }

                            // Determine whether we really want to build this face
                            // TODO: Skip bottom faces at the bottom of the world
                            const bool buildFace = true;
                            if (buildFace)
                            {
                                // Prepare face coordinates and dimensions
                                x[u] = i;
                                x[v] = j;

                                du[0] = du[1] = du[2] = 0;
                                dv[0] = dv[1] = dv[2] = 0;
                                du[u] = w;
                                dv[v] = h;

                                // Face vertices transformed to world coordinates
                                // 0--1
                                // |  |
                                // |  |
                                // 3--2
                                vecs[0] = new Vector3(x[0], x[1], x[2]) - BlockUtils.HalfBlockVector;
                                vecs[1] = new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]) - BlockUtils.HalfBlockVector;
                                vecs[2] = new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]) - BlockUtils.HalfBlockVector;
                                vecs[3] = new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]) - BlockUtils.HalfBlockVector;

                                {
                                    LocalPools        pool            = chunk.pools;
                                    VertexData[]      vertexData      = pool.PopVertexDataArray(4);
                                    VertexDataFixed[] vertexDataFixed = pool.PopVertexDataFixedArray(4);
                                    {
                                        for (int ii = 0; ii < 4; ii++)
                                        {
                                            vertexData[ii]        = pool.PopVertexData();
                                            vertexData[ii].Vertex = vecs[ii];
                                            vertexDataFixed[ii]   = VertexDataUtils.ClassToStruct(vertexData[ii]);
                                        }

                                        chunk.ChunkColliderGeometryHandler.Batcher.AddFace(vertexDataFixed, backFace);

                                        for (int ii = 0; ii < 4; ii++)
                                        {
                                            pool.PushVertexData(vertexData[ii]);
                                        }
                                    }
                                    pool.PushVertexDataFixedArray(vertexDataFixed);
                                    pool.PushVertexDataArray(vertexData);
                                }
                            }

                            // Zero out the mask
                            int l;
                            for (l = 0; l < h; ++l)
                            {
                                for (k = 0; k < w; ++k)
                                {
                                    mask[n + k + l * width] = false;
                                }
                            }

                            i += w;
                            n += w;
                        }
                    }
                }
            }

            chunk.pools.PushBoolArray(mask);
            chunk.pools.PushVector3Array(vecs);
        }
Пример #6
0
        private static void PrepareColors_Slow(Chunk chunk, ref Vector3Int globalPos, VertexData[] vertexData, Direction direction)
        {
            bool nSolid = false;
            bool eSolid = false;
            bool sSolid = false;
            bool wSolid = false;

            bool wnSolid = false;
            bool neSolid = false;
            bool esSolid = false;
            bool swSolid = false;

            //float light = 0;

            WorldBlocks blocks = chunk.world.blocks;
            Block       block;

            switch (direction)
            {
            case Direction.up:
                nSolid = blocks.GetBlock(globalPos.Add(0, 1, 1)).IsSolid(Direction.south);
                eSolid = blocks.GetBlock(globalPos.Add(1, 1, 0)).IsSolid(Direction.west);
                sSolid = blocks.GetBlock(globalPos.Add(0, 1, -1)).IsSolid(Direction.north);
                wSolid = blocks.GetBlock(globalPos.Add(-1, 1, 0)).IsSolid(Direction.east);

                block   = blocks.GetBlock(globalPos.Add(-1, 1, 1));
                wnSolid = block.IsSolid(Direction.east) && block.IsSolid(Direction.south);
                block   = blocks.GetBlock(globalPos.Add(1, 1, 1));
                neSolid = block.IsSolid(Direction.south) && block.IsSolid(Direction.west);
                block   = blocks.GetBlock(globalPos.Add(1, 1, -1));
                esSolid = block.IsSolid(Direction.west) && block.IsSolid(Direction.north);
                block   = blocks.GetBlock(globalPos.Add(-1, 1, -1));
                swSolid = block.IsSolid(Direction.north) && block.IsSolid(Direction.east);

                //light = BlockDataMap.NonSolid.Light(blocks.GetBlock(globalPos.Add(0, 1, 0)))/ 15f;
                break;

            case Direction.down:
                nSolid = blocks.GetBlock(globalPos.Add(0, -1, -1)).IsSolid(Direction.south);
                eSolid = blocks.GetBlock(globalPos.Add(1, -1, 0)).IsSolid(Direction.west);
                sSolid = blocks.GetBlock(globalPos.Add(0, -1, 1)).IsSolid(Direction.north);
                wSolid = blocks.GetBlock(globalPos.Add(-1, -1, 0)).IsSolid(Direction.east);

                block   = blocks.GetBlock(globalPos.Add(-1, -1, -1));
                wnSolid = block.IsSolid(Direction.east) && block.IsSolid(Direction.south);
                block   = blocks.GetBlock(globalPos.Add(1, -1, -1));
                neSolid = block.IsSolid(Direction.south) && block.IsSolid(Direction.west);
                block   = blocks.GetBlock(globalPos.Add(1, -1, 1));
                esSolid = block.IsSolid(Direction.west) && block.IsSolid(Direction.north);
                block   = blocks.GetBlock(globalPos.Add(-1, -1, 1));
                swSolid = block.IsSolid(Direction.north) && block.IsSolid(Direction.east);

                //light = BlockDataMap.NonSolid.Light(blocks.GetBlock(globalPos.Add(0, -1, 0))) / 15f;
                break;

            case Direction.north:
                nSolid = blocks.GetBlock(globalPos.Add(1, 0, 1)).IsSolid(Direction.west);
                eSolid = blocks.GetBlock(globalPos.Add(0, 1, 1)).IsSolid(Direction.down);
                sSolid = blocks.GetBlock(globalPos.Add(-1, 0, 1)).IsSolid(Direction.east);
                wSolid = blocks.GetBlock(globalPos.Add(0, -1, 1)).IsSolid(Direction.up);

                block   = blocks.GetBlock(globalPos.Add(-1, 1, 1));
                esSolid = block.IsSolid(Direction.east) && block.IsSolid(Direction.south);
                block   = blocks.GetBlock(globalPos.Add(1, 1, 1));
                neSolid = block.IsSolid(Direction.south) && block.IsSolid(Direction.west);
                block   = blocks.GetBlock(globalPos.Add(1, -1, 1));
                wnSolid = block.IsSolid(Direction.west) && block.IsSolid(Direction.north);
                block   = blocks.GetBlock(globalPos.Add(-1, -1, 1));
                swSolid = block.IsSolid(Direction.north) && block.IsSolid(Direction.east);

                //light = BlockDataMap.NonSolid.Light(blocks.GetBlock(globalPos.Add(0, 0, 1))) / 15f;
                break;

            case Direction.east:
                nSolid = blocks.GetBlock(globalPos.Add(1, 0, -1)).IsSolid(Direction.up);
                eSolid = blocks.GetBlock(globalPos.Add(1, 1, 0)).IsSolid(Direction.west);
                sSolid = blocks.GetBlock(globalPos.Add(1, 0, 1)).IsSolid(Direction.down);
                wSolid = blocks.GetBlock(globalPos.Add(1, -1, 0)).IsSolid(Direction.east);

                block   = blocks.GetBlock(globalPos.Add(1, 1, 1));
                esSolid = block.IsSolid(Direction.west) && block.IsSolid(Direction.north);
                block   = blocks.GetBlock(globalPos.Add(1, 1, -1));
                neSolid = block.IsSolid(Direction.south) && block.IsSolid(Direction.west);
                block   = blocks.GetBlock(globalPos.Add(1, -1, -1));
                wnSolid = block.IsSolid(Direction.east) && block.IsSolid(Direction.north);
                block   = blocks.GetBlock(globalPos.Add(1, -1, 1));
                swSolid = block.IsSolid(Direction.north) && block.IsSolid(Direction.east);

                //light = BlockDataMap.NonSolid.Light(blocks.GetBlock(globalPos.Add(1, 0, 0))) / 15f;
                break;

            case Direction.south:
                nSolid = blocks.GetBlock(globalPos.Add(-1, 0, -1)).IsSolid(Direction.down);
                eSolid = blocks.GetBlock(globalPos.Add(0, 1, -1)).IsSolid(Direction.west);
                sSolid = blocks.GetBlock(globalPos.Add(1, 0, -1)).IsSolid(Direction.up);
                wSolid = blocks.GetBlock(globalPos.Add(0, -1, -1)).IsSolid(Direction.south);

                block   = blocks.GetBlock(globalPos.Add(1, 1, -1));
                esSolid = block.IsSolid(Direction.west) && block.IsSolid(Direction.north);
                block   = blocks.GetBlock(globalPos.Add(-1, 1, -1));
                neSolid = block.IsSolid(Direction.south) && block.IsSolid(Direction.west);
                block   = blocks.GetBlock(globalPos.Add(-1, -1, -1));
                wnSolid = block.IsSolid(Direction.east) && block.IsSolid(Direction.north);
                block   = blocks.GetBlock(globalPos.Add(1, -1, -1));
                swSolid = block.IsSolid(Direction.north) && block.IsSolid(Direction.east);

                //light = BlockDataMap.NonSolid.Light(blocks.GetBlock(globalPos.Add(0, 0, -1))) / 15f;
                break;

            case Direction.west:
                nSolid = blocks.GetBlock(globalPos.Add(-1, 0, 1)).IsSolid(Direction.up);
                eSolid = blocks.GetBlock(globalPos.Add(-1, 1, 0)).IsSolid(Direction.west);
                sSolid = blocks.GetBlock(globalPos.Add(-1, 0, -1)).IsSolid(Direction.down);
                wSolid = blocks.GetBlock(globalPos.Add(-1, -1, 0)).IsSolid(Direction.east);

                block   = blocks.GetBlock(globalPos.Add(-1, 1, -1));
                esSolid = block.IsSolid(Direction.west) && block.IsSolid(Direction.north);
                block   = blocks.GetBlock(globalPos.Add(-1, 1, 1));
                neSolid = block.IsSolid(Direction.south) && block.IsSolid(Direction.west);
                block   = blocks.GetBlock(globalPos.Add(-1, -1, 1));
                wnSolid = block.IsSolid(Direction.east) && block.IsSolid(Direction.north);
                block   = blocks.GetBlock(globalPos.Add(-1, -1, -1));
                swSolid = block.IsSolid(Direction.north) && block.IsSolid(Direction.east);

                //light = BlockDataMap.NonSolid.Light(blocks.GetBlock(globalPos.Add(-1, 0, 0))) / 15f;
                break;
            }

            if (chunk.world.config.addAOToMesh)
            {
                SetColorsAO(vertexData, wnSolid, nSolid, neSolid, eSolid, esSolid, sSolid, swSolid, wSolid,
                            chunk.world.config.ambientOcclusionStrength);
            }
            else
            {
                SetColors(vertexData, 1, 1, 1, 1, 1);
            }
        }