simvx.core.physics.world2d¶
Role¶
This module defines Physics2DWorld, the abstract interface every 2D physics
backend (BuiltinPhysics2D now, an optional PymunkPhysics2D later)
implements. It is the 2D sibling of :class:~simvx.core.physics.world.PhysicsWorld
and serves the same purpose: a transport abstraction that moves rigid-body
state across the Python boundary efficiently, not a definition of solver
behaviour.
A SEPARATE seam (not the 3D one constrained to a plane) is deliberate (design
physics_2d_design.md): the bulk contract width differs ((N,4) transforms /
(N,3) velocities here vs (N,7) / (N,6) in 3D), the optional native
backend differs (pymunk / Chipmunk2D vs Jolt), and rotation is a scalar radian
angle rather than a quaternion. Dimension-agnostic pieces (:class:BodyMode,
- class:
CombineMode, :class:ContactPhase, :class:PhysicsMaterial) are REUSED by import from the 3D modules, never duplicated.
World convention (state it loudly)¶
Y-up, identical to the 3D world. Gravity defaults to Vec2(0, -9.81): down
is -Y. A Y-down game (renders +Y downward on screen) simply sets
gravity=Vec2(0, 9.81); the seam itself stays neutral and never assumes a
screen orientation. Rotation is a scalar angle in radians, positive
counter-clockwise (standard math convention).
The load-bearing part of the contract is the bulk-array transfer: per-frame
body state is exchanged as a single numpy buffer (one transfer per world per
frame), in a fixed body->row order, by filling a caller-preallocated array
in place. The transform row is (N, 4) = [px, py, cos(theta), sin(theta)]
(cos/sin rather than the bare angle so interpolation lerps the unit
vector with no +-pi wraparound, matching Transform2D and the pymunk angle
convention); the velocity row is (N, 3) = [lx, ly, omega] (linear x/y plus
scalar angular velocity in radians/s). See :meth:register_bodies,
- meth:
read_transforms, and :meth:read_velocities.
Stage T2a status¶
This module defines the FULL ABC surface so subclasses have a complete contract.
BuiltinPhysics2D implements the T2a subset (gravity, shapes, bodies,
integrator, bulk readers); the collision-dependent methods (queries, events,
joints, forces, character, one-way) are declared @abstractmethod here and
filled by later sub-stages (T2b-T2e), with honest NotImplementedError stubs
in the backend until then.
Physics2DWorld: the 2D backend transport seam (Stage T2 additive scaffolding).
Module Contents¶
Classes¶
Result of a successful 2D raycast against the world (T2d). |
|
Result of a kinematic / character shape-sweep stopping against a body (T2d). |
|
A node-agnostic 2D body-pair collision event emitted by the seam (T2d). |
|
A node-agnostic 2D sensor-overlap event emitted by the seam (T2d). |
|
Returned struct of a 2D character collide-and-slide move (T2e). |
|
Abstract 2D backend seam: one isolated simulation world. |
Data¶
API¶
- simvx.core.physics.world2d.BodyHandle¶
None
- simvx.core.physics.world2d.ShapeHandle¶
None
- simvx.core.physics.world2d.CharacterHandle¶
None
- simvx.core.physics.world2d.JointHandle¶
None
- class simvx.core.physics.world2d.RaycastHit2D[source]¶
Result of a successful 2D raycast against the world (T2d).
Attributes: body: Handle of the body 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 topointalong the ray.- body: simvx.core.physics.world2d.BodyHandle¶
None
- point: simvx.core.math.Vec2¶
None
- normal: simvx.core.math.Vec2¶
None
- distance: float¶
None
- class simvx.core.physics.world2d.Contact2D[source]¶
Result of a kinematic / character shape-sweep stopping against a body (T2d).
2D sibling of :class:
~simvx.core.physics.world.Contact: a single “other” body (like a query result); the swept body is implicit (the caller).Attributes: body: Handle of the OTHER body that was hit. point: World-space contact point (
Vec2). normal: World-space surface normal (Vec2, unit), pointing AWAY from the other body toward the moving body (the direction that separates the mover). distance: Distance the mover actually travelled before contact (TOI distance,0..|motion|).- body: simvx.core.physics.world2d.BodyHandle¶
None
- point: simvx.core.math.Vec2¶
None
- normal: simvx.core.math.Vec2¶
None
- distance: float¶
None
- class simvx.core.physics.world2d.ContactEvent2D[source]¶
A node-agnostic 2D body-pair collision event emitted by the seam (T2d).
2D sibling of :class:
~simvx.core.physics.world.ContactEvent. Keyed by body HANDLES only (the seam never names a node); orientation is fixeda -> b. Reuses :class:ContactPhase(no second phase enum).Attributes: a: Handle of the first body of the pair (canonical order). b: Handle of the second body of the pair. phase: :class:
ContactPhase(ENTER/EXIT). point: World contact point (Vec2). Meaningful onENTER; degenerate (Vec2(0)) onEXIT. normal: Unit contact normal orienteda -> b(Vec2). Degenerate (Vec2(0)) onEXIT. impulse: Normal impulse magnitude applied to the pair this step.0onEXITand0on anENTERwhere the solver applied none. rel_velocity: Pre-solve velocity ofbw.r.t.aat the contact (Vec2). Degenerate (Vec2(0)) onEXIT.- phase: simvx.core.physics.world.ContactPhase¶
None
- point: simvx.core.math.Vec2¶
None
- normal: simvx.core.math.Vec2¶
None
- impulse: float¶
None
- rel_velocity: simvx.core.math.Vec2¶
None
- class simvx.core.physics.world2d.OverlapEvent2D[source]¶
A node-agnostic 2D sensor-overlap event emitted by the seam (T2d).
2D sibling of :class:
~simvx.core.physics.world.OverlapEvent: a SECOND, independent edge-diffed stream. DIRECTEDsensor -> other(the observing sensor decides via its mask). Reuses :class:ContactPhase.Attributes: sensor: Handle of the detecting sensor body (the observer). other: Handle of the detected body (a normal body OR another sensor). phase: :class:
ContactPhase(ENTER/EXIT).- sensor: simvx.core.physics.world2d.BodyHandle¶
None
- other: simvx.core.physics.world2d.BodyHandle¶
None
- phase: simvx.core.physics.world.ContactPhase¶
None
- class simvx.core.physics.world2d.CharacterMoveResult2D[source]¶
Returned struct of a 2D character collide-and-slide move (T2e).
2D sibling of :class:
~simvx.core.physics.world.CharacterMoveResult. Floor/wall/ceiling are computed seam-side from contact normals vsup(and the character’sslope_limit) so every backend exposes identical semantics.Attributes: velocity: Post-slide velocity (deflected along contact normals); the caller writes this back as its new velocity (
Vec2). on_floor: True if a contact this move was classified as floor. on_wall: True if a contact this move was classified as wall. on_ceiling: True if a contact this move was classified as ceiling. floor_normal: Normal of the floor contact this move (unitVec2), or+upif there was no floor contact.- velocity: simvx.core.math.Vec2¶
None
- on_floor: bool¶
None
- on_wall: bool¶
None
- on_ceiling: bool¶
None
- floor_normal: simvx.core.math.Vec2¶
None
- class simvx.core.physics.world2d.Physics2DWorld(*, gravity: simvx.core.math.Vec2)[source]¶
Bases:
abc.ABCAbstract 2D backend seam: one isolated simulation world.
A
Physics2DWorldowns a set of bodies, advances them as a unit at a fixed timestep via :meth:step, and exchanges per-frame state in bulk. Concrete backends (BuiltinPhysics2D, laterPymunkPhysics2D) implement every method.Bulk-array contract (the keystone)
Call :meth:
register_bodiesonce (or whenever membership changes) to fix the body->row order used by the bulk readers.Each frame, after :meth:
step, call :meth:read_transformsand/or- meth:
read_velocities, passing a caller-preallocated, C-contiguousfloat32numpy array of the documented shape. The backend fills it in place; it must not allocate or return a new array on the hot path.
The array shapes/dtypes/contiguity are part of the contract and MUST be asserted by subclasses (see
_check_transforms_out/_check_velocities_out). The transform row is(N, 4) = [px, py, cos(theta), sin(theta)]and the velocity row is(N, 3) = [lx, ly, omega](see the module docstring for the Y-up / radians convention).Initialization
Initialise the world.
Args: gravity: World gravity acceleration vector (
Vec2), metres/s^2. Y-up:Vec2(0, -9.81)is “down”.- property gravity: simvx.core.math.Vec2[source]¶
World gravity acceleration vector (
Vec2), metres/s^2 (Y-up).
- capabilities() frozenset[simvx.core.physics.capability.Capability][source]¶
Return the set of Tier-3 :class:
Capabilityfeatures this 2D backend honours.2D sibling of :meth:
~simvx.core.physics.world.PhysicsWorld.capabilities, sharing the same dimension-agnostic :class:Capabilityenum. The default is the empty set (a backend advertises nothing it cannot honour); native backends override to list only what they actually support.
- abstractmethod create_circle(radius: float) simvx.core.physics.world2d.ShapeHandle[source]¶
Create a circle collision shape and return an opaque handle.
Args: radius: Circle radius, world units (> 0).
Returns: An opaque shape handle for use with :meth:
create_body.
- abstractmethod create_box(half_extents: simvx.core.math.Vec2) simvx.core.physics.world2d.ShapeHandle[source]¶
Create an axis-aligned (body-local) box shape, centred at the origin.
Args: half_extents: Half-sizes along x/y (
Vec2, both > 0).Returns: An opaque shape handle for use with :meth:
create_body.
- abstractmethod create_capsule(radius: float, height: float) simvx.core.physics.world2d.ShapeHandle[source]¶
Create a Y-axis capsule collision shape and return an opaque handle.
Args: radius: Capsule radius, world units (> 0). height: Total extent along Y including the two semicircular caps (> 0). The central segment half-length is
max(0, height / 2 - radius); whenheight <= 2 * radiusthe segment collapses to a point and the capsule behaves as a circle.Returns: An opaque shape handle for use with :meth:
create_body.
- abstractmethod create_segment(a: simvx.core.math.Vec2, b: simvx.core.math.Vec2, radius: float = 0.0) simvx.core.physics.world2d.ShapeHandle[source]¶
Create a line-segment collision shape (2D-only).
A thick line from
atob(a “beam”), the 2D analogue with no 3D equivalent. Useful for thin static walls / floors and one-way platforms.Args: a: Segment start, body-local (
Vec2). b: Segment end, body-local (Vec2). radius: Segment thickness radius (>= 0); 0 is an infinitely thin line.Returns: An opaque shape handle for use with :meth:
create_body.
- abstractmethod create_convex_polygon(points: numpy.ndarray) simvx.core.physics.world2d.ShapeHandle[source]¶
Create a convex polygon collision shape from CCW points.
Args: points:
(N, 2)float32 array of >= 3 points in counter-clockwise winding, defining a convex polygon (body-local).Returns: An opaque shape handle for use with :meth:
create_body.
- abstractmethod create_concave_polygon(segments: numpy.ndarray) simvx.core.physics.world2d.ShapeHandle[source]¶
Create a STATIC edge-soup collision shape (2D analogue of a mesh).
Args: segments:
(N, 2, 2)float32 array of N line segments (each an[start, end]pair ofVec2points), body-local. The 2D analogue of a static triangle mesh: STATIC-ONLY level geometry.Returns: An opaque shape handle for use with :meth:
create_body. A concave polygon is a STATIC-ONLY collider: placing it on a non-STATIC body is an error.
- abstractmethod create_body(shape: simvx.core.physics.world2d.ShapeHandle, body_type: simvx.core.physics.world.BodyMode, transform: Any, *, mass: float = 1.0, collision_layer: int = 1, collision_mask: int = 4294967295, is_sensor: bool = False, friction: float = 0.5, restitution: float = 0.0, friction_combine: simvx.core.physics.material.CombineMode = CombineMode.AVERAGE, restitution_combine: simvx.core.physics.material.CombineMode = CombineMode.AVERAGE, continuous: bool = False) simvx.core.physics.world2d.BodyHandle[source]¶
Create a body in the world and return its handle.
Mirrors :meth:
~simvx.core.physics.world.PhysicsWorld.create_body(same layer/mask, sensor, material, andcontinuoussemantics), with 2D transforms (positionVec2+ scalar rotation).Args: shape: An opaque shape handle from one of the
create_*shape factories. A concave polygon on a non-STATIC body is an error. body_type: One of :class:BodyMode. transform: Initial world transform. Accepted as aTransform2D(.position+.rotation), a bareVec2/ sequence (position only, zero rotation), or a(position, rotation)pair where rotation is a scalar in radians. mass: Body mass in kg, used only forDYNAMICbodies. Ignored forSTATIC/KINEMATIC(treated as infinite). collision_layer: 32-bit layer membership; defaults to layer 1. collision_mask: 32-bit mask of layers this body scans; defaults all. is_sensor: When True, this body is a SENSOR (trigger): broadphase only, excluded from collision resolution, feeds the separate overlap stream (one-directionalsensor.mask & other.layer). friction: Coulomb friction coefficientmu(>= 0), default 0.5. restitution: Bounciness in[0, 1](default 0.0, no bounce). friction_combine: Per-contact friction combine mode (default AVERAGE). restitution_combine: Per-contact restitution combine mode (default AVERAGE), independent offriction_combine. continuous: When True, use continuous collision detection (centre sweep vs STATIC, TOI clamp; basic-tier honesty, full CCD deferred to pymunk). Defaults False (discrete).Returns: An opaque body handle, stable until :meth:
destroy_body.
- abstractmethod destroy_body(handle: simvx.core.physics.world2d.BodyHandle) None[source]¶
Remove a body from the world; the handle is invalid afterwards.
Callers that use the bulk readers must re-call :meth:
register_bodiesto re-establish row order.
- abstractmethod set_body_transform(handle: simvx.core.physics.world2d.BodyHandle, transform: Any) None[source]¶
Teleport a body to a new world transform (position + scalar rotation).
- abstractmethod set_body_velocity(handle: simvx.core.physics.world2d.BodyHandle, linear: simvx.core.math.Vec2, angular: float = 0.0) None[source]¶
Set a body’s linear and (scalar) angular velocity directly.
Args: handle: Body handle. linear: Linear velocity (
Vec2), world units/s. angular: Angular velocity (scalar float), radians/s (CCW positive). Defaults to0.0.
- abstractmethod set_body_mode(handle: simvx.core.physics.world2d.BodyHandle, mode: simvx.core.physics.world.BodyMode) None[source]¶
Change a live body’s motion mode in place (no destroy/recreate).
Flips STATIC / KINEMATIC / DYNAMIC, updating effective (inverse) mass and moment of inertia: STATIC / KINEMATIC are infinite (inverse 0), DYNAMIC uses the body’s stored mass and per-shape moment.
- abstractmethod body_velocity(handle: simvx.core.physics.world2d.BodyHandle) tuple[simvx.core.math.Vec2, float][source]¶
Read a body’s current
(linear, angular)velocity, per-body.Cold per-body read parallel to :meth:
body_transform; the bulk- Meth:
read_velocitiesstays the hot scatter path.
Returns:
(linear, angular)velocity (Vec2, scalar float in radians/s). Returns zero velocities for an infinite-mass body that was never moved.
- abstractmethod body_transform(handle: simvx.core.physics.world2d.BodyHandle) tuple[simvx.core.math.Vec2, float][source]¶
Read a body’s current pose as
(position, rotation).Cold per-body read parallel to :meth:
body_velocity.Returns:
(position, rotation)(Vec2, scalar float radians).
- abstractmethod sleeping(handle: simvx.core.physics.world2d.BodyHandle) bool[source]¶
True if the body is asleep (skipped by integrate + solve until woken).
STATIC / KINEMATIC bodies are never ‘asleep’ (they were never awake): returns False for them.
- abstractmethod apply_impulse(handle: simvx.core.physics.world2d.BodyHandle, impulse: simvx.core.math.Vec2, *, at: simvx.core.math.Vec2 | None = None, angular: float = 0.0) None[source]¶
Apply an instantaneous velocity change to a body NOW (T2c).
Args: handle: Body handle. impulse: Linear impulse (
Vec2), N*s. at: Optional world-space application point; the offsetr = at - positioncontributes a scalar angular impulse via the 2D cross productcross(r, impulse)scaled by the inverse moment of inertia. angular: Optional explicit scalar angular impulse (radians-equivalent), applied via the inverse moment of inertia.
- abstractmethod apply_force(handle: simvx.core.physics.world2d.BodyHandle, force: simvx.core.math.Vec2, *, at: simvx.core.math.Vec2 | None = None) None[source]¶
Accumulate a continuous force, applied during the NEXT :meth:
step(T2c).Auto-cleared at the end of the step (re-add each fixed step to sustain). Inert on non-DYNAMIC.
atadds a scalar torquecross(r, force).
- abstractmethod apply_torque(handle: simvx.core.physics.world2d.BodyHandle, torque: float) None[source]¶
Accumulate a continuous scalar torque for the NEXT :meth:
step(T2c).Auto-cleared after the step (re-add each fixed step to sustain). Inert on non-DYNAMIC. Applied via the inverse moment of inertia.
- abstractmethod create_fixed_joint(a: simvx.core.physics.world2d.BodyHandle, b: simvx.core.physics.world2d.BodyHandle) simvx.core.physics.world2d.JointHandle[source]¶
Weld two bodies: lock their full relative transform (T2c).
- abstractmethod create_pin_joint(a: simvx.core.physics.world2d.BodyHandle, b: simvx.core.physics.world2d.BodyHandle, anchor: simvx.core.math.Vec2) simvx.core.physics.world2d.JointHandle[source]¶
Pin two bodies at a single world-space point, rotation free (T2c).
- abstractmethod create_hinge_joint(a: simvx.core.physics.world2d.BodyHandle, b: simvx.core.physics.world2d.BodyHandle, anchor: simvx.core.math.Vec2) simvx.core.physics.world2d.JointHandle[source]¶
Hinge two bodies at
anchor(T2c).2D rotation is 1-DOF, so a 2D hinge has no
axisargument: it is a pin atanchor(this tier). Motors and angular limits are a follow-on.
- abstractmethod create_spring_joint(a: simvx.core.physics.world2d.BodyHandle, b: simvx.core.physics.world2d.BodyHandle, rest_length: float, stiffness: float, damping: float) simvx.core.physics.world2d.JointHandle[source]¶
Soft distance-spring between the two body centres (compliant) (T2c).
rest_length < 0auto-captures the current centre distance as the rest length (the common “spring at its natural length on creation” case).
- abstractmethod create_groove_joint(a: simvx.core.physics.world2d.BodyHandle, b: simvx.core.physics.world2d.BodyHandle, groove_a: simvx.core.math.Vec2, groove_b: simvx.core.math.Vec2, anchor_b: simvx.core.math.Vec2) simvx.core.physics.world2d.JointHandle[source]¶
Constrain
b’s anchor to slide along a groove ona(2D-only) (T2g).The pymunk-native slider-on-a-line constraint with no 3D equivalent. The groove is the segment
[groove_a, groove_b]ina’s frame;b’sanchor_b(inb’s frame) is constrained to lie on that line.
- abstractmethod remove_joint(handle: simvx.core.physics.world2d.JointHandle) None[source]¶
Remove a constraint; the handle is invalid afterwards (T2c).
A no-op if
handleis unknown (already removed, or silently dropped because one of its bodies was destroyed).
- abstract property body_count: int[source]¶
Number of bodies currently in the world (skip-empty-world fast path).
- abstractmethod clear() None[source]¶
Remove every body, character, and joint, emptying the world.
2D sibling of :meth:
~simvx.core.physics.world.PhysicsWorld.clear: the seam equivalent of the old globalPhysicsServer.reset(). Returns the world to an empty state (body_count == 0) WITHOUT discarding the world, its- Attr:
gravity, or its backend; per-step edge-diff buffers and warm-start cache are reset; cached shape handles stay valid; handle counters keep advancing. After :meth:clear, re-:meth:register_bodiesbefore the bulk readers.
- abstractmethod step(dt: float) None[source]¶
Advance the whole world once by a fixed timestep
dt(seconds).
- abstractmethod drain_contact_events() list[simvx.core.physics.world2d.ContactEvent2D][source]¶
Return and CLEAR this step’s buffered enter/exit contact events (T2d).
- abstractmethod drain_overlap_events() list[simvx.core.physics.world2d.OverlapEvent2D][source]¶
Return and CLEAR this step’s buffered sensor-overlap events (T2d).
- abstractmethod set_one_way(handle: simvx.core.physics.world2d.BodyHandle, enabled: bool, normal: simvx.core.math.Vec2 = _DEFAULT_UP_2D) None[source]¶
Mark a body as a one-way platform (2D-only) (T2e).
When enabled, the body only collides with bodies approaching from the
+normalside (landing on it); bodies passing up through it (moving along+normal) are not blocked.Args: handle: Body handle. enabled: Whether one-way filtering is active. normal: World-space “solid side” normal (
Vec2, unit); the side a lander must approach from. Defaults to+Y(a floor).
- abstractmethod register_bodies(handles: list[simvx.core.physics.world2d.BodyHandle]) None[source]¶
Fix the body->row order used by the bulk readers.
After this call, :meth:
read_transforms/ :meth:read_velocitiesfill rowiwith the state ofhandles[i].len(handles)isN.
- abstractmethod read_transforms(out: numpy.ndarray) None[source]¶
Fill
outwith current body transforms, in place.Args: out: Pre-allocated array of shape
(N, 4), dtypefloat32, C-contiguous, whereNmatches the most recent :meth:register_bodies. Each row is[px, py, cos(theta), sin(theta)]: position xy followed by the rotation as a unit vector (cos/sinof the scalar angle, NOT the bare angle: interpolation lerps the unit vector with no +-pi wraparound). Rowicorresponds tohandles[i].
- abstractmethod read_velocities(out: numpy.ndarray) None[source]¶
Fill
outwith current body velocities, in place.Args: out: Pre-allocated array of shape
(N, 3), dtypefloat32, C-contiguous, whereNmatches the most recent :meth:register_bodies. Each row is[lx, ly, omega]: linear velocity xy followed by scalar angular velocity (radians/s, CCW positive). Rowicorresponds tohandles[i].
- abstractmethod raycast(origin: simvx.core.math.Vec2, direction: simvx.core.math.Vec2, max_dist: float, *, mask: int = 4294967295) simvx.core.physics.world2d.RaycastHit2D | None[source]¶
Cast a ray and return the nearest hit, or
None(T2d).
- abstractmethod raycast_all(origin: simvx.core.math.Vec2, direction: simvx.core.math.Vec2, max_dist: float, *, mask: int = 4294967295) list[simvx.core.physics.world2d.RaycastHit2D][source]¶
Cast a ray and return EVERY hit within
max_dist, sorted (T2d).
- abstractmethod shapecast(shape: simvx.core.physics.world2d.ShapeHandle, origin: simvx.core.math.Vec2, direction: simvx.core.math.Vec2, max_dist: float, *, mask: int = 4294967295) simvx.core.physics.world2d.Contact2D | None[source]¶
Sweep a shape along a ray, return the earliest-TOI contact (T2d).
- abstractmethod overlap(shape: simvx.core.physics.world2d.ShapeHandle, transform: Any, *, mask: int = 4294967295) list[simvx.core.physics.world2d.BodyHandle][source]¶
Return all bodies a static shape overlaps at
transform(T2d).
- abstractmethod move_and_collide(handle: simvx.core.physics.world2d.BodyHandle, motion: simvx.core.math.Vec2) simvx.core.physics.world2d.Contact2D | None[source]¶
Move a kinematic body by
motion, stop at first contact (T2d).
- abstractmethod create_character(shape: simvx.core.physics.world2d.ShapeHandle, transform: Any, *, up: simvx.core.math.Vec2 = _DEFAULT_UP_2D, slope_limit: float = math.radians(45.0), step_height: float = 0.0, skin_width: float = 0.001, collision_layer: int = 1, collision_mask: int = 4294967295) simvx.core.physics.world2d.CharacterHandle[source]¶
Create a 2D character controller bound to this world (T2e).
- abstractmethod destroy_character(handle: simvx.core.physics.world2d.CharacterHandle) None[source]¶
Remove a character controller from the world (T2e).
- abstractmethod set_character_transform(handle: simvx.core.physics.world2d.CharacterHandle, transform: Any) None[source]¶
Teleport a character to a new pose (no collision) (T2e).
- abstractmethod character_transform(handle: simvx.core.physics.world2d.CharacterHandle) tuple[simvx.core.math.Vec2, float][source]¶
Read a character’s current pose as
(position, rotation)(T2e).
- abstractmethod character_move_and_slide(handle: simvx.core.physics.world2d.CharacterHandle, velocity: simvx.core.math.Vec2, dt: float, *, up: simvx.core.math.Vec2, max_slides: int = 4) simvx.core.physics.world2d.CharacterMoveResult2D[source]¶
Collide-and-slide a 2D character by
velocity * dt(T2e).
- __slots__¶
()
- simvx.core.physics.world2d.__all__¶
[‘BodyMode’, ‘Capability’, ‘CombineMode’, ‘PhysicsMaterial’, ‘ContactPhase’, ‘RaycastHit2D’, ‘Contac…