TerrainGen coverage


terraingen/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
33 / 33
100.0%
Branches:
28 / 31
90.3%
Functions:
3 / 3
100.0%

pipeline/height_mesh.cpp
Line Branch Exec Source
1 #include "terraingen/pipeline/height_mesh.h"
2
3 #include <cstdint>
4 #include <limits>
5 #include <stdexcept>
6 #include <vector>
7
8 namespace terraingen {
9
10 namespace {
11
12 constexpr std::uint32_t kNoVertex = std::numeric_limits<std::uint32_t>::max();
13
14 /// Where a cell centre at `height` lies in the frame of `HeightMesh`.
15 class SiteFrame {
16 public:
17 7 SiteFrame(const Surface& surface, const Vec2d& site)
18 7 : surface_(surface), frame_(surface.Frame(site)), origin_(surface.Position(site)) {}
19
20 97048 Vec3d Place(const Vec2d& point, double height) const {
21
2/2
✓ Branch 1 taken 97039 times.
✓ Branch 2 taken 9 times.
97048 if (!surface_.IsBody()) {
22 97039 return {point.x, point.y, height};
23 }
24
1/1
✓ Branch 1 taken 9 times.
9 const LocalFrame at = surface_.Frame(point);
25
1/1
✓ Branch 2 taken 9 times.
9 const Vec3d p = surface_.Position(point) + at.up * height;
26 9 const Vec3d d = p - origin_;
27 9 return {Dot(frame_.east, d), Dot(frame_.north, d), Dot(frame_.up, d)};
28 }
29
30 private:
31 const Surface& surface_;
32 LocalFrame frame_;
33 Vec3d origin_;
34 };
35
36 } // namespace
37
38 7 TriangleMesh HeightMesh(const Raster<float>& heights, const Surface& surface, const Vec2d& site) {
39
1/1
✓ Branch 1 taken 7 times.
7 const SiteFrame frame(surface, site);
40 7 const std::size_t width = heights.Width();
41 7 TriangleMesh mesh;
42
1/1
✓ Branch 2 taken 7 times.
7 std::vector<std::uint32_t> vertex(heights.Size(), kNoVertex);
43
2/2
✓ Branch 1 taken 574 times.
✓ Branch 2 taken 7 times.
581 for (std::size_t row = 0; row < heights.Height(); ++row) {
44
2/2
✓ Branch 0 taken 97049 times.
✓ Branch 1 taken 574 times.
97623 for (std::size_t col = 0; col < width; ++col) {
45 97049 const float h = heights(col, row);
46
2/2
✓ Branch 1 taken 97048 times.
✓ Branch 2 taken 1 time.
97049 if (!heights.IsNoData(h)) {
47 97048 vertex[row * width + col] = static_cast<std::uint32_t>(mesh.positions.size());
48
2/2
✓ Branch 2 taken 97048 times.
✓ Branch 5 taken 97048 times.
97048 mesh.positions.push_back(frame.Place(heights.CellCenter(col, row), h));
49 }
50 }
51 }
52
2/2
✓ Branch 1 taken 567 times.
✓ Branch 2 taken 7 times.
574 for (std::size_t row = 0; row + 1 < heights.Height(); ++row) {
53
2/2
✓ Branch 0 taken 95887 times.
✓ Branch 1 taken 567 times.
96454 for (std::size_t col = 0; col + 1 < width; ++col) {
54 95887 const std::uint32_t nw = vertex[row * width + col];
55 95887 const std::uint32_t ne = vertex[row * width + col + 1];
56 95887 const std::uint32_t sw = vertex[(row + 1) * width + col];
57 95887 const std::uint32_t se = vertex[(row + 1) * width + col + 1];
58
5/8
✓ Branch 0 taken 95887 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 95887 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 95887 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 95886 times.
✓ Branch 7 taken 1 time.
95887 if (nw != kNoVertex && ne != kNoVertex && sw != kNoVertex && se != kNoVertex) {
59
1/1
✓ Branch 1 taken 95886 times.
95886 mesh.triangles.push_back({nw, sw, se});
60
1/1
✓ Branch 1 taken 95886 times.
95886 mesh.triangles.push_back({nw, se, ne});
61 }
62 }
63 }
64
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 6 times.
7 if (mesh.triangles.empty()) {
65
1/1
✓ Branch 2 taken 1 time.
1 throw std::invalid_argument("A height mesh needs a square of four cells with data");
66 }
67 12 return mesh;
68 8 }
69
70 } // namespace terraingen
71