TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
20 / 22
90.9%
Branches:
17 / 34
50.0%
Functions:
2 / 3, 1 excl
66.7%

layers/pavement.h
Line Branch Exec Source
1 /// @file
2 /// @brief `PavementLayer`, fractured bedrock: polygonal plates parted by cracks or raised ridges.
3 #pragma once
4
5 #include "terraingen/layers/exposure.h"
6 #include "terraingen/layers/fade.h"
7 #include "terraingen/layers/layer.h"
8 #include "terraingen/layers/material.h"
9 #include "terraingen/util/geometry.h"
10
11 #include <cstdint>
12 #include <optional>
13 #include <vector>
14
15 namespace terraingen {
16
17 /// The plates and cracks of a `PavementLayer`. Lengths are in metres, angles in radians.
18 struct PavementOptions {
19 4 double plateSize = 1.0; ///< Mean plate width: the spacing of the plates' Voronoi sites.
20 4 double jitter = 1.0; ///< How far sites stray from a square lattice, in [0, 1].
21 4 double warp = 0.15; ///< Bend of the plate edges, in plate sizes.
22 4 double crackWidth = 0.05; ///< Width of the crack between two plates.
23 4 double crackDepth = 0.05; ///< Depth of a crack, or height of a ridge with `raised`.
24 4 bool raised = false; ///< Whether plates are parted by raised ridges, not cracks.
25 4 double edgeRounding = 0.02; ///< Width of the rounded shoulder beside each crack.
26 4 double maxTilt = 0.05; ///< Largest tilt of a plate.
27 4 double maxStep = 0.03; ///< Largest height offset of a plate, up or down.
28 /// Crack octaves: each finer octave splits the plates again into plates `lacunarity` times
29 /// smaller, with cracks, rounding, tilts and steps `gain` times the octave before.
30 4 int octaves = 1;
31 4 double lacunarity = 2.0; ///< Plate size ratio between octaves, above 1.
32 4 double gain = 0.5; ///< Crack and plate relief ratio between octaves, in (0, 1].
33 4 std::uint32_t seed = 1; ///< Varies the plates.
34 /// When set, plates show where the ground beneath is bedrock (`ExposureField`), fading out
35 /// over soil.
36 4 std::optional<ExposureParams> exposure;
37 4 double exposureSpacing = 1.0; ///< Spacing the ground is read at for the exposure field.
38 /// On a body, the surface point whose tangent frame the plates are laid out in.
39 4 Vec2d anchor{};
40 4 ResolutionFade fade{}; ///< How plates and cracks too fine for the spacing fade out.
41
42
17/34
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 4 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 4 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 4 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 4 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 4 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 4 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 4 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 4 times.
4 bool operator==(const PavementOptions&) const = default;
43 };
44
45 /// Checks pavement options.
46 /// @throws std::invalid_argument for a plate size, crack width or exposure spacing that is not
47 /// positive and finite, a negative crack depth, edge rounding, tilt or step, a tilt of 90 deg or
48 /// more, a jitter outside [0, 1], a negative warp, octaves outside 1 to 8, a lacunarity not above
49 /// 1, a gain outside (0, 1], or invalid exposure or fade.
50 void ValidatePavementOptions(const PavementOptions& options);
51
52 /// The desiccation ridges of the Old Soaker slab in Gale crater (Stein et al. 2018): 2 cm
53 /// polygons parted by 5 mm high ridges about 2 mm wide (from ridges covering about 20 % of the
54 /// slab), flat and untilted. The polygons there are mostly four-sided with T-junctions; Voronoi
55 /// plates meet at Y-junctions.
56 PavementOptions MarsDesiccationRidges();
57
58 /// Fractured bedrock pavement added to the terrain: Voronoi plates, each flat with its own tilt
59 /// and height step, parted by cracks (or ridges) with rounded shoulders, and split again by finer
60 /// octaves of cracks that end at the cracks before them; each octave fades out where too fine for
61 /// the spacing. Plate heights blend
62 /// across each crack, so the surface has no steps. A function of position only, so grids, tiles
63 /// and points agree; it lays bedrock over the material map.
64 class PavementLayer final : public FormulaLayer, public MaterialSource {
65 public:
66 /// On a body, plates are laid out in the tangent frame of `options.anchor`. Applying the layer
67 /// with the exposure field enabled needs `context.ground`.
68 /// @throws std::invalid_argument as `ValidatePavementOptions`.
69 explicit PavementLayer(PavementOptions options, Surface surface = {});
70
71 /// The pavement's relief at world (x, y), every octave summed, without exposure or fading (m).
72 double ReliefAt(double x, double y) const;
73
74 /// The distance from world (x, y) to the nearest edge of the coarsest plates (m).
75 double EdgeDistanceAt(double x, double y) const;
76
77 /// The options the layer was made with.
78 ✗ const PavementOptions& Options() const {
79 ✗ return options_;
80 }
81
82 3 MaterialClass Material() const override {
83 3 return MaterialClass::Bedrock;
84 }
85 /// How fully the pavement covers (x, y): 1, or the exposure of the ground beneath.
86 /// @throws std::invalid_argument if the exposure field is enabled and `ground` is null.
87 double MaterialCoverAt(double x, double y, double spacing, const Ground* ground) const override;
88
89 protected:
90 float HeightAt(float height, double x, double y, double spacing,
91 const Ground* ground) const override;
92 void CheckContext(const LayerContext& context) const override;
93
94 private:
95 /// One crack octave: its plate size, crack and plate relief, and seed.
96 struct Level {
97 double size = 1.0;
98 double crackWidth = 0.0;
99 double crackDepth = 0.0;
100 double rounding = 0.0;
101 double maxTilt = 0.0;
102 double maxStep = 0.0;
103 std::uint32_t seed = 0;
104 };
105 /// The plate of one octave containing planar point `q`: its relief, distance to its nearest
106 /// edge, how far it lies inside the plate rather than in its crack (0 on an edge, 1 past the
107 /// shoulder), and an id that seeds the finer octave's plates within it.
108 struct Plate {
109 double relief = 0.0;
110 double edge = 0.0;
111 double interior = 1.0;
112 std::uint32_t id = 0;
113 };
114 bool Planar(double x, double y, Vec2d& planar) const;
115 Plate PlateAt(const Vec2d& q, const Level& level, std::uint32_t seed, double crackWeight) const;
116 /// The relief of every octave at planar point `q`, each faded at `spacing`; 0 for none.
117 double Relief(const Vec2d& q, double spacing) const;
118 double Gate(double x, double y, const Ground* ground) const;
119
120 PavementOptions options_;
121 std::optional<ExposureField> exposure_;
122 Vec3d anchorDirection_{};
123 std::vector<Level> levels_;
124 };
125
126 } // namespace terraingen
127