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//! let mut targets = [];
17//! assert_eq!(
18//!     query.candidates_on_layer_into(SpatialLayerId(0), &mut targets),
19//!     0,
20//! );
21//! # Ok::<(), wowlab_engine_ports::SpatialQueryError>(())
22//! ```
23
24mod rstar;
25
26use wowlab_engine_ports::{SpatialActor, SpatialQuery, SpatialQueryError};
27use wowlab_types::sim::{EnemyIdx, Position2, SpatialLayerId, StaticSpatialScene};
28
29/// Exact query result together with the number of broad-phase candidates examined.
30#[derive(Clone, Debug, Eq, PartialEq)]
31pub struct SpatialQueryObservation<T> {
32    pub result: T,
33    pub broad_phase_candidates: usize,
34}
35
36/// Implementation-neutral diagnostics used by the maintained spatial correctness benchmark.
37pub trait SpatialQueryDiagnostics {
38    /// Run a radius query and report its broad-phase candidate count.
39    fn diagnose_actors_in_radius(
40        &self,
41        query: wowlab_engine_ports::RadiusQuery,
42        allowed: Option<&[EnemyIdx]>,
43    ) -> SpatialQueryObservation<Vec<EnemyIdx>>;
44
45    /// Run a cone query and report its broad-phase candidate count.
46    fn diagnose_actors_in_cone(
47        &self,
48        query: wowlab_engine_ports::ConeQuery,
49        allowed: Option<&[EnemyIdx]>,
50    ) -> SpatialQueryObservation<Vec<EnemyIdx>>;
51
52    /// Return sorted blocker-edge IDs touching a segment and the broad-phase candidate count.
53    fn diagnose_segment_contacts(
54        &self,
55        layer: SpatialLayerId,
56        start: Position2,
57        end: Position2,
58    ) -> SpatialQueryObservation<Vec<usize>>;
59}
60
61/// Build the selected spatial query without exposing its concrete implementation.
62///
63/// # Errors
64///
65/// Returns [`SpatialQueryError`] when the scene or actor geometry is invalid.
66pub fn build_spatial_query(
67    scene: &StaticSpatialScene,
68    actors: &[SpatialActor],
69) -> Result<impl SpatialQuery + SpatialQueryDiagnostics + use<>, SpatialQueryError> {
70    rstar::RstarSpatialQuery::build(scene, actors)
71}