ludic/packages/ludic.render3d/terrain_tiles_cut.ludic

73 lines
4.1 KiB
Text

# terrain_tiles_cut.ludic — the whole height field and photograph written out tile by tile, once a map is
# made, and let go. The file is written fresh every time a map is made and never read by another
# start, so no older generator's tiles are ever read; its header goes in last, so a start that died
# writing it leaves a file whose magic is not there rather than one that looks whole.
const TT_VERSION: int = 1
const TT_HEAD: int = 64 # bytes: 16 words
@alloc_ok("a map being made: its tiles' file and their pools, once, not a frame")
function terrain_tiles_cut(render3d_st: mut Render3dState) -> void {
if render3d_st.tt_baked or render3d_st.tt_dir == "" or render3d_st.ter_heights == null { return }
let t0 = gl_now_us()
tt_close(render3d_st)
let path = `{render3d_st.tt_dir}/{render3d_st.tt_key}.tiles`
Fs.mkdir(render3d_st.tt_dir)
let f = file_open(path, "wb")
if f == null { tt_say_no_file(path); return }
# the check compares the tiles with the whole copy, so it runs on the quantized copy the write leaves
let bytes = ltt2_write(render3d_st, f, 0)
file_close(f)
if not tt_open_ltt2(render3d_st, path, 0) { tt_say_no_file(path); return }
if r3d_env_has(render3d_st, "R3D_TT_CHECK") { tt_check(render3d_st) }
ltt2_gpu_coarse(render3d_st)
tt_say_cut(path, bytes, (gl_now_us() - t0) / 1000)
}
# the last map's file let go (a world swap, or the map made again)
function tt_close(render3d_st: mut Render3dState) -> void {
if render3d_st.tt_file != null { file_close(render3d_st.tt_file); render3d_st.tt_file = null }
tf_forget(render3d_st)
}
function tt_say_no_file(path: string) -> void { print(`r3d: terrain: cannot write {path}; the whole height field stays in memory`) }
function tt_say_cut(path: string, bytes: int, ms: int) -> void { print(`r3d: terrain: tiles written to {path} ({bytes / 1048576} MB, {ms} ms); the whole copies kept until terrain_tiles_build_done`) }
# R3D_TT_CHECK: the tiles' answer against the whole copy's at 4000 points (must be exact), and the
# coarse level's (what terrain_height_near falls back to) - while both are still here
@alloc_ok("a developer check, once, under R3D_TT_CHECK")
function tt_check(render3d_st: mut Render3dState) -> void {
var worst = 0.0
var worst_c = 0.0
var seed = 12345
let half = float(render3d_st.TERRAIN_HALF) * 0.98
for k in 0 .. 4000 {
seed = (seed * 1103515245 + 12345) & 0x7FFFFFFF
let x = render3d_st.ter_ox + (float(seed % 100000) / 50000.0 - 1.0) * half
seed = (seed * 1103515245 + 12345) & 0x7FFFFFFF
let z = render3d_st.ter_oz + (float(seed % 100000) / 50000.0 - 1.0) * half
let whole = terrain_height(render3d_st, x, z)
let keep = render3d_st.ter_heights
render3d_st.ter_heights = null
let tiled = terrain_height(render3d_st, x, z)
let scale = float(TERRAIN_RES) / float(render3d_st.TERRAIN_HALF * 2)
let coarse = tt_coarse_at(render3d_st, (x - render3d_st.ter_ox + float(render3d_st.TERRAIN_HALF)) * scale, (z - render3d_st.ter_oz + float(render3d_st.TERRAIN_HALF)) * scale)
render3d_st.ter_heights = keep
worst = Math.max(worst, Math.abs(tiled - whole))
worst_c = Math.max(worst_c, Math.abs(coarse - whole))
}
print(`r3d: terrain: tiles vs the whole copy at 4000 points: worst {worst} m; the coarse level: worst {worst_c} m`)
}
# The world's build places trees, rocks and cover over the whole map, asking exact heights
# everywhere before any ring exists: through the tiles that read the file some 25 000 times. So the
# whole copies stay through the build, and the game lets them go here when it is done (the end of
# world_things, and after a swap's terrain_reload). Queries answer the same before and after.
export function terrain_tiles_build_done(render3d_st: mut Render3dState) -> void {
if render3d_st.tt_file == null { return }
if render3d_st.ter_heights != null { free(render3d_st.ter_heights); render3d_st.ter_heights = null }
if render3d_st.ter_ortho_px != null { free(render3d_st.ter_ortho_px); render3d_st.ter_ortho_px = null }
render3d_st.tt_frame_reads = 0
tt_say_done()
}
function tt_say_done() -> void { print("r3d: terrain: the world is built; the whole height and photograph copies let go, tiles from here") }