Avian Physics Engine

repository·main·Indexed 25 days ago

https://github.com/avianphysics/avian

An 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.

Tokens
24K
Snippets
44
Records
131
Agent score
84%

What's inside Avian

  1. Migrate from Avian v0.4 to v0.5

    main
    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.
  2. Configure Default Collision Layers

    main

    In v0.2, CollisionLayers no longer defaults to "all memberships, all filters". Instead, colliders only belong to the first layer by default (bit 0b0001).

    If you use the PhysicsLayer derive macro, you must implement Default for your enum and use the #[default] attribute to specify which variant represents the default layer 0b0001.

    #[derive(PhysicsLayer, Default)]
    enum GameLayer {
        #[default]
        Default,
        Player,
        Enemy,
        Ground,
    }
  3. Migrate Joint APIs to v0.4

    main

    Joints have undergone significant changes in v0.4:

    • Location: Joint APIs moved from dynamics::solver::joints to dynamics::joints.
    • Trait: The Joint trait is removed; use the EntityConstraint trait 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 (returns Option).
    • Components: Damping and force properties are removed from joint types. Use JointDamping and JointForces components 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.
  4. Migrate Broad Phase plugins from v0.5 to v0.6

    main

    The BroadPhasePlugin has 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::UpdateStructures has been removed. Acceleration structures are now updated by the ColliderTreePlugin via ColliderTreeSystems::UpdateAabbs.

  5. Run benchmarks for specific dimensions (2D or 3D)

    main

    To isolate benchmarks for a specific dimension, disable default features and enable either the 2d or 3d feature 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 3d
  6. Use the new Force API in v0.4

    main

    Avian 0.4 overhauls the force APIs. The components ExternalForce, ExternalTorque, ExternalImpulse, and ExternalAngularImpulse have been removed.

    • Persistent forces/torques: Use ConstantForce and ConstantTorque.
    • Non-persistent forces (cleared automatically): Use the Forces helper QueryData.
    • Impulses: Impulses can no longer be persistent; use persistent forces instead.

    Note: The ForcePlugin must be enabled (included in PhysicsPlugins by default) for forces to function.

  7. Update Contact Reporting and Collision Events

    main

    The ContactReportingPlugin and PhysicsStepSet::ReportContacts have been removed. Contact reporting is now handled directly by NarrowPhasePlugin.

    Collision Events

    • The Collision event no longer exists. Use the Collisions resource or the CollidingEntities component.
    • CollisionStarted and CollisionEnded events are only sent if at least one entity in the collision has the CollisionEventsEnabled component.
    • To restore old behavior (events for all entities), register CollisionEventsEnabled as a required component for Collider:
    app.register_required_components::<Collider, CollisionEventsEnabled>();
  8. Migrate Contact API and Impulses in v0.4

    main

    Contact APIs have been updated for clarity and accuracy:

    • Impulses: ContactPoint::normal_impulse now 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_impulse and warm_start_tangent_impulse.
    • Contact Points: local_point1/local_point2 are removed. Use world-space anchor1/anchor2 (relative to center of mass) or the midpoint point.
    • Contact Graph:
      • iter/iter_mut $\rightarrow$ iter_active/iter_active_mut or iter_sleeping/iter_sleeping_mut.
      • collisions_with $\rightarrow$ contact_pairs_with.
      • add_pair $\rightarrow$ add_edge.
      • remove_pair $\rightarrow$ remove_edge.
  9. Migrate Physics Scheduling to FixedPostUpdate

    main

    Avian now runs physics in Bevy's FixedPostUpdate by default instead of a custom fixed timestep in PostUpdate. This unifies physics with Bevy's APIs and simplifies scheduling.

    Configuring Timestep

    Previously, you configured the physics timestep using Time::<Physics>. Now, you should configure Time<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 before Update), camera following logic or other systems that depend on physics transforms only need to be ordered against TransformSystem::TransformPropagate rather than PhysicsSet::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:

    • TimestepMode
    • Physics::from_timestep
    • Physics::fixed_hz
    • Physics::fixed_once_hz
    • Physics::variable
    • Time::<Physics>::from_timestep
    • Time::<Physics>::timestep_mode
    • Time::<Physics>::timestep_mode_mut
    • Time::<Physics>::set_timestep_mode
  10. Migrate to Solver Bodies in v0.4

    main

    Avian's solver has moved to using SolverBody and SolverBodyInertia components for internal calculations to improve performance.

    Key Changes:

    • If you run custom logic inside the substepping loop, you should now use SolverBody instead of individual components like Position, Rotation, LinearVelocity, or AngularVelocity.
    • The following components have been removed for rigid bodies:
      • AccumulatedTranslation
      • PreSolveAccumulatedTranslation (renamed to PreSolveDeltaPosition)
      • PreSolveLinearVelocity
      • PreSolveAngularVelocity
      • PreSolveRotation
      • PreviousRotation
    • A new component PreSolveDeltaRotation has been added.
    • The current_position helper on RigidBodyQueryItem and ColliderQueryItem is removed.
    • ContactConstraintPoint no longer has local_anchor1 and local_anchor2 properties.
    • SolverSet::ApplyTranslation is now SolverSystems::Finalize.
  11. Install Avian for 2D or 3D applications

    main

    Add the appropriate crate to your Cargo.toml dependencies based on your application's dimension. Use version 0.7 for 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" }