载入中...
搜索中...
未找到
HexFogMesh.cpp
浏览该文件的文档.
1
6#include "hexmap/HexMapMesh.h"
7
9#include "hexmap/HexMap.h"
10#include "hexmap/HexMeshData.h"
11#include "hexmap/HexMetrics.h"
12#include "hexmap/HexNoise.h"
14
15#include <cstdint>
16
17namespace eve::hexmap {
18namespace {
19
21constexpr float kFogShadeSeen = 0.f;
23constexpr float kFogShadeUnknown = 1.f;
25constexpr float kFogCapLift = 0.25f;
27constexpr float kFogSkirtDepth = 6.f;
28
35[[nodiscard]] float cellTopY(const HexMap& map, HexCoordinates coordinates) noexcept {
36 const float land = map.cellPosition(coordinates).y;
37 const float surface = HexMetrics::waterSurfaceY(map.waterLevel(coordinates));
38 return land > surface ? land : surface;
39}
40
47[[nodiscard]] float neighbourhoodTopY(const HexMap& map, HexCoordinates coordinates) noexcept {
48 float top = cellTopY(map, coordinates);
49 for (std::int32_t i = 0; i < kHexDirectionCount; ++i) {
50 HexCoordinates neighbour{};
51 if (!map.getNeighbor(coordinates, static_cast<HexDirection>(i), neighbour)) continue;
52 const float candidate = cellTopY(map, neighbour);
53 if (candidate > top) top = candidate;
54 }
55 return top;
56}
57
59void emitTriangle(HexMeshData& out, const HexVec3& p0, const HexVec3& p1, const HexVec3& p2, float shade) {
60 const auto i0 = static_cast<std::uint32_t>(out.vertexCount());
61 out.addVertex(p0, shade, 0.f);
62 out.addVertex(p1, shade, 0.f);
63 out.addVertex(p2, shade, 0.f);
64 out.addTriangle(i0, i0 + 1u, i0 + 2u);
65}
66
80void appendFogColumn(const HexMap& map, HexCoordinates coordinates, float shade, HexMeshData& out) {
81 const HexNoise& noise = map.noise();
82 const HexVec3 ground = map.cellGroundPosition(coordinates);
83 const float top = neighbourhoodTopY(map, coordinates) + kFogCapLift;
84 const float bottom = HexMetrics::elevationY(HexMetrics::kMinElevation) - kFogSkirtDepth;
85
86 HexVec3 ring[kHexDirectionCount];
87 for (std::int32_t i = 0; i < kHexDirectionCount; ++i) {
88 HexVec3 corner = noise.perturb(ground + HexMetrics::corner(static_cast<HexDirection>(i)));
89 corner.y = top;
90 ring[i] = corner;
91 }
92 HexVec3 center = noise.perturb(HexVec3{ground.x, 0.f, ground.z});
93 center.y = top;
94
95 for (std::int32_t i = 0; i < kHexDirectionCount; ++i) {
96 const std::int32_t next = (i + 1) % kHexDirectionCount;
97 emitTriangle(out, center, ring[i], ring[next], shade);
98
99 HexVec3 topNear = ring[i];
100 HexVec3 topFar = ring[next];
101 HexVec3 botFar = ring[next];
102 HexVec3 botNear = ring[i];
103 botNear.y = bottom;
104 botFar.y = bottom;
105 const auto i0 = static_cast<std::uint32_t>(out.vertexCount());
106 out.addVertex(topNear, shade, 0.f);
107 out.addVertex(topFar, shade, 0.f);
108 out.addVertex(botFar, shade, 0.f);
109 out.addVertex(botNear, shade, 0.f);
110 out.addQuad(i0, i0 + 1u, i0 + 2u, i0 + 3u);
111 }
112}
113
114} // namespace
115
116void buildFogMesh(const HexMap& map, const HexVisibility& visibility, std::int32_t chunkIndex, HexMeshData& out) {
117 out.clear();
118 if (map.empty() || visibility.cellCount() != map.cellCount() || chunkIndex < 0 ||
119 chunkIndex >= map.chunkCount()) {
120 out.finalize();
121 return;
122 }
123
124 for (std::int32_t row = 0; row < HexMetrics::kChunkSizeZ; ++row) {
125 for (std::int32_t column = 0; column < HexMetrics::kChunkSizeX; ++column) {
126 const HexCoordinates coordinates = map.chunkCell(chunkIndex, column, row);
127 if (!map.contains(coordinates)) continue;
128 const std::int32_t index = map.indexOf(coordinates);
129 if (index < 0) continue;
130
131 float shade = 0.f;
132 if (!map.isExplored(coordinates)) {
133 shade = kFogShadeUnknown;
134 } else if (!visibility.isVisible(index)) {
135 shade = kFogShadeSeen;
136 } else {
137 // Fully visible: no overlay at all.
138 continue;
139 }
140 appendFogColumn(map, coordinates, shade, out);
141 }
142 }
143 out.finalize();
144}
145
146} // namespace eve::hexmap
SQInteger top
int column
uint32_t i0
Definition Grass.cpp:61
Axial hex coordinates and world-space conversion.
Per-chunk mesh generation for every hex map surface.
Editable hex cell grid: topology, queries, picking and authoring.
CPU vertex/index container shared by the hex surface builders.
Pointy-top hex metrics, directions and vertex helpers.
Deterministic asset-free noise for hex perturbation and generation.
Reference-counted cell visibility and explored state.
uint32_t index
float bottom
An editable, chunked, pointy-top hex map.
Definition HexMap.h:72
std::int32_t chunkCount() const noexcept
Total number of chunks.
Definition HexMap.h:102
bool empty() const noexcept
Whether the map holds any cell.
Definition HexMap.h:92
std::int32_t indexOf(HexCoordinates coordinates) const noexcept
Linear cell index of coordinates (offset order), or -1 when outside the grid.
Definition HexMap.cpp:64
bool contains(HexCoordinates coordinates) const noexcept
Whether coordinates address a cell inside the grid.
Definition HexMap.h:122
std::int32_t cellCount() const noexcept
Total number of cells.
Definition HexMap.h:104
bool isExplored(HexCoordinates c) const noexcept
Whether a cell has ever been seen by a viewer (the fog-of-war latch).
Definition HexMap.cpp:348
HexCoordinates chunkCell(std::int32_t chunkIndex, std::int32_t column, std::int32_t row) const noexcept
Coordinates of the cell at (column, row) inside a chunk.
Definition HexMap.cpp:115
CPU-side triangle soup for one hex chunk surface.
Definition HexMeshData.h:24
void finalize() noexcept
Computes flat per-face normals. Must be called before upload.
void clear() noexcept
Removes every vertex and index, keeping the allocated capacity.
static float waterSurfaceY(int waterLevel) noexcept
Y coordinate of a water surface at waterLevel.
Definition HexMetrics.h:273
static float elevationY(int elevation) noexcept
Y coordinate of a cell's elevation surface.
Definition HexMetrics.h:265
static HexVec3 corner(HexDirection direction, float scale=1.f) noexcept
Outer corner direction of a unit hex, scaled by scale.
Definition HexMetrics.h:183
static constexpr int kChunkSizeZ
Chunk size in the Z dimension.
Definition HexMetrics.h:158
static constexpr int kMinElevation
Minimum editable elevation.
Definition HexMetrics.h:160
static constexpr int kChunkSizeX
Chunk size in the X dimension.
Definition HexMetrics.h:156
Fog-of-war bookkeeping: how many viewers currently see each cell.
std::int32_t cellCount() const noexcept
Number of tracked cells.
bool isVisible(std::int32_t cellIndex) const noexcept
Whether any viewer currently sees the cell.
constexpr std::int32_t kHexDirectionCount
Number of hex edges / facing directions.
Definition HexMetrics.h:62
constexpr HexDirection next(HexDirection d) noexcept
The next direction clockwise (NW wraps to NE).
Definition HexMetrics.h:76
void buildFogMesh(const HexMap &map, const HexVisibility &visibility, std::int32_t chunkIndex, HexMeshData &out)
Builds the fog-of-war overlay of one chunk.
HexDirection
Hex facing directions, counter-clockwise from north-east.
Definition HexMetrics.h:59
Axial coordinates of one hex cell.