physics2d module
The 2D rigid-body world: bodies and colliders on nodes, their velocities, raycasts and overlap queries. physics holds what spans both worlds.
The 2D rigid-body world: bodies and colliders on nodes, their velocities, raycasts and overlap queries. physics holds what spans both worlds.
132 functions, 113 constants. Scripts reach it as physics2d::.
Acts on body2d, character2d, collider2d, follow2d, joint2d, softbody2d: those functions are also methods on the component's handle, without the node argument.
Functions
Argument kinds are the script values a call passes: node is a node handle, any a table or value of any kind, fn a callback.
| function | acts on | what it does |
|---|---|---|
aabb(node) -> float, float, float, float |
collider2d |
The world-space box the collider currently occupies, as its two opposite corners. |
active_bodies() -> any |
— | Every node whose body is awake this step: what a game loops over when it wants to touch only what is moving. |
add_constant_force(node, float, float) |
body2d |
Push the body every step until the constant force is set back to zero; unlike an impulse this is spread over time. |
add_constant_force_at_point(node, float, float, float, float) |
body2d |
Push at a world point every step, which also turns the body. |
add_constant_torque(node, float) |
body2d |
Turn the body every step until the constant torque is set back to zero. |
add_particle_force(node, int, any) |
softbody2d |
Push one particle with force each step until reset_softbody_forces. |
add_softbody_force(node, any) |
softbody2d |
Push every free particle with force each step until reset_softbody_forces. |
angular_velocity(node) -> float |
body2d |
How fast the body is spinning, in radians per second. |
apply_force(node, float, float) |
body2d |
Push the body for the next step only; add_constant_force keeps pushing. |
apply_force_at_point(node, float, float, float, float) |
body2d |
Push at a world point for the next step only, which also turns the body. |
apply_impulse(node, float, float) |
body2d |
Add an instant change in momentum, as if the body were struck. |
apply_impulse_at_point(node, float, float, float, float) |
body2d |
Strike the body at a world point, which spins it as well as moves it. |
apply_particle_impulse(node, int, any) |
softbody2d |
Strike one particle. |
apply_softbody_impulse(node, any) |
softbody2d |
Change every free particle's velocity by impulse at once, as a kick to the whole body. |
apply_softbody_impulse_at(node, any, any, any) |
softbody2d |
Strike the particles within radius of point, less the further they are; a radius of 0 strikes them all. |
apply_softbody_radial_impulse(node, any, any, any) |
softbody2d |
Push the particles within radius away from center, as a blast does. |
apply_torque(node, float) |
body2d |
Turn the body for the next step only; add_constant_torque keeps turning it. |
apply_torque_impulse(node, float) |
body2d |
Add an instant change in angular momentum, as if the body were spun. |
attach_particle(node, int, node) |
softbody2d |
Tie one particle to a node's rigid body where it is now: the body and the particle pull on each other. |
bodies() -> any |
— | Every node with a rigid body, sorted. |
broad_phase_aabb(node) -> float, float, float, float |
collider2d |
The box the broad phase files the collider under, which also reaches ahead by its body's speculative_distance. |
closest_point(any) -> any |
— | The closest point on any collider to a world point. |
closest_points(node, node) -> any |
— | The nearest point on each of two nodes' colliders, as #{ a, b }; nothing when they overlap. |
collider_mass(node) -> float |
collider2d |
What this collider weighs, density and size together. |
collider_mass_properties(node) -> any |
collider2d |
What this collider adds to its body, in its own space: #{ mass, center_of_mass, inertia }. |
collider_mesh(node) -> any |
collider2d |
A voxel collider's outline as points and the segments between them, #{ points, indices }, for drawing it or for spawning the pieces it broke into. |
collider_volume(node) -> float |
collider2d |
How much area the shape encloses. |
collision_aabb(node) -> float, float, float, float |
collider2d |
The box the narrow phase tests the collider in: its shape's box grown by its collision_margin and the world's prediction distance. |
combine_voxels(node, node) |
collider2d |
Tell two voxel colliders on one lattice about each other's cells, so a body sliding from one onto the other does not catch on the seam. Both must share a cell size and a rotation. |
constant_force(node) -> float, float |
body2d |
The force every step integrates until it is set back to zero. |
constant_torque(node) -> float |
body2d |
The torque every step integrates until it is set back to zero. |
contacts(node) -> any |
collider2d |
Every contact point on this node's collider this step: #{ node, point, normal, impulse } each. Empty for a sensor, which has no contacts by definition. |
crop_voxels(node, int, int, int, int) |
collider2d |
Empty every cell outside the cells from (min_x, min_y) to (max_x, max_y), both included. A range holding no filled cell leaves the grid as it was. |
cut_softbody(node, any) -> any |
softbody2d |
Cut the body along a blade at once, as softbody_crossing reads it; answers a record for each piece it changed, the one on_tear hears. |
detach_particle(node, int) -> bool |
softbody2d |
Untie one particle from every body it was attached to; answers whether it was attached. |
distance(node, node) -> any |
— | The gap between two nodes' colliders, zero when they touch. |
effective_angular_inertia(node) -> float |
body2d |
The inertia the solver turns: zero with rotation locked, and on any body that is not dynamic. |
effective_dominance(node) -> float |
body2d |
The dominance rapier will use for this body: its own group, or the rank every non-dynamic body outranks with. |
effective_mass(node) -> any |
body2d |
The mass the solver pushes against along each world axis: zero along a locked axis, and on any body that is not dynamic. |
gravity() -> float, float |
— | The 2D world's gravity. |
handles(node) -> any |
collider2d |
The rapier handles behind this node, its body and its colliders, as #{ body, colliders } of index and generation pairs. For matching a log line against rapier's own output. |
has_pending_tears(node) -> bool |
softbody2d |
Whether some edge or cell is marked to tear at the end of the next step. |
heightfield_hole(node, int) -> bool |
collider2d |
Whether a heightfield segment has no ground. |
intersects(node, node) -> any |
— | Whether two nodes' colliders overlap right now, sensor or not. |
is_ccd_active(node) -> bool |
body2d |
Whether the body moved fast enough last step for rapier to sweep it, with or without continuous_collision. |
is_moving(node) -> bool |
body2d |
Whether the body is awake and actually going somewhere. |
is_on_floor(node) -> bool |
character2d |
Whether the last move ended with ground under the character's feet. |
is_sleeping(node) -> bool |
body2d |
Whether the body is asleep and being skipped. |
joint_force(node) -> any |
joint2d |
The force and the torque the joint held through the last step, #{ force, torque }. An articulation has none to read, and says so. |
joint_state(node) -> any |
joint2d |
What the joint is doing: #{ status, angle, limit_impulses, motor_impulses, coordinates, velocities }, as in 3D: status is enabled, disabled, body_disabled or waiting; angle is a hinge's turn in radians; an articulation adds each free axis's coordinate and velocity. |
kinetic_energy(node) -> float |
body2d |
The body's kinetic energy, for a rest test the solver agrees with. |
linear_velocity(node) -> float, float |
body2d |
How fast the body is travelling, in units per second. |
local_center_of_mass(node) -> any |
body2d |
Where the body's whole mass sits, in the body's own space. |
max_contact_impulse(node) -> float |
body2d |
The hardest contact this body took in the last step, zero when nothing touched it. |
move_character(node, float, float) -> any |
character2d |
Move the character by an offset, sliding along walls, climbing steps and staying on the ground: returns #{ x, y, on_floor, sliding, collisions }, each collision carrying the same fields as in 3D. Every solid collider of the character is swept. Call it from fixed_update. |
next_position(node) -> any |
body2d |
The pose a kinematic body has been told to move to, as #{ position, rotation }. |
overlap_aabb(any) -> any |
— | Every collider whose bounds meet an axis-aligned box. |
overlap_point(any) -> any |
— | Every collider containing a world point: what a mouse click asks. |
overlap_shape(any) -> any |
— | Every collider a shape overlaps where it stands. |
overlaps(node) -> [node] |
collider2d |
The nodes this one currently intersects; rapier reports a pair only when one of the two colliders is a sensor. |
pin_particle(node, int) |
softbody2d |
Hold one particle where it is, which is how a cloth hangs from a hook. |
pose_in_body(node) -> any |
collider2d |
Where the collider sits in its body's frame, as #{ position, rotation }; nothing for a collider with no body. |
potential_energy(node) -> float |
body2d |
The body's gravitational potential energy over one step. |
predict_position(node, float) -> any |
body2d |
Where the body will be after dt seconds at its current velocity, as #{ position, rotation }. |
predict_position_with_forces(node, float) -> any |
body2d |
The same, with the forces already applied taken into account: where a thrust or a spring will have put it. |
ragdoll(node, any?) -> any |
— | Build a 2D ragdoll from the rig under this node: a body and a shape per bone, hinged to its parent's with the hinge's zero at the pose the rig is in. Options as in 3D, with shape one of capsule, rectangle or circle and axes records on rotation. Answers the body nodes it made. |
raycast(any) -> any |
— | The first collider a ray meets: #{ from = [x, y], dir = [x, y], max = 100.0, filter = #{ exclude = node } }. Returns #{ node, point, normal, distance }, or nothing. |
raycast_all(any) -> any |
— | Every collider a ray meets, nearest first. |
remove_joint(node) |
joint2d |
Undo the node's joint, leaving both bodies free. |
reset_follow(node) |
follow2d |
Forget what a pid follow summed, so it pulls from now as if it had just started. |
reset_plasticity(node) |
softbody2d |
Undo every permanent set the body took: rest lengths, rest angles and rest shapes go back to how it was built, and it springs back from where it is. |
reset_softbody_forces(node) |
softbody2d |
Take back every force add_softbody_force and add_particle_force gave the body. |
set_angular_velocity(node, float) |
body2d |
Set how fast the body spins, in radians per second. |
set_cell_tear_resistance(node, int, float) |
softbody2d |
The same for one cell's tear strain. |
set_collider(node, any) |
collider2d |
Replace the node's collider from a collider2d table: kind, radius, size, friction, and the rest of the component's own vocabulary. |
set_constant_force(node, float, float) |
body2d |
Replace the constant force with this one; zero stops the push. |
set_constant_torque(node, float) |
body2d |
Replace the constant torque with this one; zero stops the turn. |
set_edge_tear_resistance(node, int, float) |
softbody2d |
How many times the material's threshold one edge takes to tear; 1 is the material's. |
set_gravity(float, float) |
— | Set the 2D world's gravity, in units per second squared. |
set_heightfield_hole(node, int, bool) |
collider2d |
Remove or restore one segment of a heightfield's ground, numbered from the first height. |
set_joint_limits(node, string, float, float) |
joint2d |
Set how far one of the joint's free axes may travel; equal values lift the limit. Rewrites that axis's axes record. |
set_linear_velocity(node, float, float) |
body2d |
Set how fast the body travels, in units per second. |
set_motor_position(node, string, float, float, float) |
joint2d |
Drive one of the joint's free axes towards an angle or a distance, with a spring's stiffness and damping. Rewrites that axis's axes record. |
set_motor_velocity(node, string, float, float) |
joint2d |
Drive one of the joint's free axes towards a speed: how a wheel is powered. Rewrites that axis's axes record. |
set_particle_damaged(node, int, bool) |
softbody2d |
Mark one particle as damaged or mend it: a damaged particle tears as an outside one does, which seeds where a crack starts. |
set_particle_position(node, int, any) |
softbody2d |
Put one particle at at with no change of velocity. |
set_particle_target(node, int, any) |
softbody2d |
Move a held particle to at over the next step, with the velocity that takes, which is how a cloth is dragged. |
set_particle_velocity(node, int, any) |
softbody2d |
Set one particle's velocity; a held one keeps moving at it. |
set_softbody(node, any) |
softbody2d |
Build the node's soft body from a softbody2d table: kind, the shape rows, and the material rows. |
set_voxel(node, int, int, bool) |
collider2d |
Fill or empty one cell of a voxel collider: digging a hole, or building a wall, while the game runs. |
set_voxel_size(node, float, float) |
collider2d |
Resize every cell of a voxel collider, keeping which cells are filled. |
shapecast(any) -> any |
— | Sweep a shape along a direction until it hits something: a thick raycast. |
sleep(node) |
body2d |
Put the body to sleep now. |
softbody_area(node) -> float |
softbody2d |
How much area the body and every piece torn off it enclose right now, against softbody_rest_area for how far it is squeezed. |
softbody_attachments(node) -> any |
softbody2d |
Every particle tied to a rigid body, as #{ particle, body, anchor, impulse }: the anchor in the body's own space, and the impulse the tie pulled with in the last substep. |
softbody_boundary(node) -> any |
softbody2d |
The body's surface as particle indices: segments in 2D, triangles in 3D. |
softbody_cell(node, int) -> any |
softbody2d |
Everything one cell holds: #{ particles, rest_volume, stiffness_scale, tear_resistance, stress, plastic_stretch }; stress is its strain as a fraction of tear_strain, plastic_stretch the rows of the permanent stretch of its rest shape. |
softbody_cells(node) -> any |
softbody2d |
Every cell as its particle indices: triangles in 2D, tetrahedra in 3D. |
softbody_center(node) -> any |
softbody2d |
The centre of mass of the body and its pieces, which is where it is when a deformable body has no one position. |
softbody_contacts(node) -> any |
softbody2d |
What the body's surface touched in the last step: #{ edges, vertices, volumes }. Each edge and vertex contact with another soft body or itself is a pair of world points, the two witnesses; each volume contact is #{ center, normal, volume }. |
softbody_crossing(node, any) -> any |
softbody2d |
The edges and cells a blade meets, #{ edges, cells }, without cutting: the blade is a segment's two points in 2D, a triangle's three in 3D. |
softbody_edge(node, int) -> any |
softbody2d |
Everything one edge holds: #{ particles, kind, rest_length, initial_rest_length, plastic_strain, tension_only, softness_hz, softness_damping_ratio, tear_resistance, impulse, stress }; kind is structural or bending, and the softness is the edge's own or its kind's from the material. |
softbody_edges(node) -> any |
softbody2d |
Every edge as the two particle indices it joins, in the order softbody_stress reports them. |
softbody_mass(node) -> float |
softbody2d |
What the whole body weighs, every piece included. |
softbody_particle(node, int) -> any |
softbody2d |
Everything one particle holds: #{ position, velocity, force, target, rest_position, initial_rest_position, mass, inverse_mass, pinned, damaged, on_surface }. force is what add_particle_force keeps on it, target where a held particle is going (nil when none), the two rest positions are relative to the rest centre of mass, before and after plastic flow, and inverse_mass is 0 while it is held. |
softbody_particle_radius(node) -> float |
softbody2d |
How thick the particles are: what was asked for, or what the layout worked out. |
softbody_particles(node) -> int |
softbody2d |
How many particles the body has, every piece torn off it included: a generator decides, not the author. |
softbody_position(node, int) -> any |
softbody2d |
Where one particle is, in world space. |
softbody_rest_area(node) -> float |
softbody2d |
How much they enclose at rest. |
softbody_sleeping(node) -> bool |
softbody2d |
Whether the body has come to rest and stopped being simulated. |
softbody_stress(node) -> any |
softbody2d |
Each edge's load as a fraction of its tear threshold, smoothed over tear_smoothing: 0 slack, 1 tearing; the larger of its stretch over tear_strain and its force over tear_force, and 0 while neither is set. |
softbody_velocity(node, int) -> any |
softbody2d |
How fast one particle is moving, in world space. |
softbody_volume_pieces(node) -> any |
softbody2d |
Each closed piece of the surface whose volume is held, as #{ particles, rest_volume, volume }; an open sheet has none. |
solve_ik(node, float, float, any?) |
joint2d |
Move a reduced-coordinates chain so its last link reaches a world position, leaving every joint inside its limits. Options: rotation (radians to turn the link to), constrain (the world axes to match: x, y, rotation; the translation by default, every axis when rotation is given), damping (1.0), iterations (10), tolerance (0.001). |
swept_aabb(node) -> float, float, float, float |
collider2d |
The box the collider covers over the next fixed step, from where it is to where its body's velocity and forces carry it. |
tear_cell(node, int) |
softbody2d |
Tear one cell at the end of the next step: a particle near its middle splits across its main stretch. |
tear_edge(node, int) |
softbody2d |
Tear one edge at the end of the next step. |
tear_softbody(node, any, any) -> any |
softbody2d |
Tear the given edges and cells at once; answers a record for each piece it changed: #{ pieces, edges, cells, removed_edges, split_particles, inserted_particles, piece_particles, clusters, moved_joints }, the one on_tear hears. Particle indices are the torn piece's own; split_particles holds [copy, source] pairs, clusters #{ source, cluster, keeps_proxy }, and moved_joints the joint nodes a cluster split moved. |
teleport(node, float, float, any?) |
body2d |
Move the body to a world position at once, clearing its velocity: what assigning the node's position cannot do, because the step writes that back every tick. #{ rotation = angle } turns it too, in radians. |
time_of_impact(node, node, any) -> any |
— | When two moving colliders would meet, given each one's velocity: #{ velocity_a = [..], velocity_b = [..], max_time = 1.0 }. Nothing when they never do. |
time_since_can_sleep(node) -> float |
body2d |
Seconds the body has spent under its sleep thresholds; it sleeps once this reaches time_to_sleep. |
total_inertia(node) -> float |
body2d |
The body's resistance to spin, colliders included. |
total_mass(node) -> float |
body2d |
The body's total mass: its mass when it states one, or what its colliders weigh. |
unpin_particle(node, int) |
softbody2d |
Let a held particle go; it keeps the velocity it had. |
velocity_at_point(node, float, float) -> float, float |
body2d |
How fast a world point on the body is moving, spin included. |
voxel(node, int, int) -> bool |
collider2d |
Whether one cell of a voxel collider is filled. |
voxel_at(node, float, float) -> int, int |
collider2d |
The cell a world position falls in, as two whole numbers. |
voxel_size(node) -> any |
collider2d |
How big one cell of a voxel collider is, along each axis. |
wake_all() |
— | Wake every sleeping body in the 2D world. |
wake_softbody(node) |
softbody2d |
Start simulating a resting body again. |
wake_up(node) |
body2d |
Wake the body, so the next step moves it. |
world_center_of_mass(node) -> any |
body2d |
Where the body's whole mass sits, in world space. |
Constants
| name | value |
|---|---|
AXIS_ROTATION |
rotation |
AXIS_X |
x |
AXIS_Y |
y |
BIND_CELLS |
cells |
BIND_NEAREST |
nearest |
BIND_PARTICLES |
particles |
BODY_DYNAMIC |
dynamic |
BODY_KINEMATIC |
kinematic |
BODY_KINEMATIC_VELOCITY |
kinematic_velocity |
BODY_STATIC |
static |
CELL_COROTATIONAL |
corotational |
CELL_NEO_HOOKEAN |
neo_hookean |
CELL_VOLUME |
volume |
COLLIDE_DYNAMIC_DYNAMIC |
dynamic_dynamic |
COLLIDE_DYNAMIC_KINEMATIC |
dynamic_kinematic |
COLLIDE_DYNAMIC_STATIC |
dynamic_static |
COLLIDE_KINEMATIC_KINEMATIC |
kinematic_kinematic |
COLLIDE_KINEMATIC_STATIC |
kinematic_static |
COLLIDE_STATIC_STATIC |
static_static |
COMBINE_AVERAGE |
average |
COMBINE_CLAMPED_SUM |
clamped_sum |
COMBINE_GEOMETRIC_MEAN |
geometric_mean |
COMBINE_MAX |
max |
COMBINE_MIN |
min |
COMBINE_MULTIPLY |
multiply |
DRIVE_FOLLOW |
follow |
DRIVE_MOTORS |
motors |
DRIVE_NONE |
none |
EDGES_CHAIN |
chain |
EDGES_MESH |
mesh |
EDGES_OUTLINE |
outline |
EVENT_COLLISION |
collision |
EVENT_CONTACT_FORCE |
contact_force |
FILL_SOLID |
solid |
FILL_SURFACE |
surface |
FIT_AABB |
aabb |
FIT_CONVEX_DECOMPOSITION |
convex_decomposition |
FIT_CONVEX_HULL |
convex_hull |
FIT_OBB |
obb |
FLOW_BOTH |
both |
FLOW_COMPRESSION |
compression |
FLOW_TENSION |
tension |
FOLLOW_PD |
pd |
FOLLOW_PID |
pid |
IGNORE_DYNAMIC |
dynamic |
IGNORE_KINEMATIC |
kinematic |
IGNORE_SENSORS |
sensors |
IGNORE_SOLIDS |
solids |
IGNORE_STATIC |
static |
JOINT_BODY_DISABLED |
body_disabled |
JOINT_DISABLED |
disabled |
JOINT_ENABLED |
enabled |
JOINT_FIXED |
fixed |
JOINT_GENERIC |
generic |
JOINT_GROOVE |
groove |
JOINT_HINGE |
hinge |
JOINT_ROPE |
rope |
JOINT_SLIDER |
slider |
JOINT_SPRING |
spring |
JOINT_WAITING |
waiting |
LENGTHS_ABSOLUTE |
absolute |
LENGTHS_RELATIVE |
relative |
METHOD_EXACT |
exact |
METHOD_VHACD |
vhacd |
METHOD_VOXELS |
voxels |
MOTOR_MODEL_ACCELERATION |
acceleration |
MOTOR_MODEL_AUTO |
auto |
MOTOR_MODEL_FORCE |
force |
MOTOR_OFF |
off |
MOTOR_POSITION |
position |
MOTOR_VELOCITY |
velocity |
ORIENTATION_AUTO |
auto |
ORIENTATION_SHELL |
shell |
ORIENTATION_SOLID |
solid |
SHAPE_CAPSULE |
capsule |
SHAPE_CIRCLE |
circle |
SHAPE_CONVEX_DECOMPOSITION |
convex_decomposition |
SHAPE_CONVEX_HULL |
convex_hull |
SHAPE_CONVEX_POLYGON |
convex_polygon |
SHAPE_FIT |
fit |
SHAPE_HEIGHTFIELD |
heightfield |
SHAPE_MATCHING_AUTO |
auto |
SHAPE_MATCHING_OFF |
off |
SHAPE_MATCHING_ON |
on |
SHAPE_POLYLINE |
polyline |
SHAPE_RECTANGLE |
rectangle |
SHAPE_SEGMENT |
segment |
SHAPE_TRIANGLE |
triangle |
SHAPE_TRIANGLE_MESH |
triangle_mesh |
SHAPE_VOXELIZED_MESH |
voxelized_mesh |
SHAPE_VOXELIZED_POINTS |
voxelized_points |
SHAPE_VOXELS |
voxels |
SHAPE_WORLD_BOUNDARY |
world_boundary |
SOFT_CIRCLE |
circle |
SOFT_CUSTOM |
custom |
SOFT_GRID |
grid |
SOFT_OUTLINE |
outline |
SOFT_POLYGON |
polygon |
SOFT_POLYLINE |
polyline |
SOFT_ROPE |
rope |
SOFT_SOLVER_CONSTRAINTS |
constraints |
SOFT_SOLVER_FEM |
fem |
SOFT_TRIANGLE_MESH |
triangle_mesh |
SOFT_VOLUMETRIC |
volumetric |
SWEEP_CONVERGED |
converged |
SWEEP_FAILED |
failed |
SWEEP_OUT_OF_ITERATIONS |
out_of_iterations |
SWEEP_PENETRATING |
penetrating |
TENSION_ALL |
all |
TENSION_LISTED |
listed |
TENSION_NONE |
none |
TEST_BOTH |
both |
TEST_EITHER |
either |