Exemplo n.º 1
0
        public void generate(Chunk chunk, Random rnd)
        {
            CachedChunk3x3 cc3x3 = CachedChunk3x3.getNewRegion(chunk.world, chunk);

            int      x, z;
            Block    groundBlock;
            BlockPos pos, pos1;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    x = i * 5 + rnd.Next(0, 4);
                    z = j * 5 + rnd.Next(0, 4);
                    if (rnd.Next(0, 2) != 0)
                    {
                        for (int y = 0; y < Chunk.SIZE; y++)
                        {
                            pos         = new BlockPos(x, y, z);
                            pos1        = pos.move(Direction.DOWN);
                            groundBlock = cc3x3.getBlock(pos1.x, pos1.y, pos1.z);
                            if (cc3x3.getBlock(pos.x, pos.y, pos.z) == Block.air && (groundBlock == Block.dirt || groundBlock == Block.grass))
                            {
                                this.makeTree(cc3x3, rnd, pos);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        public void updateLighting(int newLight, int startX, int startY, int startZ)
        {
            Chunk c = this.world.getChunk(startX, startY, startZ);

            this.region = CachedChunk3x3.getNewRegion(this.world, c);

            this.orginX = c.worldPos.x;
            this.orginY = c.worldPos.y;
            this.orginZ = c.worldPos.z;

            /*
             *
             * // Make x, y, and z local within the chunk
             * x -= c.worldPos.x;
             * y -= c.worldPos.y;
             * z -= c.worldPos.z;
             *
             * // Populate the lookup table.
             * int i, j, k;
             * for (i = 0; i <= 29; i++) {
             *  for (j = 0; j <= 29; j++) {
             *      for (k = 0; k <= 29; k++) {
             *          this.lightLookup[(j * Chunk.SIZE * Chunk.SIZE) + (k * Chunk.SIZE) + i] =
             *              (byte)this.region.getLight(x + i - 14, y + j - 14, z + k - 14);
             *      }
             *  }
             * }
             */

            int x, y, z, neighborLevel, lightLevel;
            LightRemovalNode node;

            this.removalQueue.Enqueue(new LightRemovalNode(startX, startY, startZ, this.getLight(startX, startY, startZ)));
            this.world.setLight(startX, startY, startZ, 0);

            while (this.removalQueue.Count > 0)
            {
                node       = this.removalQueue.Dequeue();
                x          = node.x;
                y          = node.y;
                z          = node.z;
                lightLevel = node.lightLevel;

                int ox = x - this.orginX;
                int oy = y - this.orginY;
                int oz = z - this.orginZ;

                // -X
                neighborLevel = this.getLight(x - 1, y, z);
                if (neighborLevel != 0 && neighborLevel < lightLevel)
                {
                    this.region.setLight(ox - 1, oy, oz, 0);
                    this.removalQueue.Enqueue(new LightRemovalNode(x - 1, y, z, neighborLevel));
                }
                else if (neighborLevel >= lightLevel)
                {
                    this.queue.Enqueue(new BlockPos(x - 1, y, z));
                }

                // +X
                neighborLevel = this.getLight(x + 1, y, z);
                if (neighborLevel != 0 && neighborLevel < lightLevel)
                {
                    this.region.setLight(ox + 1, oy, oz, 0);
                    this.removalQueue.Enqueue(new LightRemovalNode(x + 1, y, z, neighborLevel));
                }
                else if (neighborLevel >= lightLevel)
                {
                    this.queue.Enqueue(new BlockPos(x + 1, y, z));
                }

                // -Y
                neighborLevel = this.getLight(x, y - 1, z);
                if (neighborLevel != 0 && neighborLevel < lightLevel)
                {
                    this.region.setLight(ox, oy - 1, oz, 0);
                    this.removalQueue.Enqueue(new LightRemovalNode(x, y - 1, z, neighborLevel));
                }
                else if (neighborLevel >= lightLevel)
                {
                    this.queue.Enqueue(new BlockPos(x, y - 1, z));
                }

                // +Y
                neighborLevel = this.getLight(x, y + 1, z);
                if (neighborLevel != 0 && neighborLevel < lightLevel)
                {
                    this.region.setLight(ox, oy + 1, oz, 0);
                    this.removalQueue.Enqueue(new LightRemovalNode(x, y + 1, z, neighborLevel));
                }
                else if (neighborLevel >= lightLevel)
                {
                    this.queue.Enqueue(new BlockPos(x, y + 1, z));
                }

                // -Z
                neighborLevel = this.getLight(x, y, z - 1);
                if (neighborLevel != 0 && neighborLevel < lightLevel)
                {
                    this.region.setLight(ox, oy, oz - 1, 0);
                    this.removalQueue.Enqueue(new LightRemovalNode(x, y, z - 1, neighborLevel));
                }
                else if (neighborLevel >= lightLevel)
                {
                    this.queue.Enqueue(new BlockPos(x, y, z - 1));
                }

                // +Z
                neighborLevel = this.getLight(x, y, z + 1);
                if (neighborLevel != 0 && neighborLevel < lightLevel)
                {
                    this.region.setLight(ox, oy, oz + 1, 0);
                    this.removalQueue.Enqueue(new LightRemovalNode(x, y, z + 1, neighborLevel));
                }
                else if (neighborLevel >= lightLevel)
                {
                    this.queue.Enqueue(new BlockPos(x, y, z + 1));
                }
            }

            this.setLight(startX, startY, startZ, newLight);

            this.queue.Enqueue(new BlockPos(startX, startY, startZ));

            BlockPos pos;

            while (this.queue.Count > 0)
            {
                pos = this.queue.Dequeue();
                x   = pos.x;
                y   = pos.y;
                z   = pos.z;

                lightLevel = this.getLight(x, y, z);

                if (!this.getBlock(x - 1, y, z).isSolid&& this.getLight(x - 1, y, z) + 2 <= lightLevel)
                {
                    this.setLight(x - 1, y, z, lightLevel - 1);
                    this.queue.Enqueue(new BlockPos(x - 1, y, z));
                }
                if (!this.getBlock(x + 1, y, z).isSolid&& this.getLight(x + 1, y, z) + 2 <= lightLevel)
                {
                    this.setLight(x + 1, y, z, lightLevel - 1);
                    this.queue.Enqueue(new BlockPos(x + 1, y, z));
                }
                if (!this.getBlock(x, y - 1, z).isSolid&& this.getLight(x, y - 1, z) + 2 <= lightLevel)
                {
                    this.setLight(x, y - 1, z, lightLevel - 1);
                    this.queue.Enqueue(new BlockPos(x, y - 1, z));
                }
                if (!this.getBlock(x, y + 1, z).isSolid&& this.getLight(x, y + 1, z) + 2 <= lightLevel)
                {
                    this.setLight(x, y + 1, z, lightLevel - 1);
                    this.queue.Enqueue(new BlockPos(x, y + 1, z));
                }
                if (!this.getBlock(x, y, z - 1).isSolid&& this.getLight(x, y, z - 1) + 2 <= lightLevel)
                {
                    this.setLight(x, y, z - 1, lightLevel - 1);
                    this.queue.Enqueue(new BlockPos(x, y, z - 1));
                }
                if (!this.getBlock(x, y, z + 1).isSolid&& this.getLight(x, y, z + 1) + 2 <= lightLevel)
                {
                    this.setLight(x, y, z + 1, lightLevel - 1);
                    this.queue.Enqueue(new BlockPos(x, y, z + 1));
                }
            }

            this.removalQueue.Clear();
            this.queue.Clear();
        }
Exemplo n.º 3
0
        /// <summary>
        /// Bakes the block meshes and light levels into the chunk.
        /// </summary>
        public void renderChunk()
        {
            CachedChunk3x3 cachedRegion = CachedChunk3x3.getNewRegion(this.world, this);

            if (!cachedRegion.allChunksLoaded())
            {
                // Waiting for the lazy chunk loading to finish...
                return;
            }

            this.isDirty = false;

            MeshBuilder meshBuilder = RenderManager.getMeshBuilder();

            Block currentBlock, neighborBlock;
            bool  isSolid;

            Block[]   surroundingBlocks = new Block[6];
            BlockPos  dirPos;
            int       x, y, z, i, facesCulled, x1, y1, z1, renderFaceMask, x2, y2, z2;
            Direction direction;

            // Bake blocks into mesh.
            for (x = 0; x < Chunk.SIZE; x++)
            {
                for (y = 0; y < Chunk.SIZE; y++)
                {
                    for (z = 0; z < Chunk.SIZE; z++)
                    {
                        currentBlock = this.getBlock(x, y, z);
                        if (currentBlock.renderer != null && currentBlock.renderer.bakeIntoChunks)
                        {
                            renderFaceMask = 0;

                            // Find the surrounding blocks and faces to cull.
                            facesCulled = 0;

                            for (i = 0; i < 6; i++)
                            {
                                direction = Direction.all[i];
                                dirPos    = direction.blockPos;
                                x1        = x + dirPos.x;
                                y1        = y + dirPos.y;
                                z1        = z + dirPos.z;

                                if (x1 < 0 || y1 < 0 || z1 < 0 || x1 >= Chunk.SIZE || y1 >= Chunk.SIZE || z1 >= Chunk.SIZE)
                                {
                                    neighborBlock = cachedRegion.getBlock(x1, y1, z1);
                                }
                                else
                                {
                                    neighborBlock = this.getBlock(x1, y1, z1);
                                }

                                isSolid = neighborBlock.isSolid;
                                if (!isSolid)
                                {
                                    renderFaceMask |= direction.renderMask;
                                }

                                if (currentBlock.renderer.lookupAdjacentBlocks)
                                {
                                    surroundingBlocks[i] = neighborBlock;
                                }

                                if (isSolid)
                                {
                                    facesCulled++;
                                }
                            }

                            // If at least one face is visible, render the block.
                            if (facesCulled != 6)
                            {
                                // Populate the meshData with light levels.
                                if (currentBlock.renderer.lookupAdjacentLight)
                                {
                                    for (x2 = -1; x2 <= 1; x2++)
                                    {
                                        for (y2 = -1; y2 <= 1; y2++)
                                        {
                                            for (z2 = -1; z2 <= 1; z2++)
                                            {
                                                x1 = x + x2;
                                                y1 = y + y2;
                                                z1 = z + z2;
                                                meshBuilder.setLightLevel(x2, y2, z2, x1 < 0 || y1 < 0 || z1 < 0 || x1 >= Chunk.SIZE || y1 >= Chunk.SIZE || z1 >= Chunk.SIZE ? cachedRegion.getLight(x1, y1, z1) : this.getLight(x1, y1, z1));
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    meshBuilder.setLightLevel(0, 0, 0, this.getLight(x, y, z));
                                }
                                // Render the block.
                                currentBlock.renderer.renderBlock(currentBlock, this.getMeta(x, y, z), meshBuilder, x, y, z, renderFaceMask, surroundingBlocks);
                            }
                        }
                    }
                }
            }

            // Set light UVs for tile entities that don't bake into the chunk.
            Material[] materials;
            Color      lightColor;

            foreach (TileEntityBase te in this.tileEntityDict.Values)
            {
                if (te is TileEntityGameObject)
                {
                    x          = te.posX - this.worldPos.x;
                    y          = te.posY - this.worldPos.y;
                    z          = te.posZ - this.worldPos.z;
                    materials  = ((TileEntityGameObject)te).modelMaterials;
                    lightColor = RenderManager.instance.lightColors.getColorFromBrightness(this.getLight(x, y, z));
                    for (i = 0; i < materials.Length; i++)
                    {
                        materials[i].SetColor(LightColors.SERIALIZED_LightColor, lightColor);
                    }
                }
            }

            this.filter.mesh = meshBuilder.getGraphicMesh();
            this.blockCollider.sharedMesh = meshBuilder.getColliderMesh();
        }