载入中...
搜索中...
未找到
TerrainCollisionMask.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <vector>
5
9
10namespace eve::procgen {
11using namespace raster_detail;
12
22
27
29 bool invert) {
32 return invalid("terrain.collisionMask: finite mask and valid source type required");
33 auto candidate = impl_->layers;
34 candidate.push_back({mask, type, active, invert});
35 impl_->layers.swap(candidate);
36 return Result<int>::success(static_cast<int>(impl_->layers.size()));
37}
38
40 if (impl_) impl_->layers.clear();
41}
42
44 return impl_ ? static_cast<int>(impl_->layers.size()) : 0;
45}
46
48 TerrainMaskBlend mode) const {
49 if (!impl_ || !validRaster(target) || !validRaster(input) || !validRaster(curve) ||
50 target.getWidth() != input.getWidth() || target.getHeight() != input.getHeight() ||
51 curve.getHeight() != 1 || mode < TerrainMaskBlend::Multiply || mode > TerrainMaskBlend::Subtract)
52 return invalid("terrain.collisionMask.apply: compatible finite target, input, curve and mode required");
53 std::vector<float> output(target.data().size());
54 for (int z = 0; z < target.getHeight(); ++z) {
55 for (int x = 0; x < target.getWidth(); ++x) {
56 const double u = (x + 0.5) / target.getWidth();
57 const double v = (z + 0.5) / target.getHeight();
58 double collisionFree = 1;
59 for (const auto& layer : impl_->layers) {
60 if (!layer.active) continue;
61 double baked = textureSample(layer.mask, u, v);
62 const bool layerType = layer.type == TerrainCollisionMaskType::LayerGameObject ||
64 if (layerType ? !layer.invert : layer.invert) baked = 1 - baked;
65 collisionFree = std::min(collisionFree, baked);
66 }
67 const double filtered = curveSample(curve, collisionFree);
68 const std::size_t index = static_cast<std::size_t>(z) * target.getWidth() + x;
69 const double old = input.data()[index];
70 double result = old;
71 switch (mode) {
72 case TerrainMaskBlend::Multiply: result = old * filtered; break;
73 case TerrainMaskBlend::Maximum: result = std::max(old, filtered); break;
74 case TerrainMaskBlend::Minimum: result = std::min(old, filtered); break;
75 case TerrainMaskBlend::Add: result = old + filtered; break;
76 case TerrainMaskBlend::Subtract: result = old - filtered; break;
77 }
78 if (!isRepresentable(result))
79 return invalid("terrain.collisionMask.apply: output exceeds finite float range");
80 output[index] = static_cast<float>(result);
81 }
82 }
83 return publish(target, std::move(output));
84}
85
86} // namespace eve::procgen
LogicalId target
bool & active
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
std::string output
int mask
EvpackChunkInput input
Definition Evpack.cpp:170
float u
Definition Grass.cpp:233
float v
TileLayer * layer
Heightmap curve
uint32_t index
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
In-memory terrain heightmap: a dense float grid (row-major, index = y * width + x) materialized from ...
Definition Heightmap.h:21
Own an ordered Pcg-style collision-mask stack made from caller-baked scalar rasters....
int getLayerCount() const noexcept
Return retained layer count, including inactive layers.
Result< int > apply(Heightmap &target, const Heightmap &input, const Heightmap &curve, TerrainMaskBlend mode) const
Combine active layers, apply a strength curve, then blend with input atomically. Target and input sha...
TerrainCollisionMaskStack()
Terrain collision mask stack.
~TerrainCollisionMaskStack()
Terrain collision mask stack.
double textureSample(const Heightmap &map, double u, double v)
Texture sample.
double curveSample(const Heightmap &curve, double value)
Curve 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.
bool isRepresentable(double value)
True when representable.
TerrainCollisionMaskType
Pcg baked collision-mask source categories and their inversion convention.
TerrainMaskBlend
Ordered scalar-mask arithmetic; intermediate values are not clamped.
Definition TerrainStamp.h:9