QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
PatchMesh.h
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * (c) 2009-2024 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 *
5 * QGroundControl is licensed according to the terms in the file
6 * COPYING.md in the root of the source code directory.
7 *
8 ****************************************************************************/
9
10#pragma once
11
12#include <algorithm>
13#include <array>
14
15#include <QtCore/QList>
16
20namespace PatchMesh {
21
24using LodDeltas = std::array<int, 4>;
25
30inline float vertexHeight(const QList<float>& heights, int gridSize, const LodDeltas& lodDeltas, int row, int col)
31{
32 const int verticesPerEdge = gridSize + 1;
33 if (heights.count() != (qsizetype(verticesPerEdge) * verticesPerEdge)) {
34 return 0.0f;
35 }
36 const int r = std::clamp(row, 0, gridSize);
37 const int c = std::clamp(col, 0, gridSize);
38 const auto raw = [&](int rr, int cc) { return heights.at((qsizetype(rr) * verticesPerEdge) + cc); };
39
40 int edge = -1;
41 if ((r == 0) && (lodDeltas[0] > 0)) {
42 edge = 0;
43 } else if ((r == gridSize) && (lodDeltas[1] > 0)) {
44 edge = 1;
45 } else if ((c == 0) && (lodDeltas[2] > 0)) {
46 edge = 2;
47 } else if ((c == gridSize) && (lodDeltas[3] > 0)) {
48 edge = 3;
49 }
50 if (edge < 0) {
51 return raw(r, c);
52 }
53 const bool alongCol = (edge <= 1); // north/south edges run along columns
54 const int step = 1 << lodDeltas[edge];
55 const int idx = alongCol ? c : r;
56 const int base = (idx / step) * step;
57 if (idx == base) {
58 return raw(r, c);
59 }
60 const float t = float(idx - base) / step;
61 const float a = alongCol ? raw(r, base) : raw(base, c);
62 const float b = alongCol ? raw(r, base + step) : raw(base + step, c);
63 return a + ((b - a) * t);
64}
65
69inline double surfaceHeight(const QList<float>& heights, int gridSize, const LodDeltas& lodDeltas, double row,
70 double col)
71{
72 const double r = std::clamp(row, 0.0, double(gridSize));
73 const double c = std::clamp(col, 0.0, double(gridSize));
74 const int row0 = std::min(int(r), gridSize - 1);
75 const int col0 = std::min(int(c), gridSize - 1);
76 const double fr = r - row0;
77 const double fc = c - col0;
78 const auto h = [&](int dr, int dc) {
79 return double(vertexHeight(heights, gridSize, lodDeltas, row0 + dr, col0 + dc));
80 };
81 if ((fr + fc) <= 1.0) {
82 return h(0, 0) + ((h(1, 0) - h(0, 0)) * fr) + ((h(0, 1) - h(0, 0)) * fc);
83 }
84 return h(1, 1) + ((h(0, 1) - h(1, 1)) * (1.0 - fr)) + ((h(1, 0) - h(1, 1)) * (1.0 - fc));
85}
86
87} // namespace PatchMesh
std::array< int, 4 > LodDeltas
Definition PatchMesh.h:24
double surfaceHeight(const QList< float > &heights, int gridSize, const LodDeltas &lodDeltas, double row, double col)
Definition PatchMesh.h:69
float vertexHeight(const QList< float > &heights, int gridSize, const LodDeltas &lodDeltas, int row, int col)
Definition PatchMesh.h:30