Avian Physics Engine
repository·main·Indexed 25 days ago
https://github.com/avianphysics/avianAn ECS-driven 2D and 3D physics engine built for the Bevy game engine. It provides modular, high-performance physics simulation integrated with Bevy's ECS, supporting rigid bodies, colliders, and soft constraints tuned via frequency and damping ratio. Includes support for f64 precision and a PhysicsLayer derive macro for collision filtering.
What's inside Avian
- Migrating from Avian v0.4 to v0.5 requires updating your Bevy version. Avian 0.5 migrated from Bevy 0.17 to Bevy 0.18. There are no breaking changes within the Avian API itself for this release, but you must follow Bevy's migration guide to ensure compatibility with the new Bevy version.
Configure Default Collision Layers
mainIn v0.2,
CollisionLayersno longer defaults to "all memberships, all filters". Instead, colliders only belong to the first layer by default (bit0b0001).If you use the
PhysicsLayerderive macro, you must implementDefaultfor your enum and use the#[default]attribute to specify which variant represents the default layer0b0001.#[derive(PhysicsLayer, Default)] enum GameLayer { #[default] Default, Player, Enemy, Ground, }Migrate Joint APIs to v0.4
mainJoints have undergone significant changes in v0.4:
- Location: Joint APIs moved from
dynamics::solver::jointstodynamics::joints. - Trait: The
Jointtrait is removed; use theEntityConstrainttrait or joint-specific helper methods. - Naming:
entity1/entity2$\rightarrow$body1/body2.PrismaticJoint::free_axis$\rightarrow$slider_axis.RevoluteJoint::aligned_axis$\rightarrow$hinge_axis.with_local_anchor_1/2$\rightarrow$with_local_anchor1/2(returnsOption).
- Components: Damping and force properties are removed from joint types. Use
JointDampingandJointForcescomponents instead. - Constraint: Each entity can only hold one type of joint component. To attach a rigid body to multiple bodies, each joint must reside on its own entity.
- Location: Joint APIs moved from
Migrate Broad Phase plugins from v0.5 to v0.6
mainThe
BroadPhasePluginhas been replaced by two separate plugins. To implement broad phase collision detection, you must now use both:BroadPhaseCorePlugin: Sets up necessary resources, system sets, and diagnostics.BvhBroadPhasePlugin: Implements the Bounding Volume Hierarchy (BVH) for efficient AABB overlap detection.
Note that
BroadPhaseSystems::UpdateStructureshas been removed. Acceleration structures are now updated by theColliderTreePluginviaColliderTreeSystems::UpdateAabbs.Run benchmarks for specific dimensions (2D or 3D)
mainTo isolate benchmarks for a specific dimension, disable default features and enable either the
2dor3dfeature flag.# List all 2D benchmarks cargo run --no-default-features --features 2d -- --list # Run all 3D benchmarks with default options cargo run --no-default-features --features 3dUse the new Force API in v0.4
mainAvian 0.4 overhauls the force APIs. The components
ExternalForce,ExternalTorque,ExternalImpulse, andExternalAngularImpulsehave been removed.- Persistent forces/torques: Use
ConstantForceandConstantTorque. - Non-persistent forces (cleared automatically): Use the
ForceshelperQueryData. - Impulses: Impulses can no longer be persistent; use persistent forces instead.
Note: The
ForcePluginmust be enabled (included inPhysicsPluginsby default) for forces to function.- Persistent forces/torques: Use
Update Contact Reporting and Collision Events
mainThe
ContactReportingPluginandPhysicsStepSet::ReportContactshave been removed. Contact reporting is now handled directly byNarrowPhasePlugin.Collision Events
- The
Collisionevent no longer exists. Use theCollisionsresource or theCollidingEntitiescomponent. CollisionStartedandCollisionEndedevents are only sent if at least one entity in the collision has theCollisionEventsEnabledcomponent.- To restore old behavior (events for all entities), register
CollisionEventsEnabledas a required component forCollider:
app.register_required_components::<Collider, CollisionEventsEnabled>();- The
Migrate Contact API and Impulses in v0.4
mainContact APIs have been updated for clarity and accuracy:
- Impulses:
ContactPoint::normal_impulsenow represents the total normal impulse applied at a contact point (not just the warm-starting impulse). To get force, divide by the time step. - Warm Starting: Old warm-starting impulses are now stored in
warm_start_normal_impulseandwarm_start_tangent_impulse. - Contact Points:
local_point1/local_point2are removed. Use world-spaceanchor1/anchor2(relative to center of mass) or the midpointpoint. - Contact Graph:
iter/iter_mut$\rightarrow$iter_active/iter_active_mutoriter_sleeping/iter_sleeping_mut.collisions_with$\rightarrow$contact_pairs_with.add_pair$\rightarrow$add_edge.remove_pair$\rightarrow$remove_edge.
- Impulses:
Migrate Physics Scheduling to FixedPostUpdate
mainAvian now runs physics in Bevy's
FixedPostUpdateby default instead of a custom fixed timestep inPostUpdate. This unifies physics with Bevy's APIs and simplifies scheduling.Configuring Timestep
Previously, you configured the physics timestep using
Time::<Physics>. Now, you should configureTime<Fixed>directly.Old way:
app.insert_resource(Time::new_with(Physics::fixed_hz(60.0)));New way:
app.insert_resource(Time::<Fixed>::from_hz(60.0));Ordering Systems
Because physics now runs in
FixedPostUpdate(which is beforeUpdate), camera following logic or other systems that depend on physics transforms only need to be ordered againstTransformSystem::TransformPropagaterather thanPhysicsSet::Sync.// New ordering for camera following app.add_systems( PostUpdate, camera_follow_player.before(TransformSystem::TransformPropagate), );Removed Types and Methods
The following have been removed:
TimestepModePhysics::from_timestepPhysics::fixed_hzPhysics::fixed_once_hzPhysics::variableTime::<Physics>::from_timestepTime::<Physics>::timestep_modeTime::<Physics>::timestep_mode_mutTime::<Physics>::set_timestep_mode
Migrate to Solver Bodies in v0.4
mainAvian's solver has moved to using
SolverBodyandSolverBodyInertiacomponents for internal calculations to improve performance.Key Changes:
- If you run custom logic inside the substepping loop, you should now use
SolverBodyinstead of individual components likePosition,Rotation,LinearVelocity, orAngularVelocity. - The following components have been removed for rigid bodies:
AccumulatedTranslationPreSolveAccumulatedTranslation(renamed toPreSolveDeltaPosition)PreSolveLinearVelocityPreSolveAngularVelocityPreSolveRotationPreviousRotation
- A new component
PreSolveDeltaRotationhas been added. - The
current_positionhelper onRigidBodyQueryItemandColliderQueryItemis removed. ContactConstraintPointno longer haslocal_anchor1andlocal_anchor2properties.SolverSet::ApplyTranslationis nowSolverSystems::Finalize.
- If you run custom logic inside the substepping loop, you should now use
Install Avian for 2D or 3D applications
mainAdd the appropriate crate to your
Cargo.tomldependencies based on your application's dimension. Use version0.7for Bevy 0.19.To use the most up-to-date version from the main branch, use the git dependency format.
# For 2D applications: [dependencies] avian2d = "0.7" # For 3D applications: [dependencies] avian3d = "0.7" # If you want to use the most up-to-date version, you can follow the main branch: [dependencies] avian3d = { git = "https://github.com/avianphysics/avian", branch = "main" }Modify immutable CollisionLayers and ActiveCollisionHooks
mainCollisionLayersandActiveCollisionHookscomponents are now immutable. To change their values, you must reinsert the components usingEntityCommands::insert.