载入中...
搜索中...
未找到
PcgBiomeController.cpp
浏览该文件的文档.
2
3#include <cmath>
4
5namespace eve::procgen {
6namespace {
7bool finiteBounds(double minX, double minY, double minZ, double sizeX, double sizeY, double sizeZ) {
8 return std::isfinite(minX) && std::isfinite(minY) && std::isfinite(minZ) && std::isfinite(sizeX) &&
9 std::isfinite(sizeY) && std::isfinite(sizeZ) && sizeX >= 0.0 && sizeY >= 0.0 && sizeZ >= 0.0;
10}
11
12bool contains(const PcgBiomeLoadingBounds& bounds, double x, double y, double z) noexcept {
13 if (bounds.sizeX <= 0.0 || bounds.sizeY <= 0.0 || bounds.sizeZ <= 0.0) return false;
14 return std::abs(x - bounds.centerX) <= bounds.sizeX * 0.5 &&
15 std::abs(y - bounds.centerY) <= bounds.sizeY * 0.5 &&
16 std::abs(z - bounds.centerZ) <= bounds.sizeZ * 0.5;
17}
18
19} // namespace
20
21Result<void> PcgBiomeController::publish(double x, double y, double z, double range,
22 double impostorLoadingRange, PcgBiomeLoadMode mode) {
23 const int modeValue = static_cast<int>(mode);
24 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(z) || !std::isfinite(range) ||
25 !std::isfinite(impostorLoadingRange) || range < 0.0 || impostorLoadingRange < 0.0 ||
26 modeValue < static_cast<int>(PcgBiomeLoadMode::Disabled) ||
27 modeValue > static_cast<int>(PcgBiomeLoadMode::RuntimeAlways)) {
28 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "finite position, non-negative ranges, and a valid load mode are required", {}, {},
29 "procgen.pcgBiomeController"));
30 }
31
32 PcgBiomeLoadingBounds regular;
33 PcgBiomeLoadingBounds impostor;
34 if (mode != PcgBiomeLoadMode::Disabled) {
35 const double width = range * 2.0 - 0.5;
36 if (width < 0.0) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "enabled biome range must be at least 0.25 world units", {}, {},
37 "procgen.pcgBiomeController"));
38 regular = {x, y, z, width, width, width};
39 impostor.centerX = x;
40 impostor.centerY = y;
41 impostor.centerZ = z;
42 if (impostorLoadingRange > 0.0) {
43 const double impostorWidth = width + impostorLoadingRange;
44 impostor.sizeX = impostorWidth;
45 impostor.sizeY = impostorWidth;
46 impostor.sizeZ = impostorWidth;
47 }
48 }
49
50 x_ = x;
51 y_ = y;
52 z_ = z;
53 range_ = range;
54 impostorLoadingRange_ = impostorLoadingRange;
55 mode_ = mode;
56 regular_ = regular;
57 impostor_ = impostor;
58 return Result<void>::success();
59}
60
61Result<void> PcgBiomeController::configure(double x, double y, double z, double range,
62 double impostorLoadingRange, PcgBiomeLoadMode mode) {
63 return publish(x, y, z, range, impostorLoadingRange, mode);
64}
65
66Result<void> PcgBiomeController::fitToTerrain(double minX, double originY, double minZ,
67 double sizeX, double sizeY, double sizeZ) {
68 if (!finiteBounds(minX, originY, minZ, sizeX, sizeY, sizeZ))
69 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "finite terrain origin and non-negative terrain size are required", {}, {},
70 "procgen.pcgBiomeController"));
71 return publish(minX + sizeX * 0.5, originY, minZ + sizeZ * 0.5, sizeX * 0.5,
72 impostorLoadingRange_, mode_);
73}
74
75Result<void> PcgBiomeController::fitToAllTerrains(double minX, double minY, double minZ,
76 double sizeX, double sizeY, double sizeZ) {
77 if (!finiteBounds(minX, minY, minZ, sizeX, sizeY, sizeZ))
78 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "finite world bounds and non-negative world size are required", {}, {},
79 "procgen.pcgBiomeController"));
80 return publish(minX + sizeX * 0.5, minY + sizeY * 0.5, minZ + sizeZ * 0.5, sizeX * 0.5,
81 impostorLoadingRange_, mode_);
82}
83
84PcgTerrainStreamingTier PcgBiomeController::tierAt(double x, double y, double z) const noexcept {
85 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(z) || mode_ == PcgBiomeLoadMode::Disabled)
87 if (contains(regular_, x, y, z)) return PcgTerrainStreamingTier::Regular;
88 if (contains(impostor_, x, y, z)) return PcgTerrainStreamingTier::Impostor;
90}
91
92} // namespace eve::procgen
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
std::uint32_t width
Range range
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
double range() const noexcept
Return the current biome radius.
Result< void > configure(double x, double y, double z, double range, double impostorLoadingRange, PcgBiomeLoadMode mode)
Configure the controller and reproduce Pcg's automatic regular/impostor bound calculation.
PcgTerrainStreamingTier tierAt(double x, double y, double z) const noexcept
Return the representation requested for a world-space point.
Result< void > fitToTerrain(double minX, double originY, double minZ, double sizeX, double sizeY, double sizeZ)
Fit to one terrain: use its X/Z center, origin Y, and X half-size as the biome range.
Result< void > fitToAllTerrains(double minX, double minY, double minZ, double sizeX, double sizeY, double sizeZ)
Fit to aggregate terrain bounds: use the full bounds center and X half-size.
PcgTerrainStreamingTier
Runtime representation selected by Pcg's regular and impostor ranges.
PcgBiomeLoadMode
Pcg TerrainLoader activation modes retained by a biome controller.
glm::vec4 bounds