TerrainGen coverage


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

layers/transforms.h
Line Branch Exec Source
1 /// @file
2 /// @brief Height transforms as layers: scale and offset, clamp, and a function of your own.
3 #pragma once
4
5 #include "terraingen/layers/layer.h"
6
7 #include <functional>
8 #include <optional>
9
10 namespace terraingen {
11
12 /// Scales and shifts the heights so far: height * `scale` + `offset`.
13 class ScaleLayer final : public FormulaLayer {
14 public:
15 /// @param scale Factor on the heights (vertical exaggeration).
16 /// @param offset Added after scaling, in metres.
17 /// @throws std::invalid_argument unless `scale` and `offset` are finite.
18 ScaleLayer(double scale, double offset = 0.0);
19
20 /// The factor on the heights.
21 1 double Scale() const {
22 1 return scale_;
23 }
24 /// The shift after scaling, in metres.
25 1 double Offset() const {
26 1 return offset_;
27 }
28
29 protected:
30 float HeightAt(float height, double x, double y, double spacing,
31 const Ground* ground) const override;
32
33 private:
34 double scale_;
35 double offset_;
36 };
37
38 /// Clamps the heights so far to [`min`, `max`], either bound optional.
39 class ClampLayer final : public FormulaLayer {
40 public:
41 /// @param min The lowest height kept, in metres; none for no floor.
42 /// @param max The highest height kept, in metres; none for no cap.
43 /// @throws std::invalid_argument for a bound that is not finite or `min` above `max`.
44 ClampLayer(std::optional<double> min, std::optional<double> max);
45
46 /// The lowest height kept, in metres; none for no floor.
47 1 std::optional<double> Min() const {
48 1 return min_;
49 }
50 /// The highest height kept, in metres; none for no cap.
51 1 std::optional<double> Max() const {
52 1 return max_;
53 }
54
55 protected:
56 float HeightAt(float height, double x, double y, double spacing,
57 const Ground* ground) const override;
58
59 private:
60 std::optional<double> min_;
61 std::optional<double> max_;
62 };
63
64 /// The new height at (`x`, `y`) sampled every `spacing` metres given the `height` so far; must be
65 /// deterministic and thread-safe.
66 using HeightFunction = std::function<double(double x, double y, double spacing, double height)>;
67
68 /// A layer from a function of position, sample spacing and the height so far.
69 class FunctionLayer final : public FormulaLayer {
70 public:
71 /// @param surface What the terrain lies on, which turns a grid's cell size into metres.
72 /// @throws std::invalid_argument for an empty `function`.
73 explicit FunctionLayer(HeightFunction function, Surface surface = {});
74
75 protected:
76 float HeightAt(float height, double x, double y, double spacing,
77 const Ground* ground) const override;
78
79 private:
80 HeightFunction function_;
81 };
82
83 } // namespace terraingen
84