载入中...
搜索中...
未找到
CaveCondensation.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5#include <cstddef>
6
7namespace eve::procgen {
8namespace {
9
10float smoothstep(float low, float high, float value) {
11 const float t = std::clamp((value - low) / (high - low), 0.f, 1.f);
12 return t * t * (3.f - 2.f * t);
13}
14
15float seededPhase(uint32_t seed, uint32_t salt) {
16 uint32_t value = seed ^ salt;
17 value ^= value >> 16;
18 value *= 0x7feb352du;
19 value ^= value >> 15;
20 return float(value & 0xffffu) * (6.28318530718f / 65536.f);
21}
22
23} // namespace
24
25CaveCondensationResult erodeCaveByCondensation(std::vector<float>& density, const std::vector<float>& hydraulicExposure,
26 int nx, int ny, int nz, float strength, uint32_t seed) {
28 if (strength <= 0.f || nx < 3 || ny < 3 || nz < 3 || density.size() != hydraulicExposure.size()) return result;
29
30 const std::vector<float> source = density;
31 const float phaseA = seededPhase(seed, 0x63a9f12du);
32 const float phaseB = seededPhase(seed, 0xb71d54a3u);
33 const auto index = [nx, ny](int x, int y, int z) {
34 return size_t(x) + size_t(y) * size_t(nx) + size_t(z) * size_t(nx) * size_t(ny);
35 };
36
37 for (int z = 1; z < nz - 1; ++z) {
38 const float pz = float(z) / float(nz - 1) * 2.f - 1.f;
39 for (int y = 1; y < ny - 1; ++y) {
40 const float py = float(y) / float(ny - 1) * 2.f - 1.f;
41 for (int x = 1; x < nx - 1; ++x) {
42 const size_t voxel = index(x, y, z);
43 const float d = source[voxel];
44 if (d < -0.045f || d > 0.14f) continue;
45
46 const float gx = source[index(x + 1, y, z)] - source[index(x - 1, y, z)];
47 const float gy = source[index(x, y + 1, z)] - source[index(x, y - 1, z)];
48 const float gz = source[index(x, y, z + 1)] - source[index(x, y, z - 1)];
49 const float gradientLength = std::sqrt(gx * gx + gy * gy + gz * gz);
50 if (gradientLength < 1e-5f) continue;
51
52 // Rock-facing gradients point upward on ceilings. Condensation films are
53 // favoured there and in weakly flushed sectors, not in active stream paths.
54 const float ceiling = smoothstep(0.08f, 0.72f, gy / gradientLength);
55 const float lowFlow = 1.f - smoothstep(0.75f, 1.65f, hydraulicExposure[voxel]);
56 if (ceiling <= 0.f || lowFlow <= 0.f) continue;
57
58 const float px = float(x) / float(nx - 1) * 2.f - 1.f;
59 const float humidityPatch = 0.5f + 0.5f * std::sin(px * 4.7f + pz * 3.9f + py * 1.3f + phaseA) *
60 std::sin(pz * 5.3f - px * 2.1f + phaseB);
61 const float pitCarrier =
62 0.5f + 0.5f * std::sin(px * 31.f + pz * 23.f + phaseB) * std::sin(py * 27.f - px * 17.f + phaseA);
63 const float pits = smoothstep(0.42f, 0.9f, pitCarrier);
64 const float shell = 1.f - smoothstep(0.035f, 0.14f, std::fabs(d));
65 const float retreat = std::min(0.032f, 0.032f * std::clamp(strength, 0.f, 1.f) * shell * ceiling *
66 lowFlow * (0.2f + 0.8f * humidityPatch) * pits);
67 if (retreat <= 1e-6f) continue;
68 density[voxel] -= retreat;
69 ++result.affectedVoxels;
70 result.maximumRetreat = std::max(result.maximumRetreat, retreat);
71 result.totalRetreat += retreat;
72 }
73 }
74 }
75 return result;
76}
77
78} // namespace eve::procgen
double value
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
float py
float nx
float nz
float ny
float pz
std::vector< Colorf > px
std::uint32_t seed
Definition PointSet.cpp:807
float d
float t
uint32_t index
const UnitySourceAsset & source
CaveCondensationResult erodeCaveByCondensation(std::vector< float > &density, const std::vector< float > &hydraulicExposure, int nx, int ny, int nz, float strength, uint32_t seed)
Upscale long-term condensation corrosion into shallow ceiling-wall pitting.
CaveCondensationResult public API.