Linked repository source
examples/voxel_stream/declarations/voxel_world.odin
This read-only view comes from the file in the Gododin repository. It retains its design, example or evidence context.
Download the original file · Return to the guide
// Package declarations owns the streaming lifecycle; the voxel package remains
// pure Odin. Worker results are immutable leases copied into retained staging
// before release. The scene makes one mesh_add_surface(RID, Dictionary) call
// per nonempty upload because the installed image kit cannot construct that
// Dictionary natively. The scene creates the mesh RID and transfers ownership
// with stage_front; this package creates/frees every render-instance RID and
// frees every adopted mesh. Godot owns material, lighting, camera and fog.
//
// Packed byte owners are reused at equal lengths and replaced at size changes.
// The admitted []u8 result bridge then copies each extent into a PackedByteArray.
// This is bounded whole-buffer transport, not a zero-copy or allocation-free
// engine upload claim. No per-vertex foreign calls occur on the consume path.
// shutdown needs a live Main_Call and must run before native deinit.
package declarations
import "core:mem"
import "core:time"
import raw "gododin:bindings/raw"
import godot "gododin:bindings/typed/godot"
import gd "gododin:bindings/typed/call"
import render "gododin:bindings/typed/render"
import voxel "../subsystem"
TABLE_CAPACITY :: 1024
LOD0_RING :: 2
LOD1_RING :: 4
LOD_HYSTERESIS :: 500 * time.Millisecond
WORKER_COUNT :: 3
NEIGHBOR_OFFSETS :: [4][3]i32{{-1,0,0},{1,0,0},{0,0,-1},{0,0,1}}
// A request owns a snapshot of revision at request_id. Edits change revision;
// stale results never replace the last displayed mesh. dirty work is flushed
// at begin_frame, coalescing a whole synchronous editing command into one job.
Chunk_State :: struct {
coords: [3]i32,
kind: voxel.Chunk_Kind,
voxels: ^voxel.Chunk,
pool_index: int,
mesh_rid, instance_rid: raw.RID,
voxel_digest, mesh_digest: u64,
aabb: [6]f32,
vertex_count, index_count: u32,
revision, committed_revision, request_revision: u64,
request_id: i64,
edit_tag: i64,
dirty, edited: bool,
lod, pending_lod: u8,
lod_deadline: time.Tick,
lod_armed: bool,
}
// Tombstones preserve probe chains after retirement. The fixed coordinate
// table and exact-radius voxel pool allocate only during configure.
Chunk_Table :: struct {
slots: [TABLE_CAPACITY]Chunk_State,
used, tombstone: [TABLE_CAPACITY]bool,
count: int,
}
// Voxel_World_Settings is the native settings Resource the Inspector edits
// and the saved scene retains through the world's `settings` property
// (EX-VOXEL). The scene's configure reads its seed and view radius; per-run
// control changes stay in the scene's own UI.
@(gododin_class="Resource")
Voxel_World_Settings :: struct {
seed: i64 `godot:"property"`,
view_radius: i64 `godot:"property"`,
}
// Edit_Committed is the payload of the world's coarse edit-committed signal:
// scalar identity, the count of visible chunks whose remeshes committed for
// that edit, and their combined wait in microseconds. No voxel bytes cross a
// signal emission.
Edit_Committed :: struct {
edit_id: i64,
chunks: i64,
wait_usec: i64,
}
@(gododin_class="Node3D")
Voxel_World :: struct {
allocator: mem.Allocator,
params: voxel.Params,
view_radius, upload_budget: i64,
workers: ^voxel.Worker_Pool,
table: ^Chunk_Table,
voxel_pool: []voxel.Chunk,
free_pool: [TABLE_CAPACITY]int,
free_count: int,
scratch: ^voxel.Chunk,
scratch_aprons: ^voxel.Aprons,
verify_workspace: ^voxel.Mesh_Workspace,
scenario: raw.RID,
staging_vertex, staging_attribute, staging_index: render.Packed_Byte_Staging,
front_valid: bool,
front_coords: [3]i32,
front_vertex_count, front_index_count: i64,
front_aabb: [6]f32,
front_mesh_digest, front_voxel_digest, front_revision: u64,
front_mesh_rid, front_instance_rid: raw.RID,
front_mesh_identity: i64,
front_lod: u8,
front_vertex_view, front_attribute_view, front_index_view: []u8,
anchor: [3]i32,
anchor_valid, work_pending: bool,
staged_this_frame, chunks_meshed, discarded_results, mesh_skips: i64,
lod_remeshes, staged_verified, voxels_changed, frame_counter: i64,
window_start, last_commit: time.Tick,
window_chunks, window_chunks_per_sec_milli: i64,
last_error: i64,
configured: bool,
// The authored world settings Resource (EX-VOXEL): the saved seed and
// view radius the scene's configure reads.
settings: gd.Ref(Voxel_World_Settings) `godot:"property"`,
// The coarse edit-committed event (EX-VOXEL): one scalar signal per
// accepted edit, emitted only when every visible chunk that edit touched
// has committed its remesh. Superseding or reconfiguring retires the
// pending feedback without emitting.
edit_id: i64,
edit_open: bool,
edit_pending: i64,
edit_chunks_total: i64,
edit_started_tick: time.Tick,
edit_committed_total: i64,
edit_superseded: i64,
edit_committed: gd.Signal(Edit_Committed),
}
voxel_world_init :: proc(self: ^Voxel_World, allocator: mem.Allocator) -> bool {
self^ = {}
self.allocator = allocator
self.params = voxel.DEFAULT_PARAMS
// Hard per-frame staging ceiling, sized to the worker mailbox. The scene
// applies its own time budget before reaching this.
self.upload_budget = 4
self.view_radius = 4
return true
}
// CPU-only fallback for partial configuration. The scene's shutdown owns the
// engine half because deinit carries no engine-call authority.
voxel_world_deinit :: proc(self: ^Voxel_World) {
if self.workers != nil { _ = voxel.pool_destroy(&self.workers) }
free_cpu_storage(self)
self^ = {}
}
free_cpu_storage :: proc(self: ^Voxel_World) {
if self.verify_workspace != nil {
voxel.mesh_workspace_destroy(self.verify_workspace, self.allocator)
mem.free(rawptr(self.verify_workspace), self.allocator)
self.verify_workspace = nil
}
if self.table != nil { mem.free(rawptr(self.table), self.allocator); self.table = nil }
if self.scratch != nil { mem.free(rawptr(self.scratch), self.allocator); self.scratch = nil }
if self.scratch_aprons != nil { mem.free(rawptr(self.scratch_aprons), self.allocator); self.scratch_aprons = nil }
if self.voxel_pool != nil { delete(self.voxel_pool, self.allocator); self.voxel_pool = nil }
self.free_count = 0
}
floor_chunk :: proc(value: i64) -> i32 { return i32(value >> 5) }
floor_world :: proc(value: f64) -> i64 {
integer := i64(value)
return integer - 1 if f64(integer) > value else integer
}
lod_for_ring :: proc(distance: i32) -> u8 {
if distance <= LOD0_RING { return 0 }
if distance <= LOD1_RING { return 1 }
return 2
}
chebyshev_of :: proc(coords, anchor: [3]i32) -> i32 {
return max(abs(coords[0] - anchor[0]), abs(coords[2] - anchor[2]))
}
// Return the matching slot or the earliest reusable slot. A tombstone cannot
// terminate lookup: another coordinate may lie farther down its probe chain.
slot_of :: proc(table: ^Chunk_Table, coords: [3]i32) -> int {
h := voxel.hash32(u32(coords[0]) ~ (u32(coords[2]) << 1) ~ 0x9e3779b9)
index := int(h) & (TABLE_CAPACITY - 1)
available := -1
for _ in 0..<TABLE_CAPACITY {
if table.used[index] {
if table.slots[index].coords == coords { return index }
} else {
if available < 0 { available = index }
if !table.tombstone[index] { return available }
}
index = (index + 1) & (TABLE_CAPACITY - 1)
}
return available
}
chunk_find :: proc(table: ^Chunk_Table, coords: [3]i32) -> ^Chunk_State {
if table == nil { return nil }
index := slot_of(table, coords)
if index < 0 || !table.used[index] { return nil }
return &table.slots[index]
}
type_pointer :: proc(value: rawptr) -> raw.GDExtensionTypePtr { return raw.GDExtensionTypePtr(value) }
release_world_ref :: proc(gcall: godot.Call, owner: ^godot.Owned_Ref(godot.World3D)) {
// The typed surface's one generic release path: unreference, destroy on the
// last reference, and a refusal that leaves the owner intact for a retry.
_ = godot.owned_ref_release(gcall, owner)
}
server_of :: proc(gcall: godot.Call) -> (godot.RenderingServer, godot.Call_Error) {
return godot.singleton_rendering_server(gcall)
}
free_rid :: proc(gcall: godot.Call, server: ^godot.RenderingServer, rid: ^raw.RID) -> bool {
if rid^ == (raw.RID{}) { return true }
if godot.rendering_server_free_rid(gcall, server, rid^) != .None { return false }
rid^ = {}
return true
}
retire_slot :: proc(self: ^Voxel_World, gcall: godot.Call, server: ^godot.RenderingServer, index: int) -> bool {
if !self.table.used[index] { return true }
state := &self.table.slots[index]
// Detach the instance before releasing its mesh. Preserve failed owners so
// a subsequent shutdown can retry instead of losing the only handle.
if !free_rid(gcall, server, &state.instance_rid) { return false }
if !free_rid(gcall, server, &state.mesh_rid) { return false }
// Eviction discards demo edits. Surviving neighbors must replace the
// formerly edited apron with deterministic noise, including snapshots
// already in flight; their revision invalidates those old results.
if self.edit_open && state.edit_tag == self.edit_id && self.edit_pending > 0 {
// The affected chunk left the visible window: its claim retires, and
// the remaining visible chunks still complete the edit.
self.edit_pending -= 1
}
if state.edited {
for offset in NEIGHBOR_OFFSETS {
neighbor := chunk_find(self.table, {state.coords[0]+offset[0],0,state.coords[2]+offset[2]})
if neighbor != nil {
neighbor.revision += 1
neighbor.dirty = true
edit_tag_chunk(self, neighbor)
self.work_pending = true
}
}
}
self.free_pool[self.free_count] = state.pool_index
self.free_count += 1
state^ = {}
self.table.used[index] = false
self.table.tombstone[index] = true
self.table.count -= 1
return true
}
clear_front :: proc(self: ^Voxel_World) {
self.front_valid = false
self.front_mesh_rid = {}
self.front_instance_rid = {}
self.front_mesh_identity = 0
self.front_vertex_view = nil
self.front_attribute_view = nil
self.front_index_view = nil
}
free_front :: proc(self: ^Voxel_World, gcall: godot.Call, server: ^godot.RenderingServer) -> bool {
if !free_rid(gcall, server, &self.front_instance_rid) { return false }
if !free_rid(gcall, server, &self.front_mesh_rid) { return false }
clear_front(self)
return true
}
// Reconfiguration first destroys the previous configuration, including its
// table, voxel pool and verification workspace. Failure rolls back all newly
// acquired owners and preserves a negative reason.
@(gododin)
voxel_world_configure :: proc(self: ^Voxel_World, call: gd.Main_Call, seed, view_radius: i64) -> i64 {
if gd.validate_main_call(call) != .None { return -1 }
if view_radius < 1 || view_radius > 12 { self.last_error = -2; return -2 }
// Reconfiguration retires any open edit's pending feedback: the new world
// has no relation to it, so nothing emits.
if self.edit_open { self.edit_superseded += 1 }
self.edit_open = false
self.edit_pending = 0
self.edit_chunks_total = 0
if code := voxel_world_shutdown(self, call); code != 0 { return code }
success := false
defer {
if !success {
error := self.last_error
_ = voxel_world_shutdown(self, call)
self.last_error = error
}
}
gcall := gd.godot_main_call(call)
_, facade_ok := gd.main_facade(call)
if !facade_ok { self.last_error = -3; return -3 }
object, self_ok := gd.self(call)
if !self_ok { self.last_error = -7; return -7 }
n3d, cast_ok := godot.cast_Node3D(gcall, &object)
if !cast_ok { self.last_error = -8; return -8 }
world_owned, world_error := godot.node3d_get_world_3d(gcall, n3d)
if world_error != .None { self.last_error = -9; return -9 }
defer release_world_ref(gcall, &world_owned)
scenario, scenario_error := godot.world3d_get_scenario(gcall, &world_owned.handle)
if scenario_error != .None { self.last_error = -10; return -10 }
workers, workers_ok := voxel.pool_create(self.allocator, WORKER_COUNT, true)
if !workers_ok { self.last_error = -4; return -4 }
self.workers = workers
table, table_error := mem.alloc(size_of(Chunk_Table), align_of(Chunk_Table), self.allocator)
if table_error != nil || table == nil { self.last_error = -5; return -5 }
self.table = cast(^Chunk_Table)table
self.table^ = {}
capacity := int((2 * view_radius + 1) * (2 * view_radius + 1))
pool, pool_error := make([]voxel.Chunk, capacity, self.allocator)
if pool_error != nil || pool == nil { self.last_error = -5; return -5 }
self.voxel_pool = pool
self.free_count = capacity
for index in 0..<capacity { self.free_pool[index] = index }
scratch, scratch_error := mem.alloc(size_of(voxel.Chunk), align_of(voxel.Chunk), self.allocator)
if scratch_error != nil || scratch == nil { self.last_error = -6; return -6 }
self.scratch = cast(^voxel.Chunk)scratch
aprons, apron_error := mem.alloc(size_of(voxel.Aprons), align_of(voxel.Aprons), self.allocator)
if apron_error != nil || aprons == nil { self.last_error = -6; return -6 }
self.scratch_aprons = cast(^voxel.Aprons)aprons
workspace, workspace_error := mem.alloc(size_of(voxel.Mesh_Workspace), align_of(voxel.Mesh_Workspace), self.allocator)
if workspace_error != nil || workspace == nil { self.last_error = -6; return -6 }
self.verify_workspace = cast(^voxel.Mesh_Workspace)workspace
self.verify_workspace^ = {}
if !voxel.mesh_workspace_create(self.allocator, self.verify_workspace) { self.last_error = -6; return -6 }
self.params = voxel.DEFAULT_PARAMS
self.params.seed = u32(seed & 0xFFFFFFFF)
self.view_radius = view_radius
self.scenario = scenario.value
self.configured = true
self.anchor_valid = false
self.chunks_meshed = 0
self.discarded_results = 0
self.mesh_skips = 0
self.lod_remeshes = 0
self.staged_verified = 0
self.voxels_changed = 0
self.window_start = time.tick_now()
self.last_commit = self.window_start
self.window_chunks = 0
self.window_chunks_per_sec_milli = 0
self.last_error = 0
code := voxel_world_set_anchor(self, call, 0, 0, 0)
if code < 0 { return code }
success = true
return 0
}
arm_lod :: proc(state: ^Chunk_State, desired: u8, now: time.Tick) {
if desired == state.lod && state.kind != .Pending {
state.pending_lod = desired
state.lod_armed = false
return
}
if state.pending_lod != desired || (!state.lod_armed && state.kind != .Pending) {
state.pending_lod = desired
state.lod_deadline = time.tick_add(now, LOD_HYSTERESIS)
state.lod_armed = true
}
}
// Recenter only when the camera enters a different chunk. Retired slots keep
// tombstones; each coordinate has exactly one state and one request identity.
@(gododin)
voxel_world_set_anchor :: proc(self: ^Voxel_World, call: gd.Main_Call, x, y, z: f64) -> i64 {
if gd.validate_main_call(call) != .None { return -1 }
if !self.configured { self.last_error = -2; return -2 }
if self.front_valid { self.last_error = -11; return -11 }
anchor := [3]i32{floor_chunk(floor_world(x)), 0, floor_chunk(floor_world(z))}
if self.anchor_valid && anchor == self.anchor { return 0 }
gcall := gd.godot_main_call(call)
server, server_error := server_of(gcall)
if server_error != .None { self.last_error = -3; return -3 }
self.anchor = anchor
self.anchor_valid = true
radius := i32(self.view_radius)
minimum := [3]i32{anchor[0]-radius, 0, anchor[2]-radius}
maximum := [3]i32{anchor[0]+radius, 0, anchor[2]+radius}
voxel.pool_cancel_outside(self.workers, minimum, maximum)
for index in 0..<TABLE_CAPACITY {
if self.table.used[index] && chebyshev_of(self.table.slots[index].coords, anchor) > radius {
if !retire_slot(self, gcall, &server, index) { self.last_error = -12; return -12 }
}
}
added := i64(0)
for d := i32(0); d <= radius; d += 1 {
for dx := -d; dx <= d; dx += 1 {
for dz := -d; dz <= d; dz += 1 {
if max(abs(dx), abs(dz)) != d { continue }
coords := [3]i32{anchor[0]+dx, 0, anchor[2]+dz}
index := slot_of(self.table, coords)
if index < 0 { self.last_error = -13; return -13 }
if self.table.used[index] { continue }
if self.free_count == 0 { self.last_error = -13; return -13 }
self.free_count -= 1
pool_index := self.free_pool[self.free_count]
lod := lod_for_ring(d)
self.table.slots[index] = Chunk_State{
coords=coords, kind=.Pending, pool_index=pool_index,
voxels=&self.voxel_pool[pool_index], revision=1, lod=lod, pending_lod=lod,
}
self.table.used[index] = true
self.table.tombstone[index] = false
self.table.count += 1
added += 1
}
}
}
now := time.tick_now()
for index in 0..<TABLE_CAPACITY {
if self.table.used[index] {
state := &self.table.slots[index]
arm_lod(state, lod_for_ring(chebyshev_of(state.coords, anchor)), now)
}
}
self.work_pending = true
self.last_error = 0
return added
}
// Submit edited chunks first and initial generation nearest-first. Queue-full
// is ordinary backpressure: keep work_pending and retry while stationary.
flush_work :: proc(self: ^Voxel_World) -> bool {
self.work_pending = false
now := time.tick_now()
for index in 0..<TABLE_CAPACITY {
if !self.table.used[index] { continue }
state := &self.table.slots[index]
if state.kind == .Pending || state.request_id != 0 { continue }
lod_due := state.lod_armed && time.tick_diff(state.lod_deadline, now) >= 0
if !state.dirty && !lod_due { continue }
if !voxel_world_fill_aprons(self, state.coords, self.scratch_aprons) { self.last_error = -14; return false }
lod := state.pending_lod if lod_due else state.lod
spec := voxel.Job_Spec{kind=.Remesh, coords=state.coords, params=self.params,
lod=lod, voxels=state.voxels, aprons=self.scratch_aprons}
id: i64
error: voxel.Error
if state.dirty { id, error = voxel.pool_submit_front(self.workers, spec) }
else { id, error = voxel.pool_submit(self.workers, spec) }
if error == .Queue_Full { self.work_pending = true; return true }
if error != .None { self.last_error = -15; return false }
state.request_id = id
state.request_revision = state.revision
state.dirty = false
}
radius := i32(self.view_radius)
for d := i32(0); d <= radius; d += 1 {
for dx := -d; dx <= d; dx += 1 {
for dz := -d; dz <= d; dz += 1 {
if max(abs(dx), abs(dz)) != d { continue }
state := chunk_find(self.table, {self.anchor[0]+dx, 0, self.anchor[2]+dz})
if state == nil || state.kind != .Pending || state.request_id != 0 { continue }
id, error := voxel.pool_submit(self.workers, voxel.Job_Spec{
kind=.Generate, coords=state.coords, params=self.params, lod=state.pending_lod})
if error == .Queue_Full { self.work_pending = true; return true }
if error != .None { self.last_error = -15; return false }
state.request_id = id
state.request_revision = state.revision
}
}
}
return true
}
// The deadline comparison uses time.Duration, whose unit is nanoseconds. This
// periodic bookkeeping never meshes on Main; each expired ring change submits
// one worker job and uses the same upload budget as all other chunk work.
@(gododin)
voxel_world_begin_frame :: proc(self: ^Voxel_World, call: gd.Main_Call) -> i64 {
if gd.validate_main_call(call) != .None { return -1 }
if self.last_error != 0 { return self.last_error }
self.staged_this_frame = 0
self.frame_counter += 1
if self.configured {
if self.frame_counter % 15 == 0 { self.work_pending = true }
if self.work_pending && !flush_work(self) { return self.last_error }
}
return 0
}
// Empty buffers need no staging owner. Equal-sized owners are rewritten;
// replacements are acquired before the old owner is retired.
stage_bytes :: proc(api: ^render.Bound_API, owner: ^render.Packed_Byte_Staging, source: []u8) -> ([]u8, bool) {
if len(source) == 0 { return nil, true }
if !owner.live || owner.length != len(source) {
replacement, error := render.packed_byte_staging_create(api, len(source), .Main, .Main)
if error != .None { return nil, false }
if owner.live || owner.array.live {
if render.packed_byte_staging_destroy(api, owner) != .None {
_ = render.packed_byte_staging_destroy(api, &replacement)
return nil, false
}
}
owner^ = replacement
}
view, write_error := render.packed_byte_staging_write(api, owner, .Main)
if write_error != .None || len(view) != len(source) { return nil, false }
copy(view, source)
_, publish_error := render.packed_byte_staging_publish(owner, .Main)
return view, publish_error == .None
}
neighbor_edited :: proc(self: ^Voxel_World, coords: [3]i32) -> bool {
for offset in NEIGHBOR_OFFSETS {
other := chunk_find(self.table, {coords[0]+offset[0],0,coords[2]+offset[2]})
if other != nil && other.edited { return true }
}
return false
}
// Copy a finished immutable worker lease before release. Exact request IDs
// reject late generations after a coordinate leaves and reenters the window.
// Revision mismatches discard stale meshes while keeping the last good RID.
@(gododin)
voxel_world_pump :: proc(self: ^Voxel_World, call: gd.Main_Call) -> i64 {
if gd.validate_main_call(call) != .None { return -1 }
if self.last_error != 0 { return self.last_error }
if !self.configured || self.staged_this_frame >= self.upload_budget { return 0 }
if self.front_valid { self.last_error = -11; return -11 }
gcall := gd.godot_main_call(call)
server, server_error := server_of(gcall)
if server_error != .None { self.last_error = -3; return -3 }
api, facade_ok := gd.main_facade(call)
if !facade_ok { self.last_error = -3; return -3 }
for {
result, ok := voxel.pool_take(self.workers)
if !ok { return 0 }
defer voxel.pool_release_result(self.workers, &result)
state := chunk_find(self.table, result.coords)
if state == nil || state.request_id != i64(result.request_id) {
self.discarded_results += 1
continue
}
state.request_id = 0
self.work_pending = true
if result.error != .None { self.last_error = -16; return -16 }
stale := state.request_revision != state.revision
if result.kind == .Generate {
if result.voxels == nil { self.last_error = -16; return -16 }
copy(state.voxels[:], result.voxels[:])
state.voxel_digest = result.voxel_digest
state.kind = .Generated
// A deterministic generation used noise aprons; an edited neighbor
// requires a remesh against the authoritative stored boundary.
stale = stale || neighbor_edited(self, state.coords)
}
if stale {
state.dirty = true
self.discarded_results += 1
continue
}
v, vok := stage_bytes(api, &self.staging_vertex, result.mesh.vertices)
a, aok := stage_bytes(api, &self.staging_attribute, result.mesh.attributes)
i, iok := stage_bytes(api, &self.staging_index, result.mesh.indices)
if !vok || !aok || !iok { self.last_error = -17; return -17 }
staged := result.mesh
staged.vertices = v
staged.attributes = a
staged.indices = i
if voxel.mesh_digest(&staged) != result.mesh_digest || !mesh_bounds_valid(&staged, result.coords) {
self.last_error = -18
return -18
}
self.staged_verified += 1
instance_rid: raw.RID
if result.mesh.vertex_count > 0 {
instance, error := godot.rendering_server_instance_create(gcall, &server)
if error != .None { self.last_error = -19; return -19 }
instance_rid = instance.value
self.front_instance_rid = instance_rid
if godot.rendering_server_instance_set_scenario(gcall, &server, instance_rid, self.scenario) != .None {
_ = free_rid(gcall, &server, &self.front_instance_rid)
self.last_error = -19
return -19
}
}
self.front_valid = true
self.front_coords = result.coords
self.front_vertex_count = i64(result.mesh.vertex_count)
self.front_index_count = i64(result.mesh.index_count)
self.front_aabb = result.mesh.aabb
self.front_mesh_digest = result.mesh_digest
self.front_voxel_digest = result.voxel_digest
self.front_revision = state.revision
self.front_instance_rid = instance_rid
self.front_lod = result.lod
self.front_vertex_view = v
self.front_attribute_view = a
self.front_index_view = i
self.staged_this_frame += 1
if result.skipped { self.mesh_skips += 1 }
return 1
}
}
// Return the staged position/normal extent; valid only until commit or the next pump.
@(gododin)
voxel_world_take_vertex_bytes :: proc(self: ^Voxel_World, call: gd.Main_Call) -> []u8 {
if gd.validate_main_call(call) != .None || !self.front_valid { return nil }
return self.front_vertex_view
}
// Return the staged RGBA8 extent; valid only until commit or the next pump.
@(gododin)
voxel_world_take_attribute_bytes :: proc(self: ^Voxel_World, call: gd.Main_Call) -> []u8 {
if gd.validate_main_call(call) != .None || !self.front_valid { return nil }
return self.front_attribute_view
}
// Return the staged uint16 index extent; valid only until commit or the next pump.
@(gododin)
voxel_world_take_index_bytes :: proc(self: ^Voxel_World, call: gd.Main_Call) -> []u8 {
if gd.validate_main_call(call) != .None || !self.front_valid { return nil }
return self.front_index_view
}
// Return the staged six-f32 world bounds; valid only while a front is staged.
@(gododin)
voxel_world_take_aabb_bytes :: proc(self: ^Voxel_World, call: gd.Main_Call) -> []u8 {
if gd.validate_main_call(call) != .None || !self.front_valid { return nil }
return mem.slice_ptr(cast(^u8)&self.front_aabb, 24)
}
// Report the staged chunk x coordinate; meaningful only while a front is staged.
@(gododin)
voxel_world_front_chunk_x :: proc(self: ^Voxel_World) -> i64 { return i64(self.front_coords[0]) }
// Report the staged chunk z coordinate; meaningful only while a front is staged.
@(gododin)
voxel_world_front_chunk_z :: proc(self: ^Voxel_World) -> i64 { return i64(self.front_coords[2]) }
// Report the staged vertex count, including zero for an empty chunk.
@(gododin)
voxel_world_front_vertex_count :: proc(self: ^Voxel_World) -> i64 { return self.front_vertex_count }
// Report the staged uint16 index count.
@(gododin)
voxel_world_front_index_count :: proc(self: ^Voxel_World) -> i64 { return self.front_index_count }
// Return the pure mesher's exact format word, including its index-buffer bit.
@(gododin)
voxel_world_get_surface_format :: proc(self: ^Voxel_World) -> i64 { return i64(voxel.SURFACE_FORMAT) }
// Report the staged detail level (0, 1 or 2).
@(gododin)
voxel_world_front_lod :: proc(self: ^Voxel_World) -> i64 { return i64(self.front_lod) }
// Report the adopted staged mesh identity, or zero before adoption/after commit.
@(gododin)
voxel_world_front_mesh_id :: proc(self: ^Voxel_World) -> i64 { return self.front_mesh_identity }
// The scene transfers its one mesh RID exactly once. The raw RID storage and
// identity conversion are pinned by the installed binding; no RID(int) exists
// in the scene's GDScript surface.
@(gododin)
voxel_world_stage_front :: proc(self: ^Voxel_World, call: gd.Main_Call, mesh_id: i64) -> i64 {
if gd.validate_main_call(call) != .None { return -1 }
if !self.front_valid || self.front_vertex_count == 0 || self.front_mesh_rid != (raw.RID{}) { return -2 }
if mesh_id <= 0 { return -3 }
api, ok := gd.main_facade(call)
if !ok { return -4 }
rid := transmute(raw.RID)u64(mesh_id)
if !render.rid_valid(api, rid) { return -5 }
self.front_mesh_rid = rid
self.front_mesh_identity = mesh_id
return 0
}
// Replace the visible mesh only after the new instance can bind its new base.
// Empty results also commit revision/digest/LOD and retire the old geometry.
@(gododin)
voxel_world_commit_front :: proc(self: ^Voxel_World, call: gd.Main_Call) -> i64 {
if gd.validate_main_call(call) != .None { return -1 }
if !self.front_valid { return -2 }
gcall := gd.godot_main_call(call)
server, error := server_of(gcall)
if error != .None { self.last_error = -3; return -3 }
state := chunk_find(self.table, self.front_coords)
if state == nil || state.revision != self.front_revision { self.last_error = -20; return -20 }
if self.front_vertex_count > 0 {
if self.front_mesh_rid == (raw.RID{}) { self.last_error = -21; return -21 }
if godot.rendering_server_instance_set_base(gcall, &server, self.front_instance_rid, self.front_mesh_rid) != .None {
self.last_error = -22; return -22
}
}
if !free_rid(gcall, &server, &state.instance_rid) || !free_rid(gcall, &server, &state.mesh_rid) {
self.last_error = -12; return -12
}
if state.committed_revision != 0 && state.lod != self.front_lod { self.lod_remeshes += 1 }
state.mesh_rid = self.front_mesh_rid
state.instance_rid = self.front_instance_rid
state.mesh_digest = self.front_mesh_digest
state.voxel_digest = self.front_voxel_digest
state.aabb = self.front_aabb
state.vertex_count = u32(self.front_vertex_count)
state.index_count = u32(self.front_index_count)
state.lod = self.front_lod
state.committed_revision = self.front_revision
state.kind = .Meshed if self.front_vertex_count > 0 else .Generated
state.dirty = false
if self.edit_open && state.edit_tag == self.edit_id && self.edit_pending > 0 {
self.edit_pending -= 1
if self.edit_pending == 0 {
self.edit_open = false
self.edit_committed_total += 1
payload := Edit_Committed{
edit_id = self.edit_id,
chunks = self.edit_chunks_total,
wait_usec = i64(time.duration_microseconds(time.tick_diff(self.edit_started_tick, time.tick_now()))),
}
if emit_error := gd.emit(call, self.edit_committed, payload); emit_error != .None {
self.last_error = i64(emit_error)
return i64(emit_error)
}
}
}
arm_lod(state, lod_for_ring(chebyshev_of(state.coords, self.anchor)), time.tick_now())
self.chunks_meshed += 1
clear_front(self)
now := time.tick_now()
self.last_commit = now
self.window_chunks += 1
elapsed := i64(time.duration_microseconds(time.tick_diff(self.window_start, now)))
if elapsed >= 2_000_000 {
self.window_chunks_per_sec_milli = self.window_chunks * 1_000_000_000 / elapsed
self.window_chunks = 0
self.window_start = now
}
return 0
}
// Missing/unloaded/out-of-layer coordinates are ordinary misses. Mutation
// returns changed voxels, not remesh jobs, and merely marks affected state
// dirty; begin_frame snapshots the completed command once per affected chunk.
@(gododin)
voxel_world_set_voxel :: proc(self: ^Voxel_World, call: gd.Main_Call, wx, wy, wz, id: i64) -> i64 {
if gd.validate_main_call(call) != .None { return -1 }
if !self.configured { return -2 }
if id < 0 || id > 4 { return -3 }
if wy < 0 || wy >= voxel.CHUNK { return 0 }
cx, cz := floor_chunk(wx), floor_chunk(wz)
center := chunk_find(self.table, {cx,0,cz})
if center == nil || center.kind == .Pending { return 0 }
lx, lz := int(wx-i64(cx)*voxel.CHUNK), int(wz-i64(cz)*voxel.CHUNK)
index := voxel.chunk_index(lx, int(wy), lz)
if center.voxels[index] == u8(id) { return 0 }
center.voxels[index] = u8(id)
center.edited = true
center.revision += 1
center.dirty = true
edit_tag_chunk(self, center)
for offset in NEIGHBOR_OFFSETS {
if (offset[0] < 0 && lx != 0) || (offset[0] > 0 && lx != voxel.CHUNK-1) ||
(offset[2] < 0 && lz != 0) || (offset[2] > 0 && lz != voxel.CHUNK-1) { continue }
neighbor := chunk_find(self.table, {cx+offset[0],0,cz+offset[2]})
if neighbor != nil {
neighbor.revision += 1
neighbor.dirty = true
edit_tag_chunk(self, neighbor)
}
}
self.voxels_changed += 1
self.work_pending = true
return 1
}
// edit_tag_chunk claims one newly-dirtied chunk for the open edit exactly
// once, so the pending count tracks distinct chunks rather than writes.
edit_tag_chunk :: proc(self: ^Voxel_World, state: ^Chunk_State) {
if !self.edit_open || state.edit_tag == self.edit_id { return }
state.edit_tag = self.edit_id
self.edit_pending += 1
self.edit_chunks_total += 1
}
// begin_edit opens one coarse edit identity (EX-VOXEL): the writes that
// follow until the next begin_edit, configure, or completion belong to the
// returned id, and exactly one `edit_committed` emission reports when every
// visible chunk that edit touched has committed. Opening while another edit
// is open supersedes it: the previous id never emits, and its uncommitted
// claims fold into the new edit.
//
// Returns the new edit id, -1 for a bad call, -2 when not configured.
@(gododin)
voxel_world_begin_edit :: proc(self: ^Voxel_World, call: gd.Main_Call) -> i64 {
if gd.validate_main_call(call) != .None { return -1 }
if !self.configured { return -2 }
if self.edit_open { self.edit_superseded += 1 }
self.edit_id += 1
self.edit_open = true
self.edit_pending = 0
self.edit_chunks_total = 0
self.edit_started_tick = time.tick_now()
return self.edit_id
}
@(gododin)
voxel_world_get_edit_committed_total :: proc(self: ^Voxel_World) -> i64 {
return self.edit_committed_total
}
@(gododin)
voxel_world_get_edit_superseded :: proc(self: ^Voxel_World) -> i64 {
return self.edit_superseded
}
@(gododin)
voxel_world_get_edit_pending :: proc(self: ^Voxel_World) -> i64 {
return self.edit_pending
}
// Air (0) includes ordinary unavailable coordinates, making a scene-side ray
// march a read-only query with no exception/fatal-error path for a missed dig.
@(gododin)
voxel_world_get_voxel :: proc(self: ^Voxel_World, wx, wy, wz: i64) -> i64 {
if !self.configured || wy < 0 || wy >= voxel.CHUNK { return 0 }
cx, cz := floor_chunk(wx), floor_chunk(wz)
state := chunk_find(self.table, {cx,0,cz})
if state == nil || state.kind == .Pending { return 0 }
return i64(state.voxels[voxel.chunk_index(int(wx-i64(cx)*voxel.CHUNK), int(wy), int(wz-i64(cz)*voxel.CHUNK))])
}
voxel_world_fill_aprons :: proc(self: ^Voxel_World, coords: [3]i32, aprons: ^voxel.Aprons) -> bool {
neighbors := [4][3]i32{{coords[0]-1,0,coords[2]},{coords[0]+1,0,coords[2]},
{coords[0],0,coords[2]-1},{coords[0],0,coords[2]+1}}
for side in 0..<voxel.APRON_SIDES {
neighbor := chunk_find(self.table, neighbors[side])
if neighbor != nil && neighbor.kind != .Pending {
if !voxel.extract_apron(neighbor.voxels, i32(side), aprons[side][:]) { return false }
} else {
if !voxel.generate_chunk(self.scratch, neighbors[side], self.params) { return false }
if !voxel.extract_apron(self.scratch, i32(side), aprons[side][:]) { return false }
}
}
return true
}
// Independent check of the actual staged position section against both the
// submitted box and the chunk footprint; NaNs fail the ordered comparisons.
mesh_bounds_valid :: proc(data: ^voxel.Mesh_Data, coords: [3]i32) -> bool {
lo := [3]f32{f32(coords[0]*voxel.CHUNK),0,f32(coords[2]*voxel.CHUNK)}
for axis in 0..<3 {
if !(data.aabb[axis] >= lo[axis] && data.aabb[axis+3] <= lo[axis]+voxel.CHUNK &&
data.aabb[axis] <= data.aabb[axis+3]) { return false }
}
if len(data.vertices) != int(data.vertex_count)*16 { return false }
for vertex in 0..<int(data.vertex_count) {
for axis in 0..<3 {
offset := vertex*12+axis*4
bytes := [4]u8{data.vertices[offset],data.vertices[offset+1],data.vertices[offset+2],data.vertices[offset+3]}
value := transmute(f32)bytes
if !(value >= data.aabb[axis] && value <= data.aabb[axis+3]) { return false }
}
}
return true
}
// Eval-only verification, after all work settles: every resident coordinate,
// committed revision, voxel digest, full mesh bytes and AABB. Untouched chunks
// additionally replay seed generation. This does not read back GPU surfaces.
@(gododin)
voxel_world_verify :: proc(self: ^Voxel_World, call: gd.Main_Call) -> i64 {
if gd.validate_main_call(call) != .None { return -1 }
if !voxel_world_is_settled(self) { return -2 }
verified := i64(0)
for index in 0..<TABLE_CAPACITY {
if !self.table.used[index] { continue }
state := &self.table.slots[index]
if slot_of(self.table, state.coords) != index || state.committed_revision != state.revision { return -3 }
if voxel.chunk_digest(state.voxels) != state.voxel_digest { return -4 }
if !state.edited {
if !voxel.generate_chunk(self.scratch, state.coords, self.params) ||
voxel.chunk_digest(self.scratch) != state.voxel_digest { return -4 }
}
if !voxel_world_fill_aprons(self, state.coords, self.scratch_aprons) { return -5 }
data: voxel.Mesh_Data
view := voxel.Mesher_View{chunk=state.voxels, aprons=self.scratch_aprons}
if !voxel.mesh_chunk_into(view, state.coords, self.params, voxel.lod_step(i32(state.lod)), self.verify_workspace, &data) { return -5 }
if !mesh_bounds_valid(&data, state.coords) || data.aabb != state.aabb { return -7 }
if voxel.mesh_digest(&data) != state.mesh_digest { return -6 }
verified += 1
}
return verified
}
// A teardown receipt is successful only after actual RID/staging cleanup,
// worker lease drain/join and every configure-owned CPU allocation is gone.
@(gododin)
voxel_world_shutdown :: proc(self: ^Voxel_World, call: gd.Main_Call) -> i64 {
if gd.validate_main_call(call) != .None { return -1 }
if self.workers != nil { voxel.pool_cancel_all(self.workers) }
gcall := gd.godot_main_call(call)
server, server_error := server_of(gcall)
clean := true
if voxel_world_get_owned_rids(self) > 0 && server_error != .None { clean = false }
if server_error == .None {
if !free_front(self, gcall, &server) { clean = false }
if self.table != nil {
for index in 0..<TABLE_CAPACITY {
if !retire_slot(self, gcall, &server, index) { clean = false }
}
}
}
api, facade_ok := gd.main_facade(call)
owners := [3]^render.Packed_Byte_Staging{&self.staging_vertex,&self.staging_attribute,&self.staging_index}
for owner in owners {
if owner.live || owner.array.live {
if !facade_ok { clean = false }
else if render.packed_byte_staging_destroy(api, owner) != .None { clean = false }
}
}
if self.workers != nil && !voxel.pool_destroy(&self.workers) { clean = false }
if !clean { self.last_error = -23; return -23 }
free_cpu_storage(self)
clear_front(self)
self.configured = false
self.anchor_valid = false
self.work_pending = false
self.scenario = {}
self.last_error = 0
return 0
}
// Count committed chunk states, including empty chunks and chunks awaiting replacement.
@(gododin)
voxel_world_get_chunks_resident :: proc(self: ^Voxel_World) -> i64 {
if self.table == nil { return 0 }
count := i64(0)
for index in 0..<TABLE_CAPACITY {
if self.table.used[index] && self.table.slots[index].committed_revision != 0 { count += 1 }
}
return count
}
// Count committed nonempty chunk meshes with live server RIDs.
@(gododin)
voxel_world_get_meshes_resident :: proc(self: ^Voxel_World) -> i64 {
if self.table == nil { return 0 }
count := i64(0)
for index in 0..<TABLE_CAPACITY {
if self.table.used[index] && self.table.slots[index].mesh_rid != (raw.RID{}) { count += 1 }
}
return count
}
// Count chunks awaiting generation, edit/revision completion or a matured LOD transition.
@(gododin)
voxel_world_get_unsettled_chunks :: proc(self: ^Voxel_World) -> i64 {
if self.table == nil { return 0 }
count := i64(0)
for index in 0..<TABLE_CAPACITY {
if !self.table.used[index] { continue }
state := &self.table.slots[index]
if state.kind == .Pending || state.request_id != 0 || state.dirty || state.lod_armed ||
state.pending_lod != state.lod || state.committed_revision != state.revision { count += 1 }
}
return count
}
// Report unsettled chunks, including dirty edits and LOD changes, for the scene UI.
@(gododin)
voxel_world_get_chunks_pending :: proc(self: ^Voxel_World) -> i64 { return voxel_world_get_unsettled_chunks(self) }
// Require full configured coverage and no dirty, queued, computing, leased or staged work.
@(gododin)
voxel_world_is_settled :: proc(self: ^Voxel_World) -> bool {
return self.configured && self.last_error == 0 && !self.front_valid && self.table != nil &&
i64(self.table.count) == (2*self.view_radius+1)*(2*self.view_radius+1) &&
voxel_world_get_unsettled_chunks(self) == 0 && voxel.pool_work_count(self.workers) == 0
}
// Count every retained mesh/instance RID, including a staged replacement.
@(gododin)
voxel_world_get_owned_rids :: proc(self: ^Voxel_World) -> i64 {
count := i64(0)
if self.front_mesh_rid != (raw.RID{}) { count += 1 }
if self.front_instance_rid != (raw.RID{}) { count += 1 }
if self.table != nil {
for index in 0..<TABLE_CAPACITY {
if !self.table.used[index] { continue }
if self.table.slots[index].mesh_rid != (raw.RID{}) { count += 1 }
if self.table.slots[index].instance_rid != (raw.RID{}) { count += 1 }
}
}
return count
}
// Includes fixed pool, table, validation and apron scratch; worker-owned bytes
// and Godot staging are separate owners, reported by their respective metrics.
@(gododin)
voxel_world_get_storage_bytes :: proc(self: ^Voxel_World) -> i64 {
bytes := i64(len(self.voxel_pool)*size_of(voxel.Chunk))
if self.table != nil { bytes += size_of(Chunk_Table) }
if self.scratch != nil { bytes += size_of(voxel.Chunk) }
if self.scratch_aprons != nil { bytes += size_of(voxel.Aprons) }
if self.verify_workspace != nil {
w := self.verify_workspace
bytes += i64(size_of(voxel.Mesh_Workspace)+len(w.vertices)+len(w.attributes)+len(w.indices))
}
return bytes
}
// Report retained engine staging extents, excluding transient replacement overlap and Host copies.
@(gododin)
voxel_world_get_staging_bytes :: proc(self: ^Voxel_World) -> i64 {
return i64(self.staging_vertex.length+self.staging_attribute.length+self.staging_index.length)
}
// Order-independent digest of the current voxel stores plus coordinates. This
// eval query computes actual stored bytes; it does not trust a cached counter.
@(gododin)
voxel_world_get_world_digest :: proc(self: ^Voxel_World) -> i64 {
if self.table == nil { return 0 }
hash: u64
for index in 0..<TABLE_CAPACITY {
if !self.table.used[index] || self.table.slots[index].kind == .Pending { continue }
state := &self.table.slots[index]
value := voxel.chunk_digest(state.voxels)
value = (value ~ u64(u32(state.coords[0]))) * 0x100000001b3
value = (value ~ u64(u32(state.coords[2]))) * 0x100000001b3
hash ~= value
}
return i64(hash)
}
// Count copied fronts whose staged bytes, counts and AABB matched the worker digest.
@(gododin)
voxel_world_get_staged_verified :: proc(self: ^Voxel_World) -> i64 { return self.staged_verified }
// Count actual set_voxel changes since configure; ordinary misses do not increment it.
@(gododin)
voxel_world_get_voxels_changed :: proc(self: ^Voxel_World) -> i64 { return self.voxels_changed }
// Count successful upload commits since configure, including remeshes and empty chunks.
@(gododin)
voxel_world_get_chunks_meshed :: proc(self: ^Voxel_World) -> i64 { return self.chunks_meshed }
// Count obsolete request/revision results rejected since configure.
@(gododin)
voxel_world_get_discarded_results :: proc(self: ^Voxel_World) -> i64 { return self.discarded_results }
// Count empty chunk results handled by the canonical mesher fast path since configure.
@(gododin)
voxel_world_get_mesh_skips :: proc(self: ^Voxel_World) -> i64 { return self.mesh_skips }
// Count committed replacements that changed an existing chunk detail level.
@(gododin)
voxel_world_get_lod_remeshes :: proc(self: ^Voxel_World) -> i64 { return self.lod_remeshes }
// Report the last two-second commit rate, returning zero after two idle seconds.
@(gododin)
voxel_world_get_meshes_per_second_milli :: proc(self: ^Voxel_World) -> i64 {
if time.tick_since(self.last_commit) >= 2*time.Second { return 0 }
return self.window_chunks_per_sec_milli
}
// Count begin_frame calls over this instance lifetime, across reconfiguration.
@(gododin)
voxel_world_get_frames :: proc(self: ^Voxel_World) -> i64 { return self.frame_counter }
// Report the latched failure code; successful shutdown/reconfiguration clears it.
@(gododin)
voxel_world_get_last_error :: proc(self: ^Voxel_World) -> i64 { return self.last_error }
// Report whether configuration completed and has not been shut down.
@(gododin)
voxel_world_is_configured :: proc(self: ^Voxel_World) -> bool { return self.configured }