From 82de673ce7a4eb4b5f981c248fc0d6acacb32ee6 Mon Sep 17 00:00:00 2001 From: Orkuncakilkaya Date: Tue, 29 Sep 2026 17:34:16 +0300 Subject: [PATCH] render3d: stream_capture runs the game's own fill for a chunk outside any frame, for the bake stream_capture(s, cx, cz, band) points the stream at a chunk of its own (made on the first capture), calls the registered r3d_stream_fill for that cell and band, and returns how many instances it emitted; stream_captured(i, k) reads them from stream_scratch. Build-time only; nothing in a frame calls it. Co-Authored-By: Claude Opus 5.5 --- packages/ludic.render3d/env.ludic | 1 + packages/ludic.render3d/stream_baked.ludic | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/packages/ludic.render3d/env.ludic b/packages/ludic.render3d/env.ludic index 1e0a0e49..7431de42 100644 --- a/packages/ludic.render3d/env.ludic +++ b/packages/ludic.render3d/env.ludic @@ -829,6 +829,7 @@ export state Render3dState { ter_ortho_tex: int = 0 # a photograph of the same window, draped with distance ter_carpet: int = 0 # the distant-grass carpet (carpet_bake), 0 = none ter_shadow_tex: int = 0 # height-field sun shadow: R32F, the lowest lit height + stream_capture_c: Chunk = null # the bake's capture chunk (stream_baked.ludic) sb_rec: floats = floats(8) # one decoded baked record, reused (stream_baked.ludic) tt_dir: string = "" # terrain_tiles_to: where a map's tiles are written ("" keeps the whole copies) tt_key: string = "" diff --git a/packages/ludic.render3d/stream_baked.ludic b/packages/ludic.render3d/stream_baked.ludic index aadafa51..5190b6ae 100644 --- a/packages/ludic.render3d/stream_baked.ludic +++ b/packages/ludic.render3d/stream_baked.ludic @@ -25,3 +25,22 @@ 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))) } + +# ---- the bake's capture ----------------------------------------------------------------------- +# The game's own fill for chunk (cx, cz) at a band, run outside any frame into a chunk of its own: what +# the bake records. The instances are left in stream_scratch (INST_FLOATS each: x, y, z, scale, sin yaw, +# cos yaw, seed, wind; stream_captured reads them) and their count is returned. Build-time only. +@alloc_ok("a bake's capture chunk, made on the first capture") +export function stream_capture(render3d_st: mut Render3dState, s: Stream, cx: int, cz: int, band: int) -> int { + if render3d_st.stream_scratch == null { render3d_st.stream_scratch = floats(STREAM_CHUNK_MAX * INST_FLOATS) } + if render3d_st.stream_capture_c == null { render3d_st.stream_capture_c = new Chunk } + let c = render3d_st.stream_capture_c + c.key = stream_key(cx, cz, band); c.count = 0; c.off = -1; c.used = 0 + s.cur = c + r3d_stream_fill(render3d_st, s, cx, cz, band) + s.cur = null + return c.count +} + +# field k (0 .. INST_FLOATS - 1) of captured instance i +export function stream_captured(render3d_st: Render3dState, i: int, k: int) -> float { return render3d_st.stream_scratch[i * INST_FLOATS + k] }