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,43 @@
# query.ludic - what a kind's mesh answers. A path is its corners, read back one at a time
# (nav_corner_x / _y / _z); the nearest point the same (nav_near_x / _y / _z)
# the nearest walkable point to (x, y, z) within a couple of metres; false when there is none
export function nav_nearest(nav_st: NavState, kind: int, x: float, y: float, z: float) -> bool {
let h = nv_mesh(nav_st, kind)
if h == null { return false }
return nvc_nearest(h, x, y, z, nav_st.nv_near) == 1
}
export function nav_near_x(nav_st: NavState) -> float { return nav_st.nv_near[0] }
export function nav_near_y(nav_st: NavState) -> float { return nav_st.nv_near[1] }
export function nav_near_z(nav_st: NavState) -> float { return nav_st.nv_near[2] }
# a way from one point to another: its corners, first the start and last the end (or as near the end
# as the mesh reaches - nav_partial says which); -1 when either end is off the mesh
export function nav_path(nav_st: mut NavState, kind: int, sx: float, sy: float, sz: float, ex: float, ey: float, ez: float) -> int {
let h = nv_mesh(nav_st, kind)
nav_st.nv_count = 0
if h == null { return -1 }
let n = nvc_path(h, sx, sy, sz, ex, ey, ez, nav_st.nv_out, NAV_CORNERS)
if n > 0 { nav_st.nv_count = n }
return n
}
export function nav_partial(nav_st: NavState, kind: int) -> bool {
let h = nv_mesh(nav_st, kind)
return h != null and nvc_partial(h) == 1
}
export function nav_corners(nav_st: NavState) -> int { return nav_st.nv_count }
export function nav_corner_x(nav_st: NavState, i: int) -> float { return nav_st.nv_out[i * 3] }
export function nav_corner_y(nav_st: NavState, i: int) -> float { return nav_st.nv_out[i * 3 + 1] }
export function nav_corner_z(nav_st: NavState, i: int) -> float { return nav_st.nv_out[i * 3 + 2] }
# does the straight line from (sx, sy, sz) to (ex, ez) stay walkable?
export function nav_straight(nav_st: NavState, kind: int, sx: float, sy: float, sz: float, ex: float, ez: float) -> bool {
let h = nv_mesh(nav_st, kind)
return h != null and nvc_raycast(h, sx, sy, sz, ex, ez) == 1
}
# how dear a kind of ground is to cross (1 is plain; a trail cheaper, scree dearer)
export function nav_area_cost(nav_st: NavState, kind: int, area: int, cost: float) -> void {
let h = nv_mesh(nav_st, kind)
if h != null { nvc_area_cost(h, area, cost) }
}