nav_us() gives the microseconds spent in nav_path across the loaded meshes. The shim times each path with the OS's monotonic clock (clock_gettime, or QueryPerformanceCounter from KERNEL32), so the DLL still needs no C++ runtime. Both libraries are rebuilt, and 13 tests pass on the Mac and the PC. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
4.1 KiB
Text
79 lines
4.1 KiB
Text
# 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 point about r from (x, y, z) that a walker standing there can reach (a wander's goal), read back
|
|
# as the nearest is; the seed is the caller's dice, so the same seed is the same point everywhere
|
|
export function nav_random_near(nav_st: NavState, kind: int, filter: int, x: float, y: float, z: float, r: float, seed: int) -> bool {
|
|
let h = nv_mesh(nav_st, kind)
|
|
if h == null { return false }
|
|
return nvc_random_near(h, filter, x, y, z, r, seed, nav_st.nv_near) == 1
|
|
}
|
|
|
|
# the next corner of the way from (sx, sy, sz) toward (ex, ey, ez) - the first after the start - read
|
|
# back as the nearest point is (nav_near_x / _z), so a walker's question and a goal share one answer
|
|
export function nav_next_corner(nav_st: mut NavState, kind: int, filter: int, sx: float, sy: float, sz: float, ex: float, ey: float, ez: float) -> bool {
|
|
if nav_path(nav_st, kind, filter, sx, sy, sz, ex, ey, ez) < 2 { return false }
|
|
nav_st.nv_near[0] = nav_st.nv_out[3]
|
|
nav_st.nv_near[1] = nav_st.nv_out[4]
|
|
nav_st.nv_near[2] = nav_st.nv_out[5]
|
|
return true
|
|
}
|
|
|
|
# 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, filter: 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, filter, sx, sy, sz, ex, ey, ez, nav_st.nv_out, NAV_CORNERS)
|
|
nav_st.nv_asked += 1
|
|
if n > 0 { nav_st.nv_count = n }
|
|
if n >= 2 { nav_st.nv_found += 1 }
|
|
if n > 0 and nvc_partial(h) == 1 { nav_st.nv_short += 1 }
|
|
return n
|
|
}
|
|
|
|
# how many paths were asked for, found, and cut short (the end out of reach) since the meshes loaded
|
|
export function nav_asked(nav_st: NavState) -> int { return nav_st.nv_asked }
|
|
export function nav_found(nav_st: NavState) -> int { return nav_st.nv_found }
|
|
export function nav_short(nav_st: NavState) -> int { return nav_st.nv_short }
|
|
# microseconds spent finding those paths, over every loaded mesh
|
|
export function nav_us(nav_st: NavState) -> int {
|
|
var us = 0
|
|
for k in 0 .. NAV_KINDS {
|
|
let h = nv_mesh(nav_st, k)
|
|
if h != null { us += nvc_us(h) }
|
|
}
|
|
return us
|
|
}
|
|
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, filter: 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, filter, sx, sy, sz, ex, ez) == 1
|
|
}
|
|
|
|
# how dear a kind of ground is to cross by filter f (1 is plain; a town cheaper for a person, scree
|
|
# dearer for a deer): a query names the filter it walks by, 0 .. NAV_FILTERS - 1
|
|
export function nav_area_cost(nav_st: NavState, kind: int, filter: int, area: int, cost: float) -> void {
|
|
let h = nv_mesh(nav_st, kind)
|
|
if h != null { nvc_area_cost(h, filter, area, cost) }
|
|
}
|