Bevy XPBD v0.4.0
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 theCollisions
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 foru32
. - 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
withCollider::circle
in 2D andCollider::sphere
in 3D - Replace
Collider::cuboid
withCollider::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>
whenPhysicsPlugins
are added by @johanhelsing in #276 - Implement
MapEntities
forAabbIntervals
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
- @mattdm made their first contribution in #227
- @mbrea-c made their first contribution in #241
- @Adamkob12 made their first contribution in #251
- @ollef made their first contribution in #255
- @ActuallyHappening made their first contribution in #257
- @dror-g made their first contribution in #270
- @PerryPeak made their first contribution in #280
- @TeamDman made their first contribution in #266
- @tremorris1999 made their first contribution in #290
- @Rigidity made their first contribution in #292
- @kav made their first contribution in #300
- @Affinator made their first contribution in #297
- @zwazel made their first contribution in #310
Full Changelog: v0.3.0...v0.4.0