Struct ClusterSpatialQuery<TArch>
Zero-allocation per-cell cluster AABB query for a single archetype (issue #230). The query expands the requested AABB into the overlapping grid cells, iterates each cell's Typhon.Engine.Internals.CellSpatialIndex as a linear broadphase, and for each broadphase-hit cluster performs a narrowphase scan over its occupied entity slots.
public readonly ref struct ClusterSpatialQuery<TArch> where TArch : Archetype<TArch>, new()
Type Parameters
TArch
- Inherited Members
Remarks
Opt-in. Requires the game to have called ConfigureSpatialGrid(SpatialGridConfig) before InitializeArchetypes(). Without it, the per-cell index is never populated and querying throws InvalidOperationException.
Current scope. 2D and 3D f32 bounds (AABB2F/AABB3F and BSphere2F/BSphere3F); f64 tiers (AABB2D/AABB3D) throw NotSupportedException pending a follow-up sub-issue of #228. Queries traverse both the per-cell dynamic and static indexes. No overflow R-Tree — the broadphase is a linear scan over all clusters in each cell, which is optimal for typical AntHill cell populations (≤80 clusters).
Implementation. This generic entry point exists to provide the tier-aware public API surface with a JIT-specialized dispatch path per concrete box
type. The actual state machine lives on AabbClusterEnumerator, which is also consumed directly by engine-internal non-generic consumers via
QueryAabb(SpatialGrid, float, float, float, float, float, float, uint). Both entry points drive the same iterator — the generic layer adds tier validation; the non-generic layer
is used by consumers that iterate cluster archetypes at runtime (SpatialTriggerSystem, SpatialInterestSystem, EcsQuery).
Epoch scope. The caller must be inside an Typhon.Engine.Internals.EpochGuard scope; the enumerator creates a Typhon.Engine.Internals.ChunkAccessor<TStore> on the cluster segment to read entity bounds during the narrowphase pass.
Methods
AABB<TBox>(in TBox, uint)
Query all entities in this archetype whose spatial bounds intersect the axis-aligned box carried by box. The generic type parameter
TBox determines the dimensionality and precision of the query region; it must match the archetype's cluster storage tier or
an InvalidOperationException is thrown (issue #230 Phase 2.5).
public AabbClusterEnumerator AABB<TBox>(in TBox box, uint categoryMask = 4294967295) where TBox : struct, ISpatialBox
Parameters
boxTBoxQuery region, passed by
into avoid a defensive copy.categoryMaskuintCategory bitmask; a cluster is skipped if its union mask does not intersect. Pass MaxValue (default) to accept every cluster.
Returns
- AabbClusterEnumerator
A zero-allocation enumerator suitable for
foreach.
Type Parameters
TBoxOne of AABB2F, AABB3F, AABB2D, AABB3D. The generic constraint narrows to ISpatialBox, and the JIT specializes this method per concrete
TBoxso each monomorphized version contains only the code path for its concrete type (all other dispatch branches are dead-code-eliminated at specialization time).
Exceptions
- InvalidOperationException
Thrown when the archetype has no spatial index, or when
TBox's tier does not match the archetype's cluster storage tier.- NotSupportedException
Thrown for f64
TBoxvariants (AABB2D, AABB3D). f32 variants (AABB2F, AABB3F) are fully supported. f64 support is deferred to a follow-up sub-issue of #228 and will fill in mechanically.
Radius(in BSphere2F, uint)
Query all entities in this archetype whose spatial bounds are within sphere's radius of its center, using the
closest-point-on-AABB distance semantic. DistanceSq is populated for each hit, letting callers sort
by distance without re-reading bounds. The archetype must be 2D (tier Tier2F); 3D archetypes use the BSphere3F overload.
public AabbClusterEnumerator Radius(in BSphere2F sphere, uint categoryMask = 4294967295)
Parameters
sphereBSphere2FQuery sphere (center + radius), in world units.
categoryMaskuintCategory bitmask; a cluster is skipped if its union mask does not intersect. Pass MaxValue (default) to accept every cluster.
Returns
Radius(in BSphere3F, uint)
3D variant of Radius(in BSphere2F, uint). The archetype must be 3D (tier Tier3F).
public AabbClusterEnumerator Radius(in BSphere3F sphere, uint categoryMask = 4294967295)