wowlab_engine_spatial/lib.rs
1//! Concrete spatial-query adapter for the `WoW` Lab simulation engine.
2//!
3//! ```
4//! use wowlab_engine_ports::SpatialQuery;
5//! use wowlab_engine_spatial::build_spatial_query;
6//! use wowlab_types::sim::{SpatialLayerDefinition, SpatialLayerId, StaticSpatialScene};
7//!
8//! let scene = StaticSpatialScene {
9//! layers: vec![SpatialLayerDefinition {
10//! id: SpatialLayerId(0),
11//! slug: "ground".into(),
12//! }],
13//! obstacles: Vec::new(),
14//! };
15//! let query = build_spatial_query(&scene, &[])?;
16//! assert!(query
17//! .candidates_on_layer(SpatialLayerId(0))
18//! .is_empty());
19//! # Ok::<(), wowlab_engine_ports::SpatialQueryError>(())
20//! ```
21
22mod rstar;
23
24use wowlab_engine_ports::{SpatialActor, SpatialQuery, SpatialQueryError};
25use wowlab_types::sim::{EnemyIdx, Position2, SpatialLayerId, StaticSpatialScene};
26
27/// Exact query result together with the number of broad-phase candidates examined.
28#[derive(Clone, Debug, Eq, PartialEq)]
29pub struct SpatialQueryObservation<T> {
30 pub result: T,
31 pub broad_phase_candidates: usize,
32}
33
34/// Implementation-neutral diagnostics used by the maintained spatial correctness benchmark.
35pub trait SpatialQueryDiagnostics {
36 /// Run a radius query and report its broad-phase candidate count.
37 fn diagnose_actors_in_radius(
38 &self,
39 query: wowlab_engine_ports::RadiusQuery,
40 allowed: Option<&[EnemyIdx]>,
41 ) -> SpatialQueryObservation<Vec<EnemyIdx>>;
42
43 /// Run a cone query and report its broad-phase candidate count.
44 fn diagnose_actors_in_cone(
45 &self,
46 query: wowlab_engine_ports::ConeQuery,
47 allowed: Option<&[EnemyIdx]>,
48 ) -> SpatialQueryObservation<Vec<EnemyIdx>>;
49
50 /// Return sorted blocker-edge IDs touching a segment and the broad-phase candidate count.
51 fn diagnose_segment_contacts(
52 &self,
53 layer: SpatialLayerId,
54 start: Position2,
55 end: Position2,
56 ) -> SpatialQueryObservation<Vec<usize>>;
57}
58
59/// Build the selected spatial query without exposing its concrete implementation.
60///
61/// # Errors
62///
63/// Returns [`SpatialQueryError`] when the scene or actor geometry is invalid.
64pub fn build_spatial_query(
65 scene: &StaticSpatialScene,
66 actors: &[SpatialActor],
67) -> Result<impl SpatialQuery + SpatialQueryDiagnostics + use<>, SpatialQueryError> {
68 rstar::RstarSpatialQuery::build(scene, actors)
69}