예제 #1
0
        public void GetChunk(int x, int y, int z, VoxelVolume chunk)
        {
            if (!started)
            {
                Init();
                started = true;
            }

            //for (var xx = 0; xx < ChunkManager.CHUNK_SIZE; xx++)
            //    for (var zz = 0; zz < ChunkManager.CHUNK_SIZE; zz++)
            //        chunk[xx, 0, zz] = 0xffffff;

            //chunk[0, 1, 0] = 0xffffff;
            //chunk[0, 1, 1] = 0xffffff;
            //chunk[0, 1, 2] = 0xffffff;
            //chunk[0, 1, 3] = 0xffffff;
            ////chunk[1, 2, 1] = 0xffffff;
            ////chunk[1, 2, 2] = 0xffffff;
            ////chunk[2, 2, 2] = 0xffffff;
            ////chunk[1, 0, 1] = 0xffffff;
            ////chunk[1, 0, 2] = 0xffffff;
            ////chunk[2, 0, 2] = 0xffffff;
            //return;

            bool addCaves = false; // (bool)m.GetOption("DefaultGenCaves");
            bool addCaveLava = false; // (bool)m.GetOption("DefaultGenLavaCaves");
            int ChunkSize = Constants.CHUNK_SIZE;// m.GetChunkSize();
            x *= ChunkSize;
            y *= ChunkSize;
            z *= ChunkSize;
            int chunksize = ChunkSize;
            var noise = new FastNoise();
            noise.Frequency = 0.01;

            for (int xx = 0; xx < chunksize; xx++)
            {
                for (int yy = 0; yy < chunksize; yy++)
                {
                    int currentHeight = (byte)((finalTerrain.GetValue((xx + x) / 100.0f, 0, (yy + y) / 100.0f) * 60) + 64);
                    int ymax = currentHeight;

                    int biome = (int)(BiomeSelect.GetValue((x + xx) / 100.0f, 0, (y + yy) / 100.0f) * 2); //MD * 2
                    uint toplayer = BLOCK_DIRT;
                    if (biome == 0)
                    {
                        toplayer = BLOCK_DIRT;
                    }
                    if (biome == 1)
                    {
                        toplayer = BLOCK_SAND;
                    }
                    if (biome == 2)
                    {
                        toplayer = BLOCK_DIRT;
                    }
                    if (biome == 3)
                    {
                        toplayer = BLOCK_DIRT;
                    }
                    if (biome == 4)
                    {
                        toplayer = BLOCK_DIRT;
                    }
                    if (biome == 5)
                    {
                        toplayer = BLOCK_CLAY;
                    }

                    int stoneHeight = (int)currentHeight - ((64 - (currentHeight % 64)) / 8) + 1;

                    if (ymax < seaLevel)
                    {
                        ymax = seaLevel;
                    }
                    ymax++;
                    if (ymax > z + chunksize - 1)
                    {
                        ymax = z + chunksize - 1;
                    }
                    for (int bY = z; bY <= ymax; bY++)
                    {
                        uint curBlock = 0;

                        // Place bedrock
                        if (bY == 0)
                        {
                            curBlock = BLOCK_BEDROCK;
                        }
                        else if (bY < currentHeight)
                        {
                            if (bY < stoneHeight)
                            {
                                curBlock = BLOCK_STONE;
                                // Add caves
                                if (addCaves)
                                {
                                    if (caveNoise.GetValue((x + xx) / 4.0f, (bY) / 1.5f, (y + yy) / 4.0f) > cavestreshold)
                                    {
                                        if (bY < 10 && addCaveLava)
                                        {
                                            curBlock = BLOCK_LAVA;
                                        }
                                        else
                                        {
                                            curBlock = BLOCK_AIR;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                curBlock = toplayer;
                            }
                        }
                        else if ((currentHeight + 1) == bY && bY > seaLevel && biome == 3)
                        {
                            curBlock = BLOCK_SNOW;
                            continue;
                        }
                        else if ((currentHeight + 1) == bY && bY > seaLevel + 1)
                        {
                            if (biome == 1 || biome == 0)
                            {
                                continue;
                            }
                            double f = flowers.GetValue(x + xx / 10.0f, 0, y + yy / 10.0f);
                            if (f < -0.999)
                            {
                                curBlock = BLOCK_RED_ROSE;
                            }
                            else if (f > 0.999)
                            {
                                curBlock = BLOCK_YELLOW_FLOWER;
                            }
                            else if (f < 0.001 && f > -0.001)
                            {
                                curBlock = BLOCK_PUMPKIN;
                            }
                        }
                        else if (currentHeight == bY)
                        {
                            if (bY == seaLevel || bY == seaLevel - 1 || bY == seaLevel - 2)
                            {
                                curBlock = BLOCK_SAND;  // FF
                            }
                            else if (bY < seaLevel - 1)
                            {
                                curBlock = BLOCK_GRAVEL;  // FF
                            }
                            else if (toplayer == BLOCK_DIRT)
                            {
                                curBlock = BLOCK_GRASS;
                            }
                            else
                            {
                                curBlock = toplayer; // FF
                            }
                        }
                        else
                        {
                            if (bY <= seaLevel)
                            {
                                curBlock = BLOCK_WATER;  // FF
                            }
                            else
                            {
                                curBlock = BLOCK_AIR;  // FF
                            }
                            if (bY == seaLevel && biome == 3)
                            {
                                curBlock = BLOCK_ICE;
                            }
                        }
                        //var idx = xx + chunksize * ((yy) + chunksize * (bY - z));
                        chunk[xx, bY - z, yy] = curBlock;
                        //chunk[idx] = curBlock;
                        //chunk[m.Index3d(xx, yy, bY - z, chunksize, chunksize)] = curBlock;
                    }
                }
            }
        }
예제 #2
0
        public static int ExtractMesh(VoxelVolume volume, bool disableGreedyMeshing = false, bool disableAO = false)
        {
            volume.PrepareMesh();

            VertexPositionColorNormal[] vertices = new VertexPositionColorNormal[5];

            var dims = volume.dims;

            var f = new Func<int, int, int, uint>((i, j, k) =>
            {
                if (i < 0 || j < 0 || k < 0 || i >= dims[0] || j >= dims[1] || k >= dims[2])
                    return volume.GetRelativeVoxel(i, j, k);
                //return cm.GetVoxelByRelative(volume.X, volume.Y, volume.Z, i, j, k);

                var r = volume[i + dims[0] * (j + dims[1] * k)];
                if (r > 0 && (r & 0x1000000u) > 0u)
                {
                    r = 0;
                }
                return r;
            });

            //Sweep over 3-axes
            // d0 = x, d1 = y, d2 = z
            for (var d = 0; d < 3; ++d)
            {
                int i, j, k, l, w, h
                  , u = (d + 1) % 3
                  , v = (d + 2) % 3;
                int[] x = { 0, 0, 0 };
                int[] q = { 0, 0, 0 };
                int[,] posArea = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
                int[,] negArea = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };

                if (mask.Length < dims[u] * dims[v])
                {
                    mask = new uint[dims[u] * dims[v]];
                    maskLayout = new MaskLayout[dims[u] * dims[v]];
                }
                q[d] = 1;

                posArea[0, u] = -1;
                posArea[1, v] = -1;
                posArea[2, u] = 1;
                posArea[3, v] = 1;

                negArea[0, v] = -1;
                negArea[1, u] = -1;
                negArea[2, v] = 1;
                negArea[3, u] = 1;

                for (x[d] = -1; x[d] < dims[d]; )
                {
                    //Compute mask
                    var n = 0;
                    for (x[v] = 0; x[v] < dims[v]; ++x[v])
                    {
                        for (x[u] = 0; x[u] < dims[u]; ++x[u], ++n)
                        {
                            var a = f(x[0], x[1], x[2]);
                            var b = f(x[0] + q[0], x[1] + q[1], x[2] + q[2]);

                            maskLayout[n].data = 0u;
                            if ((a != 0) == (b != 0))
                            {
                                mask[n] = 0;
                            }
                            else if (a != 0)
                            {
                                mask[n] = x[d] > -1 ? a : 0;
                                maskLayout[n].BackFace = false;
                            }
                            else
                            {
                                mask[n] = x[d] < dims[d] - 1 ? b : 0;
                                maskLayout[n].BackFace = true;
                            }

                            if (disableAO || mask[n] == 0)
                            {
                                //maskLayout[n].data = 4095u;
                            }
                            else
                            {
                                uint side1 = 0, side2 = 0, corner = 0;
                                var neighbors = new uint[4];

                                for (var t = 0; t < 4; ++t)
                                {
                                    var tt = (t + 1) % 4;

                                    if (a != 0)
                                    {
                                        side1 = (f(x[0] + q[0] + posArea[t, 0], x[1] + q[1] + posArea[t, 1], x[2] + q[2] + posArea[t, 2]) > 0u ? 1u : 0u);
                                        side2 = (f(x[0] + q[0] + posArea[tt, 0], x[1] + q[1] + posArea[tt, 1], x[2] + q[2] + posArea[tt, 2]) > 0u ? 1u : 0u);
                                    }
                                    else
                                    {
                                        side1 = (f(x[0] + negArea[t, 0], x[1] + negArea[t, 1], x[2] + negArea[t, 2]) > 0u ? 1u : 0u);
                                        side2 = (f(x[0] + negArea[tt, 0], x[1] + negArea[tt, 1], x[2] + negArea[tt, 2]) > 0u ? 1u : 0u);
                                    }

                                    if (side1 > 0 && side2 > 0)
                                    {
                                        neighbors[t] = 0;
                                    }
                                    else
                                    {
                                        if (a != 0)
                                        {
                                            corner = (f(x[0] + q[0] + posArea[t, 0] + posArea[tt, 0], x[1] + q[1] + posArea[t, 1] + posArea[tt, 1], x[2] + q[2] + posArea[t, 2] + posArea[tt, 2]) > 0u ? 1u : 0u);
                                        }
                                        else
                                        {
                                            corner = (f(x[0] + negArea[t, 0] + negArea[tt, 0], x[1] + negArea[t, 1] + negArea[tt, 1], x[2] + negArea[t, 2] + negArea[tt, 2]) > 0u ? 1u : 0u);
                                        }
                                        neighbors[t] = 3u - (side1 + side2 + corner);
                                    }

                                    maskLayout[n].SetOcclusion(t, neighbors[t]);
                                }

                                uint a00 = neighbors[1],
                                     a01 = neighbors[2],
                                     a11 = neighbors[3],
                                     a10 = neighbors[0];

                                //if (a00 + a01 + a11 + a10 != 12)
                                //    maskLayout[n].AOFace = true;
                            }
                        }
                    }
                    //Increment x[d]
                    ++x[d];
                    //Generate mesh for mask using lexicographic ordering
                    n = 0;
                    for (j = 0; j < dims[v]; ++j)
                    {
                        for (i = 0; i < dims[u]; )
                        {
                            var c = mask[n];
                            if (c != 0)
                            {
                                var a = maskLayout[n];
                                if (disableGreedyMeshing || a.AOFace)
                                {
                                    w = 1;
                                    h = 1;
                                }
                                else
                                {
                                    //Compute width
                                    for (w = 1; c == mask[n + w] && (a.data == (maskLayout[n + w].data)) && i + w < dims[u]; ++w)
                                    {
                                    }
                                    //Compute height (this is slightly awkward
                                    var done = false;
                                    for (h = 1; j + h < dims[v]; ++h)
                                    {
                                        for (k = 0; k < w; ++k)
                                        {
                                            if (c != mask[n + k + h * dims[u]] || a.data != maskLayout[n + k + h * dims[u]].data)
                                            {
                                                done = true;
                                                break;
                                            }
                                        }
                                        if (done)
                                        {
                                            break;
                                        }
                                    }
                                }

                                //Add quad
                                x[u] = i; x[v] = j;
                                int[] du = { 0, 0, 0 };
                                int[] dv = { 0, 0, 0 };

                                var normal = new Vector3(q[0], q[1], q[2]);
                                var aoFace = maskLayout[n].AOFace;

                                if (!maskLayout[n].BackFace)
                                {
                                    dv[v] = h;
                                    du[u] = w;
                                }
                                else
                                {
                                    du[v] = h;
                                    dv[u] = w;
                                    normal = -normal;
                                }

                                var cr = ((c >> 16) & 0xff) / 255f;
                                var cg = ((c >> 8) & 0xff) / 255f;
                                var cb = (c & 0xff) / 255f;

                                var ao = 0f;
                                var AOcurve = new float[] { 0.45f, 0.65f, 0.85f, 1.0f };
                                var auCurveFactor = new float[] { 1f, 0.99f, 0.98f, 0.97f, 0.96f };
                                var aoFactor = auCurveFactor[maskLayout[n].TotalOcclusion()];
                                for (var o = 0; o < 4; ++o)
                                {
                                    var pao = disableAO ? 1f : AOcurve[maskLayout[n].GetOcclusion(o)];
                                    //vertices[o].Color = new Color(cr * pao, cg * pao, cb * pao);
                                    vertices[o].Color = new Color(cr * aoFactor, cg * aoFactor, cb * aoFactor);
                                    vertices[o].Normal = normal;
                                    ao += pao;
                                }
                                ao /= 4f;

                                if (aoFace)
                                {
                                    vertices[0].Position = new Vector3(x[0], x[1], x[2]);
                                    vertices[1].Position = new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]);
                                    vertices[2].Position = new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]);
                                    vertices[3].Position = new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]);
                                    vertices[4].Position = (vertices[0].Position + vertices[1].Position + vertices[2].Position + vertices[3].Position) / 4;
                                    vertices[4].Normal = normal;
                                    vertices[4].Color = new Color(cr * ao, cg * ao, cb * ao);
                                }
                                else
                                {
                                    vertices[0].Position = new Vector3(x[0], x[1], x[2]);
                                    vertices[1].Position = new Vector3(x[0] + du[0], x[1] + du[1], x[2] + du[2]);
                                    vertices[2].Position = new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]);
                                    vertices[3].Position = new Vector3(x[0] + dv[0], x[1] + dv[1], x[2] + dv[2]);
                                }

                                var v0 = (ushort)volume.opaqueMesh.Add(vertices[0]);
                                var v1 = (ushort)volume.opaqueMesh.Add(vertices[1]);
                                var v2 = (ushort)volume.opaqueMesh.Add(vertices[2]);
                                var v3 = (ushort)volume.opaqueMesh.Add(vertices[3]);

                                if (aoFace)
                                {
                                    var v4 = (ushort)volume.opaqueMesh.Add(vertices[4]);
                                    volume.opaqueMesh.Triangle(v0, v4, v1);
                                    volume.opaqueMesh.Triangle(v1, v4, v2);
                                    volume.opaqueMesh.Triangle(v2, v4, v3);
                                    volume.opaqueMesh.Triangle(v3, v4, v0);

                                }
                                else
                                {
                                    volume.opaqueMesh.Quad(v0, v1, v2, v3);
                                }

                                //Zero-out mask
                                for (l = 0; l < h; ++l)
                                {
                                    for (k = 0; k < w; ++k)
                                    {
                                        mask[n + k + l * dims[u]] = 0;
                                        maskLayout[n + k + l * dims[u]].data = 4095u;
                                    }
                                }
                                //Increment counters and continue
                                i += w; n += w;
                            }
                            else
                            {
                                ++i; ++n;
                            }
                        }
                    }
                }
            }

            volume.opaqueMesh.Update();
            return volume.opaqueMesh.VertexCount;
        }
예제 #3
0
파일: Game1.cs 프로젝트: xposure/BOTA
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            instance = this;

            base.Initialize();

            _chunkManager = new ChunkManager(this.GraphicsDevice);

            //var data = new uint[3 * 3 *3];
            //for(var i =0;i < data.Length;i++){
            //    if((i % 4) == 0)
            //        data[i] = 0xffffff;
            //}

            //_volume = new Volume(_chunkManager, 0, 0, 0, data, new Dimensions(new int[] { 3, 3, 3 }));

            sceneCamera = new Camera(this.GraphicsDevice);

            //float tilt = MathHelper.ToRadians(0);  // 0 degree angle
            //// Use the world matrix to tilt the cube along x and y axes.
            //worldMatrix = Matrix.CreateRotationX(tilt) * Matrix.CreateRotationY(tilt);
            //viewMatrix = Matrix.CreateLookAt(new Vector3(zoom, zoom, zoom), Vector3.Zero, Vector3.Up);

            //projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
            //    MathHelper.ToRadians(45),  // 45 degree angle
            //    (float)GraphicsDevice.Viewport.Width /
            //    (float)GraphicsDevice.Viewport.Height,
            //    1.0f, 10000.0f);

            basicEffect = new BasicEffect(graphics.GraphicsDevice);

            basicEffect.World = Matrix.Identity;
            basicEffect.View = Matrix.Identity;
            basicEffect.Projection = sceneCamera.Projection;

            // primitive color
            basicEffect.AmbientLightColor = new Vector3(0.1f, 0.1f, 0.1f);
            basicEffect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
            basicEffect.SpecularColor = new Vector3(0.25f, 0.25f, 0.25f);
            basicEffect.SpecularPower = 5.0f;
            basicEffect.Alpha = 1.0f;
            basicEffect.VertexColorEnabled = true;
            //basicEffect.FogEnabled = true;
            //basicEffect.FogColor = new Vector3(0, 0, 0);
            //basicEffect.FogStart = 10;
            //basicEffect.FogEnd = 100;
            wireFrame = new BasicEffect(graphics.GraphicsDevice);

            wireFrame.World = Matrix.Identity;
            wireFrame.View = Matrix.Identity;
            wireFrame.Projection = sceneCamera.Projection;

            // primitive color
            wireFrame.AmbientLightColor = new Vector3(0.1f, 0.1f, 0.1f);
            wireFrame.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
            wireFrame.SpecularColor = new Vector3(0.25f, 0.25f, 0.25f);
            wireFrame.SpecularPower = 5.0f;
            wireFrame.Alpha = 1.0f;
            wireFrame.VertexColorEnabled = false;
            wireFrame.LightingEnabled = true;

            basicEffect.LightingEnabled = true;
            if (basicEffect.LightingEnabled)
            {
                basicEffect.DirectionalLight0.Enabled = true; // enable each light individually
                if (basicEffect.DirectionalLight0.Enabled)
                {
                    // x direction
                    basicEffect.AmbientLightColor = new Vector3(1, 1, 1);
                    basicEffect.DirectionalLight0.DiffuseColor = new Vector3(0.1f, 0.1f, 0.1f); // range is 0 to 1
                    basicEffect.DirectionalLight0.Direction = Vector3.Normalize(new Vector3(-0.25f, -1, -0.5f));
                    // points from the light to the origin of the scene
                    basicEffect.DirectionalLight0.SpecularColor = Vector3.Zero;
                    //basicEffect.DirectionalLight0.SpecularColor = Vector3.One;
                }
            }

            mouseState = Mouse.GetState();
            keyboardState = Keyboard.GetState();

            //_chunkManager.Initialize();
            var generator = new DefaultWorldGenerator();
            world = new World(GraphicsDevice, 192, 128);
            world.Generate(generator);

            arialFont = Content.Load<SpriteFont>("fonts/arial");
            voxelEffect = Content.Load<Effect>("shaders/voxelshader");

            selection = new VoxelVolume(this.GraphicsDevice, new Dimensions(new int[] { world.Size, 1, world.Size }));
        }