载入中...
搜索中...
未找到
TerrainBakedMaskCache.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <utility>
5#include <vector>
8
9namespace eve::procgen {
10namespace {
11constexpr size_t kMaxIdentityLength = 512;
12bool validIdentity(const std::string& value) { return !value.empty() && value.size() <= kMaxIdentityLength; }
13Result<int> invalid(const char* message) {
15}
16Result<int> missing(const char* message) {
18}
19} // namespace
20
22 struct Entry {
23 std::string terrainId;
24 std::string maskGuid;
26 bool dirty = false;
27 };
28 std::vector<Entry> entries;
29};
30
35
36Result<int> TerrainBakedMaskCache::store(const std::string& terrainId, const std::string& maskGuid,
37 const Heightmap& raster) {
38 using namespace raster_detail;
39 if (!impl_ || !validIdentity(terrainId) || !validIdentity(maskGuid) || !validRaster(raster))
40 return invalid("terrain.bakedMask.store: stable bounded identities and finite raster required");
41 auto candidate = impl_->entries;
42 auto it = std::find_if(candidate.begin(), candidate.end(), [&](const auto& entry) {
43 return entry.terrainId == terrainId && entry.maskGuid == maskGuid;
44 });
45 if (it == candidate.end()) candidate.push_back({terrainId, maskGuid, raster, false});
46 else {
47 it->raster = raster;
48 it->dirty = false;
49 }
50 impl_->entries.swap(candidate);
51 return Result<int>::success(static_cast<int>(impl_->entries.size()));
52}
53
54Result<int> TerrainBakedMaskCache::markDirty(const std::string& maskGuid) {
55 if (!impl_ || !validIdentity(maskGuid)) return invalid("terrain.bakedMask.markDirty: bounded mask GUID required");
56 int changed = 0;
57 for (auto& entry : impl_->entries)
58 if (entry.maskGuid == maskGuid && !entry.dirty) {
59 entry.dirty = true;
60 ++changed;
61 }
62 return Result<int>::success(changed);
63}
64
65Result<int> TerrainBakedMaskCache::erase(const std::string& terrainId, const std::string& maskGuid) {
66 if (!impl_ || !validIdentity(terrainId) || !validIdentity(maskGuid))
67 return invalid("terrain.bakedMask.erase: bounded terrain and mask identities required");
68 const auto oldSize = impl_->entries.size();
69 std::erase_if(impl_->entries, [&](const auto& entry) {
70 return entry.terrainId == terrainId && entry.maskGuid == maskGuid;
71 });
72 if (impl_->entries.size() == oldSize) return missing("terrain.bakedMask.erase: entry not found");
73 return Result<int>::success(1);
74}
75
77 if (impl_) impl_->entries.clear();
78}
80 return impl_ ? static_cast<int>(impl_->entries.size()) : 0;
81}
82
83Result<int> TerrainBakedMaskCache::copyMask(const std::string& terrainId, const std::string& maskGuid,
84 Heightmap& output) const {
85 using namespace raster_detail;
86 if (!impl_ || !validIdentity(terrainId) || !validIdentity(maskGuid) || !validRaster(output))
87 return invalid("terrain.bakedMask.copy: bounded identities and finite output required");
88 const auto it = std::find_if(impl_->entries.begin(), impl_->entries.end(), [&](const auto& entry) {
89 return entry.terrainId == terrainId && entry.maskGuid == maskGuid;
90 });
91 if (it == impl_->entries.end()) return missing("terrain.bakedMask.copy: entry not found");
92 if (it->dirty) return missing("terrain.bakedMask.copy: entry is dirty and provider rebuild is required");
93 std::vector<float> candidate(output.data().size());
94 for (int z = 0; z < output.getHeight(); ++z)
95 for (int x = 0; x < output.getWidth(); ++x)
96 candidate[size_t(z) * output.getWidth() + x] =
97 static_cast<float>(textureSample(it->raster, (x + 0.5) / output.getWidth(),
98 (z + 0.5) / output.getHeight()));
99 return publish(output, std::move(candidate));
100}
101} // namespace eve::procgen
double value
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
std::string output
std::string message
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
In-memory terrain heightmap: a dense float grid (row-major, index = y * width + x) materialized from ...
Definition Heightmap.h:21
Own Pcg-style per-terrain baked scalar masks keyed by stable terrain and mask identities....
~TerrainBakedMaskCache()
Terrain baked mask cache.
int getEntryCount() const noexcept
Return the number of retained entries, including dirty entries.
TerrainBakedMaskCache()
Terrain baked mask cache.
Result< int > markDirty(const std::string &maskGuid)
Mark every matching GUID entry stale; stale reads fail until a provider stores a replacement.
Result< int > erase(const std::string &terrainId, const std::string &maskGuid)
Remove one exact entry.
Result< int > copyMask(const std::string &terrainId, const std::string &maskGuid, Heightmap &output) const
Copy one fresh entry into any positive output resolution using Clamp/Bilinear sampling.
double textureSample(const Heightmap &map, double u, double v)
Texture sample.
Result< int > publish(Heightmap &target, std::vector< float > candidate)
Publish.
bool validRaster(const Heightmap &map)
Valid raster.
Result< int > invalid(std::string message)
Invalid.