TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
9 / 9
100.0%
Branches:
-
-%
Functions:
4 / 4
100.0%

layers/craters/crater_layer.h
Line Branch Exec Source
1 /// @file
2 /// @brief `CraterLayer`, craters generated over the grid being evaluated and applied to it.
3 #pragma once
4
5 #include "terraingen/distribution/size_frequency.h"
6 #include "terraingen/layers/craters/ages/age_model.h"
7 #include "terraingen/layers/craters/crater_placer.h"
8 #include "terraingen/layers/craters/degradation/degradation_model.h"
9 #include "terraingen/layers/craters/generation/cell_cache.h"
10 #include "terraingen/layers/craters/generation/population.h"
11 #include "terraingen/layers/craters/profiles/profile.h"
12 #include "terraingen/layers/craters/secondary_model.h"
13 #include "terraingen/layers/craters/shaping/apply.h"
14 #include "terraingen/layers/craters/shaping/attributes.h"
15 #include "terraingen/layers/density_map.h"
16 #include "terraingen/layers/layer.h"
17
18 #include <cstdint>
19 #include <limits>
20 #include <memory>
21 #include <optional>
22 #include <vector>
23
24 namespace terraingen {
25
26 /// The models a crater layer generates and shapes craters with.
27 struct CraterModels {
28 std::shared_ptr<const SizeFrequencyDistribution> density; ///< Craters per m^2 by diameter.
29 std::shared_ptr<const CraterAgeModel> ages; ///< Each crater's age.
30 std::shared_ptr<const DegradationModel> degradation; ///< Each crater's state.
31 std::shared_ptr<const CraterProfile> profile; ///< Height by distance.
32
33 /// The profile and degradation, the models that shape the craters.
34 244606 CraterShapeModels Shape() const {
35 978424 return {profile, degradation};
36 244606 }
37 };
38
39 /// How a `CraterLayer` generates and applies its craters.
40 struct CraterLayerOptions {
41 /// Generate craters from the density; otherwise only the manual craters in `generation` apply.
42 bool generate = true;
43 std::uint32_t seed = 1; ///< Varies the generated craters.
44 /// Diameter range, spacing, manual craters and cap; `marginRadii` is set from the profile's
45 /// reach.
46 CraterGenerationOptions generation{.dMin = 4.0, .dMax = 250.0};
47 CraterApplyOptions apply{}; ///< How the craters are shaped into the terrain.
48 /// Most craters to keep generated cells of (`CraterCellCache`); 0 regenerates cells every time.
49 std::size_t cacheCraters = 4000000;
50 /// What the craters lie on, copied into `generation.surface` and `apply.surface`.
51 Surface surface{};
52 /// A map that sets the density point by point (`DensityMap`); unset keeps the density the
53 /// same everywhere. Manual craters are not thinned by it; with a catalog among them, set
54 /// `generation.completeness` so generated craters do not repeat it.
55 std::optional<DensityMap> densityMap{};
56 /// The secondaries `SecondaryCraterLayer`s throw from these craters. A `total` count or areal
57 /// fraction map counts them too, so craters too small to throw secondaries the map measures
58 /// are drawn at the map less those secondaries' density there; larger craters, which throw
59 /// them, follow the map alone; with spacing they also take precedence over smaller craters, so
60 /// the throwers never depend on what they throw at. Not with `generation.maxCraters`.
61 std::vector<SecondaryCraterOptions> secondaries{};
62 };
63
64 /// Craters generated over the grid being evaluated (`GenerateCraters`) and applied to it
65 /// (`ApplyCraters`) at the evaluation's spacing.
66 ///
67 /// Generated craters are the same in a tile as in any larger grid, unless `maxCraters` caps them
68 /// over the whole grid; bands too small to resolve are not generated.
69 class CraterLayer final : public Layer, public CraterPlacer {
70 public:
71 /// @param models None may be null.
72 /// @throws std::invalid_argument for a missing model or invalid options.
73 CraterLayer(CraterModels models, CraterLayerOptions options);
74
75 /// `dMax` (the density's largest valid diameter when unbounded) or the largest manual crater,
76 /// in metres.
77 double MaxFeatureDiameter() const;
78
79 /// The craters this layer applies to a grid covering `region` (surface coordinates): generated
80 /// and manual ones centred in it or within the profile's reach of it.
81 /// @param spacing Sample spacing in metres; bands too small to resolve at it are skipped
82 /// (`CraterGenerationOptions::minResolvedDiameter`), 0 keeps every band.
83 /// @param minDiameter,maxDiameter Diameters (m) of the craters wanted: generated bands wholly
84 /// outside them may be skipped (`maxBandDiameter`), so craters outside them can still come
85 /// back.
86 CraterList Craters(const Bounds2d& region, double spacing = 0.0, double minDiameter = 0.0,
87 double maxDiameter = std::numeric_limits<double>::infinity()) const;
88
89 /// A crater's depth, rim height and freshness in the state the degradation model gives it.
90 /// @throws std::domain_error as `DegradationModel::State`.
91 CraterAttributes Attributes(const Crater& crater) const;
92
93 CraterFeatures CratersOver(const RasterGrid& grid, double spacing) const override;
94
95 /// The cell cache, or null when `cacheCraters` is 0.
96 3 const CraterCellCache* Cache() const {
97 3 return cache_.get();
98 }
99
100 /// The models the layer was made with.
101 193147 const CraterModels& Models() const {
102 193147 return models_;
103 }
104
105 /// The options, with surfaces and `marginRadii` filled in.
106 967959 const CraterLayerOptions& Options() const {
107 967959 return options_;
108 }
109
110 protected:
111 /// Generates and applies the craters reaching the samples. Datums are fitted to
112 /// `context.ground` where given, otherwise to a grid's heights as passed in.
113 /// @throws std::invalid_argument for points when the layer has a datum and no
114 /// `context.ground`, or has `maxCraters` (which ranks craters over a whole grid).
115 /// @throws std::domain_error as `DegradationModel::State`.
116 void ApplySamples(SampleBlock& samples, const LayerContext& context) const override;
117
118 private:
119 /// The keep share for craters over `region`: the map's, less the secondaries thrown there
120 /// by the craters around it that are large enough, when they are taken out of the map.
121 CraterKeepShare KeepShare(const Bounds2d& region) const;
122
123 CraterModels models_;
124 CraterLayerOptions options_;
125 std::shared_ptr<const SurfaceCells> cells_;
126 std::shared_ptr<CraterCellCache> cache_;
127 /// The density craters are drawn at: `models_.density`, times the map's largest scale.
128 std::shared_ptr<const SizeFrequencyDistribution> candidates_;
129 std::shared_ptr<const DensityScale> scale_;
130 /// Craters at least this large (m) throw secondaries the map measures and follow it alone.
131 double throwFrom_ = std::numeric_limits<double>::infinity();
132 };
133
134 } // namespace terraingen
135