예제 #1
0
        public void Process(IRenderCell cell)
        {
            _cell = cell;
            _cell.RenderMeshData.Clear();
            var maskPool = PoolManager.GetObjectPool <Dictionary <FaceDirection, SparseArray3D <BlockFace> > >();

            _masks = maskPool.Pop();
            if (_masks.Count == 0)
            {
                _masks[FaceDirection.XIncreasing] = new SparseArray3D <BlockFace>();
                _masks[FaceDirection.YIncreasing] = new SparseArray3D <BlockFace>();
                _masks[FaceDirection.ZIncreasing] = new SparseArray3D <BlockFace>();
                _masks[FaceDirection.XDecreasing] = new SparseArray3D <BlockFace>();
                _masks[FaceDirection.YDecreasing] = new SparseArray3D <BlockFace>();
                _masks[FaceDirection.ZDecreasing] = new SparseArray3D <BlockFace>();
            }
            BuildMasks();
            if (_max.x < _min.x)
            {
                return;
            }
            for (var side = 0; side < 6; side++)
            {
                var backside = side > 2;
                var axis     = side % 3;

                var u = (axis + 1) % 3;
                var v = (axis + 2) % 3;

                var mask = _masks[General.FlipDirection((FaceDirection)side)];

                var axisPos = backside ? _max[axis] - 1 : _min[axis];
                while (axisPos < _max[axis] && axisPos >= _min[axis])
                {
                    for (var j = _min[v]; j < _max[v]; j++)
                    {
                        for (var i = _min[u]; i < _max[u];)
                        {
                            var maskPosition = new Vector3Int()
                            {
                                [u]    = i,
                                [v]    = j,
                                [axis] = axisPos
                            };
                            if (!mask.ContainsKey(maskPosition))
                            {
                                i++;
                                continue;
                            }

                            var width     = 1;
                            var blockFace = mask[maskPosition];
                            while (i + width < _max[u])
                            {
                                var nextPos = maskPosition;
                                nextPos[u] += width;
                                if (blockFace != mask[nextPos])
                                {
                                    break;
                                }
                                width++;
                            }
                            int height;
                            for (height = 1; j + height < _max[v]; height++)
                            {
                                for (var k = 0; k < width; k++)
                                {
                                    var nextPos = maskPosition;
                                    nextPos[u] += k;
                                    nextPos[v] += height;
                                    if (mask[nextPos] == blockFace)
                                    {
                                        continue;
                                    }
                                    goto heightFound;
                                }
                            }

heightFound:

                            var offset = axisPos + (backside ? 1 : 0);

                            var topLeft = new Vector3
                            {
                                [u]    = i + width,
                                [v]    = j,
                                [axis] = offset
                            };
                            var topRight = new Vector3
                            {
                                [u]    = i + width,
                                [v]    = j + height,
                                [axis] = offset
                            };
                            var bottomRight = new Vector3
                            {
                                [u]    = i,
                                [v]    = j + height,
                                [axis] = offset
                            };

                            var bottomLeft = new Vector3
                            {
                                [u]    = i,
                                [v]    = j,
                                [axis] = offset
                            };

                            _cell.RenderMeshData.AddQuad(topLeft, topRight, bottomRight, bottomLeft, height, width, blockFace, side);

                            for (var l = 0; l < height; ++l)
                            {
                                for (var k = 0; k < width; ++k)
                                {
                                    var remove = maskPosition;
                                    remove[u] += k;
                                    remove[v] += l;
                                    mask.Remove(remove);
                                }
                            }

                            i += width;
                        }
                    }
                    axisPos += backside ? -1 : 1;
                }
            }
            foreach (var maskPair in _masks)
            {
                if (maskPair.Value.Count > 0)
                {
                    maskPair.Value.Clear();
                }
            }
            maskPool.Push(_masks);
        }
예제 #2
0
        public void Process(IRenderCell cell)
        {
            _cell = cell;
            _cell.RenderMeshData.Clear();

            for (var x = _cell.Min.x; x < _cell.Max.x; x++)
            {
                for (var z = _cell.Min.z; z < _cell.Max.z; z++)
                {
                    for (var y = _cell.Min.y; y < _cell.Max.y; y++)
                    {
                        var block = _cell.GetBlock(x, y, z);
                        if (!block.AddToRenderMesh)
                        {
                            continue;
                        }
                        var blockLight = _cell.GetLight(x, y, z);
                        var blockId    = block.BlockId;
                        var block100   = _cell.GetBlock(x + 1, y, z);
                        var block010   = _cell.GetBlock(x, y + 1, z);
                        var block001   = _cell.GetBlock(x, y, z + 1);
                        var blockN100  = _cell.GetBlock(x - 1, y, z);
                        var block0N10  = _cell.GetBlock(x, y - 1, z);
                        var block00N1  = _cell.GetBlock(x, y, z - 1);


                        var light100  = _cell.GetLight(x + 1, y, z);
                        var light010  = _cell.GetLight(x, y + 1, z);
                        var light001  = _cell.GetLight(x, y, z + 1);
                        var lightN100 = _cell.GetLight(x - 1, y, z);
                        var light0N10 = _cell.GetLight(x, y - 1, z);
                        var light00N1 = _cell.GetLight(x, y, z - 1);

                        //XIncreasing
                        if (!(block100.RenderOpaque || block100.BlockId == blockId))
                        {
                            var blockFace1 = new BlockFace
                            {
                                Exists       = true,
                                BlockId      = block.BlockId,
                                Tint         = block.Tints[0],
                                TextureIndex = block.GetTextureMapping(FaceDirection.XIncreasing)
                            };
                            if (block.Emissivity > 0)
                            {
                                blockFace1.LightTopLeft     = blockLight;
                                blockFace1.LightTopRight    = blockLight;
                                blockFace1.LightBottomRight = blockLight;
                                blockFace1.LightBottomLeft  = blockLight;
                            }
                            else
                            {
                                blockFace1.LightTopLeft     = light100;
                                blockFace1.LightTopRight    = light100;
                                blockFace1.LightBottomRight = light100;
                                blockFace1.LightBottomLeft  = light100;
                            }

                            var topLeft     = new Vector3(x + 1, y + 1, z);
                            var topRight    = new Vector3(x + 1, y + 1, z + 1);
                            var bottomRight = new Vector3(x + 1, y, z + 1);
                            var bottomLeft  = new Vector3(x + 1, y, z);

                            _cell.RenderMeshData.AddQuad(topLeft, topRight, bottomRight, bottomLeft, 1, 1, blockFace1,
                                                         (int)General.FlipDirection(FaceDirection.XIncreasing));
                        }

                        //YIncreasing
                        if (!(block010.RenderOpaque || block010.BlockId == blockId))
                        {
                            var blockFace2 = new BlockFace
                            {
                                Exists       = true,
                                BlockId      = block.BlockId,
                                Tint         = block.Tints[1],
                                TextureIndex = block.GetTextureMapping(FaceDirection.YIncreasing)
                            };
                            if (block.Emissivity > 0)
                            {
                                blockFace2.LightTopLeft     = blockLight;
                                blockFace2.LightTopRight    = blockLight;
                                blockFace2.LightBottomRight = blockLight;
                                blockFace2.LightBottomLeft  = blockLight;
                            }
                            else
                            {
                                blockFace2.LightTopLeft     = light010;
                                blockFace2.LightTopRight    = light010;
                                blockFace2.LightBottomRight = light010;
                                blockFace2.LightBottomLeft  = light010;
                            }

                            var topLeft     = new Vector3(x, y + 1, z + 1);
                            var topRight    = new Vector3(x + 1, y + 1, z + 1);
                            var bottomRight = new Vector3(x + 1, y + 1, z);
                            var bottomLeft  = new Vector3(x, y + 1, z);

                            _cell.RenderMeshData.AddQuad(topLeft, topRight, bottomRight, bottomLeft, 1, 1, blockFace2,
                                                         (int)General.FlipDirection(FaceDirection.YIncreasing));
                        }

                        //ZIncreasing
                        if (!(block001.RenderOpaque || block001.BlockId == blockId))
                        {
                            var blockFace3 = new BlockFace
                            {
                                Exists       = true,
                                BlockId      = block.BlockId,
                                Tint         = block.Tints[2],
                                TextureIndex = block.GetTextureMapping(FaceDirection.ZIncreasing)
                            };
                            if (block.Emissivity > 0)
                            {
                                blockFace3.LightTopLeft     = blockLight;
                                blockFace3.LightTopRight    = blockLight;
                                blockFace3.LightBottomRight = blockLight;
                                blockFace3.LightBottomLeft  = blockLight;
                            }
                            else
                            {
                                blockFace3.LightTopLeft     = light001;
                                blockFace3.LightTopRight    = light001;
                                blockFace3.LightBottomRight = light001;
                                blockFace3.LightBottomLeft  = light001;
                            }

                            var topLeft     = new Vector3(x + 1, y, z + 1);
                            var topRight    = new Vector3(x + 1, y + 1, z + 1);
                            var bottomRight = new Vector3(x, y + 1, z + 1);
                            var bottomLeft  = new Vector3(x, y, z + 1);

                            _cell.RenderMeshData.AddQuad(topLeft, topRight, bottomRight, bottomLeft, 1, 1, blockFace3,
                                                         (int)General.FlipDirection(FaceDirection.ZIncreasing));
                        }

                        //XDecreasing
                        if (!(blockN100.RenderOpaque || blockN100.BlockId == blockId))
                        {
                            var blockFace4 = new BlockFace
                            {
                                Exists       = true,
                                BlockId      = block.BlockId,
                                Tint         = block.Tints[3],
                                TextureIndex = block.GetTextureMapping(FaceDirection.XDecreasing)
                            };
                            if (block.Emissivity > 0)
                            {
                                blockFace4.LightTopLeft     = blockLight;
                                blockFace4.LightTopRight    = blockLight;
                                blockFace4.LightBottomRight = blockLight;
                                blockFace4.LightBottomLeft  = blockLight;
                            }
                            else
                            {
                                blockFace4.LightTopLeft     = lightN100;
                                blockFace4.LightTopRight    = lightN100;
                                blockFace4.LightBottomRight = lightN100;
                                blockFace4.LightBottomLeft  = lightN100;
                            }

                            var topLeft     = new Vector3(x, y + 1, z);
                            var topRight    = new Vector3(x, y + 1, z + 1);
                            var bottomRight = new Vector3(x, y, z + 1);
                            var bottomLeft  = new Vector3(x, y, z);

                            _cell.RenderMeshData.AddQuad(topLeft, topRight, bottomRight, bottomLeft, 1, 1, blockFace4,
                                                         (int)General.FlipDirection(FaceDirection.XDecreasing));
                        }

                        //YDecreasing
                        if (!(block0N10.RenderOpaque || block0N10.BlockId == blockId))
                        {
                            var blockFace5 = new BlockFace
                            {
                                Exists       = true,
                                BlockId      = block.BlockId,
                                Tint         = block.Tints[4],
                                TextureIndex = block.GetTextureMapping(FaceDirection.YDecreasing)
                            };
                            if (block.Emissivity > 0)
                            {
                                blockFace5.LightTopLeft     = blockLight;
                                blockFace5.LightTopRight    = blockLight;
                                blockFace5.LightBottomRight = blockLight;
                                blockFace5.LightBottomLeft  = blockLight;
                            }
                            else
                            {
                                blockFace5.LightTopLeft     = light0N10;
                                blockFace5.LightTopRight    = light0N10;
                                blockFace5.LightBottomRight = light0N10;
                                blockFace5.LightBottomLeft  = light0N10;
                            }

                            var topLeft     = new Vector3(x, y, z + 1);
                            var topRight    = new Vector3(x + 1, y, z + 1);
                            var bottomRight = new Vector3(x + 1, y, z);
                            var bottomLeft  = new Vector3(x, y, z);

                            _cell.RenderMeshData.AddQuad(topLeft, topRight, bottomRight, bottomLeft, 1, 1, blockFace5,
                                                         (int)General.FlipDirection(FaceDirection.YDecreasing));
                        }

                        //ZDecreasing
                        if (!(block00N1.RenderOpaque || block00N1.BlockId == blockId))
                        {
                            var blockFace6 = new BlockFace
                            {
                                Exists       = true,
                                BlockId      = block.BlockId,
                                Tint         = block.Tints[5],
                                TextureIndex = block.GetTextureMapping(FaceDirection.ZDecreasing)
                            };
                            if (block.Emissivity > 0)
                            {
                                blockFace6.LightTopLeft     = blockLight;
                                blockFace6.LightTopRight    = blockLight;
                                blockFace6.LightBottomRight = blockLight;
                                blockFace6.LightBottomLeft  = blockLight;
                            }
                            else
                            {
                                blockFace6.LightTopLeft     = light00N1;
                                blockFace6.LightTopRight    = light00N1;
                                blockFace6.LightBottomRight = light00N1;
                                blockFace6.LightBottomLeft  = light00N1;
                            }

                            var topLeft     = new Vector3(x + 1, y, z);
                            var topRight    = new Vector3(x + 1, y + 1, z);
                            var bottomRight = new Vector3(x, y + 1, z);
                            var bottomLeft  = new Vector3(x, y, z);

                            _cell.RenderMeshData.AddQuad(topLeft, topRight, bottomRight, bottomLeft, 1, 1, blockFace6, (int)General.FlipDirection(FaceDirection.ZDecreasing));
                        }
                    }
                }
            }
        }