Skip to content

ENG2-P8-09: Navmesh generation/query for 3D navigation #807

Description

@aram-devdocs

Parent

  • Program: ENG2 — GoudEngine v2 Rebuild (see the pinned master tracking issue)
  • Phase / Milestone: Phase 8 — Capability Gaps (eng2-p8-capabilities)
  • Batch / Group: Batch 8.3 — Big-world, Group A
  • Runbook spec: docs/src/runbook/phases/phase-8.md (committed with the roadmap)

Summary

Add navmesh generation (from static 3D collision/mesh geometry) and navmesh query (find-path, find-nearest-point-on-mesh) for 3D navigation, complementing the 2D grid A*/flow-field system.

Architecture Context

Layer: Layer 3 (Services, ecs/nav/) — extends the module ENG2-P8-01 establishes.
Modules/types touched:

  • goud_engine/src/ecs/nav/navmesh.rs (new) — navmesh generation (voxelization or direct polygon-mesh reduction from walkable geometry) and query (A*/funnel-algorithm path over navmesh polygons).
  • goud_engine/src/ffi/nav/ — new exports alongside ENG2-P8-01's grid A*/flow-field surface, following the same handle-registry shape.

Boundary constraints (only those that apply):

  • No raw GPU calls; navmesh generation and query are CPU-only.
  • FFI exports: #[no_mangle] extern "C", #[repr(C)], null checks, // SAFETY: comments.
  • ecs/nav/ MUST NOT depend on rendering/, ffi/, or sdk/ — it consumes raw mesh/geometry data, not renderer-owned mesh handles.

Pattern to follow: ENG2-P8-01's nav module structure and FFI handle-registry pattern (mirroring ffi/spatial_grid/mod.rs) — this issue is a second capability inside the same ecs/nav/ module and ffi/nav/ FFI surface, not a parallel navigation stack.

Scope

  • Navmesh generation from input geometry: accept a set of walkable triangles (or a voxelized heightfield) and produce a simplified navigable polygon mesh.
  • Navmesh query: path lookup between two world-space points across navmesh polygons (e.g. A* over the polygon adjacency graph + a funnel/string-pulling pass for a smooth path, not just polygon-center waypoints).
  • Nearest-point-on-navmesh query (for snapping an arbitrary world position onto the walkable surface).
  • FFI exports: build a navmesh from geometry, destroy it, query a path, query nearest point.
  • Tests: spec test + unit tests on fixture geometry (flat plane, plane with a hole/obstacle, two disconnected islands) verifying path existence/absence and path validity (stays within navmesh polygons).
  • Docs/rules updates: mdBook page covering navmesh generation inputs and query API, cross-referencing the grid A* system from ENG2-P8-01 for when to use which.

Acceptance Criteria

  • Navmesh generated from a fixture mesh with an obstacle correctly routes around it; a query between two disconnected islands correctly reports no path.
  • Generated paths stay within navmesh polygon boundaries (no cutting through unwalkable space).
  • FFI navmesh exports have wrappers in all 10 SDKs and pass python codegen/validate_coverage.py.
  • cargo check && cargo fmt --all -- --check && cargo clippy -- -D warnings clean; cargo test green; ./codegen.sh && git diff --exit-code (drift gate)

Breaking Change & Throne Follow-up

None — additive/internal (new module, new FFI surface).

Blocked By

ENG2-P8-01 (grid A* + flow fields + nav FFI surface — this issue extends the same ecs/nav/ module and FFI handle-registry pattern that P8-01 establishes; building navmesh support before the base nav module exists would mean redoing the module scaffolding).

Files Likely Touched

  • New: goud_engine/src/ecs/nav/navmesh.rs, goud_engine/src/ffi/nav/navmesh.rs (or additions to the ffi/nav/ files from ENG2-P8-01)
  • Generated: SDK bindings under sdks/*/ for the new navmesh FFI exports
  • Modified: codegen/goud_sdk.schema.json

Agent Notes

  • No navigation module of any kind exists yet — grep-verified (pathfind|navmesh|flow.?field|nav_grid, case-insensitive, across goud_engine/src) returns zero matches repo-wide, so both the 2D grid system (ENG2-P8-01) and this 3D navmesh system are entirely new capability with no prior partial implementation to build from.
  • This is deliberately sequenced after ENG2-P8-01 rather than in parallel with it, because both should live in the same ecs/nav/ module and share the same FFI handle-registry shape (mirroring ffi/spatial_grid/mod.rs's lifecycle/operations/queries split) — building navmesh support in isolation first would risk a second, inconsistent nav FFI shape that later needs reconciling with P8-01's.
  • Navmesh input geometry should be a plain vertex/triangle-index buffer passed across FFI (consistent with how the rest of the engine treats geometry crossing the FFI boundary as raw arrays, e.g. component data in component_ops), not a reference into a renderer-owned mesh handle — this keeps ecs/nav/ free of any dependency on rendering/ or libs/graphics/, preserving the downward-only layer rule.

Verification

cargo check && cargo fmt --all -- --check && cargo clippy -- -D warnings
cargo test
./codegen.sh && git diff --exit-code

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions