载入中...
搜索中...
未找到
TerrainTreePlacement.cpp
浏览该文件的文档.
30 return static_cast<float>(x + y) / static_cast<float>(std::numeric_limits<std::uint64_t>::max());
48 return value >= TerrainTreeYOffsetMode::TerrainHeight && value <= TerrainTreeYOffsetMode::Custom;
61Result<int> exportTerrainTreePoints(PointSet& output, const Heightmap& fitness, const Heightmap& heights,
65 !std::isfinite(s.originZ) || !std::isfinite(s.width) || s.width <= 0 || !std::isfinite(s.depth) ||
69 !std::isfinite(s.customOffset) || !std::isfinite(s.minimumYOffset) || !std::isfinite(s.maximumYOffset) ||
70 s.maximumYOffset < s.minimumYOffset || !validScaleMode(s.scaleMode) || !validYOffsetMode(s.yOffsetMode) ||
74 !normalized(s.widthRandomPercentage) || !normalized(s.heightRandomPercentage) || !normalized(s.healthyR) ||
75 !normalized(s.healthyG) || !normalized(s.healthyB) || !normalized(s.healthyA) || !normalized(s.dryR) ||
76 !normalized(s.dryG) || !normalized(s.dryB) || !normalized(s.dryA) || !std::isfinite(s.bendFactor) ||
77 s.bendFactor < 0 || !std::isfinite(s.boundsRadius) || s.boundsRadius <= 0 || s.namespaceId == 0 ||
79 return invalid("terrain.treePoints: valid rasters, domain, prototype, probabilities and budget required");
90 if (!std::isfinite(xSteps) || !std::isfinite(zSteps) || xSteps > std::numeric_limits<int>::max() ||
96 next.reserve(std::min<std::size_t>(static_cast<std::size_t>(xSteps * zSteps), static_cast<std::size_t>(s.maxPoints)));
110 const std::uint64_t cell = std::uint64_t(xi) * std::uint64_t(static_cast<int>(zSteps)) + std::uint64_t(zi);
113 if (point.id == 0) return invalid("terrain.treePoints: reserved zero identity; choose another namespace");
153 if (!std::isfinite(radius)) return invalid("terrain.treePoints: generated bounds are not representable");
162 auto candidate = next.trySetIntAttribute(row, "treeCandidate", static_cast<std::int64_t>(cell));
174Result<int> removeTerrainTreePoints(PointSet& output, const PointSet& input, const Heightmap& fitness,
177 if (!validRaster(fitness) || !std::all_of(fitness.data().begin(), fitness.data().end(), [](float value) {
180 !std::isfinite(s.originX) || !std::isfinite(s.originZ) || !std::isfinite(s.width) || s.width <= 0 ||
182 return invalid("terrain.removeTreePoints: valid fitness, domain, threshold and asset required");
206Result<int> rescaleTerrainTreePoints(PointSet& output, const PointSet& input, const TerrainTreeRescaleSettings& s) {
211 if (!validScaleMode(s.scaleMode) || !orderedPositive(s.previousMinimumWidth, s.previousMaximumWidth) ||
253 TerrainTreeOperationMode mode, bool worldMapOperation, const std::vector<std::string>& validTerrainNames) {
255 const bool validMode = mode == TerrainTreeOperationMode::Add || mode == TerrainTreeOperationMode::Replace ||
257 if (tiles.empty() || !validMode || !validRaster(operationFitness) || !std::isfinite(s.heightScale) ||
258 !std::isfinite(s.spacing) || s.spacing <= 0 || !std::isfinite(s.spawnDensity) || s.spawnDensity <= 0 ||
260 !std::isfinite(s.seaLevel) || !std::isfinite(s.customOffset) || !std::isfinite(s.minimumYOffset) ||
261 !std::isfinite(s.maximumYOffset) || s.maximumYOffset < s.minimumYOffset || !validScaleMode(s.scaleMode) ||
263 !std::isfinite(s.maximumWidth) || s.maximumWidth < s.minimumWidth || !std::isfinite(s.minimumHeight) ||
265 !normalized(s.widthRandomPercentage) || !normalized(s.heightRandomPercentage) || !normalized(s.healthyR) ||
266 !normalized(s.healthyG) || !normalized(s.healthyB) || !normalized(s.healthyA) || !normalized(s.dryR) ||
267 !normalized(s.dryG) || !normalized(s.dryB) || !normalized(s.dryA) || !std::isfinite(s.bendFactor) ||
268 s.bendFactor < 0 || !std::isfinite(s.boundsRadius) || s.boundsRadius <= 0 || s.namespaceId == 0 ||
271 DiagnosticCode::InvalidArgument, "terrain.tree.multitile: valid tiles, operation and prototype required"));
275 DiagnosticCode::InvalidArgument, "terrain.tree.multitile: normalized operation fitness required"));
281 if (!tile.trees || !tile.heights || !owners.insert(tile.trees).second || !validRaster(*tile.heights))
283 DiagnosticCode::InvalidArgument, "terrain.tree.multitile: distinct outputs and finite heights required"));
287 auto mapped = mapTerrainOperationMultiTile(operationTiles, operationSettings, TerrainOperationDomain::Tree,
294 DiagnosticCode::InvalidArgument, "terrain.tree.multitile: operation fitness dimensions must match window"));
298 DiagnosticCode::InvalidArgument, "terrain.tree.multitile: effective spacing is not representable"));
310 DiagnosticCode::InvariantViolation, "terrain.tree.multitile: mapped terrain was not supplied"));
320 const int localX = nearestEven((double(point.x) - tile->originX) * tile->treeResolutionX / tile->width);
321 const int localY = nearestEven((double(point.z) - tile->originZ) * tile->treeResolutionY / tile->depth);
339 const double stopX = (mapping.localX + mapping.width) * tile->width / tile->treeResolutionX + increment;
340 const double stopZ = (mapping.localY + mapping.height) * tile->depth / tile->treeResolutionY + increment;
369 if (s.scaleMode == TerrainTreeScaleMode::Fitness || s.scaleMode == TerrainTreeScaleMode::FitnessRandomized) {
390 point.yaw = random.next(0, 360); point.scaleX = point.scaleZ = float(width); point.scaleY = float(height);
392 point.colorG = std::lerp(s.dryG, s.healthyG, strength); point.colorB = std::lerp(s.dryB, s.healthyB, strength);
415 DiagnosticCode::InvalidArgument, "terrain.tree.multitile: changed point count exceeds integer range"));
461TerrainMultiTreeWorkspace::TerrainMultiTreeWorkspace(TerrainMultiTreeWorkspace&&) noexcept = default;
462TerrainMultiTreeWorkspace& TerrainMultiTreeWorkspace::operator=(TerrainMultiTreeWorkspace&&) noexcept = default;
470 if (std::any_of(impl_->tiles.begin(), impl_->tiles.end(), [&](const auto& tile) { return tile.name == name; }))
475 candidate->tiles.push_back({name, trees, heights, originX, originZ, width, depth, resolutionX, resolutionY,
479 descriptors.push_back({tile.name, tile.originX, tile.originZ, tile.width, tile.depth, tile.resolutionX,
486 auto checked = mapTerrainOperationMultiTile(descriptors, bounds, TerrainOperationDomain::Tree, worldMap, {name});
503 descriptors.push_back({tile.name, &tile.trees, &tile.heights, tile.originX, tile.originZ, tile.width,
505 auto applied = applyTerrainTreesMultiTile(descriptors, operationFitness, settings, operationSettings, mode,
517Result<int> TerrainMultiTreeWorkspace::copyTile(const std::string& name, PointSet& output) const {
521 if (found == impl_->tiles.end()) return invalidTreeWorkspace("terrain.tree.workspace: tile not found");
539int TerrainMultiTreeWorkspace::getTileCount() const noexcept { return impl_ ? int(impl_->tiles.size()) : 0; }
549int TerrainMultiTreeWorkspace::getAppliedCount() const noexcept { return impl_ ? impl_->cursor : 0; }
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
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
Result< int > appendPointFrom(const PointSet &source, std::size_t sourceIndex)
Append a point and its attributes from another set.
Definition PointSet.cpp:69
void reserve(std::size_t count)
Reserve point storage without changing point or attribute row counts.
Definition PointSet.cpp:60
Owning script-safe multi-terrain tree transaction workspace. Tree sets and height rasters are copied ...
Definition TerrainTreePlacement.h:90
~TerrainMultiTreeWorkspace()
Terrain multi tree workspace.
constexpr HexDirection next(HexDirection d) noexcept
The next direction clockwise (NW wraps to NE).
Definition HexMetrics.h:76
double textureSample(const Heightmap &map, double u, double v)
Texture sample.
Definition TerrainRasterInternal.h:38
Definition EvpackPointGraphLoader.h:12
Result< int > removeTerrainTreePoints(PointSet &output, const PointSet &input, const Heightmap &fitness, const TerrainTreePlacementSettings &s)
Remove matching tree points wherever the current fitness is strictly above the threshold.
Definition TerrainTreePlacement.cpp:174
Result< int > rescaleTerrainTreePoints(PointSet &output, const PointSet &input, const TerrainTreeRescaleSettings &s)
Atomically refresh scale, bounds and bend metadata for one tree asset while preserving identity/trans...
Definition TerrainTreePlacement.cpp:206
Result< TerrainMultiTileReport > mapTerrainOperationMultiTile(const std::vector< TerrainOperationTile > &tiles, const TerrainStampSettings &settings, TerrainOperationDomain domain, bool worldMapOperation, const std::vector< std::string > &validTerrainNames)
Calculate Pcg-compatible local and shared pixel rectangles for any multi-terrain raster domain.
Definition TerrainMultiTile.cpp:71
Result< TerrainMultiTileReport > applyTerrainTreesMultiTile(const std::vector< TerrainTreeTile > &tiles, const Heightmap &operationFitness, const TerrainTreePlacementSettings &s, const TerrainStampSettings &operationSettings, TerrainTreeOperationMode mode, bool worldMapOperation, const std::vector< std::string > &validTerrainNames)
Apply one Pcg tree distribution window across selected terrain tiles atomically.
Definition TerrainTreePlacement.cpp:250
TerrainTreeScaleMode
Pcg-compatible rules for deriving tree scale from placement fitness.
Definition TerrainTreePlacement.h:17
@ FitnessRandomized
TerrainTreeYOffsetMode
Height reference used when a tree does not snap directly to terrain.
Definition TerrainTreePlacement.h:20
@ TerrainHeight
Result< int > exportTerrainTreePoints(PointSet &output, const Heightmap &fitness, const Heightmap &heights, const TerrainTreePlacementSettings &s)
Scan a terrain rectangle and atomically export accepted Pcg-style tree instances.
Definition TerrainTreePlacement.cpp:61
TerrainTreeOperationMode
Pcg SetTerrainTrees operation branch. Add and Replace both append after upstream clearing policy.
Definition TerrainTreePlacement.h:55
@ InvalidArgument
@ InvariantViolation
Definition Container.h:602
One deterministic sample used by script-first procedural pipelines.
Definition PointSet.h:17
std::uint64_t id
Stable non-zero identity; zero marks legacy or not-yet-assigned data.
Definition PointSet.h:19
Completed multi-tile stamp statistics and Pcg-compatible affected-pixel mappings.
Definition TerrainMultiTile.h:55
std::vector< PointSet > trees
Definition TerrainTreePlacement.cpp:433
TerrainMultiTileReport report
Definition TerrainTreePlacement.cpp:434
Heightmap heights
Definition TerrainTreePlacement.cpp:427
int resolutionX
Definition TerrainTreePlacement.cpp:429
double width
Definition TerrainTreePlacement.cpp:428
PointSet trees
Definition TerrainTreePlacement.cpp:426
double originZ
Definition TerrainTreePlacement.cpp:428
double depth
Definition TerrainTreePlacement.cpp:428
bool worldMap
Definition TerrainTreePlacement.cpp:430
std::string name
Definition TerrainTreePlacement.cpp:425
int resolutionY
Definition TerrainTreePlacement.cpp:429
double originX
Definition TerrainTreePlacement.cpp:428
int cursor
Definition TerrainTreePlacement.cpp:439
Snapshot snapshot() const
Definition TerrainTreePlacement.cpp:440
std::vector< Tile > tiles
Definition TerrainTreePlacement.cpp:436
std::vector< Snapshot > history
Definition TerrainTreePlacement.cpp:438
TerrainMultiTileReport last
Definition TerrainTreePlacement.cpp:437
void restore(const Snapshot &snapshot)
Definition TerrainTreePlacement.cpp:447
Value configuration for a rectangular stamp in world X/Z coordinates.
Definition TerrainStamp.h:22
Explicit deterministic tree placement configuration for one terrain rectangle and resource.
Definition TerrainTreePlacement.h:23
Previous and replacement prototype values used for atomic Pcg-style tree refresh.
Definition TerrainTreePlacement.h:44