waymark 0.1.0

Pathfinding and spatial queries on navigation meshes
Documentation
# waymark

Pathfinding and spatial queries on navigation meshes.

[![Crates.io](https://img.shields.io/crates/v/waymark.svg)](https://crates.io/crates/waymark)
[![Documentation](https://docs.rs/waymark/badge.svg)](https://docs.rs/waymark)
[![License](https://img.shields.io/crates/l/waymark.svg)](../LICENSE-MIT)
[![WASM](https://img.shields.io/badge/WASM-compatible-green.svg)](https://webassembly.org/)

## Overview

`waymark` provides pathfinding on navigation meshes generated by `landmark` or
other tools. It implements A* pathfinding, spatial queries, and supports
multi-tile navigation meshes.

Rust port of the Detour component from [RecastNavigation][recast-cpp].

[recast-cpp]: https://github.com/recastnavigation/recastnavigation

## Features

- **A* Pathfinding**: Find paths between points on the navmesh
- **Path Straightening**: Funnel algorithm for optimal paths
- **Raycasting**: Line-of-sight queries against the navmesh
- **Spatial Queries**: Find nearest points, random points, polygon heights
- **Off-mesh Connections**: Support for jumps, ladders, and teleports
- **Multi-tile Support**: Large world navigation with tiled meshes
- **Query Filters**: Customizable traversal costs and area filtering

## Optional Features

- `serialization` - Save/load navigation meshes via Serde

## WASM Support

This crate is fully compatible with WebAssembly. Build for WASM with:

```bash
cargo build --target wasm32-unknown-unknown -p waymark
```

The `serialization` feature works on WASM with in-memory buffers. File-based
save/load is not available on WASM.

## Example

```rust,ignore
use waymark::{NavMesh, NavMeshFlags, NavMeshParams, NavMeshQuery, QueryFilter};
use glam::Vec3;

// Build a NavMesh from landmark output
let params = NavMeshParams::default();
let nav_mesh = NavMesh::build_from_recast(params, &poly_mesh, &detail_mesh, NavMeshFlags::empty())?;

// Create a query object
let mut query = NavMeshQuery::new(&nav_mesh);
let filter = QueryFilter::default();
let extents = Vec3::new(2.0, 4.0, 2.0);

// Find the start and end polygons
let (start_ref, _) = query.find_nearest_poly(start_pos, extents, &filter)?;
let (end_ref, _) = query.find_nearest_poly(end_pos, extents, &filter)?;

// Find a path (A* polygon corridor)
let path = query.find_path(start_ref, end_ref, start_pos, end_pos, &filter)?;

// Straighten the path using the funnel algorithm
let straight_path = query.find_straight_path(start_pos, end_pos, &path)?;
```

## Query Types

| Query | Description |
|-------|-------------|
| `find_path` | A* path between two polygons |
| `find_straight_path` | Straightened path with corners |
| `raycast` | Line-of-sight test |
| `find_nearest_poly` | Closest polygon to a point |
| `find_random_point` | Random navigable location |
| `get_poly_height` | Height at a point on a polygon |

## License

Dual-licensed under either:

- MIT License ([LICENSE-MIT]../../LICENSE-MIT)
- Apache License, Version 2.0 ([LICENSE-APACHE]../../LICENSE-APACHE)