fix(nav): nothing allocated per build - the configuration and the empty lists live in NavState, because Ludic never gives an allocation back and a map is thousands of tile builds; nav_drop lets one kind's mesh go; the detail mesh's spacing is a NavConfig setting held to Recast's own floor of 0.9 m (0 took a 40 m test meadow to 3.5 GB)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
e6893f58be
commit
950d3134f2
4 changed files with 22 additions and 11 deletions
|
|
@ -5,25 +5,28 @@ function nv_ground_ok(g: NavGround) -> bool {
|
|||
if g.nc > 0 and (g.cyl == null or len(g.cyl) < g.nc * 5) { return false }
|
||||
return g.nf == 0 or (g.foot != null and len(g.foot) >= g.nf)
|
||||
}
|
||||
function nv_cfg(c: NavConfig) -> []float {
|
||||
let cfg = floats(6)
|
||||
# the configuration in the state's own buffer: a map is thousands of tile builds, and nothing
|
||||
# allocated per build is ever given back
|
||||
function nv_cfg(nav_st: mut NavState, c: NavConfig) -> []float {
|
||||
let cfg = nav_st.nv_cfg
|
||||
cfg[0] = c.cell
|
||||
cfg[1] = c.cell_h
|
||||
cfg[2] = c.height
|
||||
cfg[3] = c.radius
|
||||
cfg[4] = c.climb
|
||||
cfg[5] = c.slope
|
||||
cfg[6] = Math.max(c.detail, 0.9)
|
||||
return cfg
|
||||
}
|
||||
function nv_or_none(xs: []float) -> []float {
|
||||
if xs == null { return floats(1) }
|
||||
function nv_or_none(nav_st: NavState, xs: []float, n: int) -> []float {
|
||||
if xs == null or n == 0 { return nav_st.nv_empty }
|
||||
return xs
|
||||
}
|
||||
|
||||
# one mesh over the whole of g
|
||||
export function nav_build(nav_st: mut NavState, kind: int, g: NavGround, c: NavConfig) -> bool {
|
||||
if not nv_ground_ok(g) { return false }
|
||||
return nv_set(nav_st, kind, nvc_build(g.v, g.nv, g.t, g.nt, g.area, nv_or_none(g.cyl), g.nc, nv_or_none(g.foot), g.nf, nv_cfg(c)))
|
||||
return nv_set(nav_st, kind, nvc_build(g.v, g.nv, g.t, g.nt, g.area, nv_or_none(nav_st, g.cyl, g.nc), g.nc, nv_or_none(nav_st, g.foot, g.nf), g.nf, nv_cfg(nav_st, c)))
|
||||
}
|
||||
|
||||
# an empty mesh of square tiles `tile` metres across from (ox, oz), for a map built a tile at a time
|
||||
|
|
@ -31,10 +34,10 @@ export function nav_tiled(nav_st: mut NavState, kind: int, ox: float, oz: float,
|
|||
return nv_set(nav_st, kind, nvc_tiled(ox, oz, tile, max_tiles, max_polys))
|
||||
}
|
||||
# tile (tx, tz) from ground g covering it and a few metres round it: its polygons, 0 none, -1 failed
|
||||
export function nav_tile_build(nav_st: NavState, kind: int, tx: int, tz: int, g: NavGround, c: NavConfig) -> int {
|
||||
export function nav_tile_build(nav_st: mut NavState, kind: int, tx: int, tz: int, g: NavGround, c: NavConfig) -> int {
|
||||
let h = nv_mesh(nav_st, kind)
|
||||
if h == null or not nv_ground_ok(g) { return -1 }
|
||||
return nvc_tile_build(h, tx, tz, g.v, g.nv, g.t, g.nt, g.area, nv_or_none(g.cyl), g.nc, nv_or_none(g.foot), g.nf, nv_cfg(c))
|
||||
return nvc_tile_build(h, tx, tz, g.v, g.nv, g.t, g.nt, g.area, nv_or_none(nav_st, g.cyl, g.nc), g.nc, nv_or_none(nav_st, g.foot, g.nf), g.nf, nv_cfg(nav_st, c))
|
||||
}
|
||||
|
||||
# the polygons a kind's mesh has (0: none)
|
||||
|
|
@ -44,7 +47,8 @@ export function nav_polygons(nav_st: NavState, kind: int) -> int {
|
|||
return nvc_polys(h)
|
||||
}
|
||||
|
||||
# a kind's mesh written to a file, and read back
|
||||
# a kind's mesh written to a file, and read back. Reading holds the file's bytes for good (a slice
|
||||
# is never given back), so a mesh is loaded once per map, never per frame
|
||||
export function nav_save_file(nav_st: NavState, kind: int, path: string) -> bool {
|
||||
let h = nv_mesh(nav_st, kind)
|
||||
if h == null { return false }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue