Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Below are some of the current features of Avian.
- Ergonomic component-based API for raycasts and shapecasts
- Flexible `SpatialQuery` system parameter
- Spatial query filters
- `Transform` interpolation and extrapolation for fixed timesteps
- Debug rendering for colliders, AABBs, contacts, joints, sleeping, axes and spatial queries
- Configurable scheduling and high customizability
- Highly modular plugin architecture, freely extend and replace parts of the engine
Expand Down
7 changes: 7 additions & 0 deletions src/collision/collider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ pub trait ScalableCollider: AnyCollider {
/// Note that a disabled collider will still contribute to the mass properties of the rigid body
/// it is attached to. Set the [`Mass`] of the collider to zero to prevent this.
///
/// [`ColliderDisabled`] only applies to the entity it is attached to, not its children.
///
/// # Example
///
/// ```
Expand Down Expand Up @@ -145,6 +147,11 @@ pub trait ScalableCollider: AnyCollider {
/// }
/// }
/// ```
///
/// # Related Components
///
/// - [`RigidBodyDisabled`]: Disables a rigid body.
/// - [`JointDisabled`]: Disables a joint constraint.
#[derive(Reflect, Clone, Copy, Component, Debug, Default)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
Expand Down
22 changes: 5 additions & 17 deletions src/collision/collider/parry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ impl From<TrimeshFlags> for parry::shape::TriMeshFlags {
/// RigidBody::Dynamic,
#[cfg_attr(feature = "2d", doc = " Collider::circle(0.5),")]
#[cfg_attr(feature = "3d", doc = " Collider::sphere(0.5),")]
/// TransformBundle::from_transform(Transform::from_xyz(0.0, 2.0, 0.0)),
/// Transform::from_xyz(0.0, 2.0, 0.0),
/// ));
#[cfg_attr(
feature = "2d",
Expand Down Expand Up @@ -301,25 +301,13 @@ impl From<TrimeshFlags> for parry::shape::TriMeshFlags {
/// // Spawn the child colliders positioned relative to the rigid body
#[cfg_attr(
feature = "2d",
doc = " children.spawn((
Collider::circle(0.5),
TransformBundle::from_transform(Transform::from_xyz(2.0, 0.0, 0.0)),
));
children.spawn((
Collider::circle(0.5),
TransformBundle::from_transform(Transform::from_xyz(-2.0, 0.0, 0.0)),
));"
doc = " children.spawn((Collider::circle(0.5), Transform::from_xyz(2.0, 0.0, 0.0)));
children.spawn((Collider::circle(0.5), Transform::from_xyz(-2.0, 0.0, 0.0)));"
)]
#[cfg_attr(
feature = "3d",
doc = " children.spawn((
Collider::sphere(0.5),
TransformBundle::from_transform(Transform::from_xyz(2.0, 0.0, 0.0)),
));
children.spawn((
Collider::sphere(0.5),
TransformBundle::from_transform(Transform::from_xyz(-2.0, 0.0, 0.0)),
));"
doc = " children.spawn((Collider::sphere(0.5), Transform::from_xyz(2.0, 0.0, 0.0)));
children.spawn((Collider::sphere(0.5), Transform::from_xyz(-2.0, 0.0, 0.0)));"
)]
/// });
/// }
Expand Down
14 changes: 9 additions & 5 deletions src/dynamics/ccd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,12 @@
//! especially for thin objects spinning at very high speeds. This is typically quite rare however,
//! and speculative collision should work fine for the majority of cases.
//!
//! For an approach that is more expensive but doesn't suffer from ghost collisions
//! or missed collisions, consider using swept CCD, which is described in the following section.
//! Speculative collisions can also absorb some energy in contacts, causing even perfectly elastic
//! objects to lose kinetic energy over several bounces.
//!
//! For an approach that is more expensive but doesn't suffer from ghost collisions,
//! missed collisions, or inaccurate restitution, consider using swept CCD,
//! which is described in the following section.
//!
//! ## Swept CCD
//!
Expand Down Expand Up @@ -333,7 +337,7 @@ impl SpeculativeMargin {
#[cfg_attr(feature = "3d", doc = " LinearVelocity(Vec3::X * 100.0),")]
#[cfg_attr(feature = "2d", doc = " Collider::circle(0.1),")]
#[cfg_attr(feature = "3d", doc = " Collider::sphere(0.1),")]
/// TransformBundle::from_transform(Transform::from_xyz(-10.0, 3.0, 0.0)),
/// Transform::from_xyz(-10.0, 3.0, 0.0),
/// ));
///
/// // Spawn another dynamic rigid body with swept CCD, but this time only considering
Expand All @@ -345,7 +349,7 @@ impl SpeculativeMargin {
#[cfg_attr(feature = "3d", doc = " LinearVelocity(Vec3::X * 100.0),")]
#[cfg_attr(feature = "2d", doc = " Collider::circle(0.1),")]
#[cfg_attr(feature = "3d", doc = " Collider::sphere(0.1),")]
/// TransformBundle::from_transform(Transform::from_xyz(-10.0, -3.0, 0.0)),
/// Transform::from_xyz(-10.0, -3.0, 0.0),
/// ));
///
/// // Spawn a thin, long object rotating at a high speed.
Expand All @@ -366,7 +370,7 @@ impl SpeculativeMargin {
/// RigidBody::Static,
#[cfg_attr(feature = "2d", doc = " Collider::rectangle(0.2, 10.0),")]
#[cfg_attr(feature = "3d", doc = " Collider::cuboid(0.2, 10.0, 10.0),")]
/// TransformBundle::from_transform(Transform::from_xyz(15.0, 0.0, 0.0)),
/// Transform::from_xyz(15.0, 0.0, 0.0),
/// ));
/// }
/// ```
Expand Down
4 changes: 3 additions & 1 deletion src/dynamics/rigid_body/mass_properties/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Mass property functionality for [rigid bodies] and [colliders].
//!
//! # Overview
//!
//! Every dynamic rigid body has [mass], [angular inertia], and a [center of mass].
//! These mass properties determine how the rigid body responds to forces and torques.
//!
Expand Down Expand Up @@ -30,7 +32,7 @@
//! [angular inertia]: components::AngularInertia
//! [center of mass]: components::CenterOfMass
//!
//! # Example
//! ## Example
//!
//! If no mass properties are set, they are computed automatically from attached colliders
//! based on their shape and density.
Expand Down
8 changes: 8 additions & 0 deletions src/dynamics/rigid_body/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ use derive_more::From;
/// - [Lock translational and rotational axes](LockedAxes)
/// - [Dominance]
/// - [Continuous Collision Detection](dynamics::ccd)
/// - [Speculative collision](dynamics::ccd#speculative-collision)
/// - [Swept CCD](dynamics::ccd#swept-ccd)
/// - [`Transform` interpolation and extrapolation](PhysicsInterpolationPlugin)
/// - [Temporarily disabling a rigid body](RigidBodyDisabled)
/// - [Automatic deactivation with sleeping](Sleeping)
#[derive(Reflect, Clone, Copy, Component, Debug, Default, PartialEq, Eq)]
Expand Down Expand Up @@ -349,6 +352,11 @@ pub(crate) type RigidBodyActiveFilter = (Without<RigidBodyDisabled>, Without<Sle
/// }
/// }
/// ```
///
/// # Related Components
///
/// - [`ColliderDisabled`]: Disables a collider.
/// - [`JointDisabled`]: Disables a joint constraint.
#[derive(Reflect, Clone, Copy, Component, Debug, Default)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
Expand Down
1 change: 1 addition & 0 deletions src/dynamics/rigid_body/physics_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ impl From<Scalar> for Friction {
///
/// - Collisions can have more or less bounce than expected, especially when objects are moving very fast.
/// This is largely due to the the sequential solver and [speculative collision](dynamics::ccd#speculative-collision).
/// For more accurate restitution, consider disabling speculative collision and using [`SweptCcd`] instead.
///
/// - An object falling flat on the ground with multiple contact points may tip over on one side or corner a bit.
/// This is because contact points are solved sequentially, and the order of contact points affects the result.
Expand Down
5 changes: 5 additions & 0 deletions src/dynamics/solver/joints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,11 @@ impl AngleLimit {
///
/// Note that when re-enabling the joint, the bodies may snap back violently
/// if they have moved significantly from the constrained positions while the joint was disabled.
///
/// # Related Components
///
/// - [`RigidBodyDisabled`]: Disables a rigid body.
/// - [`ColliderDisabled`]: Disables a collider.
#[derive(Reflect, Clone, Copy, Component, Debug, Default)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serialize", reflect(Serialize, Deserialize))]
Expand Down
38 changes: 24 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
//! **Avian** is an ECS-driven 2D and 3D physics engine for the [Bevy game engine](https://bevyengine.org/).
//!
//! Check out the [GitHub repository](https://github.com/Jondolf/avian)
//! for more information about the design, read the [Getting started](#getting-started)
//! guide below to get up to speed, and take a look at the [Table of contents](#table-of-contents)
//! for more information about the design, read the [Getting Started](#getting-started)
//! guide below to get up to speed, and take a look at the [Table of Contents](#table-of-contents)
//! for an overview of the engine's features and their documentation.
//!
//! You can also check out the [FAQ](#frequently-asked-questions), and if you encounter
Expand Down Expand Up @@ -58,13 +58,14 @@
doc = "| `collider-from-mesh` | Allows you to create [`Collider`]s from `Mesh`es. | Yes |"
)]
//! | `bevy_scene` | Enables [`ColliderConstructorHierarchy`] to wait until a [`Scene`] has loaded before processing it. | Yes |
//! | `bevy_picking` | Enables physics picking support for `bevy_picking` using the [`PhysicsPickingPlugin`]. The plugin must be added separately. | Yes |
//! | `bevy_picking` | Enables physics picking support for [`bevy_picking`] using the [`PhysicsPickingPlugin`]. The plugin must be added separately. | Yes |
//! | `debug-plugin` | Enables physics debug rendering using the [`PhysicsDebugPlugin`]. The plugin must be added separately. | Yes |
//! | `enhanced-determinism` | Enables increased determinism. | No |
//! | `enhanced-determinism` | Enables cross-platform deterministic math, improving determinism across architectures at a small performance cost. | No |
//! | `parallel` | Enables some extra multithreading, which improves performance for larger simulations but can add some overhead for smaller ones. | Yes |
//! | `simd` | Enables [SIMD] optimizations. | No |
//! | `serialize` | Enables support for serialization and deserialization using Serde. | No |
//!
//! [`bevy_picking`]: bevy::picking
//! [SIMD]: https://en.wikipedia.org/wiki/Single_instruction,_multiple_data
//!
//! ### Add the Plugins
Expand Down Expand Up @@ -131,6 +132,7 @@
//! - [Continuous Collision Detection (CCD)](dynamics::ccd)
//! - [Speculative collision](dynamics::ccd#speculative-collision)
//! - [Swept CCD](dynamics::ccd#swept-ccd)
//! - [`Transform` interpolation and extrapolation](PhysicsInterpolationPlugin)
//! - [Temporarily disabling a rigid body](RigidBodyDisabled)
//! - [Automatic deactivation with sleeping](Sleeping)
//!
Expand Down Expand Up @@ -266,14 +268,6 @@
//! larger velocities and forces than you would in 3D. Make sure you set [`Gravity`] to some larger value
//! as well, because its magnitude is `9.81` by default, which is tiny in pixels.
//!
//! ### Why did my rigid body suddenly vanish?
//!
//! Make sure to [give your rigid bodies some mass](RigidBody#adding-mass-properties), either by adding a [`Collider`]
//! or a [`MassPropertiesBundle`]. If your bodies don't have any mass, any physical interaction is likely to
//! instantly give them infinite velocity.
//!
//! Avian should automatically print warnings when it detects bodies with an invalid mass or inertia.
//!
//! ### Why is performance so bad?
//!
//! Make sure you are building your project in release mode using `cargo build --release`.
Expand Down Expand Up @@ -314,8 +308,7 @@
//! }
//! ```
//!
//! If you want *all* rigid bodies to be interpolated or extrapolated by default, you can use
//! [`PhysicsInterpolationPlugin::interpolate_all()`]:
//! To make *all* rigid bodies interpolated by default, use [`PhysicsInterpolationPlugin::interpolate_all()`]:
//!
//! ```no_run
#![cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
Expand All @@ -332,6 +325,23 @@
//!
//! See the [`PhysicsInterpolationPlugin`] for more information.
//!
//! If this does not fix the choppiness, the problem could also be related to system ordering.
//! If you have a system for camera following, make sure it runs *after* physics,
//! but *before* Bevy's transform propagation in `PostUpdate`.
//!
//! ```
//! # use bevy::prelude::*;
//! #
//! # let mut app = App::new();
//! #
//! app.add_systems(
//! PostUpdate,
//! camera_follow_player.before(TransformSystem::TransformPropagate),
//! );
//! #
//! # fn camera_follow_player() {}
//! ```
//!
//! ### Is there a character controller?
//!
//! Avian does not have a built-in character controller, so if you need one,
Expand Down
Loading