Merge commit '1fd87c7' into lang/foundations
This commit is contained in:
commit
104ba696c2
3 changed files with 46 additions and 7 deletions
|
|
@ -47,6 +47,7 @@ import "fog_casters.ludic"
|
||||||
import "fog_impostors.ludic"
|
import "fog_impostors.ludic"
|
||||||
import "actor.ludic"
|
import "actor.ludic"
|
||||||
import "stream.ludic"
|
import "stream.ludic"
|
||||||
|
import "stream_baked.ludic"
|
||||||
import "fog_streams.ludic"
|
import "fog_streams.ludic"
|
||||||
import "grass.ludic"
|
import "grass.ludic"
|
||||||
import "grass_gpu.ludic"
|
import "grass_gpu.ludic"
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,9 @@ property Stream {
|
||||||
arena: words, # every kept chunk's instances, in the order of `chunks`
|
arena: words, # every kept chunk's instances, in the order of `chunks`
|
||||||
top: int = 0, # words of the arena in use
|
top: int = 0, # words of the arena in use
|
||||||
spare: []Chunk, # records not in use: all of them are made with the stream
|
spare: []Chunk, # records not in use: all of them are made with the stream
|
||||||
cap0: int = 0 # the layer's capacity for the whole reach (fog_streams.ludic)
|
cap0: int = 0, # the layer's capacity for the whole reach (fog_streams.ludic)
|
||||||
|
ox: float = 0.0, # the grid's corner: 0 for cells from world zero, the terrain's for baked chunks
|
||||||
|
oz: float = 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
# microseconds spent per frame, split so the hitch can be attributed (R3D_PROF=1)
|
# microseconds spent per frame, split so the hitch can be attributed (R3D_PROF=1)
|
||||||
|
|
@ -220,8 +222,8 @@ function stream_evict(render3d_st: mut Render3dState, s: Stream) -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
function stream_update(render3d_st: mut Render3dState, s: Stream, cam_x: float, cam_z: float) -> void {
|
function stream_update(render3d_st: mut Render3dState, s: Stream, cam_x: float, cam_z: float) -> void {
|
||||||
let ccx = int(Math.floor(cam_x / s.size))
|
let ccx = int(Math.floor((cam_x - s.ox) / s.size))
|
||||||
let ccz = int(Math.floor(cam_z / s.size))
|
let ccz = int(Math.floor((cam_z - s.oz) / s.size))
|
||||||
if ccx == s.last_cx and ccz == s.last_cz and not s.pending and s.view_gen == render3d_st.sc_view_gen { return }
|
if ccx == s.last_cx and ccz == s.last_cz and not s.pending and s.view_gen == render3d_st.sc_view_gen { return }
|
||||||
let first = s.last_cx == 999999
|
let first = s.last_cx == 999999
|
||||||
s.view_gen = render3d_st.sc_view_gen
|
s.view_gen = render3d_st.sc_view_gen
|
||||||
|
|
@ -244,8 +246,8 @@ function stream_update(render3d_st: mut Render3dState, s: Stream, cam_x: float,
|
||||||
while cx <= ccx + ring {
|
while cx <= ccx + ring {
|
||||||
let edge = (cz == ccz - ring) or (cz == ccz + ring) or (cx == ccx - ring) or (cx == ccx + ring)
|
let edge = (cz == ccz - ring) or (cz == ccz + ring) or (cx == ccx - ring) or (cx == ccx + ring)
|
||||||
if edge {
|
if edge {
|
||||||
let wx = (float(cx) + 0.5) * s.size
|
let wx = s.ox + (float(cx) + 0.5) * s.size
|
||||||
let wz = (float(cz) + 0.5) * s.size
|
let wz = s.oz + (float(cz) + 0.5) * s.size
|
||||||
let dx = wx - cam_x; let dz = wz - cam_z
|
let dx = wx - cam_x; let dz = wz - cam_z
|
||||||
let d = Math.sqrt(dx * dx + dz * dz)
|
let d = Math.sqrt(dx * dx + dz * dz)
|
||||||
let band = stream_band(s, d)
|
let band = stream_band(s, d)
|
||||||
|
|
@ -323,8 +325,8 @@ function stream_update(render3d_st: mut Render3dState, s: Stream, cam_x: float,
|
||||||
# whose short shadows still fall inside it.
|
# whose short shadows still fall inside it.
|
||||||
function stream_chunk_visible(render3d_st: Render3dState, s: Stream, cx: int, cz: int, c: Chunk) -> bool {
|
function stream_chunk_visible(render3d_st: Render3dState, s: Stream, cx: int, cz: int, c: Chunk) -> bool {
|
||||||
let half = s.size * 0.5
|
let half = s.size * 0.5
|
||||||
let wx = float(cx) * s.size + half
|
let wx = s.ox + float(cx) * s.size + half
|
||||||
let wz = float(cz) * s.size + half
|
let wz = s.oz + float(cz) * s.size + half
|
||||||
let hy = (c.ymax - c.ymin) * 0.5
|
let hy = (c.ymax - c.ymin) * 0.5
|
||||||
let cy = c.ymin + hy
|
let cy = c.ymin + hy
|
||||||
let r = Math.sqrt(half * half * 2.0 + hy * hy) + 8.0
|
let r = Math.sqrt(half * half * 2.0 + hy * hy) + 8.0
|
||||||
|
|
|
||||||
36
packages/ludic.render3d/stream_baked.ludic
Normal file
36
packages/ludic.render3d/stream_baked.ludic
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# 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 is 12 bytes: u16 x, u16 z (1/65536 of the chunk), u16 y (cm above the chunk's y_base),
|
||||||
|
# u8 scale (lo..hi, the kind's range), u8 yaw, u8 seed, u8 wind.
|
||||||
|
|
||||||
|
const SB_REC: int = 12
|
||||||
|
|
||||||
|
# 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` records of a chunk emitted into the chunk being filled (inside r3d_stream_fill)
|
||||||
|
export function stream_emit_baked(render3d_st: mut Render3dState, s: Stream, recs: pointer, count: int, keep: int, x0: float, z0: float, y_base: float, lo: float, hi: float) -> void {
|
||||||
|
let n = min(keep, count)
|
||||||
|
let span = s.size / 65536.0
|
||||||
|
let sr = (hi - lo) / 255.0
|
||||||
|
for i in 0 .. n {
|
||||||
|
let o = i * SB_REC
|
||||||
|
let x = x0 + float(recs[o] | (recs[o + 1] << 8)) * span
|
||||||
|
let z = z0 + float(recs[o + 2] | (recs[o + 3] << 8)) * span
|
||||||
|
let y = y_base + float(recs[o + 4] | (recs[o + 5] << 8)) * 0.01
|
||||||
|
let scale = lo + float(recs[o + 6]) * sr
|
||||||
|
let yaw = float(recs[o + 7]) * (2.0 * PI / 256.0)
|
||||||
|
stream_emit(render3d_st, s, x, y, z, scale, yaw, float(recs[o + 8]) / 255.0, float(recs[o + 9]) / 255.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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)))
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue