TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
14 / 16
87.5%
Branches:
11 / 22
50.0%
Functions:
2 / 3, 1 excl
66.7%

layers/strata.h
Line Branch Exec Source
1 /// @file
2 /// @brief `StrataLayer`, layered rock: the ground beneath terraced into benches and cliffs.
3 #pragma once
4
5 #include "terraingen/layers/layer.h"
6 #include "terraingen/layers/material.h"
7 #include "terraingen/util/geometry.h"
8
9 #include <cstdint>
10
11 namespace terraingen {
12
13 /// The beds a `StrataLayer` cuts. Lengths are in metres, angles in radians.
14 struct StrataOptions {
15 4 double bedThickness = 2.0; ///< Mean thickness of a bed.
16 /// How far each bed boundary strays, in bed thicknesses, in [0, 1).
17 4 double thicknessVariation = 0.4;
18 4 double dip = 0.0; ///< Dip of the beds from horizontal, below 90 deg.
19 /// Direction the beds dip toward, radians counter-clockwise from +x (local east on a body).
20 4 double dipAzimuth = 0.0;
21 /// How sharply each bed is cut into a flat bench and a cliff, at least 1: 1 leaves the ground
22 /// as it is, larger values flatten the benches and steepen the cliffs.
23 4 double sharpness = 4.0;
24 4 double strength = 1.0; ///< Share of the terracing applied, in [0, 1].
25 /// Share of a bed's height, at its top, that counts as the cliff (bedrock) in the material map,
26 /// in (0, 1].
27 4 double cliffShare = 0.3;
28 4 std::uint32_t seed = 1; ///< Varies the bed boundaries.
29 /// On a body, the surface point whose tangent frame the dip is measured in.
30 4 Vec2d anchor{};
31 /// Share of the beds that are hard, resistant rock, in [0, 1]: a hard bed is cut at
32 /// `sharpness` into a bench and a cliff and lays bedrock there, a soft one at `softSharpness`
33 /// into a slope without bedrock. Each bed is drawn hard or soft by the seed.
34 4 double hardShare = 1.0;
35 4 double softSharpness = 1.0; ///< How sharply soft beds are cut, at least 1.
36
37
11/22
✗ 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 17 not taken.
✓ Branch 18 taken 4 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 4 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 4 times.
4 bool operator==(const StrataOptions&) const = default;
38 };
39
40 /// Checks strata options.
41 /// @throws std::invalid_argument for a bed thickness that is not positive and finite, a thickness
42 /// variation outside [0, 1), a dip outside [0, 90) deg, a sharpness or soft sharpness below 1, a
43 /// strength or hard share outside [0, 1], a cliff share outside (0, 1], or a non-finite azimuth or
44 /// anchor.
45 void ValidateStrataOptions(const StrataOptions& options);
46
47 /// Layered rock: the ground beneath terraced into beds, each a flat bench below a cliff at its
48 /// top, so hills become stepped buttes and mesas.
49 ///
50 /// A point's stratigraphic level is its height less the dipping bed plane; within its bed it is
51 /// remapped by u^sharpness (u its height through the bed), which keeps the bed's top and bottom in
52 /// place, so the surface stays continuous. A function of the height beneath and position only, so
53 /// grids, tiles and points agree; it lays bedrock over the material map on the cliffs.
54 class StrataLayer final : public FormulaLayer, public MaterialSource {
55 public:
56 /// On a body, the dip is measured in the tangent frame of `options.anchor`.
57 /// @throws std::invalid_argument as `ValidateStrataOptions`.
58 explicit StrataLayer(StrataOptions options, Surface surface = {});
59
60 /// The terraced height of ground `height` metres high at world (x, y) (m).
61 double TerracedAt(double height, double x, double y) const;
62
63 /// How far through its bed ground `height` metres high at world (x, y) lies, in [0, 1).
64 double BedPositionAt(double height, double x, double y) const;
65
66 /// The options the layer was made with.
67 ✗ const StrataOptions& Options() const {
68 ✗ return options_;
69 }
70
71 3 MaterialClass Material() const override {
72 3 return MaterialClass::Bedrock;
73 }
74 /// 1 on the cliffs of hard beds, the top `cliffShare` of each, fading to 0 on the benches; 0 on
75 /// soft beds.
76 /// @throws std::invalid_argument without `ground`.
77 double MaterialCoverAt(double x, double y, double spacing, const Ground* ground) const override;
78
79 protected:
80 float HeightAt(float height, double x, double y, double spacing,
81 const Ground* ground) const override;
82
83 private:
84 /// The bed holding stratigraphic level `level`: its bottom and top levels.
85 struct Bed {
86 double bottom = 0.0;
87 double top = 0.0;
88 bool hard = true;
89 };
90 Bed BedOf(double level) const;
91 double BoundaryOf(std::int64_t k) const;
92 /// The stratigraphic level of ground `height` metres high at (x, y): its height less the
93 /// dipping bed plane. False on the far hemisphere of a body, where the layer does nothing.
94 bool LevelOf(double height, double x, double y, double& level) const;
95
96 StrataOptions options_;
97 Vec2d dipDirection_{1.0, 0.0};
98 double dipSlope_ = 0.0;
99 Vec3d anchorDirection_{};
100 };
101
102 } // namespace terraingen
103