simvx.core.physics.query2d

Role

The 2D sibling of :mod:~simvx.core.physics.query. The seam (:class:~simvx.core.physics.world2d.Physics2DWorld) is node-agnostic: its queries return opaque body HANDLES (and seam-level RaycastHit2D / Contact2D keyed by handle). :class:PhysicsQuery2D is the thin node-facing wrapper that maps those handles back to scene nodes (via the tree’s register_physics_node registry) and applies node-level filters (exclude= a set of nodes), returning typed :class:RayHit2D / :class:ShapeHit2D results (or plain nodes for overlap).

Constructed fresh per node.physics_2d access (cold path) bound to (world, node_map) where node_map is the per-world handle -> Node weak map. The seam never learns about nodes; all handle->node mapping happens here.

Node-level spatial query API for the 2D physics seam (Stage T2f).

Module Contents

Classes

RayHit2D

A node-level 2D raycast result (mapped from the seam’s RaycastHit2D).

ShapeHit2D

A node-level 2D shapecast result (mapped from the seam’s Contact2D).

PhysicsQuery2D

Node-facing 2D spatial query wrapper over a :class:Physics2DWorld.

Data

API

simvx.core.physics.query2d.__all__

[‘RayHit2D’, ‘ShapeHit2D’, ‘PhysicsQuery2D’]

class simvx.core.physics.query2d.RayHit2D[source]

A node-level 2D raycast result (mapped from the seam’s RaycastHit2D).

Carries the resolved scene node, so user code never touches handles. Always truthy, so if hit: reads naturally; a miss is None (falsy).

Attributes: node: The body node the ray hit. point: World-space contact point (Vec2). normal: World-space surface normal at the hit (Vec2, unit length). distance: Distance from the ray origin to point along the ray.

node: simvx.core.physics.nodes2d.PhysicsBody2D

None

point: simvx.core.math.Vec2

None

normal: simvx.core.math.Vec2

None

distance: float

None

__bool__() bool[source]
class simvx.core.physics.query2d.ShapeHit2D[source]

A node-level 2D shapecast result (mapped from the seam’s Contact2D).

Mirrors :class:RayHit2D for a swept-shape query; a miss is None.

Attributes: node: The body node the shape swept into. point: World-space contact point (Vec2). normal: World-space separating normal pointing back toward the cast origin (Vec2, unit length). distance: Time-of-impact distance along the cast direction.

node: simvx.core.physics.nodes2d.PhysicsBody2D

None

point: simvx.core.math.Vec2

None

normal: simvx.core.math.Vec2

None

distance: float

None

class simvx.core.physics.query2d.PhysicsQuery2D(world: simvx.core.physics.world2d.Physics2DWorld, node_map: weakref.WeakValueDictionary[simvx.core.physics.world2d.BodyHandle, simvx.core.node.Node] | None)[source]

Node-facing 2D spatial query wrapper over a :class:Physics2DWorld.

Bound to one world and that world’s handle -> Node map. Exposes

Meth:

raycast / :meth:raycast_all / :meth:shapecast / :meth:overlap with typed results and keyword-only mask / exclude / distance filters. Constructed fresh per node.physics_2d access; bind it locally if a hot loop wants to avoid the per-call construction.

node_map may be None (no bodies registered in this world yet); then every hit maps to None and is dropped, so queries against an empty world return None / [] rather than raising.

Initialization

__slots__

(‘_world’, ‘_node_map’)

raycast(origin: simvx.core.math.Vec2, direction: simvx.core.math.Vec2, *, distance: float = math.inf, mask: int = 4294967295, exclude: set[simvx.core.node.Node] | None = None) simvx.core.physics.query2d.RayHit2D | None[source]

Cast a ray, return the nearest non-excluded hit, or None.

With no exclude the seam’s single-nearest :meth:raycast is used directly. With exclude it falls back to :meth:raycast_all and returns the first non-excluded hit, so an excluded body never shadows a farther real one.

Args: origin: Ray origin (Vec2). direction: Ray direction (Vec2); need not be normalised. distance: Maximum ray distance (default unbounded). mask: Query layer mask (matched against each body’s layer). exclude: Optional set of nodes to ignore (e.g. {self}).

Returns: The nearest :class:RayHit2D, or None on miss / all-excluded.

raycast_all(origin: simvx.core.math.Vec2, direction: simvx.core.math.Vec2, *, distance: float = math.inf, mask: int = 4294967295, exclude: set[simvx.core.node.Node] | None = None) list[simvx.core.physics.query2d.RayHit2D][source]

Cast a ray, return ALL non-excluded hits sorted by distance.

Drops hits whose handle is unmapped (transient/destroyed body) or whose node is in exclude.

Returns: List of :class:RayHit2D, ascending by distance (empty on miss).

shapecast(shape: simvx.core.physics.shapes2d.Shape2D, origin: simvx.core.math.Vec2, direction: simvx.core.math.Vec2, *, distance: float = math.inf, mask: int = 4294967295, exclude: set[simvx.core.node.Node] | None = None) simvx.core.physics.query2d.ShapeHit2D | None[source]

Sweep a shape resource along a ray, return the earliest-TOI hit.

The wrapper owns building the transient seam shape handle from the

Class:

Shape2D resource, keeping the public API node-level.

A swept shape needs a bounded sweep length, so unlike :meth:raycast distance must be FINITE; pass an explicit distance.

Returns: The earliest-TOI :class:ShapeHit2D, or None on miss / excluded / unmapped.

overlap(shape: simvx.core.physics.shapes2d.Shape2D, transform: object, *, mask: int = 4294967295, exclude: set[simvx.core.node.Node] | None = None) list[simvx.core.physics.nodes2d.PhysicsBody2D][source]

Return all bodies a static shape overlaps at transform.

Returns plain nodes (not typed hits): an overlap has no single point / normal / distance. Drops unmapped and excluded handles.

Args: shape: A :class:Shape2D resource. transform: World pose to place the shape at (the flexible forms the seam accepts: Transform2D / Vec2 / (pos, rot)). mask: Query layer mask. exclude: Optional set of nodes to ignore.

Returns: List of overlapping body nodes (empty if none / all dropped).