Skip to main content

avian3d/
lib.rs

1//! ![Avian Physics](https://raw.githubusercontent.com/Jondolf/avian/avian/assets/branding/logo.svg)
2//!
3//! **Avian** is an ECS-driven 2D and 3D physics engine for the [Bevy game engine](https://bevyengine.org/).
4//!
5//! Check out the [GitHub repository](https://github.com/avianphysics/avian)
6//! for more information about the design, read the [Getting Started](#getting-started)
7//! guide below to get up to speed, and take a look at the [Table of Contents](#table-of-contents)
8//! for an overview of the engine's features and their documentation.
9//!
10//! You can also check out the [FAQ](#frequently-asked-questions), and if you encounter
11//! any further problems, consider saying hello on the [Bevy Discord](https://discord.gg/bevy)!
12//!
13//! # Getting Started
14//!
15//! This short guide should help you get started with Avian.
16//!
17//! ## Add the Dependency
18//!
19//! First, add `avian2d` or `avian3d` to the dependencies in your `Cargo.toml`:
20//!
21//! ```toml
22//! # For 2D applications:
23//! [dependencies]
24//! avian2d = "0.7"
25//!
26//! # For 3D applications:
27//! [dependencies]
28//! avian3d = "0.7"
29//!
30//! # If you want to use the most up-to-date version, you can follow the main branch:
31//! [dependencies]
32//! avian3d = { git = "https://github.com/avianphysics/avian", branch = "main" }
33//! ```
34//!
35//! You can specify features by disabling the default features and manually adding
36//! the feature flags you want:
37//!
38//! ```toml
39//! [dependencies]
40//! # Add 3D Avian with double-precision floating point numbers.
41//! # `parry-f64` enables collision detection using Parry.
42//! avian3d = { version = "0.7", default-features = false, features = ["3d", "f64", "parry-f64", "xpbd_joints"] }
43//! ```
44//!
45//! ## Feature Flags
46//!
47//! | Feature                | Description                                                                                                                                        | Default feature |
48//! | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
49//! | `2d`                   | Enables 2D physics. Incompatible with `3d`.                                                                                                        | Yes (`avian2d`) |
50//! | `3d`                   | Enables 3D physics. Incompatible with `2d`.                                                                                                        | Yes (`avian3d`) |
51//! | `f32`                  | Enables `f32` precision for physics. Incompatible with `f64`.                                                                                      | Yes             |
52//! | `f64`                  | Enables `f64` precision for physics. Incompatible with `f32`.                                                                                      | No              |
53//! | `default-collider`     | Enables the default [`Collider`]. Required for [spatial queries](spatial_query). Requires either the `parry-f32` or `parry-f64` feature.           | Yes             |
54//! | `parry-f32`            | Enables the `f32` version of the Parry collision detection library. Also enables the `default-collider` feature.                                   | Yes             |
55//! | `parry-f64`            | Enables the `f64` version of the Parry collision detection library. Also enables the `default-collider` feature.                                   | No              |
56//! | `xpbd_joints`          | Enables support for [XPBD joints](dynamics::solver::xpbd).                            .                                                            | Yes             |
57#![cfg_attr(
58    feature = "3d",
59    doc = "| `collider-from-mesh`   | Allows you to create [`Collider`]s from `Mesh`es.                                                                                                  | Yes             |"
60)]
61//! | `bevy_scene`           | Enables [`ColliderConstructorHierarchy`] to wait until a [`Scene`] has loaded before processing it.                                                 | Yes             |
62//! | `bevy_picking`         | Enables physics picking support for [`bevy_picking`] using the [`PhysicsPickingPlugin`]. The plugin must be added separately.                       | Yes             |
63//! | `bevy_diagnostic`      | Enables writing [physics diagnostics] to the [`DiagnosticsStore`] with the [`PhysicsDiagnosticsPlugin`]. The plugin must be added separately.       | No              |
64//! | `diagnostic_ui`        | Enables [physics diagnostics] UI for performance timers and counters using the [`PhysicsDiagnosticsUiPlugin`]. The plugin must be added separately. | No              |
65//! | `debug-plugin`         | Enables physics debug rendering using the [`PhysicsDebugPlugin`]. The plugin must be added separately.                                              | Yes             |
66//! | `enhanced-determinism` | Enables cross-platform deterministic math, improving determinism across architectures at a small performance cost.                                  | No              |
67//! | `parallel`             | Enables some extra multithreading, which improves performance for larger simulations but can add some overhead for smaller ones.                    | Yes             |
68//! | `simd`                 | Enables [SIMD] optimizations.                                                                                                                       | No              |
69//! | `serialize`            | Enables support for serialization and deserialization using Serde.                                                                                  | No              |
70//! | `validate`             | Enables additional correctness checks and validation at the cost of worse performance.                                                              | No              |
71//!
72//! [`bevy_picking`]: bevy::picking
73//! [physics diagnostics]: diagnostics
74//! [`DiagnosticsStore`]: bevy::diagnostic::DiagnosticsStore
75//! [SIMD]: https://en.wikipedia.org/wiki/Single_instruction,_multiple_data
76//!
77//! ## Add the Plugins
78//!
79//! Avian is designed to be very modular. It is built from several [plugins](PhysicsPlugins) that
80//! manage different parts of the engine. These plugins can be easily initialized and configured through
81//! the [`PhysicsPlugins`] plugin group.
82//!
83//! ```no_run
84#![cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
85#![cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
86//! use bevy::prelude::*;
87//!
88//! fn main() {
89//!     App::new()
90//!         .add_plugins((DefaultPlugins, PhysicsPlugins::default()))
91//!         // ...your other plugins, systems and resources
92//!         .run();
93//! }
94//! ```
95//!
96//! Now you can use all of Avian's components and resources to build whatever you want!
97//!
98//! For example, adding a [rigid body](RigidBody) with a [collider](Collider) is as simple as spawning an entity
99//! with the [`RigidBody`] and [`Collider`] components:
100//!
101//! ```
102#![cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
103#![cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
104//! use bevy::prelude::*;
105//!
106//! fn setup(mut commands: Commands) {
107#![cfg_attr(
108    feature = "2d",
109    doc = "    commands.spawn((RigidBody::Dynamic, Collider::circle(0.5)));"
110)]
111#![cfg_attr(
112    feature = "3d",
113    doc = "    commands.spawn((RigidBody::Dynamic, Collider::sphere(0.5)));"
114)]
115//! }
116//! ```
117//!
118//! You can find lots of [usage examples](https://github.com/avianphysics/avian#more-examples)
119//! in the project's [repository](https://github.com/avianphysics/avian).
120//!
121//! # Table of Contents
122//!
123//! Below is a structured overview of the documentation for the various
124//! features of the engine.
125//!
126//! ## Rigid Body Dynamics
127//!
128//! - [Rigid body types](RigidBody#rigid-body-types)
129//! - [Creating rigid bodies](RigidBody#creation)
130//! - [Movement](RigidBody#movement)
131//!     - [Linear](LinearVelocity) and [angular](AngularVelocity) velocity
132//!     - [External forces, impulses, and acceleration](dynamics::rigid_body::forces)
133//! - [Gravity] and [gravity scale](GravityScale)
134//! - [Mass properties](dynamics::rigid_body::mass_properties)
135//! - [Linear](LinearDamping) and [angular](AngularDamping) velocity damping
136//! - [Lock translational and rotational axes](LockedAxes)
137//! - [Dominance]
138//! - [Continuous Collision Detection (CCD)](dynamics::ccd)
139//!     - [Speculative collision](dynamics::ccd#speculative-collision)
140//!     - [Swept CCD](dynamics::ccd#swept-ccd)
141//! - [`Transform` interpolation and extrapolation](PhysicsInterpolationPlugin)
142//! - [Temporarily disabling a rigid body](RigidBodyDisabled)
143//! - [Automatic deactivation with sleeping](Sleeping)
144//!
145//! See the [`dynamics`] module for more details about rigid body dynamics in Avian.
146//!
147//! ## Collision Detection
148//!
149//! - [Colliders](Collider)
150//!     - [Creation](Collider#creation)
151//!     - [Density](ColliderDensity)
152//!     - [Friction] and [restitution](Restitution) (bounciness)
153//!     - [Collision layers](CollisionLayers)
154//!     - [Sensors](Sensor)
155#![cfg_attr(
156    feature = "3d",
157    doc = "- Generating colliders for meshes and scenes with [`ColliderConstructor`] and [`ColliderConstructorHierarchy`]"
158)]
159//! - [Get colliding entities](CollidingEntities)
160//! - [Collision events](collision#collision-events)
161//! - [Accessing collision data](Collisions)
162//! - [Filtering and modifying contacts with hooks](CollisionHooks)
163//! - [Manual contact queries](collision::collider::contact_query)
164//! - [Temporarily disabling a collider](ColliderDisabled)
165//!
166//! See the [`collision`] module for more details about collision detection and colliders in Avian.
167//!
168//! ## Constraints and Joints
169//!
170//! - [Joints](dynamics::joints)
171//!     - [Fixed joint](FixedJoint)
172//!     - [Distance joint](DistanceJoint)
173//!     - [Prismatic joint](PrismaticJoint)
174//!     - [Revolute joint](RevoluteJoint)
175#![cfg_attr(feature = "3d", doc = "    - [Spherical joint](SphericalJoint)")]
176//! - [Temporarily disabling a joint](JointDisabled)
177#![cfg_attr(
178    feature = "xpbd_joints",
179    doc = "- [Custom XPBD constraints](dynamics::solver::xpbd#constraints) (advanced)"
180)]
181//!
182//! Joint motors and articulations are not supported yet, but they will be implemented in a future release.
183//!
184//! ## Spatial Queries
185//!
186//! - [Spatial query types](spatial_query)
187//!     - [Raycasting](spatial_query#raycasting) and [`RayCaster`]
188//!     - [Shapecasting](spatial_query#shapecasting) and [`ShapeCaster`]
189//!     - [Point projection](spatial_query#point-projection)
190//!     - [Intersection tests](spatial_query#intersection-tests)
191//! - [Spatial query filters](SpatialQueryFilter)
192//! - [The `SpatialQuery` system parameter](SpatialQuery)
193//!
194//! ## Configuration
195//!
196//! - [Gravity]
197//! - [`Transform` interpolation and extrapolation](PhysicsInterpolationPlugin)
198//! - [Physics speed](Physics#physics-speed)
199//! - [Configure simulation fidelity with substeps](SubstepCount)
200//!
201//! ## Debugging and Profiling
202//!
203//! - [Physics debug rendering](PhysicsDebugPlugin)
204//! - [Physics diagnostics](diagnostics)
205//!
206//! ## Scheduling
207//!
208//! - [Schedules and sets](PhysicsSchedulePlugin#schedules-and-sets)
209//!     - [`PhysicsSystems`]
210//!     - [`PhysicsSchedule`] and [`PhysicsStepSystems`]
211//!     - [`SubstepSchedule`]
212//!     - [`SolverSystems`] and [`SubstepSolverSystems`](dynamics::solver::schedule::SubstepSolverSystems)
213//!     - [`SpatialQuerySystems`]
214//!     - Many more internal system sets
215//! - [Configure the schedule used for running physics](PhysicsPlugins#custom-schedule)
216//! - [Pausing, resuming and stepping physics](Physics#pausing-resuming-and-stepping-physics)
217//! - [Usage on servers](#can-the-engine-be-used-on-servers)
218//!
219//! ## Architecture
220//!
221//! - [List of plugins and their responsibilities](PhysicsPlugins)
222//! - [Custom plugins](PhysicsPlugins#custom-plugins)
223//!
224//! # Frequently Asked Questions
225//!
226//! - [How does Avian compare to Rapier and bevy_rapier?](#how-does-avian-compare-to-rapier-and-bevy_rapier)
227//! - [Why is nothing happening?](#why-is-nothing-happening)
228//! - [Why is everything moving so slowly?](#why-is-everything-moving-so-slowly)
229//! - [Why did my rigid body suddenly vanish?](#why-did-my-rigid-body-suddenly-vanish)
230//! - [Why is performance so bad?](#why-is-performance-so-bad)
231//! - [Why does movement look choppy?](#why-does-movement-look-choppy)
232//! - [Is there a character controller?](#is-there-a-character-controller)
233//! - [Why are there separate `Position` and `Rotation` components?](#why-are-there-separate-position-and-rotation-components)
234//! - [Can the engine be used on servers?](#can-the-engine-be-used-on-servers)
235//! - [Something else?](#something-else)
236//!
237//! ## How does Avian compare to Rapier and bevy_rapier?
238//!
239//! Rapier is the biggest and most used physics engine in the Rust ecosystem, and it is currently
240//! the most mature and feature-rich option.
241//!
242//! `bevy_rapier` is a great physics integration for Bevy, but it does have several problems:
243//!
244//! - It has to maintain a separate physics world and synchronize a ton of data with Bevy each frame
245//! - The source code is difficult to inspect, as the vast majority of it is glue code and wrappers
246//! for Bevy
247//! - It has poor docs.rs documentation, and the documentation on rapier.rs is often outdated and
248//! missing features
249//! - Overall, it doesn't have a native ECS-like feel
250//!
251//! Avian on the other hand is built *for* Bevy *with* Bevy, and it uses the ECS for both the internals
252//! and the public API. This removes the need for a separate physics world, reduces overhead, and makes
253//! the source code much more approachable and easy to inspect for Bevy users.
254//!
255//! In part thanks to Bevy's modular architecture and the ECS, Avian is also highly composable,
256//! as it consists of several independent plugins and provides lots of options for configuration and extensions,
257//! from [custom schedules](PhysicsPlugins#custom-schedule) and [plugins](PhysicsPlugins#custom-plugins) to
258//! [custom joints](dynamics::joints#custom-joints) and [constraints](dynamics::solver::xpbd#custom-constraints).
259//!
260//! One disadvantage of Avian is that it is still relatively young, so it can have more bugs,
261//! some missing features, and fewer community resources and third party crates. However, it is growing quite
262//! rapidly, and it is already pretty close to feature-parity with Rapier.
263//!
264//! At the end of the day, both engines are solid options. If you are looking for a more mature and tested
265//! physics integration, `bevy_rapier` is the better choice, but if you prefer an engine with less overhead
266//! and a more native Bevy integration, consider using Avian. Their core APIs are also quite similar,
267//! so switching between them shouldn't be too difficult.
268//!
269//! ## Why is nothing happening?
270//!
271//! Make sure you have added the [`PhysicsPlugins`] plugin group and you have given your rigid bodies
272//! a [`RigidBody`] component. See the [getting started](#getting-started) section.
273//!
274//! ## Why is everything moving so slowly?
275//!
276//! If your application is in 2D, you might be using pixels as length units. This will require you to use
277//! larger velocities and forces than you would in 3D. Make sure you set [`Gravity`] to some larger value
278//! as well, because its magnitude is `9.81` by default, which is tiny in pixels.
279//!
280//! ## Why is performance so bad?
281//!
282//! It is highly recommended to enable some optimizations for debug builds, or to run your project
283//! in release mode. This can have over a 100x performance impact in some cases.
284//!
285//! Add the following to your `Cargo.toml` to enable optimizations for debug builds:
286//!
287//! ```toml
288//! # Enable a small amount of optimization in the dev profile.
289//! [profile.dev]
290//! opt-level = 1
291//!
292//! # Enable a large amount of optimization in the dev profile for dependencies.
293//! [profile.dev.package."*"]
294//! opt-level = 3
295//! ```
296//!
297//! You can also further optimize release builds by setting the number of codegen units to `1`,
298//! although this will also increase build times.
299//!
300//! ```toml
301//! [profile.release]
302//! codegen-units = 1
303//! ```
304//!
305//! If you still have performance issues, consider enabling the [`PhysicsDiagnosticsPlugin`]
306//! and [`PhysicsDiagnosticsUiPlugin`] (requires the `diagnostic_ui` feature) to see where time is being spent.
307//! See the [diagnostics](diagnostics) module for more information.
308//!
309//! ## Why does movement look choppy?
310//!
311//! To produce consistent, frame rate independent behavior, physics by default runs
312//! in the [`FixedPostUpdate`] schedule with a fixed timestep, meaning that the time between
313//! physics ticks remains constant. On some frames, physics can either not run at all or run
314//! more than once to catch up to real time. This can lead to visible stutter for movement.
315//!
316//! This stutter can be resolved by *interpolating* or *extrapolating* the positions of physics objects
317//! in between physics ticks. Avian has built-in support for this through the [`PhysicsInterpolationPlugin`],
318//! which is included in the [`PhysicsPlugins`] by default.
319//!
320//! Interpolation can be enabled for an individual entity by adding the [`TransformInterpolation`] component:
321//!
322//! ```
323#![cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
324#![cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
325//! # use bevy::prelude::*;
326//! #
327//! fn setup(mut commands: Commands) {
328//!     // Enable interpolation for this rigid body.
329//!     commands.spawn((
330//!         RigidBody::Dynamic,
331//!         Transform::default(),
332//!         TransformInterpolation,
333//!     ));
334//! }
335//! ```
336//!
337//! To make *all* rigid bodies interpolated by default, use [`PhysicsInterpolationPlugin::interpolate_all()`]:
338//!
339//! ```no_run
340#![cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
341#![cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
342//! # use bevy::prelude::*;
343//! #
344//! fn main() {
345//!    App::new()
346//!       .add_plugins(PhysicsPlugins::default().set(PhysicsInterpolationPlugin::interpolate_all()))
347//!       // ...
348//!       .run();
349//! }
350//! ```
351//!
352//! See the [`PhysicsInterpolationPlugin`] for more information.
353//!
354//! If this does not fix the choppiness, the problem could also be related to system ordering.
355//! If you have a system for camera following, make sure it runs *after* physics,
356//! but *before* Bevy's transform propagation in `PostUpdate`.
357//!
358//! ```
359//! # use bevy::prelude::*;
360//! #
361//! # let mut app = App::new();
362//! #
363//! app.add_systems(
364//!     PostUpdate,
365//!     camera_follow_player.before(TransformSystems::Propagate),
366//! );
367//! #
368//! # fn camera_follow_player() {}
369//! ```
370//!
371//! ## Is there a character controller?
372//!
373//! Avian does not have a built-in character controller yet. However, it has a [`MoveAndSlide`]
374//! system parameter with utilities for implementing your own kinematic character controllers.
375//! See its documentation for more information.
376//!
377//! There are also some third party character controllers such as [`bevy_ahoy`](https://github.com/janhohenheim/bevy_ahoy)
378//! (kinematic) and [`bevy_tnua`](https://github.com/idanarye/bevy-tnua) (dynamic) that work with Avian.
379//!
380//! For custom character controllers, you can take a look at the
381#![cfg_attr(
382    feature = "2d",
383    doc = "[`dynamic_character_2d`] and [`kinematic_character_2d`] examples to get started."
384)]
385#![cfg_attr(
386    feature = "3d",
387    doc = "[`dynamic_character_3d`] and [`kinematic_character_3d`] examples to get started."
388)]
389//!
390#![cfg_attr(
391    feature = "2d",
392    doc = "[`dynamic_character_2d`]: https://github.com/avianphysics/avian/tree/main/crates/avian2d/examples/dynamic_character_2d
393[`kinematic_character_2d`]: https://github.com/avianphysics/avian/tree/main/crates/avian2d/examples/kinematic_character_2d"
394)]
395#![cfg_attr(
396    feature = "3d",
397    doc = "[`dynamic_character_3d`]: https://github.com/avianphysics/avian/tree/main/crates/avian3d/examples/dynamic_character_3d
398[`kinematic_character_3d`]: https://github.com/avianphysics/avian/tree/main/crates/avian3d/examples/kinematic_character_3d"
399)]
400//!
401//! ## Why are there separate `Position` and `Rotation` components?
402//!
403//! While `Transform` can be used for the vast majority of things, Avian internally
404//! uses separate [`Position`] and [`Rotation`] components. These are automatically
405//! kept in sync by the [`PhysicsTransformPlugin`].
406//!
407//! There are several reasons why the separate components are currently used.
408//!
409//! - Position and rotation should be global from the physics engine's point of view.
410//! - Transform scale and shearing can cause issues and rounding errors in physics.
411//! - Transform hierarchies can be problematic.
412//! - There is no `f64` version of `Transform`.
413//! - There is no 2D version of `Transform` (yet), and having a 2D version can optimize several computations.
414//! - When position and rotation are separate, we can technically have more systems running in parallel.
415//! - Only rigid bodies have rotation, particles typically don't (although we don't make a distinction yet).
416//!
417//! In external projects however, using [`Position`] and [`Rotation`] is only necessary when you
418//! need to manage positions within [`PhysicsSystems::StepSimulation`]. Elsewhere, you should be able to use `Transform`.
419//!
420//! There is also a possibility that we will revisit this if/when Bevy has a `Transform2d` component.
421//! Using `Transform` feels more idiomatic and simple, so it would be nice if it could be used directly
422//! as long as we can get around the drawbacks.
423//!
424//! ## Can the engine be used on servers?
425//!
426//! Yes! Networking often requires running the simulation in a specific schedule, and in Avian it is straightforward
427//! to [set the schedule that runs physics](PhysicsPlugins#custom-schedule) and [configure the timestep](Physics) if needed.
428//! By default, physics runs at a fixed timestep in [`FixedPostUpdate`].
429//!
430//! ## Something else?
431//!
432//! Physics engines are very large and Avian is still young, so stability issues and bugs are to be expected.
433//!
434//! If you encounter issues, please consider first taking a look at the
435//! [issues on GitHub](https://github.com/avianphysics/avian/issues) and
436//! [open a new issue](https://github.com/avianphysics/avian/issues/new) if there already isn't one regarding your problem.
437//!
438//! You can also come and say hello on the [Bevy Discord server](https://discord.com/invite/gMUk5Ph).
439//! There, you can find an Avian Physics topic on the `#ecosystem-crates` channel where you can ask questions.
440//!
441//! # License
442//!
443//! Avian is free and open source. All code in the Avian repository is dual-licensed under either:
444//!
445//! - MIT License ([LICENSE-MIT](https://github.com/avianphysics/avian/blob/main/LICENSE-MIT)
446//! or <http://opensource.org/licenses/MIT>)
447//! - Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/avianphysics/avian/blob/main/LICENSE-APACHE)
448//! or <http://www.apache.org/licenses/LICENSE-2.0>)
449//!
450//! at your option.
451
452#![doc(
453    html_logo_url = "https://raw.githubusercontent.com/Jondolf/avian/avian/assets/branding/icon.png",
454    html_favicon_url = "https://raw.githubusercontent.com/Jondolf/avian/avian/assets/branding/icon.png"
455)]
456#![allow(
457    unexpected_cfgs,
458    clippy::type_complexity,
459    clippy::too_many_arguments,
460    rustdoc::invalid_rust_codeblocks
461)]
462#![warn(clippy::doc_markdown, missing_docs)]
463
464#[cfg(all(not(feature = "f32"), not(feature = "f64")))]
465compile_error!("either feature \"f32\" or \"f64\" must be enabled");
466
467#[cfg(all(feature = "f32", feature = "f64"))]
468compile_error!("feature \"f32\" and feature \"f64\" cannot be enabled at the same time");
469
470#[cfg(all(not(feature = "2d"), not(feature = "3d")))]
471compile_error!("either feature \"2d\" or \"3d\" must be enabled");
472
473#[cfg(all(feature = "2d", feature = "3d"))]
474compile_error!("feature \"2d\" and feature \"3d\" cannot be enabled at the same time");
475
476#[cfg(all(
477    feature = "default-collider",
478    feature = "f32",
479    not(feature = "parry-f32")
480))]
481compile_error!(
482    "feature \"default-collider\" requires the feature \"parry-f32\" when \"f32\" is enabled"
483);
484
485#[cfg(all(
486    feature = "default-collider",
487    feature = "f64",
488    not(feature = "parry-f64")
489))]
490compile_error!(
491    "feature \"default-collider\" requires the feature \"parry-f64\" when \"f64\" is enabled"
492);
493
494extern crate alloc;
495
496#[cfg(all(feature = "2d", feature = "parry-f32"))]
497pub extern crate parry2d as parry;
498
499#[cfg(all(feature = "2d", feature = "parry-f64"))]
500pub extern crate parry2d_f64 as parry;
501
502#[cfg(all(feature = "3d", feature = "parry-f32"))]
503pub extern crate parry3d as parry;
504
505#[cfg(all(feature = "3d", feature = "parry-f64"))]
506pub extern crate parry3d_f64 as parry;
507
508#[cfg(all(
509    feature = "default-collider",
510    any(feature = "parry-f32", feature = "parry-f64")
511))]
512pub mod character_controller;
513pub mod collider_tree;
514pub mod collision;
515#[cfg(feature = "debug-plugin")]
516pub mod debug_render;
517pub mod diagnostics;
518pub mod dynamics;
519pub mod interpolation;
520pub mod math;
521pub mod physics_transform;
522#[cfg(feature = "bevy_picking")]
523pub mod picking;
524pub mod schedule;
525pub mod spatial_query;
526
527pub mod data_structures;
528
529// TODO: Where should this go?
530pub(crate) mod ancestor_marker;
531
532/// Re-exports common components, bundles, resources, plugins and types.
533pub mod prelude {
534    #[cfg(feature = "debug-plugin")]
535    pub use crate::debug_render::*;
536    #[cfg(feature = "bevy_diagnostic")]
537    pub use crate::diagnostics::PhysicsDiagnosticsPlugin;
538    #[cfg(feature = "diagnostic_ui")]
539    pub use crate::diagnostics::ui::{PhysicsDiagnosticsUiPlugin, PhysicsDiagnosticsUiSettings};
540    #[cfg(feature = "default-collider")]
541    pub(crate) use crate::physics_transform::RotationValue;
542    #[cfg(feature = "bevy_picking")]
543    pub use crate::picking::{
544        PhysicsPickable, PhysicsPickingFilter, PhysicsPickingPlugin, PhysicsPickingSettings,
545    };
546    #[expect(deprecated)]
547    pub use crate::{
548        PhysicsPlugins,
549        collider_tree::{ColliderTreeOptimization, ColliderTreePlugin, TreeOptimizationMode},
550        collision::prelude::*,
551        dynamics::{self, ccd::SpeculativeMargin, prelude::*},
552        interpolation::*,
553        physics_transform::{PhysicsTransformHelper, PhysicsTransformPlugin, Position, Rotation},
554        schedule::{
555            Physics, PhysicsSchedule, PhysicsSchedulePlugin, PhysicsSet, PhysicsStepSet,
556            PhysicsStepSystems, PhysicsSystems, PhysicsTime, Substeps,
557        },
558        spatial_query::{self, *},
559    };
560
561    #[cfg(all(
562        feature = "default-collider",
563        any(feature = "parry-f32", feature = "parry-f64")
564    ))]
565    pub use crate::character_controller::prelude::*;
566    pub(crate) use crate::{
567        diagnostics::AppDiagnosticsExt,
568        math::*,
569        physics_transform::{PreSolveDeltaPosition, PreSolveDeltaRotation},
570        schedule::TimePrecisionAdjusted,
571    };
572    pub use avian_derive::*;
573}
574
575mod utils;
576
577#[cfg(test)]
578mod tests;
579
580use bevy::{
581    app::PluginGroupBuilder,
582    ecs::{intern::Interned, schedule::ScheduleLabel, system::SystemParamItem},
583    prelude::*,
584};
585#[allow(unused_imports)]
586use prelude::*;
587
588/// A plugin group containing Avian's plugins.
589///
590/// # Plugins
591///
592/// By default, the following plugins will be added:
593///
594/// | Plugin                            | Description                                                                                                                                                |
595/// | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
596/// | [`PhysicsSchedulePlugin`]         | Sets up the physics engine by initializing the necessary schedules, sets and resources.                                                                    |
597/// | [`ColliderBackendPlugin`]         | Handles generic collider backend logic, like initializing colliders and AABBs and updating related components.                                             |
598/// | [`ColliderHierarchyPlugin`]       | Manages [`ColliderOf`] relationships based on the entity hierarchy.                                                                                        |
599/// | [`ColliderTransformPlugin`]       | Propagates and updates transforms for colliders.
600#[cfg_attr(
601    all(feature = "collider-from-mesh", feature = "default-collider"),
602    doc = "| [`ColliderCachePlugin`]           | Caches colliders created from meshes. Requires `collider-from-mesh` and `default-collider` features.                                                       |"
603)]
604/// | [`ColliderTreePlugin`]            | Manages [`ColliderTrees`] for broad phase collision detection and spatial queries.                                                                         |
605/// | [`BroadPhaseCorePlugin`]          | The core [broad phase] plugin that sets up the required resources, system sets, and diagnostics.                                                           |
606/// | [`BvhBroadPhasePlugin`]           | A [broad phase] plugin that uses a [Bounding Volume Hierarchy (BVH)][BVH] to efficiently find pairs of colliders with overlapping AABBs.                   |
607/// | [`NarrowPhasePlugin`]             | Manages contacts and generates contact constraints.                                                                                                        |
608/// | [`SolverPlugins`]                 | A plugin group for the physics solver's plugins. See the plugin group's documentation for more information.                                                |
609/// | [`JointPlugin`]                   | A plugin for managing and initializing [joints](dynamics::joints). Does *not* include the actual joint solver.                                             |
610/// | [`MassPropertyPlugin`]            | Manages mass properties of dynamic [rigid bodies](RigidBody).                                                                                              |
611/// | [`ForcePlugin`]                   | Manages and applies external forces, torques, and acceleration for rigid bodies. See the [module-level documentation](dynamics::rigid_body::forces).       |
612/// | [`SpatialQueryPlugin`]            | Handles spatial queries like [raycasting](spatial_query#raycasting) and [shapecasting](spatial_query#shapecasting).                                        |
613/// | [`PhysicsInterpolationPlugin`]    | [`Transform`] interpolation and extrapolation for rigid bodies.                                                                                            |
614/// | [`PhysicsTransformPlugin`]        | Manages physics transforms and synchronizes them with [`Transform`].                                                                                       |
615///
616/// Optional additional plugins include:
617///
618/// | Plugin                            | Description                                                                                                                                                |
619/// | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
620/// | [`PhysicsPickingPlugin`]          | Enables a physics picking backend for [`bevy_picking`](bevy::picking) (only with `bevy_picking` feature enabled).                                          |
621/// | [`PhysicsDebugPlugin`]            | Renders physics objects and events like [AABBs](ColliderAabb) and contacts for debugging purposes (only with `debug-plugin` feature enabled).              |
622/// | [`PhysicsDiagnosticsPlugin`]      | Writes [physics diagnostics](diagnostics) to the [`DiagnosticsStore`] (only with `bevy_diagnostic` feature enabled).                                       |
623/// | [`PhysicsDiagnosticsUiPlugin`]    | Displays [physics diagnostics](diagnostics) with a debug UI overlay (only with `diagnostic_ui` feature enabled).                                           |
624///
625/// [`ColliderTrees`]: collider_tree::ColliderTrees
626/// [broad phase]: collision::broad_phase
627/// [BVH]: https://en.wikipedia.org/wiki/Bounding_volume_hierarchy
628/// [`DiagnosticsStore`]: bevy::diagnostic::DiagnosticsStore
629///
630/// Refer to the documentation of the plugins for more information about their responsibilities and implementations.
631///
632/// # World Scale
633///
634/// The [`PhysicsLengthUnit`] resource is a units-per-meter scaling factor
635/// that adjusts the engine's internal properties to the scale of the world.
636/// It is recommended to configure the length unit to match the approximate length
637/// of the average dynamic object in the world to get the best simulation results.
638///
639/// For example, a 2D game might use pixels as units and have an average object size
640/// of around 100 pixels. By setting the length unit to `100.0`, the physics engine
641/// will interpret 100 pixels as 1 meter for internal thresholds, improving stability.
642///
643/// The length unit can be set by inserting the resource like normal,
644/// but it can also be specified through the [`PhysicsPlugins`] plugin group.
645///
646/// ```no_run
647/// # #[cfg(feature = "2d")]
648/// use avian2d::prelude::*;
649/// use bevy::prelude::*;
650///
651/// # #[cfg(feature = "2d")]
652/// fn main() {
653///     App::new()
654///         .add_plugins((
655///             DefaultPlugins,
656///             // A 2D game with 100 pixels per meter
657///             PhysicsPlugins::default().with_length_unit(100.0),
658///         ))
659///         .run();
660/// }
661/// # #[cfg(not(feature = "2d"))]
662/// # fn main() {} // Doc test needs main
663/// ```
664///
665/// # Custom Schedule
666///
667/// You can run the [`PhysicsSchedule`] in any schedule you want by specifying the schedule when adding the plugin group:
668///
669/// ```no_run
670#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
671#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
672/// use bevy::prelude::*;
673///
674/// fn main() {
675///     App::new()
676///         // Run physics at a variable timestep in `PostUpdate`.
677///         .add_plugins((DefaultPlugins, PhysicsPlugins::new(PostUpdate)))
678///         .run();
679/// }
680/// ```
681pub struct PhysicsPlugins {
682    schedule: Interned<dyn ScheduleLabel>,
683    length_unit: Scalar,
684}
685
686impl PhysicsPlugins {
687    /// Creates a [`PhysicsPlugins`] plugin group using the given schedule for running the [`PhysicsSchedule`].
688    ///
689    /// The default schedule is `FixedPostUpdate`.
690    pub fn new(schedule: impl ScheduleLabel) -> Self {
691        Self {
692            schedule: schedule.intern(),
693            length_unit: 1.0,
694        }
695    }
696
697    /// Adds the given [`CollisionHooks`] for user-defined contact filtering and modification.
698    ///
699    /// Returns a [`PhysicsPluginsWithHooks`] plugin group, which wraps the original [`PhysicsPlugins`],
700    /// and applies the provided hooks. Only one set of collision hooks can be defined per application.
701    pub fn with_collision_hooks<H: CollisionHooks + 'static>(self) -> PhysicsPluginsWithHooks<H>
702    where
703        for<'w, 's> SystemParamItem<'w, 's, H>: CollisionHooks,
704    {
705        PhysicsPluginsWithHooks::<H> {
706            plugins: self,
707            _phantom: core::marker::PhantomData,
708        }
709    }
710
711    /// Sets the value used for the [`PhysicsLengthUnit`], a units-per-meter scaling factor
712    /// that adjusts the engine's internal properties to the scale of the world.
713    ///
714    /// For example, a 2D game might use pixels as units and have an average object size
715    /// of around 100 pixels. By setting the length unit to `100.0`, the physics engine
716    /// will interpret 100 pixels as 1 meter for internal thresholds, improving stability.
717    ///
718    /// Note that this is *not* used to scale forces or any other user-facing inputs or outputs.
719    /// Instead, the value is only used to scale some internal length-based tolerances, such as
720    /// [`SleepingThreshold::linear`] and [`NarrowPhaseConfig::default_speculative_margin`],
721    /// as well as the scale used for [debug rendering](PhysicsDebugPlugin).
722    ///
723    /// Choosing the appropriate length unit can help improve stability and robustness.
724    ///
725    /// # Example
726    ///
727    /// ```no_run
728    /// # #[cfg(feature = "2d")]
729    /// use avian2d::prelude::*;
730    /// use bevy::prelude::*;
731    ///
732    /// # #[cfg(feature = "2d")]
733    /// fn main() {
734    ///     App::new()
735    ///         .add_plugins((
736    ///             DefaultPlugins,
737    ///             // A 2D game with 100 pixels per meter
738    ///             PhysicsPlugins::default().with_length_unit(100.0),
739    ///         ))
740    ///         .run();
741    /// }
742    /// # #[cfg(not(feature = "2d"))]
743    /// # fn main() {} // Doc test needs main
744    /// ```
745    pub fn with_length_unit(mut self, unit: Scalar) -> Self {
746        self.length_unit = unit;
747        self
748    }
749}
750
751impl Default for PhysicsPlugins {
752    fn default() -> Self {
753        Self::new(FixedPostUpdate)
754    }
755}
756
757impl PluginGroup for PhysicsPlugins {
758    fn build(self) -> PluginGroupBuilder {
759        let builder = PluginGroupBuilder::start::<Self>()
760            .add(PhysicsSchedulePlugin::new(self.schedule))
761            .add(MassPropertyPlugin::new(self.schedule))
762            .add(ForcePlugin)
763            .add(ColliderHierarchyPlugin)
764            .add(ColliderTransformPlugin::new(self.schedule));
765
766        #[cfg(all(feature = "collider-from-mesh", feature = "default-collider"))]
767        let builder = builder.add(ColliderCachePlugin);
768
769        #[cfg(all(
770            feature = "default-collider",
771            any(feature = "parry-f32", feature = "parry-f64")
772        ))]
773        let builder = builder
774            .add(ColliderBackendPlugin::<Collider>::new(self.schedule))
775            .add(ColliderTreePlugin::<Collider>::default())
776            .add(NarrowPhasePlugin::<Collider>::default());
777
778        // Add solver plugins.
779        let builder = builder.add_group(SolverPlugins::new_with_length_unit(self.length_unit));
780
781        builder
782            .add(BroadPhaseCorePlugin)
783            .add(BvhBroadPhasePlugin::<()>::default())
784            .add(JointPlugin)
785            .add(SpatialQueryPlugin::new(self.schedule))
786            .add(PhysicsTransformPlugin::new(self.schedule))
787            .add(PhysicsInterpolationPlugin::default())
788    }
789}
790
791// This type is separate from `PhysicsPlugins` to avoid requiring users to use generics
792// like `PhysicsPlugins::<()>::default()` unless they actually want to use collision hooks.
793/// A [`PhysicsPlugins`] plugin group with [`CollisionHooks`] specified.
794pub struct PhysicsPluginsWithHooks<H: CollisionHooks> {
795    plugins: PhysicsPlugins,
796    _phantom: core::marker::PhantomData<H>,
797}
798
799impl<H: CollisionHooks> PhysicsPluginsWithHooks<H> {
800    /// Creates a new [`PhysicsPluginsWithHooks`] plugin group using the given [`CollisionHooks`]
801    /// and schedule for running the [`PhysicsSchedule`].
802    ///
803    /// The default schedule is [`FixedPostUpdate`].
804    pub fn new(schedule: impl ScheduleLabel) -> Self {
805        Self {
806            plugins: PhysicsPlugins::new(schedule),
807            _phantom: core::marker::PhantomData,
808        }
809    }
810
811    /// Sets the value used for the [`PhysicsLengthUnit`], a units-per-meter scaling factor
812    /// that adjusts the engine's internal properties to the scale of the world.
813    ///
814    /// See [`PhysicsPlugins::with_length_unit`] for more information.
815    pub fn with_length_unit(mut self, unit: Scalar) -> Self {
816        self.plugins.length_unit = unit;
817        self
818    }
819}
820
821impl<H: CollisionHooks> Default for PhysicsPluginsWithHooks<H> {
822    fn default() -> Self {
823        Self {
824            plugins: PhysicsPlugins::default(),
825            _phantom: core::marker::PhantomData,
826        }
827    }
828}
829
830impl<H: CollisionHooks + 'static> PluginGroup for PhysicsPluginsWithHooks<H>
831where
832    for<'w, 's> SystemParamItem<'w, 's, H>: CollisionHooks,
833{
834    fn build(self) -> PluginGroupBuilder {
835        // Replace the default collision hooks with the user-defined ones.
836        let builder = self
837            .plugins
838            .build()
839            .disable::<BvhBroadPhasePlugin>()
840            .add(BvhBroadPhasePlugin::<H>::default());
841
842        #[cfg(all(
843            feature = "default-collider",
844            any(feature = "parry-f32", feature = "parry-f64")
845        ))]
846        let builder = builder
847            .disable::<NarrowPhasePlugin<Collider>>()
848            .add(NarrowPhasePlugin::<Collider, H>::default());
849
850        builder
851    }
852}