feat(nav): 17.1/17.3 - ludic.nav over Recast & Detour v1.6.0 (zlib), built here from the pinned tag on the Mac and the PC (the DLL imports KERNEL32 alone): a navmesh per kind of walker from triangles with an area byte each and cylinders nothing stands in, saved and loaded as bytes; the nearest point, a path as corners (partial when the end cannot be reached), whether a straight line stays walkable, a cost per kind of ground. Tests on a hand-built meadow: round a post, over a ford, stopped at a bank, a saved mesh answering alike - Mac and PC

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-27 15:29:11 +03:00
parent e397e4eee9
commit 9b8606483d
17 changed files with 587 additions and 0 deletions

View file

@ -0,0 +1,37 @@
# build.ludic - a kind's mesh from triangles, or from a file a bake wrote
# v: nv points (x, y, z); t: nt triangles (three indices each); area: one byte per triangle, 0 not
# walkable, 1..62 a kind of ground; cyl: nc cylinders (x, y, z, r, h) nothing stands in
export function nav_build(nav_st: mut NavState, kind: int, v: []float, nv: int, t: []int, nt: int, area: []byte, cyl: []float, nc: int, c: NavConfig) -> bool {
if len(v) < nv * 3 or len(t) < nt * 3 or len(area) < nt or len(cyl) < nc * 5 { return false }
let cfg = floats(6)
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
return nv_set(nav_st, kind, nvc_build(v, nv, t, nt, area, cyl, nc, cfg))
}
# 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
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)
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 {
if not Fs.exists(path) { return false }
let buf = Fs.read_bytes(path)
if buf == null or len(buf) == 0 { return false }
return nv_set(nav_st, kind, nvc_load(buf, len(buf)))
}