sources/synthetic_terrain.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "terraingen/sources/synthetic_terrain.h" | ||
| 2 | |||
| 3 | #include "terraingen/util/checks.h" | ||
| 4 | #include "terraingen/util/log.h" | ||
| 5 | |||
| 6 | #include <cmath> | ||
| 7 | #include <stdexcept> | ||
| 8 | #include <string> | ||
| 9 | |||
| 10 | namespace terraingen { | ||
| 11 | |||
| 12 | 349 | void ValidateSyntheticTerrain(const SyntheticTerrainParams& params) { | |
| 13 | 349 | if (params.layers.empty() || params.layers.size() > kMaxNoiseLayers) { | |
| 14 | 12 | throw std::invalid_argument("A synthetic terrain needs between 1 and " + | |
| 15 | 18 | std::to_string(kMaxNoiseLayers) + " layers"); | |
| 16 | } | ||
| 17 | 746 | for (std::size_t i = 0; i < params.layers.size(); ++i) { | |
| 18 | try { | ||
| 19 | 405 | ValidateNoiseLayer(params.layers[i]); | |
| 20 | 2 | } catch (const std::invalid_argument& error) { | |
| 21 | 2 | throw std::invalid_argument("Layer " + std::to_string(i + 1) + ": " + error.what()); | |
| 22 | 2 | } | |
| 23 | } | ||
| 24 | 341 | } | |
| 25 | |||
| 26 | 34 | void FillSyntheticTerrain(Raster<float>& raster, const SyntheticTerrainParams& params) { | |
| 27 | 34 | ValidateSyntheticTerrain(params); | |
| 28 | 33 | const Stopwatch stopwatch; | |
| 29 | 601 | for (std::size_t row = 0; row < raster.Height(); ++row) { | |
| 30 | 19848 | for (std::size_t col = 0; col < raster.Width(); ++col) { | |
| 31 | 19280 | const Vec2d centre = raster.CellCenter(col, row); | |
| 32 | 19280 | raster(col, row) = | |
| 33 | 19280 | EvaluateNoiseLayers(static_cast<float>(centre.x), static_cast<float>(centre.y), | |
| 34 | params.layers.data(), params.layers.size()); | ||
| 35 | } | ||
| 36 | } | ||
| 37 | 33 | LogInfo("sources", "Filled ", raster.Width(), "x", raster.Height(), " synthetic terrain (", | |
| 38 | 33 | params.layers.size(), params.layers.size() == 1 ? " layer" : " layers", ") in ", | |
| 39 | 66 | FormatDuration(stopwatch.Milliseconds())); | |
| 40 | 33 | } | |
| 41 | |||
| 42 | 18 | Raster<float> GenerateSyntheticTerrain(std::size_t width, std::size_t height, double pixelSize, | |
| 43 | const SyntheticTerrainParams& params) { | ||
| 44 | 18 | if (width == 0 || height == 0) { | |
| 45 | 3 | throw std::invalid_argument("Raster width and height must be at least 1"); | |
| 46 | } | ||
| 47 | 15 | RequirePositive(pixelSize, "Pixel size"); | |
| 48 | 13 | ValidateSyntheticTerrain(params); | |
| 49 | |||
| 50 | 12 | Raster<float> raster(width, height); | |
| 51 | 12 | raster.SetTransform(GeoTransform::NorthUp(-0.5 * static_cast<double>(width) * pixelSize, | |
| 52 | 12 | 0.5 * static_cast<double>(height) * pixelSize, | |
| 53 | pixelSize)); | ||
| 54 | 12 | FillSyntheticTerrain(raster, params); | |
| 55 | 12 | return raster; | |
| 56 | } | ||
| 57 | |||
| 58 | } // namespace terraingen | ||
| 59 |