TerrainGen coverage


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

layers/layer.h
Line Branch Exec Source
1 /// @file
2 /// @brief `Layer`, relief added on top of a source, and `FormulaLayer` for point-wise layers.
3 #pragma once
4
5 #include "terraingen/gpu/backend.h"
6 #include "terraingen/layers/ground.h"
7 #include "terraingen/layers/sample_block.h"
8 #include "terraingen/raster/raster.h"
9 #include "terraingen/util/surface.h"
10
11 #include <string_view>
12
13 namespace terraingen {
14
15 class EvaluationCache;
16
17 /// How a layer is evaluated.
18 struct LayerContext {
19 /// Sample spacing in world units; features unresolvable at it are left out. At least the cell
20 /// size in `Layer::Apply`; positive in `Layer::ApplyAt`.
21 double spacing = 0.0;
22 unsigned threads = 1; ///< Worker threads, 0 for all; the result does not depend on it.
23 const Ground* ground = nullptr; ///< The terrain beneath the layer; null where none is needed.
24 /// Where grids are evaluated, already resolved to `Cpu` or `Vulkan`. Layers whose relief is a
25 /// kernel follow it; other layers, and every point query, run on the CPU.
26 Backend backend = Backend::Cpu;
27 /// Values the batches of one evaluation of points share, such as crater datums; null for none.
28 EvaluationCache* cache = nullptr;
29 };
30
31 /// Checks the context of a point query (`Layer::ApplyAt`).
32 /// @throws std::invalid_argument if `context.spacing` is not positive and finite.
33 void ValidatePointContext(const LayerContext& context);
34
35 /// Checks that a layer that reads the ground beneath it was given one.
36 /// @param what What reads it, which starts the error message ("<what> need the ground").
37 /// @throws std::invalid_argument if `ground` is null.
38 void RequireGround(const Ground* ground, std::string_view what);
39
40 /// Relief added on top of a source: noise, craters, or a layer of your own.
41 ///
42 /// A layer implements `ApplySamples` over a `SampleBlock` (a grid's cells or scattered points), so
43 /// a point gets the same height as a grid cell centred there. Implementations must be
44 /// deterministic and thread-safe. Layers that place features list them on request
45 /// (`CraterPlacer`, `BoulderPlacer`).
46 class Layer {
47 public:
48 11516 virtual ~Layer() = default;
49
50 /// Adds the layer's relief to the cells of `heights` that hold data.
51 void Apply(Raster<float>& heights, const LayerContext& context) const;
52
53 /// Adds the layer's relief to every sample of `samples` that holds data.
54 /// @throws std::invalid_argument for points without a positive `context.spacing`.
55 void Apply(SampleBlock& samples, const LayerContext& context) const;
56
57 /// The height at one point after this layer, from `height` before it.
58 /// @throws std::invalid_argument without a positive `context.spacing`.
59 float ApplyAt(float height, double x, double y, const LayerContext& context) const;
60
61 protected:
62 /// Adds the layer's relief to `samples`. A grid's spacing is `context.spacing` raised to the
63 /// grid's own; points come with a positive one.
64 virtual void ApplySamples(SampleBlock& samples, const LayerContext& context) const = 0;
65 };
66
67 /// A layer whose height at a point depends only on the height there and the point (noise,
68 /// roughness, transforms); the base applies `HeightAt` to every sample in parallel.
69 class FormulaLayer : public Layer {
70 protected:
71 /// @param surface What the layer's coordinates lie on, which converts a grid's cell size to
72 /// metres for the sample spacing.
73 10260 explicit FormulaLayer(Surface surface = {}) : surface_(surface) {}
74
75 /// The height at (x, y) after the layer, from `height` before it.
76 /// @param spacing Sample spacing in metres.
77 /// @param ground The terrain beneath the layer, null when the context gives none.
78 virtual float HeightAt(float height, double x, double y, double spacing,
79 const Ground* ground) const = 0;
80
81 /// Checks the context before any sample is evaluated; accepts any by default.
82 3808434 virtual void CheckContext(const LayerContext& /*context*/) const {}
83
84 void ApplySamples(SampleBlock& samples, const LayerContext& context) const final;
85
86 Surface surface_; ///< What the layer's coordinates lie on.
87 };
88
89 } // namespace terraingen
90