Skip to main content

HybridSpace

Struct HybridSpace 

Source
pub struct HybridSpace { /* private fields */ }
Expand description

A space that layers continuous 3D zones on top of a graph topology.

Internally composes a GraphSpace for the graph structure (edges, BFS, directed/undirected). Each graph node carries a ZoneExtent defining its 3D bounding box, an optional ZoneWalkmap for obstacle collision, and an optional spatial hash for fast Euclidean queries within zones that contain many agents.

Agents can:

  • Move within a zone (continuous 3D displacement, respecting obstacles)
  • Transition between zones along graph edges
  • Query neighbors across both hops and Euclidean distance

Zones can optionally carry a ZoneWalkmap that marks non-walkable voxels (columns, walls, barriers). Movement functions check the walkmap and reject displacements into blocked cells.

Implementations§

Source§

impl HybridSpace

Source

pub fn new(zone_extents: Vec<ZoneExtent>) -> Self

Create a hybrid space with n zones, each having the given extents.

The underlying graph starts with no edges – add them with add_edge. Zones start with no obstacle maps (fully walkable) and no spatial hashing.

Source

pub fn uniform(n: usize, extent: ZoneExtent) -> Self

Create a hybrid space where all zones share the same extent.

Source

pub fn num_nodes(&self) -> usize

Number of zone nodes in the graph.

Source

pub fn num_edges(&self) -> usize

Number of edges connecting zones.

Source

pub fn add_edge(&mut self, a: GraphPos, b: GraphPos) -> bool

Add an undirected edge between two zone nodes.

Returns false if the edge already exists or either node is invalid.

Source

pub fn rem_edge(&mut self, a: GraphPos, b: GraphPos) -> bool

Remove an edge between two zone nodes.

Returns false if the edge did not exist.

Source

pub fn neighbors(&self, node: GraphPos, kind: NeighborType) -> Vec<GraphPos>

Get neighboring zone nodes according to a NeighborType selector.

Source

pub fn graph(&self) -> &GraphSpace

Immutable reference to the underlying graph topology.

Source

pub fn zone_extent(&self, node: GraphPos) -> &ZoneExtent

Get the 3D extent descriptor for a zone.

Source

pub fn set_zone_walkmap( &mut self, node: GraphPos, walkmap: ZoneWalkmap, ) -> Result<(), HybridSpaceError>

Set a walkability map for a zone.

Source

pub fn clear_zone_walkmap(&mut self, node: GraphPos)

Remove the walkability map for a zone (making it fully walkable again).

Source

pub fn zone_walkmap(&self, node: GraphPos) -> Option<&ZoneWalkmap>

Get the walkability map for a zone, if any.

Source

pub fn is_walkable(&self, node: GraphPos, pos: &ContinuousPos3D) -> bool

Check if a continuous position within a zone is walkable.

Returns true if the zone has no walkmap (fully walkable) or if the voxel containing the position is marked walkable.

Source

pub fn enable_zone_spatial_hash( &mut self, node: GraphPos, spacing: f64, ) -> Result<(), HybridSpaceError>

Enable spatial hashing for a zone to accelerate Euclidean neighbor queries.

Source

pub fn disable_zone_spatial_hash(&mut self, node: GraphPos)

Disable spatial hashing for a zone (reverts to linear scan).

Source

pub fn has_zone_spatial_hash(&self, node: GraphPos) -> bool

Whether spatial hashing is enabled for a zone.

Source

pub fn add_node(&mut self, extent: ZoneExtent) -> GraphPos

Add a new zone node with the given extent and return its index.

Source

pub fn agent_position(&self, id: AgentId) -> Option<&HybridPos>

Look up the current hybrid position of an agent.

Source

pub fn agents_at_node(&self, node: GraphPos) -> &[AgentId]

Get the agent IDs stored at a given zone node.

Source

pub fn add_agent_internal( &mut self, id: AgentId, pos: HybridPos, ) -> Result<(), HybridSpaceError>

Place an agent at a position in the hybrid space.

The offset is clamped to the zone’s bounds. If a walkmap is present, the target voxel must be walkable or HybridSpaceError::Blocked is returned.

Source

pub fn move_within_zone( &mut self, id: AgentId, displacement: ContinuousPos3D, ) -> Result<HybridPos, HybridSpaceError>

Move an agent within its current zone by a 3D displacement.

The resulting position is clamped to the zone bounds. If a walkmap is present and the target voxel is blocked, the agent stays at its current position and HybridSpaceError::Blocked is returned.

Source

pub fn move_to_offset( &mut self, id: AgentId, offset: ContinuousPos3D, ) -> Result<HybridPos, HybridSpaceError>

Move an agent to a specific 3D position within its current zone.

If a walkmap is present and the target voxel is blocked, the agent stays at its current position and HybridSpaceError::Blocked is returned.

Source

pub fn transition_to_zone( &mut self, id: AgentId, to_node: GraphPos, entry_offset: ContinuousPos3D, ) -> Result<HybridPos, HybridSpaceError>

Transition an agent to an adjacent zone along a graph edge.

The agent is placed at entry_offset in the destination zone (clamped to the zone’s bounds). Returns an error if no edge exists between the current node and to_node, or if the destination voxel is blocked.

Source

pub fn transition_to_zone_center( &mut self, id: AgentId, to_node: GraphPos, ) -> Result<HybridPos, HybridSpaceError>

Transition to an adjacent zone, placing the agent at the center of the destination zone.

Source

pub fn nearby_ids( &self, pos: &HybridPos, graph_radius: usize, euclidean_radius: f64, ) -> Vec<AgentId>

Find all agent IDs within graph_radius hops AND within euclidean_radius distance of the query position within each reached zone.

Semantics:

  • for the origin zone, this performs a true Euclidean query
  • for reached non-origin zones, this returns all agents in those zones
  • no synthetic cross-zone Euclidean metric is imposed by the engine

Use nearby_ids_same_zone for geometric proximity and nearby_ids_by_hops for purely topological reachability.

Source

pub fn nearby_ids_by_hops( &self, node: GraphPos, graph_radius: usize, ) -> Vec<AgentId>

All agent IDs within graph_radius hops (ignoring Euclidean distance).

Source

pub fn nearby_ids_same_zone(&self, pos: &HybridPos, radius: f64) -> Vec<AgentId>

All agent IDs in the same zone within Euclidean distance.

Uses spatial hashing if enabled for the zone (O(k)), otherwise falls back to linear scan over all agents in the zone (O(n)).

Trait Implementations§

Source§

impl Clone for HybridSpace

Source§

fn clone(&self) -> HybridSpace

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for HybridSpace

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<A> SpaceInteraction<A> for HybridSpace
where A: PositionedAgent<Position = HybridPos>,

Source§

type Error = HybridSpaceError

Error type for space operations.
Source§

fn random_position<R: RngCore>(&self, rng: &mut R) -> A::Position

Generate a random valid position within this space.
Source§

fn add_agent(&mut self, agent: &A) -> Result<(), Self::Error>

Register an agent with the space at its current position.
Source§

fn remove_agent(&mut self, agent: &A) -> Result<(), Self::Error>

Deregister an agent from the space.
Source§

fn nearby_ids(&self, position: &A::Position, radius: usize) -> Vec<AgentId>

Return all agent IDs within radius of position. Read more
Source§

impl Space for HybridSpace

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> Message for T
where T: Clone + Send + Sync + 'static,