Ejemplo n.º 1
0
        public bool[,] Generate(int sizeX, int sizeY, int nThreads, int seed)
        {
            bool[,] tiles = new bool[sizeX, sizeY];

            Func <Vector3, float, float> sampler = (pos, scale) =>
                                                   NoiseAlgos3D.LinearNoise(pos * scale);

            float seedF = (float)seed;

            ThreadedRunner.Run(nThreads, sizeY,
                               (startY, endY) =>
            {
                for (int y = startY; y <= endY; ++y)
                {
                    float yF = (float)y;
                    for (int x = 0; x < sizeX; ++x)
                    {
                        float xF = (float)x;

                        float val   = Noise.Sample(new Vector3(xF, yF, seedF), sampler);
                        val         = Mathf.Pow(val, Exponent);
                        tiles[x, y] = (val > Threshold);
                    }
                }
            });

            return(tiles);
        }
Ejemplo n.º 2
0
        public BiomeTile[,] Generate(int sizeX, int sizeY, int nThreads, int seed)
        {
            BiomeTile[,] tiles = new BiomeTile[sizeX, sizeY];

            Func <Vector3, float, float> sampler = (pos, scale) =>
                                                   NoiseAlgos3D.LinearNoise(pos * scale);

            float seedF = (float)seed;

            ThreadedRunner.Run(nThreads, sizeY,
                               (startY, endY) =>
            {
                for (int y = startY; y <= endY; ++y)
                {
                    float yF = (float)y;
                    for (int x = 0; x < sizeX; ++x)
                    {
                        float xF = (float)x;

                        tiles[x, y] = new BiomeTile();
                        tiles[x, y].CaveSmoothness = Noise.Sample(new Vector3(xF, yF, seedF),
                                                                  sampler);
                    }
                }
            });

            return(tiles);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Performs the DFT -- converting a 2D position-domain signal into a 2D frequency-domain signal.
        /// </summary>
        /// <param name="samples">
        /// The samples from an input signal.
        /// </param>
        /// <param name="outResult">
        /// The output array.
        /// If it's null or the wrong size, it will be automatically created.
        /// Contains the sine/cosine wave amplitudes for each frequency in the signal.
        /// </param>
        public static void Forward(Complex[,] samples, ref Complex[,] outResult)
        {
            //Make sure the output array is the right size.
            if (outResult == null ||
                outResult.GetLength(0) != samples.GetLength(0) ||
                outResult.GetLength(1) != samples.GetLength(1))
            {
                outResult = new Complex[samples.GetLength(0), samples.GetLength(1)];
            }


            //Perform the 1D DFT along every row and column.

            //Row:
            Complex[][] dftByRow = new Complex[samples.GetLength(1)][];
            ThreadedRunner.Run(NThreads, samples.GetLength(1),
                               (startY, endY) =>
            {
                Complex[] sampleLine = new Complex[samples.GetLength(0)];
                for (int sampleY = startY; sampleY <= endY; ++sampleY)
                {
                    //Populate the sample array.
                    for (int sampleX = 0; sampleX < samples.GetLength(0); ++sampleX)
                    {
                        sampleLine[sampleX] = samples[sampleX, sampleY];
                    }
                    //Run the dft.
                    dftByRow[sampleY] = Algo1D.Forward(sampleLine);
                }
            });

            //Column:
            var _outResult = outResult; //ref variables can't be used inside a lambda.

            ThreadedRunner.Run(NThreads, samples.GetLength(0),
                               (startX, endX) =>
            {
                Complex[] sampleLine = new Complex[samples.GetLength(1)];
                for (int sampleX = startX; sampleX <= endX; ++sampleX)
                {
                    //Populate the sample array.
                    for (int sampleY = 0; sampleY < samples.GetLength(1); ++sampleY)
                    {
                        sampleLine[sampleY] = dftByRow[sampleY][sampleX];
                    }
                    //Run the dft.
                    var results = Algo1D.Forward(sampleLine);
                    for (int sampleY = 0; sampleY < samples.GetLength(1); ++sampleY)
                    {
                        _outResult[sampleX, sampleY] = results[sampleY];
                    }
                }
            });
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Performs the inverse DFT -- converting a frequency-domain signal
        ///     back into a 2D position-domain signal.
        /// </summary>
        /// <param name="dftResults">
        /// The frequency-domain signal.
        /// </param>
        /// <param name="outSamples">
        /// The position-domain signal samples.
        /// If the array is null or the wrong size, it will be automatically created.
        /// </param>
        public static void Inverse(Complex[,] dftResults, ref Complex[,] outSamples)
        {
            //Make sure the output array is the right size.
            if (outSamples == null ||
                outSamples.GetLength(0) != dftResults.GetLength(0) ||
                outSamples.GetLength(1) != dftResults.GetLength(1))
            {
                outSamples = new Complex[dftResults.GetLength(0), dftResults.GetLength(1)];
            }

            //Perform the 1D inverse DFT along each row/column.
            //Column:
            Complex[][] inverseDFTByCol = new Complex[dftResults.GetLength(0)][];
            ThreadedRunner.Run(NThreads, dftResults.GetLength(0),
                               (startX, endX) =>
            {
                Complex[] sampleLine = new Complex[dftResults.GetLength(1)];
                for (int sampleX = startX; sampleX <= endX; ++sampleX)
                {
                    //Populate the sample array.
                    for (int sampleY = 0; sampleY < dftResults.GetLength(1); ++sampleY)
                    {
                        sampleLine[sampleY] = dftResults[sampleX, sampleY];
                    }
                    //Run the dft.
                    inverseDFTByCol[sampleX] = Algo1D.Inverse(sampleLine);
                }
            });
            //Row:
            var _outSamples = outSamples; //Can't use a ref variable in a lambda.

            ThreadedRunner.Run(NThreads, dftResults.GetLength(1),
                               (startY, endY) =>
            {
                Complex[] sampleLine = new Complex[dftResults.GetLength(0)];
                for (int sampleY = startY; sampleY <= endY; ++sampleY)
                {
                    //Populate the sample array.
                    for (int sampleX = 0; sampleX < dftResults.GetLength(0); ++sampleX)
                    {
                        sampleLine[sampleX] = inverseDFTByCol[sampleX][sampleY];
                    }
                    //Run the dft.
                    var results = Algo1D.Inverse(sampleLine);
                    for (int sampleX = 0; sampleX < dftResults.GetLength(0); ++sampleX)
                    {
                        _outSamples[sampleX, sampleY] = results[sampleX];
                    }
                }
            });
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Returns the tiles as booleans indicating whether they're solid.
        /// </summary>
        public bool[,] Generate(BiomeTile[,] biomes, List <Room> rooms, int nThreads, int seed)
        {
            //Use a blend between a room's biome and the tile's own biome.
            BiomeTile[,] oldBiomes = biomes;
            biomes = new BiomeTile[oldBiomes.GetLength(0), oldBiomes.GetLength(1)];
            foreach (Vector2i tilePos in biomes.AllIndices())
            {
                Room r = rooms.FirstOrDefault(_r => _r.Spaces.Contains(tilePos));
                if (r == null)
                {
                    biomes.Set(tilePos, oldBiomes.Get(tilePos));
                }
                else
                {
                    biomes.Set(tilePos, new BiomeTile(r.Biome, oldBiomes.Get(tilePos), TileVariation));
                }
            }

            //Turn the room data into a grid of tiles.
            bool[,] tiles1 = new bool[biomes.GetLength(0), biomes.GetLength(1)];
            foreach (Vector2i tilePos in tiles1.AllIndices())
            {
                tiles1.Set(tilePos, !rooms.Any(r => r.Spaces.Contains(tilePos)));
            }
            //Create a second copy to ping-pong back and forth between iterations.
            bool[,] tiles2 = new bool[tiles1.GetLength(0), tiles1.GetLength(1)];
            foreach (Vector2i tilePos in tiles2.AllIndices())
            {
                tiles2.Set(tilePos, tiles1.Get(tilePos));
            }

            //Run the cellular automata.
            for (int i = 0; i < NIterations; ++i)
            {
                ThreadedRunner.Run(nThreads, tiles1.GetLength(1),
                                   (startI, endI) => RunIteration(startI, endI, biomes, seed, tiles1, tiles2));

                //Swap tiles1 and tiles2.
                bool[,] _tiles1 = tiles1;
                tiles1          = tiles2;
                tiles2          = _tiles1;
            }

            return(tiles1);
        }