layers/exposure.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief `ExposureField`, how far the ground is bare bedrock rather than soil, and `PatchNoise`. | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "terraingen/layers/ground.h" | ||
| 6 | #include "terraingen/raster/raster.h" | ||
| 7 | #include "terraingen/util/surface.h" | ||
| 8 | |||
| 9 | #include <cstdint> | ||
| 10 | |||
| 11 | namespace terraingen { | ||
| 12 | |||
| 13 | /// Two-octave patch noise in [-1, 1]: clamp(2.5 (0.7 n(p / size) + 0.3 n(4 p / size)), -1, 1). | ||
| 14 | /// | ||
| 15 | /// n is 2D Perlin noise on a plane and 3D at the 3D point on a sphere; the finer octave is seeded | ||
| 16 | /// `seed` + 1. About half the ground lies near either end. | ||
| 17 | /// @param size Typical width of a patch, in metres; positive. | ||
| 18 | /// @param seed Seed of the coarser octave. | ||
| 19 | double PatchNoise(const Surface& surface, double x, double y, double size, std::uint32_t seed); | ||
| 20 | |||
| 21 | /// The thresholds an `ExposureField` tells soil from bedrock by; a rule of thumb, not a | ||
| 22 | /// measurement. | ||
| 23 | struct ExposureParams { | ||
| 24 | 5 | double reach = 12.0; ///< How far around a point its surroundings are read (m). | |
| 25 | 5 | double riseSoil = | |
| 26 | 0.010; ///< Standing this share of the reach above the surroundings or less: soil. | ||
| 27 | 5 | double riseBoulder = 0.035; ///< Standing this share of the reach above them or more: bedrock. | |
| 28 | 5 | double slopeSoil = 0.20; ///< Slope (rise over run) at or under which soil holds. | |
| 29 | 5 | double slopeBoulder = 0.40; ///< Slope at or over which none does. | |
| 30 | 5 | double floorCover = | |
| 31 | 0.0; ///< Share of level ground that is bedrock too, in patches; 0 for none. | ||
| 32 | 5 | double floorPatch = 60.0; ///< How far across those patches are (m). | |
| 33 | 5 | std::uint32_t seed = 0; ///< Varies the floor patches. | |
| 34 | |||
| 35 | 5 | bool operator==(const ExposureParams&) const = default; | |
| 36 | }; | ||
| 37 | |||
| 38 | /// Checks exposure thresholds. | ||
| 39 | /// @throws std::invalid_argument unless `reach` and `floorPatch` are positive, each boulder | ||
| 40 | /// threshold is over its soil one, and `floorCover` is in [0, 1). | ||
| 41 | void ValidateExposureParams(const ExposureParams& params); | ||
| 42 | |||
| 43 | /// How far the ground at a point is bedrock rather than soil, from its shape alone. | ||
| 44 | /// | ||
| 45 | /// Rises above the mean of eight points a reach around, and steep slopes, grade from soil to | ||
| 46 | /// bedrock by smoothsteps between their thresholds (the larger wins); `floorCover` of level ground | ||
| 47 | /// is bedrock in noise patches. Reads the ground at points, so it agrees on every grid and tile. | ||
| 48 | class ExposureField { | ||
| 49 | public: | ||
| 50 | /// Makes a field; on a sphere, surroundings are read in each point's local frame. | ||
| 51 | /// @throws std::invalid_argument as `ValidateExposureParams`. | ||
| 52 | explicit ExposureField(const ExposureParams& params = {}, const Surface& surface = {}); | ||
| 53 | |||
| 54 | /// The share of bedrock at world (x, y), in [0, 1] (0 soil, 1 bedrock; 0 without data). | ||
| 55 | /// Neighbours without data count as level with the point. | ||
| 56 | /// @param spacing Sample spacing in world units. | ||
| 57 | double Exposure(const Ground& ground, double x, double y, double spacing) const; | ||
| 58 | |||
| 59 | /// Fills `raster` with `Exposure` at each cell centre. | ||
| 60 | /// @param spacing Sample spacing in world units. | ||
| 61 | /// @param threads Worker threads; 0 for every hardware thread. | ||
| 62 | void Fill(Raster<float>& raster, const Ground& ground, double spacing, | ||
| 63 | unsigned threads = 1) const; | ||
| 64 | |||
| 65 | /// The thresholds the field was made with. | ||
| 66 | 1 | const ExposureParams& Params() const { | |
| 67 | 1 | return params_; | |
| 68 | } | ||
| 69 | |||
| 70 | /// What the ground lies on. | ||
| 71 | const Surface& GetSurface() const { | ||
| 72 | return surface_; | ||
| 73 | } | ||
| 74 | |||
| 75 | private: | ||
| 76 | ExposureParams params_; | ||
| 77 | Surface surface_; | ||
| 78 | }; | ||
| 79 | |||
| 80 | } // namespace terraingen | ||
| 81 |