载入中...
搜索中...
未找到
HexMetrics.h
浏览该文件的文档.
1#pragma once
2
5#include <algorithm>
6#include <cmath>
7#include <cstdint>
8
9namespace eve::hexmap {
10
18struct HexVec3 {
19 float x = 0.f;
20 float y = 0.f;
21 float z = 0.f;
22};
23
25[[nodiscard]] constexpr HexVec3 operator+(HexVec3 a, HexVec3 b) noexcept {
26 return HexVec3{a.x + b.x, a.y + b.y, a.z + b.z};
27}
29[[nodiscard]] constexpr HexVec3 operator-(HexVec3 a, HexVec3 b) noexcept {
30 return HexVec3{a.x - b.x, a.y - b.y, a.z - b.z};
31}
33[[nodiscard]] constexpr HexVec3 operator*(HexVec3 a, float s) noexcept { return HexVec3{a.x * s, a.y * s, a.z * s}; }
35[[nodiscard]] constexpr HexVec3 operator*(float s, HexVec3 a) noexcept { return a * s; }
37[[nodiscard]] constexpr HexVec3& operator+=(HexVec3& a, HexVec3 b) noexcept {
38 a = a + b;
39 return a;
40}
41
43struct HexVec4 {
44 float x = 0.f;
45 float y = 0.f;
46 float z = 0.f;
47 float w = 0.f;
48};
49
51[[nodiscard]] constexpr HexVec3 lerp(HexVec3 a, HexVec3 b, float t) noexcept {
52 return HexVec3{a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t};
53}
54
56[[nodiscard]] constexpr HexVec3 weightsLerp(HexVec3 a, HexVec3 b, float t) noexcept { return lerp(a, b, t); }
57
59enum class HexDirection : std::int32_t { NE = 0, E = 1, SE = 2, SW = 3, W = 4, NW = 5 };
60
62inline constexpr std::int32_t kHexDirectionCount = 6;
63
65[[nodiscard]] constexpr HexDirection opposite(HexDirection d) noexcept {
66 const auto v = static_cast<std::int32_t>(d);
67 return static_cast<HexDirection>(v < 3 ? v + 3 : v - 3);
68}
69
71[[nodiscard]] constexpr HexDirection previous(HexDirection d) noexcept {
72 return d == HexDirection::NE ? HexDirection::NW : static_cast<HexDirection>(static_cast<int>(d) - 1);
73}
74
76[[nodiscard]] constexpr HexDirection next(HexDirection d) noexcept {
77 return d == HexDirection::NW ? HexDirection::NE : static_cast<HexDirection>(static_cast<int>(d) + 1);
78}
79
81[[nodiscard]] constexpr HexDirection previous2(HexDirection d) noexcept {
82 const auto v = static_cast<std::int32_t>(d) - 2;
83 return static_cast<HexDirection>(v < 0 ? v + 6 : v);
84}
85
87[[nodiscard]] constexpr HexDirection next2(HexDirection d) noexcept {
88 const auto v = static_cast<std::int32_t>(d) + 2;
89 return static_cast<HexDirection>(v > 5 ? v - 6 : v);
90}
91
93enum class HexEdgeType : std::int32_t { Flat = 0, Slope = 1, Cliff = 2 };
94
96[[nodiscard]] constexpr HexEdgeType edgeType(int elevation1, int elevation2) noexcept {
97 if (elevation1 == elevation2) return HexEdgeType::Flat;
98 const int delta = elevation2 - elevation1;
99 if (delta == 1 || delta == -1) return HexEdgeType::Slope;
100 return HexEdgeType::Cliff;
101}
102
112public:
114 static constexpr float kOuterToInner = 0.866025404f;
116 static constexpr float kInnerToOuter = 1.f / kOuterToInner;
118 static constexpr float kDefaultOuterRadius = 10.f;
120 static constexpr float kElevationStep = 3.f;
122 static constexpr int kTerracesPerSlope = 2;
124 static constexpr int kTerraceSteps = kTerracesPerSlope * 2 + 1;
126 static constexpr float kHorizontalTerraceStepSize = 1.f / static_cast<float>(kTerraceSteps);
128 static constexpr float kVerticalTerraceStepSize = 1.f / static_cast<float>(kTerracesPerSlope + 1);
130 static constexpr float kSolidFactor = 0.8f;
132 static constexpr float kBlendFactor = 1.f - kSolidFactor;
134 static constexpr float kWaterFactor = 0.6f;
136 static constexpr float kWaterBlendFactor = 1.f - kWaterFactor;
138 static constexpr float kCellPerturbStrength = 4.f;
140 static constexpr float kElevationPerturbStrength = 1.5f;
142 static constexpr float kStreamBedElevationOffset = -1.75f;
144 static constexpr float kWaterElevationOffset = -0.5f;
146 static constexpr float kRiverSurfaceScale = 0.6f;
148 static constexpr float kWallHeight = 4.f;
150 static constexpr float kWallYOffset = -1.f;
152 static constexpr float kWallThickness = 0.75f;
156 static constexpr int kChunkSizeX = 5;
158 static constexpr int kChunkSizeZ = 5;
160 static constexpr int kMinElevation = -4;
162 static constexpr int kMaxElevation = 8;
163
165 static constexpr float kOuterRadius = kDefaultOuterRadius;
169 static constexpr float kInnerDiameter = kInnerRadius * 2.f;
171 static constexpr float kRowSpacing = kDefaultOuterRadius * 1.5f;
172
174 [[nodiscard]] static constexpr float outerRadius() noexcept { return kOuterRadius; }
176 [[nodiscard]] static constexpr float innerRadius() noexcept { return kInnerRadius; }
178 [[nodiscard]] static constexpr float innerDiameter() noexcept { return kInnerDiameter; }
180 [[nodiscard]] static constexpr float rowSpacing() noexcept { return kRowSpacing; }
181
183 [[nodiscard]] static HexVec3 corner(HexDirection direction, float scale = 1.f) noexcept {
184 const float r = kOuterRadius * scale;
185 const float i = kInnerRadius * scale;
186 switch (direction) {
187 case HexDirection::NE: return HexVec3{0.f, 0.f, r};
188 case HexDirection::E: return HexVec3{i, 0.f, 0.5f * r};
189 case HexDirection::SE: return HexVec3{i, 0.f, -0.5f * r};
190 case HexDirection::SW: return HexVec3{0.f, 0.f, -r};
191 case HexDirection::W: return HexVec3{-i, 0.f, -0.5f * r};
192 case HexDirection::NW: return HexVec3{-i, 0.f, 0.5f * r};
193 }
194 return HexVec3{0.f, 0.f, r};
195 }
196
198 [[nodiscard]] static HexVec3 firstCorner(HexDirection d) noexcept { return corner(d); }
200 [[nodiscard]] static HexVec3 secondCorner(HexDirection d) noexcept { return corner(next(d)); }
202 [[nodiscard]] static HexVec3 firstSolidCorner(HexDirection d) noexcept { return corner(d, kSolidFactor); }
204 [[nodiscard]] static HexVec3 secondSolidCorner(HexDirection d) noexcept { return corner(next(d), kSolidFactor); }
206 [[nodiscard]] static HexVec3 solidEdgeMiddle(HexDirection d) noexcept {
207 return (corner(d) + corner(next(d))) * (0.5f * kSolidFactor);
208 }
210 [[nodiscard]] static HexVec3 firstWaterCorner(HexDirection d) noexcept { return corner(d, kWaterFactor); }
212 [[nodiscard]] static HexVec3 secondWaterCorner(HexDirection d) noexcept { return corner(next(d), kWaterFactor); }
214 [[nodiscard]] static HexVec3 bridge(HexDirection d) noexcept {
215 return (corner(d) + corner(next(d))) * kBlendFactor;
216 }
218 [[nodiscard]] static HexVec3 waterBridge(HexDirection d) noexcept {
219 return (corner(d) + corner(next(d))) * kWaterBlendFactor;
220 }
221
229 [[nodiscard]] static HexVec3 terraceLerp(HexVec3 a, HexVec3 b, int step) noexcept {
230 const float h = static_cast<float>(step) * kHorizontalTerraceStepSize;
231 a.x += (b.x - a.x) * h;
232 a.z += (b.z - a.z) * h;
233 const float v = static_cast<float>((step + 1) / 2) * kVerticalTerraceStepSize;
234 a.y += (b.y - a.y) * v;
235 return a;
236 }
237
239 [[nodiscard]] static HexVec3 terraceLerpWeights(HexVec3 a, HexVec3 b, int step) noexcept {
240 const float h = static_cast<float>(step) * kHorizontalTerraceStepSize;
242 return lerp(a, b, h);
243 }
244
246 [[nodiscard]] static HexVec3 wallLerp(HexVec3 near, HexVec3 far) noexcept {
247 near.x += (far.x - near.x) * 0.5f;
248 near.z += (far.z - near.z) * 0.5f;
249 const float v = near.y < far.y ? kWallElevationOffset : (1.f - kWallElevationOffset);
250 near.y += (far.y - near.y) * v + kWallYOffset;
251 return near;
252 }
253
255 [[nodiscard]] static HexVec3 wallThicknessOffset(HexVec3 near, HexVec3 far) noexcept {
256 float dx = far.x - near.x;
257 float dz = far.z - near.z;
258 const float len = std::sqrt(dx * dx + dz * dz);
259 if (len <= 1e-6f) return HexVec3{0.f, 0.f, 0.f};
260 const float s = (kWallThickness * 0.5f) / len;
261 return HexVec3{dx * s, 0.f, dz * s};
262 }
263
265 [[nodiscard]] static float elevationY(int elevation) noexcept {
266 return static_cast<float>(elevation) * kElevationStep;
267 }
269 [[nodiscard]] static float streamBedY(int elevation) noexcept {
270 return static_cast<float>(elevation) * kElevationStep + kStreamBedElevationOffset;
271 }
273 [[nodiscard]] static float waterSurfaceY(int waterLevel) noexcept {
274 return static_cast<float>(waterLevel) * kElevationStep + kWaterElevationOffset;
275 }
276
278 [[nodiscard]] static float solidRadius() noexcept { return innerRadius() * kSolidFactor; }
279};
280
288
290 EdgeVertices() = default;
291
293 EdgeVertices(HexVec3 c1, HexVec3 c2) noexcept {
294 v1 = c1;
295 v2 = lerp(c1, c2, 0.25f);
296 v3 = lerp(c1, c2, 0.5f);
297 v4 = lerp(c1, c2, 0.75f);
298 v5 = c2;
299 }
300
302 EdgeVertices(HexVec3 c1, HexVec3 c2, float outerStep) noexcept {
303 v1 = c1;
304 v2 = lerp(c1, c2, outerStep);
305 v3 = lerp(c1, c2, 0.5f);
306 v4 = lerp(c1, c2, 1.f - outerStep);
307 v5 = c2;
308 }
309
311 [[nodiscard]] static EdgeVertices terraceLerp(const EdgeVertices& a, const EdgeVertices& b, int step) noexcept {
312 EdgeVertices result;
313 result.v1 = HexMetrics::terraceLerp(a.v1, b.v1, step);
314 result.v2 = HexMetrics::terraceLerp(a.v2, b.v2, step);
315 result.v3 = HexMetrics::terraceLerp(a.v3, b.v3, step);
316 result.v4 = HexMetrics::terraceLerp(a.v4, b.v4, step);
317 result.v5 = HexMetrics::terraceLerp(a.v5, b.v5, step);
318 return result;
319 }
320};
321
322} // namespace eve::hexmap
const std::string & s
double r
std::int32_t waterLevel
float v
float elevation
int h
std::array< float, 3 > scale
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
graphics::Canvas * previous
float d
float t
RoadLaneDirection direction
float dz
float dx
float step
Definition TreeMesh.cpp:314
Hexagon metrics shared by the map model and every mesh builder.
Definition HexMetrics.h:111
static constexpr float kInnerDiameter
Width of one hex column.
Definition HexMetrics.h:169
static constexpr float outerRadius() noexcept
Radius of a hex cell in world units.
Definition HexMetrics.h:174
static HexVec3 firstSolidCorner(HexDirection d) noexcept
First solid corner of direction.
Definition HexMetrics.h:202
static constexpr float kWallThickness
Wall thickness.
Definition HexMetrics.h:152
static HexVec3 wallThicknessOffset(HexVec3 near, HexVec3 far) noexcept
Half-thickness offset applied to a wall segment.
Definition HexMetrics.h:255
static float solidRadius() noexcept
Distance from a cell centre to its nearest edge midpoint.
Definition HexMetrics.h:278
static HexVec3 secondSolidCorner(HexDirection d) noexcept
Second solid corner of direction.
Definition HexMetrics.h:204
static constexpr float kElevationPerturbStrength
Strength of the vertical elevation perturbation.
Definition HexMetrics.h:140
static HexVec3 secondWaterCorner(HexDirection d) noexcept
Second water corner of direction.
Definition HexMetrics.h:212
static constexpr float innerDiameter() noexcept
Width of one hex column.
Definition HexMetrics.h:178
static constexpr int kTerracesPerSlope
Terraces generated per slope.
Definition HexMetrics.h:122
static HexVec3 terraceLerpWeights(HexVec3 a, HexVec3 b, int step) noexcept
Interpolates terrain weights along a terraced slope.
Definition HexMetrics.h:239
static constexpr int kTerraceSteps
Terrace interpolation steps per slope (terracesPerSlope * 2 + 1).
Definition HexMetrics.h:124
static constexpr float kDefaultOuterRadius
Default outer (corner) radius of one hex cell.
Definition HexMetrics.h:118
static HexVec3 secondCorner(HexDirection d) noexcept
Second (clockwise) outer corner of direction.
Definition HexMetrics.h:200
static float waterSurfaceY(int waterLevel) noexcept
Y coordinate of a water surface at waterLevel.
Definition HexMetrics.h:273
static constexpr float kWallElevationOffset
Wall elevation offset, matching the vertical terrace step size.
Definition HexMetrics.h:154
static HexVec3 wallLerp(HexVec3 near, HexVec3 far) noexcept
Position of the midpoint of a wall between two elevations.
Definition HexMetrics.h:246
static HexVec3 bridge(HexDirection d) noexcept
Bridge vector from the solid edge of direction to the neighbour.
Definition HexMetrics.h:214
static constexpr float kRiverSurfaceScale
Width of the river channel.
Definition HexMetrics.h:146
static HexVec3 firstWaterCorner(HexDirection d) noexcept
First water corner of direction.
Definition HexMetrics.h:210
static HexVec3 solidEdgeMiddle(HexDirection d) noexcept
Midpoint of the solid edge of direction.
Definition HexMetrics.h:206
static constexpr float kInnerToOuter
Ratio of the inner radius to the outer radius.
Definition HexMetrics.h:116
static constexpr float kVerticalTerraceStepSize
Vertical fraction of one terrace interpolation step.
Definition HexMetrics.h:128
static constexpr float kElevationStep
Vertical distance between two elevation levels.
Definition HexMetrics.h:120
static constexpr float kHorizontalTerraceStepSize
Horizontal fraction of one terrace interpolation step.
Definition HexMetrics.h:126
static HexVec3 waterBridge(HexDirection d) noexcept
Bridge vector from the water edge of direction to the neighbour.
Definition HexMetrics.h:218
static constexpr float kInnerRadius
Inner (edge) radius of one hex cell in world units.
Definition HexMetrics.h:167
static constexpr float kWaterBlendFactor
Factor of the water blend region between two cells.
Definition HexMetrics.h:136
static constexpr float kOuterToInner
Ratio of the outer radius to the inner radius.
Definition HexMetrics.h:114
static constexpr float kWaterFactor
Factor of the solid water surface inscribed in a cell.
Definition HexMetrics.h:134
static constexpr float kWallHeight
Height of a city/farm wall.
Definition HexMetrics.h:148
static constexpr float kRowSpacing
Row spacing between hex rows.
Definition HexMetrics.h:171
static constexpr float kWaterElevationOffset
Elevation offset of a water surface relative to the water level.
Definition HexMetrics.h:144
static constexpr float kCellPerturbStrength
Strength of the XZ position perturbation.
Definition HexMetrics.h:138
static constexpr float kOuterRadius
Outer (corner) radius of one hex cell in world units.
Definition HexMetrics.h:165
static constexpr float kWallYOffset
Vertical wall offset; negative so walls do not float above the surface.
Definition HexMetrics.h:150
static constexpr float kStreamBedElevationOffset
Elevation offset of a carved river bed relative to the cell.
Definition HexMetrics.h:142
static float elevationY(int elevation) noexcept
Y coordinate of a cell's elevation surface.
Definition HexMetrics.h:265
static float streamBedY(int elevation) noexcept
Y coordinate of a river bed inside a cell.
Definition HexMetrics.h:269
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 float kBlendFactor
Factor of the blend region between two neighbouring cells.
Definition HexMetrics.h:132
static constexpr float rowSpacing() noexcept
Row spacing between hex rows.
Definition HexMetrics.h:180
static constexpr int kChunkSizeZ
Chunk size in the Z dimension.
Definition HexMetrics.h:158
static HexVec3 terraceLerp(HexVec3 a, HexVec3 b, int step) noexcept
Interpolates a position along a terraced slope.
Definition HexMetrics.h:229
static constexpr int kMinElevation
Minimum editable elevation.
Definition HexMetrics.h:160
static constexpr float innerRadius() noexcept
Inner radius of a hex cell.
Definition HexMetrics.h:176
static constexpr float kSolidFactor
Factor of the solid, uniform-colour hex inscribed in a cell.
Definition HexMetrics.h:130
static HexVec3 firstCorner(HexDirection d) noexcept
First (counter-clockwise) outer corner of direction.
Definition HexMetrics.h:198
static constexpr int kChunkSizeX
Chunk size in the X dimension.
Definition HexMetrics.h:156
static constexpr int kMaxElevation
Maximum editable elevation.
Definition HexMetrics.h:162
constexpr HexVec3 operator-(HexVec3 a, HexVec3 b) noexcept
Operator -.
Definition HexMetrics.h:29
constexpr HexVec3 weightsLerp(HexVec3 a, HexVec3 b, float t) noexcept
Blends the three terrain-layer weights of a hex vertex.
Definition HexMetrics.h:56
constexpr HexDirection opposite(HexDirection d) noexcept
The direction opposite to d.
Definition HexMetrics.h:65
constexpr HexDirection previous2(HexDirection d) noexcept
Two steps counter-clockwise.
Definition HexMetrics.h:81
constexpr HexVec3 operator+(HexVec3 a, HexVec3 b) noexcept
Operator +.
Definition HexMetrics.h:25
constexpr std::int32_t kHexDirectionCount
Number of hex edges / facing directions.
Definition HexMetrics.h:62
constexpr HexEdgeType edgeType(int elevation1, int elevation2) noexcept
The relationship between two elevations (single-step changes are slopes).
Definition HexMetrics.h:96
HexEdgeType
Relationship between two neighbouring cells of different elevation.
Definition HexMetrics.h:93
constexpr HexDirection next(HexDirection d) noexcept
The next direction clockwise (NW wraps to NE).
Definition HexMetrics.h:76
constexpr HexVec3 lerp(HexVec3 a, HexVec3 b, float t) noexcept
Linear interpolation between two positions.
Definition HexMetrics.h:51
constexpr HexVec3 operator*(HexVec3 a, float s) noexcept
Operator *.
Definition HexMetrics.h:33
constexpr HexDirection next2(HexDirection d) noexcept
Two steps clockwise.
Definition HexMetrics.h:87
constexpr HexVec3 & operator+=(HexVec3 &a, HexVec3 b) noexcept
Operator +=.
Definition HexMetrics.h:37
HexDirection
Hex facing directions, counter-clockwise from north-east.
Definition HexMetrics.h:59
Five sample points along one hex edge, from v1 to v5.
Definition HexMetrics.h:282
EdgeVertices(HexVec3 c1, HexVec3 c2, float outerStep) noexcept
Samples the segment using an explicit outer step for v2/v4.
Definition HexMetrics.h:302
EdgeVertices(HexVec3 c1, HexVec3 c2) noexcept
Evenly samples the segment c1 -> c2 at 0, 0.25, 0.5, 0.75 and 1.
Definition HexMetrics.h:293
EdgeVertices()=default
Constructs a EdgeVertices.
static EdgeVertices terraceLerp(const EdgeVertices &a, const EdgeVertices &b, int step) noexcept
Terrace-interpolates every sample between two edges.
Definition HexMetrics.h:311
Minimal 3-component float vector used by the hex mesh builders.
Definition HexMetrics.h:18
Four-component float vector, matching the reference four-channel noise sample.
Definition HexMetrics.h:43