载入中...
搜索中...
未找到
CaveFieldSampling.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5#include <cstddef>
6
7namespace eve::procgen {
8
9float sampleCaveDensity(const std::vector<float>& density, int nx, int ny, int nz, CaveFieldPoint point) {
10 const float gx = std::clamp((point.x + 1.f) * 0.5f * float(nx - 1), 0.f, float(nx - 1));
11 const float gy = std::clamp((point.y + 1.f) * 0.5f * float(ny - 1), 0.f, float(ny - 1));
12 const float gz = std::clamp((point.z + 1.f) * 0.5f * float(nz - 1), 0.f, float(nz - 1));
13 const int x0 = int(std::floor(gx)), y0 = int(std::floor(gy)), z0 = int(std::floor(gz));
14 const int x1 = std::min(x0 + 1, nx - 1), y1 = std::min(y0 + 1, ny - 1), z1 = std::min(z0 + 1, nz - 1);
15 const float tx = gx - float(x0), ty = gy - float(y0), tz = gz - float(z0);
16 auto at = [&](int x, int y, int z) {
17 return density[size_t(x) + size_t(y) * size_t(nx) + size_t(z) * size_t(nx) * size_t(ny)];
18 };
19 auto lerp = [](float a, float b, float t) { return a + (b - a) * t; };
20 const float x00 = lerp(at(x0, y0, z0), at(x1, y0, z0), tx);
21 const float x10 = lerp(at(x0, y1, z0), at(x1, y1, z0), tx);
22 const float x01 = lerp(at(x0, y0, z1), at(x1, y0, z1), tx);
23 const float x11 = lerp(at(x0, y1, z1), at(x1, y1, z1), tx);
24 return lerp(lerp(x00, x10, ty), lerp(x01, x11, ty), tz);
25}
26
27CaveFieldPoint sampleCaveDensityGradient(const std::vector<float>& density, int nx, int ny, int nz,
29 const CaveFieldPoint step{1.f / float(nx - 1), 1.f / float(ny - 1), 1.f / float(nz - 1)};
30 return {(sampleCaveDensity(density, nx, ny, nz, {point.x + step.x, point.y, point.z}) -
31 sampleCaveDensity(density, nx, ny, nz, {point.x - step.x, point.y, point.z})) /
32 (2.f * step.x),
33 (sampleCaveDensity(density, nx, ny, nz, {point.x, point.y + step.y, point.z}) -
34 sampleCaveDensity(density, nx, ny, nz, {point.x, point.y - step.y, point.z})) /
35 (2.f * step.y),
36 (sampleCaveDensity(density, nx, ny, nz, {point.x, point.y, point.z + step.z}) -
37 sampleCaveDensity(density, nx, ny, nz, {point.x, point.y, point.z - step.z})) /
38 (2.f * step.z)};
39}
40
41CaveFieldPoint projectToCaveDensitySurface(CaveFieldPoint meshPoint, const std::vector<float>& density, int nx, int ny,
42 int nz) {
43 CaveFieldPoint point{meshPoint.x * 2.f, meshPoint.y * 2.f, meshPoint.z * 2.f};
44 const CaveFieldPoint step{1.f / float(nx - 1), 1.f / float(ny - 1), 1.f / float(nz - 1)};
45 for (int iteration = 0; iteration < 4; ++iteration) {
46 const float value = sampleCaveDensity(density, nx, ny, nz, point);
47 const CaveFieldPoint gradient = sampleCaveDensityGradient(density, nx, ny, nz, point);
48 const float length2 = gradient.x * gradient.x + gradient.y * gradient.y + gradient.z * gradient.z;
49 if (length2 < 1e-8f) break;
50 point.x = std::clamp(point.x - gradient.x * value / length2, -1.f, 1.f);
51 point.y = std::clamp(point.y - gradient.y * value / length2, -1.f, 1.f);
52 point.z = std::clamp(point.z - gradient.z * value / length2, -1.f, 1.f);
53 }
54 return {point.x * 0.5f, point.y * 0.5f, point.z * 0.5f};
55}
56
57CaveResampledField resampleCaveDensity(const std::vector<float>& density, int nx, int ny, int nz, int factor) {
58 CaveResampledField result;
59 result.nx = (nx - 1) * factor + 1;
60 result.ny = (ny - 1) * factor + 1;
61 result.nz = (nz - 1) * factor + 1;
62 result.density.resize(size_t(result.nx) * size_t(result.ny) * size_t(result.nz));
63 for (int z = 0; z < result.nz; ++z) {
64 for (int y = 0; y < result.ny; ++y) {
65 for (int x = 0; x < result.nx; ++x) {
66 const CaveFieldPoint point{float(x) / float(result.nx - 1) * 2.f - 1.f,
67 float(y) / float(result.ny - 1) * 2.f - 1.f,
68 float(z) / float(result.nz - 1) * 2.f - 1.f};
69 result.density[size_t(x) + size_t(y) * size_t(result.nx) +
70 size_t(z) * size_t(result.nx) * size_t(result.ny)] =
71 sampleCaveDensity(density, nx, ny, nz, point);
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 nx
float nz
float ny
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
float t
float step
Definition TreeMesh.cpp:314
std::size_t at
glm::vec3 point
float sampleCaveDensity(const std::vector< float > &density, int nx, int ny, int nz, CaveFieldPoint point)
Sample cave density.
CaveFieldPoint projectToCaveDensitySurface(CaveFieldPoint meshPoint, const std::vector< float > &density, int nx, int ny, int nz)
Project to cave density surface.
CaveFieldPoint sampleCaveDensityGradient(const std::vector< float > &density, int nx, int ny, int nz, CaveFieldPoint point)
Sample cave density gradient.
CaveResampledField resampleCaveDensity(const std::vector< float > &density, int nx, int ny, int nz, int factor)
Resample cave density.
CaveFieldPoint public API.
CaveResampledField public API.