ludic/packages/ludic.render3d/stream_baked.ludic
Orkuncakilkaya 8589a5a7b4 render3d: place_rec.ludic, the one encoder and decoder of a baked placement
prec_put / prec_get / prec_size (Physics' spec): PREC_FULL, 12 bytes, for trees, boulders and stones
(u16 x, z in 1/65536 of the chunk; u16 y in cm above y_base; u8 scale over the kind's lo..hi, yaw, seed,
wind), and PREC_PACKED, 7 bytes, for the stream kinds (56 bits, least significant first: x 12, z 12,
y 12 in cm, scale 6, yaw 6, seed 4, wind 4). An encode takes the cell a value falls in, a decode its
centre, so a round trip is stable; a record is read from a []byte at an offset, never a pointer.
stream_emit_baked and layer_chunk_put take (recs, at, fmt) and decode through it; the earlier sb7_*
pair is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 17:28:11 +03:00

27 lines
1.4 KiB
Text

# stream_baked.ludic — a stream filled from baked chunks instead of generated ones (plan 26 of
# maroon-lake). The bake stores every instance of a kind once per 64 m chunk, at full density and in a
# shuffled order, so a distance band draws a PREFIX of it: a nearer band holds everything a farther one
# does. A record's layout is place_rec.ludic's.
# the stream's cells laid on the baked chunks' grid: `size` metres from the corner (ox, oz)
export function stream_set_grid(s: Stream, ox: float, oz: float) -> void {
s.ox = ox
s.oz = oz
}
# the first `keep` of a chunk's `count` records (format fmt, place_rec.ludic) at byte `at` of recs
# emitted into the chunk being filled
export function stream_emit_baked(render3d_st: mut Render3dState, s: Stream, recs: []byte, at: int, fmt: int, count: int, keep: int, x0: float, z0: float, y_base: float, lo: float, hi: float) -> void {
let v = render3d_st.sb_rec
for i in 0 .. min(keep, count) {
prec_get(fmt, recs, at, i, x0, z0, s.size, y_base, lo, hi, v)
stream_emit(render3d_st, s, v[0], v[1], v[2], v[3], Math.atan2(v[4], v[5]), v[6], v[7])
}
}
# how many of a chunk's records a band keeps: all at band 0, then the share each band out had of the
# generated density (the caller's table), rounded so a band is never empty where the chunk is not
export function stream_band_keep(count: int, share: float) -> int {
if count == 0 { return 0 }
return max(1, min(count, int(float(count) * share + 0.5)))
}