feat(nav): nav_next_corner - a way's next corner read back as the nearest point is, so a walker's question and a goal share one answer and a game needs no state of its own for them
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
6ccbed923e
commit
de9c92b360
3 changed files with 23 additions and 0 deletions
|
|
@ -48,6 +48,7 @@ import "ludic.nav"
|
||||||
| `nav_save_file(kind, path)`, `nav_load_file(kind, path)`, `nav_reset()` | a baked mesh written and read; every mesh let go |
|
| `nav_save_file(kind, path)`, `nav_load_file(kind, path)`, `nav_reset()` | a baked mesh written and read; every mesh let go |
|
||||||
| `nav_nearest(kind, x, y, z) -> bool`, `nav_near_x/y/z()` | the nearest walkable point within a couple of metres |
|
| `nav_nearest(kind, x, y, z) -> bool`, `nav_near_x/y/z()` | the nearest walkable point within a couple of metres |
|
||||||
| `nav_path(kind, filter, sx, sy, sz, ex, ey, ez) -> int`, `nav_corners()`, `nav_corner_x/y/z(i)`, `nav_partial(kind)` | a way as corners |
|
| `nav_path(kind, filter, sx, sy, sz, ex, ey, ez) -> int`, `nav_corners()`, `nav_corner_x/y/z(i)`, `nav_partial(kind)` | a way as corners |
|
||||||
|
| `nav_next_corner(kind, filter, sx, sy, sz, ex, ey, ez) -> bool` | the next corner of that way, read back as the nearest point is (a walker's one question a frame) |
|
||||||
| `nav_straight(kind, filter, sx, sy, sz, ex, ez) -> bool` | does the straight line stay walkable |
|
| `nav_straight(kind, filter, sx, sy, sz, ex, ez) -> bool` | does the straight line stay walkable |
|
||||||
| `nav_random_near(kind, filter, x, y, z, r, seed) -> bool`, `nav_near_x/y/z()` | a reachable point about r away, from the caller's seed |
|
| `nav_random_near(kind, filter, x, y, z, r, seed) -> bool`, `nav_near_x/y/z()` | a reachable point about r away, from the caller's seed |
|
||||||
| `nav_area_cost(kind, filter, area, cost)` | how dear a kind of ground is to cross by that filter |
|
| `nav_area_cost(kind, filter, area, cost)` | how dear a kind of ground is to cross by that filter |
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,16 @@ export function nav_random_near(nav_st: NavState, kind: int, filter: int, x: flo
|
||||||
return nvc_random_near(h, filter, x, y, z, r, seed, nav_st.nv_near) == 1
|
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
|
# 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
|
# 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 {
|
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 {
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,18 @@ program NavTest {
|
||||||
expect_eq(nav_near_z(nav_st), z7)
|
expect_eq(nav_near_z(nav_st), z7)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "the next corner is the path's second, read back as the nearest point" (nav_st: mut NavState) {
|
||||||
|
expect(meadow(nav_st, NAV_PERSON, 0, true))
|
||||||
|
let n = nav_path(nav_st, NAV_PERSON, 0, 5.0, 0.0, 20.0, 35.0, 0.0, 20.0)
|
||||||
|
let cx = nav_corner_x(nav_st, 1)
|
||||||
|
let cz = nav_corner_z(nav_st, 1)
|
||||||
|
expect(n >= 3)
|
||||||
|
expect(nav_next_corner(nav_st, NAV_PERSON, 0, 5.0, 0.0, 20.0, 35.0, 0.0, 20.0))
|
||||||
|
expect_near(nav_near_x(nav_st), cx, 0.0001)
|
||||||
|
expect_near(nav_near_z(nav_st), cz, 0.0001)
|
||||||
|
expect(not nav_next_corner(nav_st, NAV_PERSON, 0, -50.0, 0.0, -50.0, 35.0, 0.0, 20.0))
|
||||||
|
}
|
||||||
|
|
||||||
test "a filter that dislikes a band of thicket walks round it; the plain one goes through" (nav_st: mut NavState) {
|
test "a filter that dislikes a band of thicket walks round it; the plain one goes through" (nav_st: mut NavState) {
|
||||||
expect(meadow(nav_st, NAV_PERSON, 3, false))
|
expect(meadow(nav_st, NAV_PERSON, 3, false))
|
||||||
nav_area_cost(nav_st, NAV_PERSON, 1, 2, 20.0)
|
nav_area_cost(nav_st, NAV_PERSON, 1, 2, 20.0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue