载入中...
搜索中...
未找到
CaveMixingCorrosion.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5
6namespace eve::procgen {
7namespace {
8
9CaveHydrologyVec3 subtract(CaveHydrologyVec3 a, CaveHydrologyVec3 b) { return {a.x - b.x, a.y - b.y, a.z - b.z}; }
10
11float dot(CaveHydrologyVec3 a, CaveHydrologyVec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
12
13CaveHydrologyVec3 normalize(CaveHydrologyVec3 value) {
14 const float length = std::sqrt(dot(value, value));
15 return length > 1e-6f ? CaveHydrologyVec3{value.x / length, value.y / length, value.z / length}
16 : CaveHydrologyVec3{1.f, 0.f, 0.f};
17}
18
19float smoothstep(float lo, float hi, float value) {
20 const float t = std::clamp((value - lo) / std::max(hi - lo, 1e-6f), 0.f, 1.f);
21 return t * t * (3.f - 2.f * t);
22}
23
24uint32_t hash(uint32_t value) {
25 value ^= value >> 16u;
26 value *= 0x7feb352du;
27 value ^= value >> 15u;
28 value *= 0x846ca68bu;
29 return value ^ (value >> 16u);
30}
31
32} // namespace
33
34std::vector<CaveMixingSite> createCaveMixingSites(const std::vector<CaveHydrologyPoint>& trunk,
35 const std::vector<CaveHydrologyBranch>& branches, uint32_t seed) {
36 std::vector<CaveMixingSite> sites;
37 sites.reserve(branches.size());
38 for (size_t branchIndex = 0; branchIndex < branches.size(); ++branchIndex) {
39 const CaveHydrologyBranch& branch = branches[branchIndex];
40 if (trunk.size() < 2 || branch.points.size() < 2) continue;
41 const size_t anchor = size_t(std::clamp(branch.trunkAnchor, 0, int(trunk.size() - 1)));
42 const size_t before = anchor > 0 ? anchor - 1 : anchor;
43 const size_t after = std::min(anchor + 1, trunk.size() - 1);
44 const CaveHydrologyVec3 tangent = normalize(subtract(trunk[after].position, trunk[before].position));
45 const float trunkRadius = trunk[anchor].radius;
46 const float branchRadius = branch.points[1].radius;
47 const float trunkCapacity = trunkRadius * trunkRadius;
48 const float branchCapacity = branchRadius * branchRadius;
49 const float branchFraction = branchCapacity / std::max(trunkCapacity + branchCapacity, 1e-6f);
50 const float balancedMixing = 4.f * branchFraction * (1.f - branchFraction);
51 const float chemistryContrast =
52 0.45f + 0.55f * (float(hash(seed ^ uint32_t(branchIndex) * 0x9e3779b9u) & 0xffffu) / 65535.f);
53 const float radius = 0.5f * (trunkRadius + branchRadius);
54 sites.push_back(
55 {trunk[anchor].position, tangent, radius * 2.1f, radius * 1.18f, balancedMixing * chemistryContrast});
56 }
57 return sites;
58}
59
62 for (size_t index = 0; index < sites.size(); ++index) {
63 const CaveMixingSite& site = sites[index];
64 const CaveHydrologyVec3 delta = subtract(point, site.center);
65 const float along = dot(delta, site.tangent);
66 const CaveHydrologyVec3 radial{delta.x - site.tangent.x * along, delta.y - site.tangent.y * along,
67 delta.z - site.tangent.z * along};
68 const float normalizedDistance =
69 std::sqrt((along * along) / std::max(site.alongRadius * site.alongRadius, 1e-6f) +
70 dot(radial, radial) / std::max(site.radialRadius * site.radialRadius, 1e-6f));
71 const float envelope = 1.f - smoothstep(0.18f, 1.f, normalizedDistance);
72 const float erosion = envelope * site.mixingPotential;
73 if (erosion > result.erosion) {
74 result.erosion = erosion;
75 result.mixingPotential = site.mixingPotential;
76 result.siteIndex = int(index);
77 }
78 }
79 return result;
80}
81
82} // namespace eve::procgen
double value
Vec3 tangent
Definition CaveMesh.cpp:80
float length
Definition CaveMesh.cpp:94
Vec3 anchor
Definition CaveMesh.cpp:90
std::array< std::uint8_t, 32 > hash
Definition Evpack.cpp:172
std::array< float, 3 > position
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
float radius
std::uint32_t seed
Definition PointSet.cpp:807
float t
float trunkRadius
Definition TreeMesh.cpp:306
uint32_t index
glm::vec3 point
Vec2 normalize(const Vec2 &a)
Normalize.
Definition UrbanTypes.h:44
double dot(const Vec2 &a, const Vec2 &b)
Dot.
Definition UrbanTypes.h:38
CaveMixingCorrosionSample sampleCaveMixingCorrosion(CaveHydrologyVec3 point, const std::vector< CaveMixingSite > &sites)
Sample localized shell retreat around branch-to-trunk mixing sites.
std::vector< CaveMixingSite > createCaveMixingSites(const std::vector< CaveHydrologyPoint > &trunk, const std::vector< CaveHydrologyBranch > &branches, uint32_t seed)
Derive mixing sites from authoritative branch anchors in a cave hydrology network.
CaveHydrologyBranch public API.
std::vector< CaveHydrologyPoint > points
CaveHydrologyVec3 public API.
Local corrosion strength and the contributing mixing-water potential.
One chemistry-weighted branch-to-trunk mixing site.