diff --git a/packages/ludic.nav/README.md b/packages/ludic.nav/README.md index 59c4541d..a873c946 100644 --- a/packages/ludic.nav/README.md +++ b/packages/ludic.nav/README.md @@ -75,7 +75,7 @@ the PC (Git Bash, the LLVM installer's clang). `native/LICENSE-recastnavigation` ## Crowds (phase 18) `nav_crowd_start(kind, max, max_radius)` puts a DetourCrowd on a kind's mesh, with the mesh's tastes as -its filters. `nav_crowd_add(kind, x, y, z, radius, height, speed, filter)` adds a walker (snapped to +its filters. `nav_crowd_add(kind, x, y, z, radius, height, speed, filter, separation)` adds a walker (snapped to the mesh, -1 off it), `nav_crowd_target` and `nav_crowd_speed` say where and how fast, and `nav_crowd_step(dt)` steps every crowd. `nav_crowd_read` puts a walker into `nav_agent_x/y/z/vx/vz`, and `nav_crowd_us()` is what the stepping has cost. The mechanic decides and the crowd moves, and diff --git a/packages/ludic.nav/crowd.ludic b/packages/ludic.nav/crowd.ludic index f0930676..519ead41 100644 --- a/packages/ludic.nav/crowd.ludic +++ b/packages/ludic.nav/crowd.ludic @@ -20,11 +20,12 @@ function nv_crowd_drop(nav_st: mut NavState, kind: int) -> void { nav_st.nv_crowds[kind] = null } -# a walker at (x, y, z) with its width, height, top speed and taste: its index, or -1 -export function nav_crowd_add(nav_st: NavState, kind: int, x: float, y: float, z: float, radius: float, height: float, speed: float, filter: int) -> int { +# 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 +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) + return nvc_crowd_add(c, x, y, z, radius, height, speed, filter, separation) } export function nav_crowd_remove(nav_st: NavState, kind: int, i: int) -> void { let c = nv_crowd(nav_st, kind) diff --git a/packages/ludic.nav/lib/macos-arm64/libludicnav.dylib b/packages/ludic.nav/lib/macos-arm64/libludicnav.dylib index 214b2e5a..474332e5 100755 --- a/packages/ludic.nav/lib/macos-arm64/libludicnav.dylib +++ b/packages/ludic.nav/lib/macos-arm64/libludicnav.dylib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0994fc60f85002f8c95ed2a8a75886a94ce8abb46950248f8a6fa42a81bf3538 +oid sha256:82c2b394bc9a6640055be28ce5172057b665759828e499d057df0cffe94aa05a size 198320 diff --git a/packages/ludic.nav/lib/windows-x64/ludicnav.dll b/packages/ludic.nav/lib/windows-x64/ludicnav.dll index b0c6761f..253cf5f0 100644 --- a/packages/ludic.nav/lib/windows-x64/ludicnav.dll +++ b/packages/ludic.nav/lib/windows-x64/ludicnav.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7626d464f2588054610dc27a655d67acf66649ea120120705cdf5f1fca5fe34 +oid sha256:1a0eea4d94669a548e4874c07bc23caa321bf891f7a724331163e64f10006099 size 374784 diff --git a/packages/ludic.nav/native.ludic b/packages/ludic.nav/native.ludic index 7414cfb5..0f1db0f2 100644 --- a/packages/ludic.nav/native.ludic +++ b/packages/ludic.nav/native.ludic @@ -17,7 +17,7 @@ extern function nvc_random_near(h: pointer, f: int, x: float, y: float, z: float extern function nvc_stage(size: int) -> pointer = "nav_stage" extern function nvc_crowd_new(h: pointer, max: int, max_radius: float) -> pointer = "nav_crowd_new" extern function nvc_crowd_free(c: pointer) -> void = "nav_crowd_free" -extern function nvc_crowd_add(c: pointer, x: float, y: float, z: float, radius: float, height: float, speed: float, filter: int) -> int = "nav_crowd_add" +extern function nvc_crowd_add(c: pointer, x: float, y: float, z: float, radius: float, height: float, speed: float, filter: int, separation: float) -> int = "nav_crowd_add" extern function nvc_crowd_remove(c: pointer, i: int) -> void = "nav_crowd_remove" extern function nvc_crowd_target(c: pointer, i: int, x: float, y: float, z: float) -> int = "nav_crowd_target" extern function nvc_crowd_speed(c: pointer, i: int, speed: float) -> void = "nav_crowd_speed" diff --git a/packages/ludic.nav/native/shim/nav_crowd.inl b/packages/ludic.nav/native/shim/nav_crowd.inl index 7c6585b9..178df676 100644 --- a/packages/ludic.nav/native/shim/nav_crowd.inl +++ b/packages/ludic.nav/native/shim/nav_crowd.inl @@ -24,8 +24,9 @@ NAV_SHIM void nav_crowd_free(void *p) { delete c; } -// a walker at (x, y, z): its index, or -1 when the crowd is full or the point is off the mesh -NAV_SHIM int nav_crowd_add(void *p, float x, float y, float z, float radius, float height, float speed, int filter) { +// a walker at (x, y, z): its index, or -1 when the crowd is full or the point is off the mesh; +// separation is how hard it keeps its distance (a herd animal more than a loner) +NAV_SHIM int nav_crowd_add(void *p, float x, float y, float z, float radius, float height, float speed, int filter, float separation) { Crowd *c = static_cast(p); dtCrowdAgentParams ap; memset(&ap, 0, sizeof(ap)); @@ -35,7 +36,7 @@ NAV_SHIM int nav_crowd_add(void *p, float x, float y, float z, float radius, flo ap.maxAcceleration = speed * 4.0f; ap.collisionQueryRange = radius * 12.0f; ap.pathOptimizationRange = radius * 30.0f; - ap.separationWeight = 2.0f; + ap.separationWeight = separation; ap.updateFlags = DT_CROWD_ANTICIPATE_TURNS | DT_CROWD_OBSTACLE_AVOIDANCE | DT_CROWD_SEPARATION | DT_CROWD_OPTIMIZE_TOPO | DT_CROWD_OPTIMIZE_VIS; ap.obstacleAvoidanceType = 3; ap.queryFilterType = (unsigned char)(filter >= 0 && filter < NAV_FILTERS ? filter : 0); diff --git a/packages/ludic.nav/tests/crowd_test.ludic b/packages/ludic.nav/tests/crowd_test.ludic index 4e0fc3d6..183e87cd 100644 --- a/packages/ludic.nav/tests/crowd_test.ludic +++ b/packages/ludic.nav/tests/crowd_test.ludic @@ -25,7 +25,7 @@ program CrowdTest { x0 = 36.0 x1 = 4.0 } - let id = nav_crowd_add(nav_st, NAV_PERSON, x0, 0.0, z, 0.35, 1.8, 1.4, 0) + let id = nav_crowd_add(nav_st, NAV_PERSON, x0, 0.0, z, 0.35, 1.8, 1.4, 0, 2.0) expect(id >= 0) expect(nav_crowd_target(nav_st, NAV_PERSON, id, x1, 0.0, z)) push(ct.ids, id) @@ -73,12 +73,12 @@ program CrowdTest { expect(not nav_crowd_start(nav_st, NAV_PERSON, 8, 0.6)) expect(nav_build(nav_st, NAV_PERSON, ground(40, 0), new NavConfig)) expect(nav_crowd_start(nav_st, NAV_PERSON, 8, 0.6)) - expect_eq(nav_crowd_add(nav_st, NAV_PERSON, -50.0, 0.0, -50.0, 0.35, 1.8, 1.4, 0), -1) - let a = nav_crowd_add(nav_st, NAV_PERSON, 5.0, 0.0, 5.0, 0.35, 1.8, 1.4, 0) + expect_eq(nav_crowd_add(nav_st, NAV_PERSON, -50.0, 0.0, -50.0, 0.35, 1.8, 1.4, 0, 2.0), -1) + let a = nav_crowd_add(nav_st, NAV_PERSON, 5.0, 0.0, 5.0, 0.35, 1.8, 1.4, 0, 2.0) expect(a >= 0) expect(not nav_crowd_target(nav_st, NAV_PERSON, a, -50.0, 0.0, -50.0)) nav_drop(nav_st, NAV_PERSON) expect(not nav_crowd_read(nav_st, NAV_PERSON, a)) - expect_eq(nav_crowd_add(nav_st, NAV_PERSON, 5.0, 0.0, 5.0, 0.35, 1.8, 1.4, 0), -1) + expect_eq(nav_crowd_add(nav_st, NAV_PERSON, 5.0, 0.0, 5.0, 0.35, 1.8, 1.4, 0, 2.0), -1) } } diff --git a/packages/ludic.wildlife/species.ludic b/packages/ludic.wildlife/species.ludic index aa72763e..882330a9 100644 --- a/packages/ludic.wildlife/species.ludic +++ b/packages/ludic.wildlife/species.ludic @@ -30,6 +30,7 @@ export property WildSpecies { keep_away: float = 60.0 # how far its ranges keep from where the valley starts, m range: float = 100.0 # how wide one of its ranges is, m scale: float = 1.0 # its size, times + spacing: float = 2.0 # how much room it keeps from others walking by (a herd more): a crowd's separation } export state WildlifeState {