Avian Physics 0.3 has been released! 🪶

Highlights
Avian 0.3 is another huge release, with several new features, quality-of-life improvements, and important bug fixes. Highlights include:
- Opt-in contact reporting: Collision events are now only sent for entities that have the
CollisionEventsEnabled
component, reducing unwanted overhead and iteration. - Observable collision events: Observers finally support collision events, making it easy to define per-entity collision handlers.
- Collision hooks: Users can "hook into" the collision pipeline, making it possible to efficiently filter and modify contacts.
- Per-manifold material properties: Friction, restitution, and tangent velocity can be modified for contact manifolds, allowing the simulation of non-uniform materials and conveyor belts.
- Collider context: Custom colliders that implement
AnyCollider
have aContext
for ECS access. - Physics diagnostics: Avian has built-in diagnostics and a debug UI for runtime physics profiling.
- Reworked contact pair management: Contacts have been massively reworked to reduce allocations and unnecessary work while increasing parallelism.
- Faster collisions and spatial queries: Collisions and spatial queries have much less overhead.
- Bevy 0.16 support: Avian has been updated to the latest version of Bevy, and is taking advantage of relationships for attaching colliders to rigid bodies.
Check out the announcement blog post for a more in-depth overview of what has changed and why. A more complete changelog can also be found after the migration guide below.
Migration Guide
Collision Hooks #610
The BroadPhasePlugin
, NarrowPhasePlugin
, and many NarrowPhase
methods now take generics for CollisionHooks
. If you have no collision hooks, you can use ()
.
Physics Picking #632
The RenderLayers
of cameras and collider entities no longer affect physics picking. Add the new PhysicsPickingFilter
component to cameras to control which CollisionLayers
and colliders are included in picking.
Default Layers for ColliderConstructorHierarchy
#649
ColliderConstructorHierarchy
now defaults to one membership (the first layer) and all filters for the CollisionLayers
of generated colliders. This is consistent with how the CollisionLayers
component already works normally.
Previously, it was still using the old default of all memberships and all filters.
Improved Contact Types #616 #685
There have been several changes to Avian's contact types to make them more optimized and clear.
Contacts
Contacts
has been renamed toContactPair
.- The
total_normal_impulse
property has been replaced with atotal_normal_impulse
helper method. - The
total_normal_force
helper has been deprecated. Instead, just divide the impulse by the substep timestep. - The
total_tangent_impulse
property andtotal_friction_force
helper have been removed for being inaccurate/misleading. The tangent impulse magnitudes of each individual point can still be accessed.
ContactManifold
ContactManifold::contacts
has been renamed toContactManifold::points
.- The local
normal1
andnormal2
have been replaced with a single world-spacenormal
, pointing from the first shape to the second.
ContactData
ContactData
has been renamed toContactPoint
, since it specifically represents a point in a contact manifold, not general contact data.point1
andpoint2
have been renamed tolocal_point1
andlocal_point2
for explicitness.normal1
andnormal2
have been removed, since the normal is already stored in theContactManifold
.
Add Context
to AnyCollider
#665
AnyCollider
implementors now need to specify aContext
associatedSystemParam
. If this is unnecessary,()
should be used.- When trying to use methods from
AnyCollider
on an implementation with()
context,SimpleCollider
should be used instead. - Methods on
AnyCollider
have been suffixed with_with_context
.
Bevy 0.16 Support #670
Avian now uses Bevy 0.16.
The AncestorMarkerPlugin
no longer requires a schedule or system set.
Change ColliderParent
to ColliderOf
relationship #671
The ColliderParent
component has been renamed to ColliderOf
, and it is now a Relationship
. The ColliderHierarchyPlugin
(included in PhysicsPlugins
) must be enabled for colliders to be automatically attached to rigid bodies, but ColliderOf
can also be inserted manually otherwise.
The transform management in ColliderHierarchyPlugin
has been extracted into a new ColliderTransformPlugin
. The ColliderHierarchyPlugin
no longer takes a schedule.
Reworked Contact Pair Management #683
Avian's collision detection pipelines and contact pair management have been massively reworked for better performance and robustness.
PostProcessCollisions
The PostProcessCollisions
schedule and NarrowPhaseSet::PostProcess
system set have been removed, as it is incompatible with new optimizations to narrow phase collision detection. Instead, use CollisionHooks
for contact modification.
Contact Reporting
The ContactReportingPlugin
and PhysicsStepSet::ReportContacts
system set have been removed. Contact reporting is now handled by the NarrowPhasePlugin
directly.
The Collision
event no longer exists. Instead, use Collisions
directly, or get colliding entities using the CollidingEntities
component.
The CollisionStarted
and CollisionEnded
events are now only sent if either entity in the collision has the CollisionEventsEnabled
component. If you'd like to revert to the old behavior of having collision events for all entities, consider making CollisionEventsEnabled
a required component for Collider
:
app.register_required_components::<Collider, CollisionEventsEnabled>();
Collisions
The Collisions
resource is now a SystemParam
.
// Old
fn iter_collisions(collisions: Res<Collisions>) {
todo!()
}
// New
fn iter_collisions(collisions: Collisions) {
todo!()
}
Internally, Collisions
now stores a ContactGraph
that stores both touching and non-touching contact pairs. The Collisions
system parameter is just a wrapper that provides a simpler API and only returns touching contacts.
The collisions_with_entity
method has also been renamed to collisions_with
, and all methods that mutatate, add, or remove contact pairs have been removed from Collisions
. However, the following mutating methods are available on ContactGraph
:
get_mut
iter_mut
iter_touching_mut
collisions_with_mut
add_pair
/add_pair_with_key
insert_pair
/insert_pair_with_key
remove_pair
remove_collider_with
For most scenarios, contact modification and removal are intended to be handled with CollisionHooks
.
ContactPair
(previously Contacts
)
The during_current_frame
and during_previous_frame
properties of ContactPair
have been removed in favor of a flags
property storing information in a more compact bitflag format. The is_sensor
, is_touching
, collision_started
, and collision_ended
helper methods can be used instead.
ContactManifold
Methods such as AnyCollider::contact_manifolds_with_context
now take &mut Vec<ContactManifold>
instead of returning a new vector every time. This allows manifolds to be persisted more effectively, and reduces unnecessary allocations.
BroadCollisionPairs
The BroadCollisionPairs
resource has been removed. Use the ContactGraph
resource instead.
AabbIntersections
The AabbIntersections
component has been removed. Use ContactGraph::entities_colliding_with
instead.
Change CollisionLayers
to a Required Component #693
CollisionLayers
is now a required component for colliders and is inserted automatically. Collision detection may not work properly without it.
Reorganize Collision Detection Modules and Re-Exports #698
Some collision detection modules and imports have been reorganized.
The following modules have been moved:
layers
fromcollision
tocollision::collider
contact_query
fromcollision
tocollision::collider::parry
feature_id
fromcollision
tocollision::contact_types
Previously, a lot of collision detection types were also re-exported directly from the collision
module. Now, there is instead a prelude
for the collision
module.
Contact Constraint Generation System Ordering #699
NarrowPhaseSet::GenerateConstraints
has been removed. Contact constraints are now generated as part of NarrowPhaseSet::Update
.
Rename Entity Properties #718 #719
ContactPair
: Theentity1
andentity2
properties are nowcollider1
andcollider2
, andbody_entity1
andbody_entity2
are nowbody1
andbody2
.ContactConstraint
: Theentity1
andentity2
properties are nowbody1
andbody2
, andcollider_entity1
andcollider_entity2
are nowcollider1
andcollider2
.ColliderQuery
: Therigid_body
property has been renamed toof
(forColliderOf
) and there is a newbody
helper to get the contained entity directly.
What's Changed
- Collision Hooks @Jondolf in #610
- Fix collisions not being cleared for immediately despawned entities by @Jondolf in #642
- Introduce
PhysicsPickingFilter
by @morgenthum in #632 - Remove unnecessary
cfg_attr
fromfrom_shape
mass helpers by @Jondolf in #644 - Fix the default layers used by
ColliderConstructorHierarchy
by @Jondolf in #649 - Physics Diagnostics by @Jondolf in #653
- Improved contact types by @Jondolf in #616
- Per-manifold material properties and tangent velocity by @Jondolf in #660
- Add Context to AnyCollider by @NiseVoid in #665
- Refactor to minimise
std
usage by @bushrat011899 in #668 - Remove unsafe
ColliderAabb
initialization by @Jondolf in #669 - Update to Bevy 0.16.0-rc.1 by @Jondolf in #670
- Change
ColliderParent
to aColliderOf
relationship and reworkColliderHierarchyPlugin
by @Jondolf in #671 - Fix panic caused by despawning entity with
ColliderOf
by @Jondolf in #677 - Update to Bevy 0.16.0-rc.2 by @Jondolf in #680
- Make CI faster by caching Rust build outputs by @kristoff3r in #681
- Fix
ColliderOf
updates when a rigid body is added in the hierarchy by @Jondolf in #682 - Rework Contact Pair Management by @Jondolf in #683
- Rename
Contacts
toContactPair
by @Jondolf in #685 - Create thread-local contact status bit vecs with correct block count by @Jondolf in #686
- Fix removing colliders from contact graph
EntityDataIndex
by @Jondolf in #688 - Register some types by @janhohenheim in #691
- Refactor ChildOf from named to tuple struct by @austincummings in #692
- Fix contact pair removal bugs by @Jondolf in #693
- Handle entity disabling properly by @Jondolf in #694
- Use sparse entity-to-node mapping for
ContactGraph
by @Jondolf in #689 - Reduce
SpatialQueryPipeline
overhead by @Jondolf in #696 - Clean up collision detection module structure and re-exports by @Jondolf in #698
- Updated to Bevy 0.16.0-rc.5 by @lufog in #701
- Optimize contact constraint generation by @Jondolf in #699
- Add observable
OnCollisionStart
andOnCollisionEnd
events by @Jondolf in #704 - Update to Bevy 0.16.0 by @Jondolf in #711
- Sort contact constraints for determinism when
parallel
feature is enabled by @Jondolf in #712 - Use try_remove to avoid errors on AncestorMarker removal by @ramirezmike in #714
- Fix
ColliderOf
not being inserted whenCollider
is added to child by @Jondolf in #716 - Include rigid body entity in
OnCollisionStart
andOnCollisionEnd
by @Jondolf in #717 - Rename most
rigid_body
names tobody
by @Jondolf in #718 - Rename entity properties in
ContactPair
andContactConstraint
by @Jondolf in #719 - Fix wrong shape order in
shape_intersections_callback
by @Jondolf in #722 - Fix doc comment for
Rotation::from_sin_cos
by @Jondolf in #723 - Add Ease implementations on Position/Rotation by @cBournhonesque in #724
- Replaced Avian transform syncs with 0.16 Bevy versions by @ramirezmike in #725
New Contributors
- @morgenthum made their first contribution in #632
- @bushrat011899 made their first contribution in #668
- @kristoff3r made their first contribution in #681
- @austincummings made their first contribution in #692
- @lufog made their first contribution in #701
Full Changelog: v0.2.1...v0.3.0