Skip to content

Bevy XPBD v0.4.0

Compare
Choose a tag to compare
@Jondolf Jondolf released this 20 Feb 18:47

Bevy XPBD 0.4 features several new features, bug fixes, and quality of life improvements. Here are some highlights:

  • Generic colliders: Bevy XPBD no longer relies on just Collider for collision detection. You can implement custom collision backends!
  • Parry and Nalgebra are optional: The Parry and Nalgebra dependencies are now behind feature flags (enabled by default). If you don't need collision detection or have a custom collision backend, you can disable them!
  • Access contact impulses: It is often useful to know how strong collisions are. This information is now available in Collision events and the Collisions resource.
  • Debug render contacts: Contact normals and impulses can now be debug rendered.
  • Layer rework: Collision layers have been reworked to be more versatile and explicit with less footguns.
  • Bevy 0.13 support: Bevy XPBD has been updated to the latest version of Bevy.
  • Colliders from primitives: Colliders can be created from the new geometric primitives introduced in Bevy 0.13.
  • PhysicsGizmos gizmo config group: Debug rendering has its own gizmo configuration instead of using the global configuration.

Check out the announcement blog post for a more in-depth overview of what's changed and why. A more complete changelog can also be found after the migration guide below.

Migration Guide

Default Features (#327)

The default Collider now requires either the parry-f32 or parry-f64 feature depending on the precision you are using for Bevy XPBD. However, if you don't need colliders or have a custom collision backend, you can leave the feature disabled.

Layer Rework (#313)

Collision layers have been reworked, see #313.

  • Groups are now called memberships and masks are called filters. This also matches Rapier's naming.
  • Memberships and filters use a type called LayerMask, which is a bitmask for layers and a newtype for u32.
  • All methods like add_group, remove_mask, and so on have been removed. Instead, modify the properties directly.
let layers1 = CollisionLayers::new(0b00010, 0b0111);
let layers2 = CollisionLayers::new(GameLayer::Player, [GameLayer::Enemy, GameLayer::Ground]);
let layers3 = CollisionLayers::new(LayerMask(0b0001), LayerMask::ALL);

Modifying layers is now done by modifying the memberships or filters directly:

layers.memberships.remove(GameLayer::Environment);
layers.filters.add([GameLayer::Environment, GameLayer::Tree]);

// Bitwise ops also work since we're accessing the bitmasks/layermasks directly.
layers.memberships |= GameLayer::Player; // You could also use a bitmask like 0b0010.

Debug rendering

The PhysicsDebugConfig resource and PhysicsDebugRenderer system parameter have been removed in favor of the new PhysicsGizmos gizmo configuration group.

Before:

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            PhysicsPlugins::default(),
            PhysicsDebugPlugin::default(),
        ))
        // Configure physics debug rendering
        .insert_resource(PhysicsDebugConfig {
            aabb_color: Some(Color::WHITE),
            ..default()
        })
        .run();
}

After:

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            PhysicsPlugins::default(),
            PhysicsDebugPlugin::default(),
        ))
        // Configure physics debug rendering
        .insert_gizmo_group(
            PhysicsGizmos {
                aabb_color: Some(Color::WHITE),
                ..default()
            },
            GizmoConfig::default(),
        )
        .run();
}

This also allows you to configure e.g. line width for just physics gizmos by configuring their GizmoConfig.

Renamed Collider constructors (#326)

  • Replace Collider::ball with Collider::circle in 2D and Collider::sphere in 3D
  • Replace Collider::cuboid with Collider::rectangle in 2D

Ray and shape casting (#329)

For spatial queries, replace Vec2/Vec3 directions with Direction2d/Direction3d.

// Before
let caster = RayCaster::new(Vec3::ZERO, Vec3::X);

// After
let caster = RayCaster::new(Vec3::ZERO, Direction3d::X);

This applies to RayCaster, ShapeCaster, SpatialQuery methods like cast_ray, and many other methods that use directions.

What's Changed

  • docs: Fix incorrect docs for mass component auto-initialization by @johanhelsing in #234
  • Don't overwrite schedules when adding plugin by @johanhelsing in #236
  • Take child collider rotation into account for contact normals by @Jondolf in #238
  • Fix mesh visibility not being reset when physics debug is disabled by @Jondolf in #242
  • Filter collisions between children of the same rigidbody in broad phase by @mbrea-c in #241
  • Added variant TriMeshWithFlags to ComputedCollider, fix #248 by @Adamkob12 in #251
  • Fix rotations when center of mass is offset by @mbrea-c in #250
  • Use any_orthogonal_vector to get orthogonal vector by @ollef in #255
  • Fix tests and doc examples, make cargo test compile by @Jondolf in #267
  • fix: make clear_forces_and_impulses public by @ActuallyHappening in #257
  • Scale debug rendering of center of mass dot by axis lengths by @Jondolf in #268
  • docs: Added Character Controller recommendation for Bevy Tnua what supports Bevy XPBD by @dror-g in #270
  • Fix Rotation change detection triggering every frame by @Jondolf in #272
  • Don't overwrite Time<Physics> when PhysicsPlugins are added by @johanhelsing in #276
  • Implement MapEntities for AabbIntervals by @johanhelsing in #275
  • Implement MapEntities for collider components by @johanhelsing in #277
  • Apply scale in Collider::set_shape by @Jondolf in #278
  • Fix dead custom constraints link in docs by @PerryPeak in #280
  • Ignore static-static collisions in broad phase by @Jondolf in #283
  • Fix rotation change detection in integrator by @Jondolf in #284
  • Fix static body handling in update_aabb_intervals by @Jondolf in #285
  • Fix DistanceJoint distance limits by @Jondolf in #286
  • Preserve collisions between inactive entities, add sensor example by @TeamDman in #266
  • docs: use the read function for iterating over events by @tremorris1999 in #290
  • docs: corrects other outdated calls to .iter by @tremorris1999 in #291
  • Fix Time inconsistency after substepping loop by @Jondolf in #294
  • Make PreparePlugin configurable by @Rigidity in #292
  • Adding Collider::round_cuboid by @kav in #300
  • Add section about camera following jitter to FAQ by @Jondolf in #305
  • Add intersection and point queries to Collider by @Jondolf in #307
  • Debug render contact normals by @Jondolf in #308
  • Implement cast_ray_predicate to allow filtering the colliders with a function by @Affinator in #297
  • Fix colliders without RigidBody not working by @Jondolf in #323
  • fix raycast does not follow entity transform without rigidbody by @zwazel in #310
  • Store impulses in contacts and refactor contact data by @Jondolf in #324
  • Add ColliderBackendPlugin and support generic colliders by @Jondolf in #311
  • Rework layers by @Jondolf in #313
  • Make Collider optional, allowing usage without Parry or Nalgebra by @Jondolf in #327
  • Fix doc examples by @Jondolf in #330
  • Update to Bevy 0.13 by @Jondolf in #315

New Contributors

Full Changelog: v0.3.0...v0.4.0