# build.ludic - a kind's mesh: whole from its ground, or tile by tile (a map), or from a bake's file function nv_ground_ok(g: NavGround) -> bool { if g.v == null or g.t == null or g.area == null { return false } if len(g.v) < g.nv * 3 or len(g.t) < g.nt * 3 or len(g.area) < g.nt { return false } 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) } # 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(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(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 export function nav_tiled(nav_st: mut NavState, kind: int, ox: float, oz: float, tile: float, max_tiles: int, max_polys: int) -> bool { 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: 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(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) export function nav_polygons(nav_st: NavState, kind: int) -> int { let h = nv_mesh(nav_st, kind) if h == null { return 0 } return nvc_polys(h) } # a kind's mesh written to a file, and read back - through the asset pack when it is in one - into the # shim's own memory, which it frees once the tiles are made, so a map swap leaves nothing behind 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 } let n = nvc_save(h, null, 0) if n <= 0 { return false } let buf = buffer(n) if nvc_save(h, buf, n) != n { return false } return Fs.write_bytes(path, buf, n) } export function nav_load_file(nav_st: mut NavState, kind: int, path: string) -> bool { let f = file_open(path, "rb") if f == null { return false } file_seek(f, 0, 2) let n = file_tell(f) file_seek(f, 0, 0) let buf = nvc_stage(n) var got = 0 if buf != null { got = file_read(f, buf, n) } file_close(f) return nv_set(nav_st, kind, nvc_load_staged(buf, got)) }