- Standalone/Core: public header VoxelForgeCore.h (no Unreal types), static library target, ResolvedWorldSnapshot (from the schema-v1 JSON), World (compile, generateTile, density/sign, point/segment solid, classifyBox), host-supplied JobScheduler (the core starts no threads), sequenced, idempotent EditTransaction returning affected tiles per LOD. - The viewer, benchmarks, edits and audits run on Core; StreamingWorld stays host code. - Same as round 11: 11 hash rows at W1 and W8, routes 5642/5642, look/passage/far audits pass, bad-shell control fails, six fixed captures byte-identical; cold W8 1.025 s vs 1.041 s reference. - SHARED_CPP_LIBRARY_PLAN.md rewritten for a UBT module compiling the same sources via shims. Open issue before Unreal: Core's implementation still compiles the Compat stand-ins named like Unreal types (TArray, FVector...); inside a UE binary that is an ODR clash. Must be namespaced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
5.2 KiB
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.
Units and ownership
Vec3dquery positions andVec3ivoxel coordinates are in voxels.TileKey.coordinateis a tile coordinate; one coordinate step spans32 << lodvoxels.- Mesh vertex positions are centimetres. UVs, RGBA8 colors, normals and 32-bit indices are
returned per vertex / triangle in owned
std::vectors. MeshGroups::groundTriangleCountandceilingTriangleCountdescribe the contiguous index runs emitted by the mesher. Ceiling is the final run.skirtTriangleCountis a subset of the ground and ceiling runs.surfaceVertexCountends before skirt vertices.- A
Worldowns 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 sameWorld.
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.
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 */ }
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:
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:
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.