powerOf2Log2() public static method

public static powerOf2Log2 ( int n ) : int
n int
return int
Beispiel #1
0
        public static void Main(String[] args)
        {
            Console.WriteLine("Procedurality CLI - (c)2009 Rob \"N3X15\" Nelson");
            Console.WriteLine("_______________________________________________________________\n");

            foreach (String s in args)
            {
                //Console.WriteLine(s);
            }
            Arguments CommandLine = new Arguments(args);

            String action = "help";
            String file   = "in.png";
            String ofile  = "out";
            int    seed   = DateTime.Now.Millisecond;

            Size = 256;
            bool FlipV = false;

            if (CommandLine["flip-v"] != null)
            {
                FlipV = true;
            }

            // --help
            if (CommandLine["help"] != null)
            {
                Help();
            }

            // --seed=1234567890
            if (CommandLine["seed"] != null)
            {
                seed = int.Parse(CommandLine["seed"]);
            }

            Console.WriteLine(" * Random seed: " + seed.ToString());

            if (CommandLine["size"] != null)
            {
                Size = uint.Parse(CommandLine["size"]);
            }

            Channel terrain;

            if (CommandLine["perlin"] != null)
            {
                Console.Write("Generating terrain with perlin noise...");
                terrain = new Mountain((int)Size, Utils.powerOf2Log2((int)Size) - 6, 0.5f, seed).toChannel();
                Console.WriteLine(" DONE!");
            }
            else if (CommandLine["in"] != null)
            {
                Console.Write("Loading " + file + "...");
                terrain = LoadTerrain(CommandLine["in"]);
                if (FlipV)
                {
                    terrain = terrain.flipV();
                }
                Console.WriteLine(" Done!");

                if (CommandLine["tiledir"] != null && CommandLine["tilesize"] != null)
                {
                    string tiledir = CommandLine["tiledir"];
                    if (!Directory.Exists(tiledir))
                    {
                        Directory.CreateDirectory(tiledir);
                    }
                    MakeTiles(terrain, uint.Parse(CommandLine["tilesize"]), tiledir);
                }
            }
            else if (CommandLine["hills"] != null)
            {
                Console.Write("Generating " + CommandLine["hills"] + " hills...");
                terrain = HillsAlgo((int)Size, int.Parse(CommandLine["hills"]), seed);
                Console.WriteLine(" DONE!");
            }
            else if (CommandLine["craters"] != null)
            {
                Console.Write("Generating " + CommandLine["craters"] + " craters...");
                terrain = CratersAlgo((int)Size, int.Parse(CommandLine["craters"]), seed);
                Console.WriteLine(" DONE!");
            }
            else
            {
                Console.WriteLine("Please use --perlin, --in, --hills, or --craters to load some terrain.");
                return;
            }

            ofile = args[args.Length - 1];


            if (CommandLine["addcliffs"] != null)
            {
                int features = 4;
                if (CommandLine["features"] != null)
                {
                    features = int.Parse(CommandLine["features"]);
                }

                Console.WriteLine("Adding cliffs.");
                // add mountain peaks
                Voronoi voronoi = new Voronoi(256, 4, 4, 1, 1f, seed);
                Channel cliffs  = voronoi.getDistance(-1f, 1f, 0f).brightness(1.5f).multiply(0.33f);
                terrain.multiply(0.67f).channelAdd(cliffs);
                terrain.channelSubtract(voronoi.getDistance(1f, 0f, 0f).gamma(.5f).flipV().rotate(90));
            }
            if (CommandLine["iceage"] != null)
            {
                float hills = 0.5f;
                if (CommandLine["hillratio"] != null)
                {
                    hills = float.Parse(CommandLine["hillratio"]);
                }

                Console.WriteLine("Ice age erosion in progress.");
                terrain.perturb(new Midpoint((int)Size, 2, hills, seed).toChannel(), 0.25f);
            }

            if (CommandLine["thermal"] != null)
            {
                float hills = 0.5f;
                if (CommandLine["hillratio"] != null)
                {
                    hills = float.Parse(CommandLine["hillratio"]);
                }

                terrain.erodeThermal((24f - hills * 12f) / (int)Size, (int)Size >> 2);
            }

            // Hydraulic Erosion
            if (CommandLine["hydraulic"] != null)
            {
                Console.WriteLine("Hydraulic erosion in progress.");

                // let it rain for a couple of thousand years
                float hills = 0.5f;
                if (CommandLine["hillratio"] != null)
                {
                    hills = float.Parse(CommandLine["hillratio"]);
                }

                terrain.erode((24f - hills * 12f) / (int)Size, (int)Size >> 2);
            }
            if (CommandLine["slow-hydro"] != null)
            {
                terrain = ErosionHydraulic.erode1(terrain, terrain.copy().multiply(0.01f), 0.1f, 1, 100);
                terrain = ErosionHydraulic.erode2(terrain, terrain.copy().multiply(0.01f), 0.1f, 1, 100);
                terrain = ErosionHydraulic.erode3(terrain, terrain.copy().multiply(0.01f), 0.1f, 1, 100);
                terrain = ErosionHydraulic.erode4(terrain, 0.01f, 0.1f, 1, 100);
                terrain = ErosionHydraulic.erode5(terrain, terrain.copy().multiply(0.01f), 0.1f, 0.1f, 0.1f, 20f, 0.5f, 1, 100);
            }
            if (CommandLine["add-silt"] != null)
            {
                float wl = 20f / 256f;
                wl      = float.Parse(CommandLine["add-silt"]);
                terrain = terrain.silt(wl, true);
            }
            if (CommandLine["add-river"] != null)
            {
                terrain.normalize(1f, 0.3f);
                List <PathFinderNode> path;
                terrain = (new RiverBuilder(terrain)).GenerateRiver(20f, seed, out path).toChannel();
                terrain.normalize();
                string rpath = "";
                foreach (PathFinderNode p in path)
                {
                    rpath += string.Format("{0},{1}\n", p.X, p.Y);
                }
                File.WriteAllText(ofile + ".river.txt", rpath);
            }
            terrain.smooth(1);

            float nm = 0f;
            float nM = 1f;

            if (CommandLine["range-max"] != null)
            {
                nM = float.Parse(CommandLine["range-max"]);
            }

            if (CommandLine["range-min"] != null)
            {
                nm = float.Parse(CommandLine["range-min"]);
            }

            if (nm > 1f || nM > 1f)
            {
                nm = nm / 256f;
                nM = nM / 256f;
            }

            terrain.normalize(nm, nM).toLayer().saveAsPNG(ofile);
        }
Beispiel #2
0
        private void Gen(int size, int base_freq, float pers, long seed, int x_o, int y_o)
        {
            if (!Utils.isPowerOf2(size))
            {
                throw new Exception("size must be power of 2");
            }

            int iterations = Utils.powerOf2Log2(size);

            base_freq = Math.Max(base_freq, 0);
            base_freq = Math.Min(base_freq, iterations);
            random    = new Random((int)seed);
            channel   = new Channel(size, size);

            int x_block, y_block, x, y;

            if (base_freq > 0)
            {
                int block_size = size >> base_freq;
                for (int x_b = 0; x_b < (1 << base_freq); x_b++)
                {
                    for (int y_b = 0; y_b < (1 << base_freq); y_b++)
                    {
                        x = x_b * block_size;
                        y = y_b * block_size;
                        channel.putPixel(x, y, (float)random.NextDouble());
                    }
                }
            }

            float v1, v2, v3, v4, v5, v6, v7, v8, v9;


            for (int i = base_freq; i < iterations; i++)
            {
                int   block_size      = size >> i;
                int   block_size_half = size >> (i + 1);
                float amp             = (float)Math.Pow(pers, i - base_freq);
                float amp_half        = 0.5f * amp;
                float avr;
                // calculate center midpoints
                if (i < 2)
                {
                    for (x_block = 0, x = 0; x_block < (1 << i); x_block++)
                    {
                        for (y_block = 0, y = 0; y_block < (1 << i); y_block++)
                        {
                            v1  = channel.getPixel(x, y);
                            v2  = channel.getPixel((x + block_size) % size, y);
                            v3  = channel.getPixel(x, (y + block_size) % size);
                            v4  = channel.getPixel((x + block_size) % size, (y + block_size) % size);
                            avr = 0.25f * (v1 + v2 + v3 + v4);
                            v5  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            channel.putPixel(x + block_size_half, y + block_size_half, v5);
                            y += block_size;
                        }
                        x += block_size;
                    }
                }
                else
                {
                    // safe blocks
                    for (x_block = 1, x = block_size; x_block < (1 << i) - 1; x_block++)
                    {
                        for (y_block = 1, y = block_size; y_block < (1 << i) - 1; y_block++)
                        {
                            v1  = channel.getPixel(x, y);
                            v2  = channel.getPixel(x + block_size, y);
                            v3  = channel.getPixel(x, y + block_size);
                            v4  = channel.getPixel(x + block_size, y + block_size);
                            avr = 0.25f * (v1 + v2 + v3 + v4);
                            v5  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            channel.putPixel(x + block_size_half, y + block_size_half, v5);
                            y += block_size;
                        }
                        x += block_size;
                    }
                    // left and right edge blocks
                    for (x_block = 0; x_block < (1 << i); x_block += (1 << i) - 1)
                    {
                        x = x_block * block_size;
                        for (y_block = 0, y = 0; y_block < (1 << i); y_block++)
                        {
                            v1  = channel.getPixel(x, y);
                            v2  = channel.getPixel((x + block_size) % size, y);
                            v3  = channel.getPixel(x, (y + block_size) % size);
                            v4  = channel.getPixel((x + block_size) % size, (y + block_size) % size);
                            avr = 0.25f * (v1 + v2 + v3 + v4);
                            v5  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            channel.putPixel(x + block_size_half, y + block_size_half, v5);
                            y += block_size;
                        }
                    }
                    // top and bottom edge blocks
                    for (x_block = 1, x = block_size; x_block < (1 << i) - 1; x_block++)
                    {
                        for (y_block = 0; y_block < (1 << i); y_block += (1 << i) - 1)
                        {
                            y   = y_block * block_size;
                            v1  = channel.getPixel(x, y);
                            v2  = channel.getPixel((x + block_size) % size, y);
                            v3  = channel.getPixel(x, (y + block_size) % size);
                            v4  = channel.getPixel((x + block_size) % size, (y + block_size) % size);
                            avr = 0.25f * (v1 + v2 + v3 + v4);
                            v5  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            channel.putPixel(x + block_size_half, y + block_size_half, v5);
                        }
                        x += block_size;
                    }
                }
                // calculate left and bottom edge midpoints
                if (i < 2)
                {
                    for (x_block = 0, x = 0; x_block < (1 << i); x_block++)
                    {
                        for (y_block = 0, y = 0; y_block < (1 << i); y_block++)
                        {
                            v1  = channel.getPixel(x, y);
                            v5  = channel.getPixel(x + block_size_half, y + block_size_half);
                            v2  = channel.getPixel((x + block_size) % size, y);
                            v3  = channel.getPixel(x, (y + block_size) % size);
                            v6  = channel.getPixel(((x - block_size_half) + size) % size, (y + block_size_half) % size);
                            v7  = channel.getPixel((x + block_size_half) % size, ((y - block_size_half) + size) % size);
                            avr = 0.25f * (v1 + v3 + v5 + v6);
                            v8  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            avr = 0.25f * (v1 + v2 + v5 + v7);
                            v9  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            channel.putPixel(x, y + block_size_half, v8);
                            channel.putPixel(x + block_size_half, y, v9);
                            y += block_size;
                        }
                        x += block_size;
                    }
                }
                else
                {
                    // safe blocks
                    for (x_block = 1, x = block_size; x_block < (1 << i) - 1; x_block++)
                    {
                        for (y_block = 1, y = block_size; y_block < (1 << i) - 1; y_block++)
                        {
                            v1  = channel.getPixel(x, y);
                            v5  = channel.getPixel(x + block_size_half, y + block_size_half);
                            v2  = channel.getPixel(x + block_size, y);
                            v3  = channel.getPixel(x, y + block_size);
                            v6  = channel.getPixel(x - block_size_half, y + block_size_half);
                            v7  = channel.getPixel(x + block_size_half, y - block_size_half);
                            avr = 0.25f * (v1 + v3 + v5 + v6);
                            v8  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            avr = 0.25f * (v1 + v2 + v5 + v7);
                            v9  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            channel.putPixel(x, y + block_size_half, v8);
                            channel.putPixel(x + block_size_half, y, v9);
                            y += block_size;
                        }
                        x += block_size;
                    }
                    // left and right edge blocks
                    for (x_block = 0; x_block < (1 << i); x_block += (1 << i) - 1)
                    {
                        x = x_block * block_size;
                        for (y_block = 0, y = 0; y_block < (1 << i); y_block++)
                        {
                            v1  = channel.getPixel(x, y);
                            v5  = channel.getPixel(x + block_size_half, y + block_size_half);
                            v2  = channel.getPixel((x + block_size) % size, y);
                            v3  = channel.getPixel(x, (y + block_size) % size);
                            v6  = channel.getPixel(((x - block_size_half) + size) % size, (y + block_size_half) % size);
                            v7  = channel.getPixel((x + block_size_half) % size, ((y - block_size_half) + size) % size);
                            avr = 0.25f * (v1 + v3 + v5 + v6);
                            v8  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            avr = 0.25f * (v1 + v2 + v5 + v7);
                            v9  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            channel.putPixel(x, y + block_size_half, v8);
                            channel.putPixel(x + block_size_half, y, v9);
                            y += block_size;
                        }
                    }
                    // top and bottom edge blocks
                    for (x_block = 1, x = block_size; x_block < (1 << i) - 1; x_block++)
                    {
                        for (y_block = 0; y_block < (1 << i); y_block += (1 << i) - 1)
                        {
                            y   = y_block * block_size;
                            v1  = channel.getPixel(x, y);
                            v5  = channel.getPixel(x + block_size_half, y + block_size_half);
                            v2  = channel.getPixel((x + block_size) % size, y);
                            v3  = channel.getPixel(x, (y + block_size) % size);
                            v6  = channel.getPixel(((x - block_size_half) + size) % size, (y + block_size_half) % size);
                            v7  = channel.getPixel((x + block_size_half) % size, ((y - block_size_half) + size) % size);
                            avr = 0.25f * (v1 + v3 + v5 + v6);
                            v8  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            avr = 0.25f * (v1 + v2 + v5 + v7);
                            v9  = avr * (1f + (float)random.NextDouble() * amp - amp_half);
                            channel.putPixel(x, y + block_size_half, v8);
                            channel.putPixel(x + block_size_half, y, v9);
                        }
                        x += block_size;
                    }
                }
            }
            float[] mm = channel.findMinMax();
            Console.WriteLine("Range Mountain->[{0},{1}]", mm[0], mm[1]);
            channel.normalize();
            mm = channel.findMinMax();
            Console.WriteLine("Range Mountain->[{0},{1}]", mm[0], mm[1]);
        }