Skip to main content

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}