12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- /*
- Copyright (C) 2015 Marien Raat
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <random>
- #include <iostream>
- #include <functional>
- // The map array is a one dimensional array used to describe a two
- // dimensional array. The array is layed out with the rows next to
- // each other, so (x, y) kan be accesed on the index x + y * width.
- // To ease the use of this array, the simple macro TO_ARRAY_INDEX
- // is provided.
- #define TO_ARRAY_INDEX(x, y, width) (x + y * width)
- enum DiamondSquareMapType {
- MAPTYPE_LAND = 0,
- MAPTYPE_ISLAND,
- MAPTYPE_ARCHIPELAGO
- };
- struct DiamondSquareMapSettings{
- int size; // Size of the square, should be a power of 2 plus 1
- double h; // The displacement will be decreased by 2 ^ (- h) each pass
- // A high h-value will result in a smooth map and a low h-value
- // will result in a rough maps
- DiamondSquareMapType mapType;
- bool overwriteOldMap; // If false, new space will be allocated in the
- // heap for the new map.
- // The user of the class is responsible for cleaning
- // up all maps and repeatedly running with this as
- // false will leak memory.
- double (*modifierFunction)(int, double);
- };
- struct PassSettings {
- double *map; // Map to run the pass on
- double displacementModifier; // Displacement from drand() is multiplied
- // by this value. Given by 2 ^ (- (h * pass))
- int passSize; // Length of the sides of the square
- int mapSize; // Size of each side of the map
- };
- class HeightmapGenerator {
- public:
- HeightmapGenerator(std::mt19937 *mt);
- ~HeightmapGenerator();
- void createNewMap(DiamondSquareMapSettings settings);
- void pass(); // Apply the next pass to the map if it is made and
- // it is not done
- void finishMap(); // Calls pass() until isMapDone
- void normalizeMap();
- bool isMapDone();
- PassSettings currentPassSettings;
- double *map;
- private:
- DiamondSquareMapSettings currentMapSettings;
- bool mapInitialized, firstMap;
- std::mt19937 *mt;
- std::normal_distribution<double> *stdDist;
- void passDiamondSquare(PassSettings *settings);
- void diamond(int x, int y, PassSettings *settings);
- void square(int x, int y, PassSettings *settings);
- bool isValid(int x, int y, int size);
- double drand(); // Returns a random double between -1.0 and 1.0
- // using the given mt and the stdDist
- void fillSidesWith(double *map, double cornerValue, int size);
- };
- // Simple functions to use as modifier functions
- double logaritmicDisplacementModifier(int pass, double h);
- double customDisplacementModifier(int pass, double h);
|