ludic/packages/ludic.nav/crowd.ludic

76 lines
3.9 KiB
Text

# crowd.ludic - a crowd per kind of walker (phase 18): many walkers steered along their paths at
# once, each kept clear of the others. The mechanic decides where and how fast; the crowd moves.
# a crowd on kind's mesh for at most max walkers, none wider than max_radius; false with no mesh
export function nav_crowd_start(nav_st: mut NavState, kind: int, max: int, max_radius: float) -> bool {
let h = nv_mesh(nav_st, kind)
if h == null { return false }
nv_crowd_drop(nav_st, kind)
nav_st.nv_crowds[kind] = nvc_crowd_new(h, max, max_radius)
return nav_st.nv_crowds[kind] != null
}
function nv_crowd(nav_st: NavState, kind: int) -> pointer {
if kind < 0 or kind >= NAV_KINDS { return null }
return nav_st.nv_crowds[kind]
}
# let kind's crowd go (before its mesh, which it walks on)
function nv_crowd_drop(nav_st: mut NavState, kind: int) -> void {
if kind < 0 or kind >= NAV_KINDS or nav_st.nv_crowds[kind] == null { return }
nvc_crowd_free(nav_st.nv_crowds[kind])
nav_st.nv_crowds[kind] = null
}
# a walker at (x, y, z) with its width, height, top speed, taste and how hard it keeps its distance
# from the others (2 an ordinary walker): its index, or -1
@creates(NavAgent)
export function nav_crowd_add(nav_st: NavState, kind: int, x: float, y: float, z: float, radius: float, height: float, speed: float, filter: int, separation: float) -> int {
let c = nv_crowd(nav_st, kind)
if c == null { return -1 }
return nvc_crowd_add(c, x, y, z, radius, height, speed, filter, separation)
}
# a walker the crowd avoids but never moves (a player): put where it is each frame with nav_crowd_place
@creates(NavAgent)
export function nav_crowd_add_fixed(nav_st: NavState, kind: int, x: float, y: float, z: float, radius: float, height: float) -> int {
let c = nv_crowd(nav_st, kind)
if c == null { return -1 }
return nvc_crowd_add_fixed(c, x, y, z, radius, height)
}
# walker i put at (x, y, z) going (vx, vz); false off the mesh
export function nav_crowd_place(nav_st: NavState, kind: int, i: int, x: float, y: float, z: float, vx: float, vz: float) -> bool {
let c = nv_crowd(nav_st, kind)
return c != null and i >= 0 and nvc_crowd_place(c, i, x, y, z, vx, vz) == 1
}
@releases(NavAgent)
export function nav_crowd_remove(nav_st: NavState, kind: int, i: int) -> void {
let c = nv_crowd(nav_st, kind)
if c != null and i >= 0 { nvc_crowd_remove(c, i) }
}
# where walker i is going, snapped to the mesh; false off it
export function nav_crowd_target(nav_st: NavState, kind: int, i: int, x: float, y: float, z: float) -> bool {
let c = nv_crowd(nav_st, kind)
return c != null and i >= 0 and nvc_crowd_target(c, i, x, y, z) == 1
}
export function nav_crowd_speed(nav_st: NavState, kind: int, i: int, speed: float) -> void {
let c = nv_crowd(nav_st, kind)
if c != null and i >= 0 { nvc_crowd_speed(c, i, speed) }
}
# every crowd one step on
export function nav_crowd_step(nav_st: NavState, dt: float) -> void {
for k in 0 .. NAV_KINDS { if nav_st.nv_crowds[k] != null { nvc_crowd_update(nav_st.nv_crowds[k], dt) } }
}
# walker i read into nav_agent_*; false when there is none
export function nav_crowd_read(nav_st: NavState, kind: int, i: int) -> bool {
let c = nv_crowd(nav_st, kind)
return c != null and i >= 0 and nvc_crowd_read(c, i, nav_st.nv_agent) == 1
}
export function nav_agent_x(nav_st: NavState) -> float { return nav_st.nv_agent[0] }
export function nav_agent_y(nav_st: NavState) -> float { return nav_st.nv_agent[1] }
export function nav_agent_z(nav_st: NavState) -> float { return nav_st.nv_agent[2] }
export function nav_agent_vx(nav_st: NavState) -> float { return nav_st.nv_agent[3] }
export function nav_agent_vz(nav_st: NavState) -> float { return nav_st.nv_agent[5] }
# microseconds the crowds have spent stepping
export function nav_crowd_us(nav_st: NavState) -> int {
var us = 0
for k in 0 .. NAV_KINDS { if nav_st.nv_crowds[k] != null { us += nvc_crowd_us(nav_st.nv_crowds[k]) } }
return us
}