Files
VoxelForge/Standalone/Core/API.md
T
Fr0zkaandClaude Opus 5.5 3b37d5702e standalone: owner review fixes -- paged streaming in Core, no LOD fins, LOD0 stair patches fixed
From the owner's fly-through ("very impressive, in some cases slightly better than the original"):
- Streaming: Core compiles world-aligned fine-detail pages for tiles entering the view and releases
  them when they leave; the viewer keeps resident tiles. One chunk crossing: 144 new tiles, 1,822
  kept (was a full rebuild). A tile built as a late page hashes identically (density, mesh, payload,
  topology) to the same tile from an initial build.
- LOD>=1 fins: off-surface planar connector panels are now checked against the source surface and
  projected onto it; coarse audit 0 off-surface panels; far survival passes, bad-shell still fails.
- LOD0 stair patches: 2,630 sign-changing edges had one endpoint at the fixed +-4.125 fallback
  (carve surfaces were excluded from distance storage); distances now completed analytically, 462
  packed signs corrected; the audit now fails on any sign edge missing either endpoint (0 of 952,997).
- W1/W8 hashes equal; routes 5642/5642; look, passage and far audits pass.
Verified by me, interleaved (8 workers, cold): 1.014 s vs 1.008 s for aeeedaa, no regression.
Open: a chunk crossing still costs ~1.2 s of page compilation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
2026-10-05 18:17:25 +02:00

143 lines
6.9 KiB
Markdown

# VoxelForgeCore API reference
Public header: `Core/include/VoxelForgeCore/VoxelForgeCore.h` (C++20, standard library only).
Build the static library and viewer with `Build.ps1 -Target All`, or only the library with
`Build.ps1 -Target Core`.
The public header uses only standard C++ types and can be included after Unreal's `CoreMinimal.h`.
`Core/verification/UnrealHeaderCoexistence.cpp` is the compile smoke check against the installed
Unreal 5.7 headers. Copied generator and compatibility declarations stay in the private
`vfcore::detail` implementation and do not appear in this API.
## Units and ownership
- `Vec3d` query positions and `Vec3i` voxel coordinates are in **voxels**.
- `TileKey.coordinate` is a tile coordinate; one coordinate step spans `32 << lod` voxels.
- Mesh vertex positions are **centimetres**. UVs, RGBA8 colors, normals and 32-bit indices are
returned per vertex / triangle in owned `std::vector`s.
- `MeshGroups::groundTriangleCount` and `ceilingTriangleCount` describe the contiguous index runs
emitted by the mesher. Ceiling is the final run. `skirtTriangleCount` is a subset of the ground
and ceiling runs. `surfaceVertexCount` ends before skirt vertices.
- A `World` owns its compiled field and edit log. The snapshot can be shared as immutable input.
Serialize compile/edit changes against query and tile-generation calls on that same `World`.
## Load and compile
`ResolvedWorldSnapshot::FromJson` accepts the normalized UTF-8 schema-v1 owner export used by the
standalone loader. It returns `std::nullopt` and fills `error` when parsing or asset resolution
fails. Read `configuration()` for the resolved scalar settings.
Implement `JobScheduler::parallel_for` in the host. It must run each index from zero to `count - 1`
exactly once and return only after all submitted work is complete. The library creates no threads.
`ShapeBuildRequest` supplies the detail and clip bounds in voxels, worker limit, detail variant,
far-world inclusion, and optional tunnel/detail profiles.
```cpp
std::string error;
auto snapshot = VoxelForgeCore::ResolvedWorldSnapshot::FromJson(json, error);
if (!snapshot) { /* report error */ }
VoxelForgeCore::World world(std::move(*snapshot));
VoxelForgeCore::ShapeBuildRequest build;
build.minVoxel = {-256, -768, -384};
build.maxVoxel = { 256, -256, 128};
build.clipMinVoxel = {-57344, -57344, -8192};
build.clipMaxVoxel = { 49152, 49152, 8192};
build.workerLimit = 8;
build.includeFarWorld = true;
if (!world.compile(build, hostScheduler, error)) { /* report error */ }
```
For a streamed shape world, compile the initial camera region once, then add deterministic detail
pages before generating any newly desired fine tile outside that region:
```cpp
const auto entering = world.desiredTiles(newCameraVoxels);
VoxelForgeCore::TileGenerationOptions options;
std::size_t pageCoveredTiles = 0;
if (!world.compileTileRegion(entering, 8, hostScheduler, error, &pageCoveredTiles)) {
/* report error */
}
for (const auto& key : entering) {
if (auto mesh = world.generateTile(key, options, error)) { /* upload and retain */ }
}
world.retainTileRegions(entering);
```
The Core groups fine tiles into pages using absolute tile coordinates, so a page's contents do not
depend on the camera or the order in which the player reaches it. Pages cover a 128-voxel cube (or
one larger coarse tile), with an 8-voxel sampling apron. `compileTileRegion` skips LODs at or above
`fullResolutionLodCount`, keys covered by the initial `ShapeBuildRequest`, and pages already
resident. Its optional output counts requested fine tile keys that needed a newly compiled page;
it does not count the page's internal lattice samples. After all pages needed by the next desired
set compile, call `retainTileRegions` with that set to release pages no longer needed. The Core
owns page lifetime and mesh data; the host keeps still-visible meshes resident until replacement
tiles are generated and uploaded.
## Queries and tiles
`densityAt(position)` returns signed density; negative is solid and nonnegative is air.
`isSolidAt` wraps that sign test. `isSolidAlongSegment(start, end, spacing)` samples evenly along
the segment with no interval wider than `spacing` voxels; it returns true if any sample is solid.
`classifyBox(origin, step, cells)` returns `allSolid`, `allAir` or `mixed` for mesher tile
classification.
`desiredTiles(cameraVoxels)` returns the snapshot's clipmap set. Pass it to
`prioritizeTiles(tiles, centerChunk)` when submitting work. Generate independent keys concurrently
on host workers:
```cpp
VoxelForgeCore::TileGenerationOptions options;
auto mesh = world.generateTile(key, options, error);
if (!mesh) { /* report error */ }
// mesh->vertices, mesh->indices and mesh->groups are owned by this result.
```
The optional `hashDensity` flag fills deterministic density, viewer-mesh, payload and topology
hashes. `captureDensitySamples` is a diagnostic option and retains the sampled lattice values.
## Deterministic edits
Build an `EditTransaction` with a monotonically increasing authority sequence and an ordered brush
array (`sphere`, `capsule`, `roundedBox`; `carve`, `addRock`, `densityOffset`). `carve` and
`addRock` apply hard signed-distance CSG. `densityOffset` applies `strength` inside a sphere or
inside/around a capsule or box with its `falloff` band; negative strength carves and positive
strength adds rock. This operation maps the plugin's soft `FVoxelModification` brushes into the
shared field. Apply the transaction against the currently desired keys:
```cpp
VoxelForgeCore::EditTransaction edit;
edit.sequence = 12;
VoxelForgeCore::EditBrush brush;
brush.shape = VoxelForgeCore::EditBrush::Shape::capsule;
brush.operation = VoxelForgeCore::EditBrush::Operation::densityOffset;
brush.a = {0.0, 0.0, 0.0};
brush.b = {12.0, 0.0, 0.0};
brush.radius = 3.0;
brush.strength = -10.0f;
brush.falloff = 2.0f;
edit.brushes.push_back(brush);
const auto affected = world.applyEditTransaction(edit, currentTiles, error);
if (affected) {
for (const auto& lodTiles : affected->affectedByLod)
for (const auto& key : lodTiles)
submitHostJob([&, key] {
std::string tileError;
return world.generateTile(key, options, tileError);
});
}
```
The transaction digest covers the sequence and each brush field in order. Replaying the same
sequence and values returns the original result; reusing a sequence with different values or
applying an older sequence is rejected. Each client must deserialize identical brush values and
apply transactions in the same sequence. `affectedByLod` is limited to the desired keys passed to
the call.
## Other outputs
`farConnectorSegments()` returns owned connector geometry, while `farConnectorCandidates(min,max)`
returns candidate indices overlapping a voxel-space box. The audit methods expose shape detail,
surface-family and camera-look checks for host diagnostics. All returned values are standard C++;
the host owns conversion to engine mesh, collision or renderer objects.