avian3d/lib.rs
1//! 
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.8"
25//!
26//! # For 3D applications:
27//! [dependencies]
28//! avian3d = "0.8"
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.8", default-features = false, features = ["3d", "f64", "parry-f64", "xpbd_joints"] }
43//! ```
44//!
45//! ## Feature Flags
46//!
47//! The following feature flags are available for customizing Avian.
48//!
49//! | Feature | Description | Default feature |
50//! | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
51//! | `2d` | Enables 2D physics. Incompatible with `3d`. | Yes (`avian2d`) |
52//! | `3d` | Enables 3D physics. Incompatible with `2d`. | Yes (`avian3d`) |
53//! | `f64` | Enables double-precision numbers. See [Large Worlds](#large-worlds). | No |
54//! | `default-collider` | Enables the default [`Collider`]. Required for [spatial queries](spatial_query). Requires either the `parry-f32` or `parry-f64` feature. | Yes |
55//! | `parry-f32` | Enables the `f32` version of the Parry collision detection library. Also enables the `default-collider` feature. | Yes |
56//! | `parry-f64` | Enables the `f64` version of the Parry collision detection library. Also enables the `default-collider` feature. | No |
57//! | `xpbd_joints` | Enables support for [XPBD joints](dynamics::solver::xpbd). . | Yes |
58#![cfg_attr(
59 feature = "3d",
60 doc = "| `collider-from-mesh` | Allows you to create [`Collider`]s from `Mesh`es. | Yes |"
61)]
62//! | `bevy_scene` | Enables [`ColliderConstructorHierarchy`] to wait until a [`Scene`] has loaded before processing it. | Yes |
63//! | `bevy_picking` | Enables physics picking support for [`bevy_picking`] using the [`PhysicsPickingPlugin`]. The plugin must be added separately. | Yes |
64//! | `bevy_diagnostic` | Enables writing [physics diagnostics] to the [`DiagnosticsStore`] with the [`PhysicsDiagnosticsPlugin`]. The plugin must be added separately. | No |
65//! | `diagnostic_ui` | Enables [physics diagnostics] UI for performance timers and counters using the [`PhysicsDiagnosticsUiPlugin`]. The plugin must be added separately. | No |
66//! | `debug-plugin` | Enables physics debug rendering using the [`PhysicsDebugPlugin`]. The plugin must be added separately. | Yes |
67//! | `enhanced-determinism` | Enables cross-platform deterministic math, improving determinism across architectures at a small performance cost. | No |
68//! | `parallel` | Enables some extra multithreading, which improves performance for larger simulations but can add some overhead for smaller ones. | Yes |
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//! - [Swept CCD](dynamics::ccd#swept-ccd)
140//! - [Speculative collision](dynamics::ccd#speculative-collision)
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#")]
176//! - [Temporarily disabling a joint](JointDisabled)
177# (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//! - [Large worlds](#large-worlds)
201//!
202//! ## Debugging and Profiling
203//!
204//! - [Physics debug rendering](PhysicsDebugPlugin)
205//! - [Physics diagnostics](diagnostics)
206//!
207//! ## Scheduling
208//!
209//! - [Schedules and sets](PhysicsSchedulePlugin#schedules-and-sets)
210//! - [`PhysicsSystems`]
211//! - [`PhysicsSchedule`] and [`PhysicsStepSystems`]
212//! - [`SubstepSchedule`]
213//! - [`SolverSystems`] and [`SubstepSolverSystems`](dynamics::solver::schedule::SubstepSolverSystems)
214//! - [`SpatialQuerySystems`]
215//! - Many more internal system sets
216//! - [Configure the schedule used for running physics](PhysicsPlugins#custom-schedule)
217//! - [Pausing, resuming and stepping physics](Physics#pausing-resuming-and-stepping-physics)
218//! - [Usage on servers](#can-the-engine-be-used-on-servers)
219//!
220//! ## Architecture
221//!
222//! - [List of plugins and their responsibilities](PhysicsPlugins)
223//! - [Custom plugins](PhysicsPlugins#custom-plugins)
224//!
225//! # Large Worlds
226//!
227//! Avian supports double-precision floating-point numbers using the `f64` feature.
228//! This can significantly improve the accuracy of physics simulations far from the origin.
229//! With single-precision numbers, at a distance of `1e7` units from the origin, the precision
230//! of `f32` is only about one unit, which would cause bodies to snap to a coarse grid, but with `f64`,
231//! precision remains at sub-millimeter resolution out to planetary distances.
232//!
233//! To support both `f32` and `f64` precision, Avian uses type aliases such as [`Real`],
234//! [`RVec2`], and [`RVec3`]. For example, [`RVec2`] is an alias for [`Vec2`] in single-precision
235//! mode and [`DVec2`](bevy::math::DVec2) in double-precision mode.
236//!
237//! Only world-space coordinates such as body positions, ray cast origins, and world-space
238//! contact points use double-precision numbers. Everything else, including velocities, forces,
239//! contact manifolds, joints, broad phase acceleration structures, and the physics solver,
240//! remain in single-precision. This limits the cost of double-precision numbers to just a few percent,
241//! while still maintaining high accuracy far from the origin.
242//!
243//! Note that because the broad phase acceleration structures remain in single-precision,
244//! the bounding boxes of colliders will become more conservative and inflated at large distances.
245//! The correctness of the simulation is not affected, but the effectiveness of the broad phase
246//! may be reduced. See [`ColliderAabb`] for more information.
247//!
248//! This approach to double-precision support is inspired by [Jolt].
249//!
250//! [Jolt]: https://jrouwe.github.io/JoltPhysics/index.html#big-worlds
251//!
252//! # Frequently Asked Questions
253//!
254//! - [How does Avian compare to Rapier and bevy_rapier?](#how-does-avian-compare-to-rapier-and-bevy_rapier)
255//! - [Why is nothing happening?](#why-is-nothing-happening)
256//! - [Why is everything moving so slowly?](#why-is-everything-moving-so-slowly)
257//! - [Why did my rigid body suddenly vanish?](#why-did-my-rigid-body-suddenly-vanish)
258//! - [Why is performance so bad?](#why-is-performance-so-bad)
259//! - [Why does movement look choppy?](#why-does-movement-look-choppy)
260//! - [Is there a character controller?](#is-there-a-character-controller)
261//! - [Why are there separate `Position` and `Rotation` components?](#why-are-there-separate-position-and-rotation-components)
262//! - [Can the engine be used on servers?](#can-the-engine-be-used-on-servers)
263//! - [Something else?](#something-else)
264//!
265//! ## How does Avian compare to Rapier and bevy_rapier?
266//!
267//! Rapier is the biggest and most used physics engine in the Rust ecosystem, and it is currently
268//! the most mature and feature-rich option.
269//!
270//! `bevy_rapier` is a great physics integration for Bevy, but it does have several problems:
271//!
272//! - It has to maintain a separate physics world and synchronize a ton of data with Bevy each frame
273//! - The source code is difficult to inspect, as the vast majority of it is glue code and wrappers
274//! for Bevy
275//! - It has poor docs.rs documentation, and the documentation on rapier.rs is often outdated and
276//! missing features
277//! - Overall, it doesn't have a native ECS-like feel
278//!
279//! Avian on the other hand is built *for* Bevy *with* Bevy, and it uses the ECS for both the internals
280//! and the public API. This removes the need for a separate physics world, reduces overhead, and makes
281//! the source code much more approachable and easy to inspect for Bevy users.
282//!
283//! In part thanks to Bevy's modular architecture and the ECS, Avian is also highly composable,
284//! as it consists of several independent plugins and provides lots of options for configuration and extensions,
285//! from [custom schedules](PhysicsPlugins#custom-schedule) and [plugins](PhysicsPlugins#custom-plugins) to
286//! [custom joints](dynamics::joints#custom-joints) and [constraints](dynamics::solver::xpbd#custom-constraints).
287//!
288//! One disadvantage of Avian is that it is still relatively young, so it can have more bugs,
289//! some missing features, and fewer community resources and third party crates. However, it is growing quite
290//! rapidly, and it is already pretty close to feature-parity with Rapier.
291//!
292//! At the end of the day, both engines are solid options. If you are looking for a more mature and tested
293//! physics integration, `bevy_rapier` is the better choice, but if you prefer an engine with less overhead
294//! and a more native Bevy integration, consider using Avian. Their core APIs are also quite similar,
295//! so switching between them shouldn't be too difficult.
296//!
297//! ## Why is nothing happening?
298//!
299//! Make sure you have added the [`PhysicsPlugins`] plugin group and you have given your rigid bodies
300//! a [`RigidBody`] component. See the [getting started](#getting-started) section.
301//!
302//! ## Why is everything moving so slowly?
303//!
304//! If your application is in 2D, you might be using pixels as length units. This will require you to use
305//! larger velocities and forces than you would in 3D. Make sure you set [`Gravity`] to some larger value
306//! as well, because its magnitude is `9.81` by default, which is tiny in pixels.
307//!
308//! ## Why is performance so bad?
309//!
310//! It is highly recommended to enable some optimizations for debug builds, or to run your project
311//! in release mode. This can have over a 100x performance impact in some cases.
312//!
313//! Add the following to your `Cargo.toml` to enable optimizations for debug builds:
314//!
315//! ```toml
316//! # Enable a small amount of optimization in the dev profile.
317//! [profile.dev]
318//! opt-level = 1
319//!
320//! # Enable a large amount of optimization in the dev profile for dependencies.
321//! [profile.dev.package."*"]
322//! opt-level = 3
323//! ```
324//!
325//! You can also further optimize release builds by setting the number of codegen units to `1`,
326//! although this will also increase build times.
327//!
328//! ```toml
329//! [profile.release]
330//! codegen-units = 1
331//! ```
332//!
333//! If you still have performance issues, consider enabling the [`PhysicsDiagnosticsPlugin`]
334//! and [`PhysicsDiagnosticsUiPlugin`] (requires the `diagnostic_ui` feature) to see where time is being spent.
335//! See the [diagnostics] module for more information.
336//!
337//! ## Why does movement look choppy?
338//!
339//! To produce consistent, frame rate independent behavior, physics by default runs
340//! in the [`FixedPostUpdate`] schedule with a fixed timestep, meaning that the time between
341//! physics ticks remains constant. On some frames, physics can either not run at all or run
342//! more than once to catch up to real time. This can lead to visible stutter for movement.
343//!
344//! This stutter can be resolved by *interpolating* or *extrapolating* the positions of physics objects
345//! in between physics ticks. Avian has built-in support for this through the [`PhysicsInterpolationPlugin`],
346//! which is included in the [`PhysicsPlugins`] by default.
347//!
348//! Interpolation can be enabled for an individual entity by adding the [`TransformInterpolation`] component:
349//!
350//! ```
351#![cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
352#![cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
353//! # use bevy::prelude::*;
354//! #
355//! fn setup(mut commands: Commands) {
356//! // Enable interpolation for this rigid body.
357//! commands.spawn((
358//! RigidBody::Dynamic,
359//! Transform::default(),
360//! TransformInterpolation,
361//! ));
362//! }
363//! ```
364//!
365//! To make *all* rigid bodies interpolated by default, use [`PhysicsInterpolationPlugin::interpolate_all()`]:
366//!
367//! ```no_run
368#![cfg_attr(feature = "2d", doc = "# use avian2d::prelude::*;")]
369#![cfg_attr(feature = "3d", doc = "# use avian3d::prelude::*;")]
370//! # use bevy::prelude::*;
371//! #
372//! fn main() {
373//! App::new()
374//! .add_plugins(PhysicsPlugins::default().set(PhysicsInterpolationPlugin::interpolate_all()))
375//! // ...
376//! .run();
377//! }
378//! ```
379//!
380//! See the [`PhysicsInterpolationPlugin`] for more information.
381//!
382//! If this does not fix the choppiness, the problem could also be related to system ordering.
383//! If you have a system for camera following, make sure it runs *after* physics,
384//! but *before* Bevy's transform propagation in `PostUpdate`.
385//!
386//! ```
387//! # use bevy::prelude::*;
388//! #
389//! # let mut app = App::new();
390//! #
391//! app.add_systems(
392//! PostUpdate,
393//! camera_follow_player.before(TransformSystems::Propagate),
394//! );
395//! #
396//! # fn camera_follow_player() {}
397//! ```
398//!
399//! ## Is there a character controller?
400//!
401//! Avian does not have a built-in character controller yet. However, it has a [`MoveAndSlide`]
402//! system parameter with utilities for implementing your own kinematic character controllers.
403//! See its documentation for more information.
404//!
405//! There are also some third party character controllers such as [`bevy_ahoy`](https://github.com/janhohenheim/bevy_ahoy)
406//! (kinematic) and [`bevy_tnua`](https://github.com/idanarye/bevy-tnua) (dynamic) that work with Avian.
407//!
408//! For custom character controllers, you can take a look at the
409#![cfg_attr(
410 feature = "2d",
411 doc = "[`dynamic_character_2d`] and [`kinematic_character_2d`] examples to get started."
412)]
413#![cfg_attr(
414 feature = "3d",
415 doc = "[`dynamic_character_3d`] and [`kinematic_character_3d`] examples to get started."
416)]
417//!
418#![cfg_attr(
419 feature = "2d",
420 doc = "[`dynamic_character_2d`]: https://github.com/avianphysics/avian/tree/main/crates/avian2d/examples/dynamic_character_2d
421[`kinematic_character_2d`]: https://github.com/avianphysics/avian/tree/main/crates/avian2d/examples/kinematic_character_2d"
422)]
423#![cfg_attr(
424 feature = "3d",
425 doc = "[`dynamic_character_3d`]: https://github.com/avianphysics/avian/tree/main/crates/avian3d/examples/dynamic_character_3d
426[`kinematic_character_3d`]: https://github.com/avianphysics/avian/tree/main/crates/avian3d/examples/kinematic_character_3d"
427)]
428//!
429//! ## Why are there separate `Position` and `Rotation` components?
430//!
431//! While `Transform` can be used for the vast majority of things, Avian internally
432//! uses separate [`Position`] and [`Rotation`] components. These are automatically
433//! kept in sync by the [`PhysicsTransformPlugin`].
434//!
435//! There are several reasons why the separate components are currently used.
436//!
437//! - Position and rotation should be global from the physics engine's point of view.
438//! - Transform scale and shearing can cause issues and rounding errors in physics.
439//! - Transform hierarchies can be problematic.
440//! - There is no `f64` version of `Transform`.
441//! - There is no 2D version of `Transform` (yet), and having a 2D version can optimize several computations.
442//! - When position and rotation are separate, we can technically have more systems running in parallel.
443//! - Only rigid bodies have rotation, particles typically don't (although we don't make a distinction yet).
444//!
445//! In external projects however, using [`Position`] and [`Rotation`] is only necessary when you
446//! need to manage positions within [`PhysicsSystems::StepSimulation`]. Elsewhere, you should be able to use `Transform`.
447//!
448//! There is also a possibility that we will revisit this if/when Bevy has a `Transform2d` component.
449//! Using `Transform` feels more idiomatic and simple, so it would be nice if it could be used directly
450//! as long as we can get around the drawbacks.
451//!
452//! ## Can the engine be used on servers?
453//!
454//! Yes! Networking often requires running the simulation in a specific schedule, and in Avian it is straightforward
455//! to [set the schedule that runs physics](PhysicsPlugins#custom-schedule) and [configure the timestep](Physics) if needed.
456//! By default, physics runs at a fixed timestep in [`FixedPostUpdate`].
457//!
458//! ## Something else?
459//!
460//! Physics engines are very large and Avian is still young, so stability issues and bugs are to be expected.
461//!
462//! If you encounter issues, please consider first taking a look at the
463//! [issues on GitHub](https://github.com/avianphysics/avian/issues) and
464//! [open a new issue](https://github.com/avianphysics/avian/issues/new) if there already isn't one regarding your problem.
465//!
466//! You can also come and say hello on the [Bevy Discord server](https://discord.com/invite/gMUk5Ph).
467//! There, you can find an Avian Physics topic on the `#ecosystem-crates` channel where you can ask questions.
468//!
469//! # License
470//!
471//! Avian is free and open source. All code in the Avian repository is dual-licensed under either:
472//!
473//! - MIT License ([LICENSE-MIT](https://github.com/avianphysics/avian/blob/main/LICENSE-MIT)
474//! or <http://opensource.org/licenses/MIT>)
475//! - Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/avianphysics/avian/blob/main/LICENSE-APACHE)
476//! or <http://www.apache.org/licenses/LICENSE-2.0>)
477//!
478//! at your option.
479
480#![doc(
481 html_logo_url = "https://raw.githubusercontent.com/Jondolf/avian/avian/assets/branding/icon.png",
482 html_favicon_url = "https://raw.githubusercontent.com/Jondolf/avian/avian/assets/branding/icon.png"
483)]
484#![allow(
485 unexpected_cfgs,
486 clippy::type_complexity,
487 clippy::too_many_arguments,
488 rustdoc::invalid_rust_codeblocks
489)]
490#![warn(clippy::doc_markdown, missing_docs)]
491
492#[cfg(all(not(feature = "2d"), not(feature = "3d")))]
493compile_error!("either feature \"2d\" or \"3d\" must be enabled");
494
495#[cfg(all(feature = "2d", feature = "3d"))]
496compile_error!("feature \"2d\" and feature \"3d\" cannot be enabled at the same time");
497
498#[cfg(all(
499 feature = "default-collider",
500 not(feature = "f64"),
501 not(feature = "parry-f32")
502))]
503compile_error!(
504 "feature \"default-collider\" requires the feature \"parry-f32\" when \"f32\" is enabled"
505);
506
507#[cfg(all(
508 feature = "default-collider",
509 feature = "f64",
510 not(feature = "parry-f64")
511))]
512compile_error!(
513 "feature \"default-collider\" requires the feature \"parry-f64\" when \"f64\" is enabled"
514);
515
516#[cfg(all(feature = "parry-f32", feature = "parry-f64"))]
517compile_error!(
518 "features \"parry-f32\" and \"parry-f64\" cannot be enabled at the same time; please disable default features, and choose only one of them"
519);
520
521extern crate alloc;
522
523#[cfg(all(feature = "2d", feature = "parry-f32"))]
524pub extern crate parry2d as parry;
525
526#[cfg(all(feature = "2d", feature = "parry-f64"))]
527pub extern crate parry2d_f64 as parry;
528
529#[cfg(all(feature = "3d", feature = "parry-f32"))]
530pub extern crate parry3d as parry;
531
532#[cfg(all(feature = "3d", feature = "parry-f64"))]
533pub extern crate parry3d_f64 as parry;
534
535#[cfg(all(
536 feature = "default-collider",
537 any(feature = "parry-f32", feature = "parry-f64")
538))]
539pub mod character_controller;
540pub mod collider_tree;
541pub mod collision;
542#[cfg(feature = "debug-plugin")]
543pub mod debug_render;
544pub mod diagnostics;
545pub mod dynamics;
546pub mod interpolation;
547pub mod math;
548pub mod physics_transform;
549#[cfg(feature = "bevy_picking")]
550pub mod picking;
551pub mod schedule;
552pub mod spatial_query;
553
554pub mod data_structures;
555
556// TODO: Where should this go?
557pub(crate) mod ancestor_marker;
558
559/// Re-exports common components, bundles, resources, plugins and types.
560pub mod prelude {
561 #[cfg(feature = "debug-plugin")]
562 pub use crate::debug_render::*;
563 #[cfg(feature = "bevy_diagnostic")]
564 pub use crate::diagnostics::PhysicsDiagnosticsPlugin;
565 #[cfg(feature = "diagnostic_ui")]
566 pub use crate::diagnostics::ui::{PhysicsDiagnosticsUiPlugin, PhysicsDiagnosticsUiSettings};
567 #[cfg(feature = "bevy_picking")]
568 pub use crate::picking::{
569 PhysicsPickable, PhysicsPickingFilter, PhysicsPickingPlugin, PhysicsPickingSettings,
570 };
571 #[expect(deprecated)]
572 pub use crate::{
573 PhysicsPlugins,
574 collider_tree::{ColliderTreeOptimization, ColliderTreePlugin, TreeOptimizationMode},
575 collision::prelude::*,
576 dynamics::{self, prelude::*},
577 interpolation::*,
578 physics_transform::{PhysicsTransformHelper, PhysicsTransformPlugin, Position, Rotation},
579 schedule::{
580 Physics, PhysicsSchedule, PhysicsSchedulePlugin, PhysicsSet, PhysicsStepSet,
581 PhysicsStepSystems, PhysicsSystems, PhysicsTime, Substeps,
582 },
583 spatial_query::{self, *},
584 };
585
586 #[cfg(all(
587 feature = "default-collider",
588 any(feature = "parry-f32", feature = "parry-f64")
589 ))]
590 pub use crate::character_controller::prelude::*;
591 pub(crate) use crate::{
592 diagnostics::AppDiagnosticsExt,
593 math::*,
594 physics_transform::{PreSolveDeltaPosition, PreSolveDeltaRotation},
595 };
596 pub use avian_derive::*;
597}
598
599mod utils;
600
601#[cfg(test)]
602mod tests;
603
604use bevy::{
605 app::PluginGroupBuilder,
606 ecs::{intern::Interned, schedule::ScheduleLabel, system::SystemParamItem},
607 prelude::*,
608};
609#[allow(unused_imports)]
610use prelude::*;
611
612/// A plugin group containing Avian's plugins.
613///
614/// # Plugins
615///
616/// By default, the following plugins will be added:
617///
618/// | Plugin | Description |
619/// | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
620/// | [`PhysicsSchedulePlugin`] | Sets up the physics engine by initializing the necessary schedules, sets and resources. |
621/// | [`ColliderBackendPlugin`] | Handles generic collider backend logic, like initializing colliders and AABBs and updating related components. |
622/// | [`ColliderHierarchyPlugin`] | Manages [`ColliderOf`] relationships based on the entity hierarchy. |
623/// | [`ColliderTransformPlugin`] | Propagates and updates transforms for colliders.
624#[cfg_attr(
625 all(feature = "collider-from-mesh", feature = "default-collider"),
626 doc = "| [`ColliderCachePlugin`] | Caches colliders created from meshes. Requires `collider-from-mesh` and `default-collider` features. |"
627)]
628/// | [`ColliderTreePlugin`] | Manages [`ColliderTrees`] for broad phase collision detection and spatial queries. |
629/// | [`BroadPhaseCorePlugin`] | The core [broad phase] plugin that sets up the required resources, system sets, and diagnostics. |
630/// | [`BvhBroadPhasePlugin`] | A [broad phase] plugin that uses a [Bounding Volume Hierarchy (BVH)][BVH] to efficiently find pairs of colliders with overlapping AABBs. |
631/// | [`NarrowPhasePlugin`] | Manages contacts and generates contact constraints. |
632/// | [`SolverPlugins`] | A plugin group for the physics solver's plugins. See the plugin group's documentation for more information. |
633/// | [`JointPlugin`] | A plugin for managing and initializing [joints](dynamics::joints). Does *not* include the actual joint solver. |
634/// | [`MassPropertyPlugin`] | Manages mass properties of dynamic [rigid bodies](RigidBody). |
635/// | [`ForcePlugin`] | Manages and applies external forces, torques, and acceleration for rigid bodies. See the [module-level documentation](dynamics::rigid_body::forces). |
636/// | [`BodySizeMetricsPlugin`] | Manages [`BodySizeMetrics`] for rigid bodies, which are used for various optimizations. |
637/// | [`SpatialQueryPlugin`] | Handles spatial queries like [raycasting](spatial_query#raycasting) and [shapecasting](spatial_query#shapecasting). |
638/// | [`PhysicsInterpolationPlugin`] | [`Transform`] interpolation and extrapolation for rigid bodies. |
639/// | [`PhysicsTransformPlugin`] | Manages physics transforms and synchronizes them with [`Transform`]. |
640///
641/// Optional additional plugins include:
642///
643/// | Plugin | Description |
644/// | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
645/// | [`PhysicsPickingPlugin`] | Enables a physics picking backend for [`bevy_picking`](bevy::picking) (only with `bevy_picking` feature enabled). |
646/// | [`PhysicsDebugPlugin`] | Renders physics objects and events like [AABBs](ColliderAabb) and contacts for debugging purposes (only with `debug-plugin` feature enabled). |
647/// | [`PhysicsDiagnosticsPlugin`] | Writes [physics diagnostics](diagnostics) to the [`DiagnosticsStore`] (only with `bevy_diagnostic` feature enabled). |
648/// | [`PhysicsDiagnosticsUiPlugin`] | Displays [physics diagnostics](diagnostics) with a debug UI overlay (only with `diagnostic_ui` feature enabled). |
649///
650/// [`ColliderTrees`]: collider_tree::ColliderTrees
651/// [broad phase]: collision::broad_phase
652/// [BVH]: https://en.wikipedia.org/wiki/Bounding_volume_hierarchy
653/// [`DiagnosticsStore`]: bevy::diagnostic::DiagnosticsStore
654///
655/// Refer to the documentation of the plugins for more information about their responsibilities and implementations.
656///
657/// # World Scale
658///
659/// The [`PhysicsLengthUnit`] resource is a units-per-meter scaling factor
660/// that adjusts the engine's internal properties to the scale of the world.
661/// It is recommended to configure the length unit to match the approximate length
662/// of the average dynamic object in the world to get the best simulation results.
663///
664/// For example, a 2D game might use pixels as units and have an average object size
665/// of around 100 pixels. By setting the length unit to `100.0`, the physics engine
666/// will interpret 100 pixels as 1 meter for internal thresholds, improving stability.
667///
668/// The length unit can be set by inserting the resource like normal,
669/// but it can also be specified through the [`PhysicsPlugins`] plugin group.
670///
671/// ```no_run
672/// # #[cfg(feature = "2d")]
673/// use avian2d::prelude::*;
674/// use bevy::prelude::*;
675///
676/// # #[cfg(feature = "2d")]
677/// fn main() {
678/// App::new()
679/// .add_plugins((
680/// DefaultPlugins,
681/// // A 2D game with 100 pixels per meter
682/// PhysicsPlugins::default().with_length_unit(100.0),
683/// ))
684/// .run();
685/// }
686/// # #[cfg(not(feature = "2d"))]
687/// # fn main() {} // Doc test needs main
688/// ```
689///
690/// # Custom Schedule
691///
692/// You can run the [`PhysicsSchedule`] in any schedule you want by specifying the schedule when adding the plugin group:
693///
694/// ```no_run
695#[cfg_attr(feature = "2d", doc = "use avian2d::prelude::*;")]
696#[cfg_attr(feature = "3d", doc = "use avian3d::prelude::*;")]
697/// use bevy::prelude::*;
698///
699/// fn main() {
700/// App::new()
701/// // Run physics at a variable timestep in `PostUpdate`.
702/// .add_plugins((DefaultPlugins, PhysicsPlugins::new(PostUpdate)))
703/// .run();
704/// }
705/// ```
706pub struct PhysicsPlugins {
707 schedule: Interned<dyn ScheduleLabel>,
708 length_unit: f32,
709}
710
711impl PhysicsPlugins {
712 /// Creates a [`PhysicsPlugins`] plugin group using the given schedule for running the [`PhysicsSchedule`].
713 ///
714 /// The default schedule is `FixedPostUpdate`.
715 pub fn new(schedule: impl ScheduleLabel) -> Self {
716 Self {
717 schedule: schedule.intern(),
718 length_unit: 1.0,
719 }
720 }
721
722 /// Adds the given [`CollisionHooks`] for user-defined contact filtering and modification.
723 ///
724 /// Returns a [`PhysicsPluginsWithHooks`] plugin group, which wraps the original [`PhysicsPlugins`],
725 /// and applies the provided hooks. Only one set of collision hooks can be defined per application.
726 pub fn with_collision_hooks<H: CollisionHooks + 'static>(self) -> PhysicsPluginsWithHooks<H>
727 where
728 for<'w, 's> SystemParamItem<'w, 's, H>: CollisionHooks,
729 {
730 PhysicsPluginsWithHooks::<H> {
731 plugins: self,
732 _phantom: core::marker::PhantomData,
733 }
734 }
735
736 /// Sets the value used for the [`PhysicsLengthUnit`], a units-per-meter scaling factor
737 /// that adjusts the engine's internal properties to the scale of the world.
738 ///
739 /// For example, a 2D game might use pixels as units and have an average object size
740 /// of around 100 pixels. By setting the length unit to `100.0`, the physics engine
741 /// will interpret 100 pixels as 1 meter for internal thresholds, improving stability.
742 ///
743 /// Note that this is *not* used to scale forces or any other user-facing inputs or outputs.
744 /// Instead, the value is only used to scale some internal length-based tolerances, such as
745 /// [`SleepingThreshold::linear`] and [`NarrowPhaseConfig::contact_tolerance`], as well as
746 /// the scale used for [debug rendering](PhysicsDebugPlugin).
747 ///
748 /// Choosing the appropriate length unit can help improve stability and robustness.
749 ///
750 /// # Example
751 ///
752 /// ```no_run
753 /// # #[cfg(feature = "2d")]
754 /// use avian2d::prelude::*;
755 /// use bevy::prelude::*;
756 ///
757 /// # #[cfg(feature = "2d")]
758 /// fn main() {
759 /// App::new()
760 /// .add_plugins((
761 /// DefaultPlugins,
762 /// // A 2D game with 100 pixels per meter
763 /// PhysicsPlugins::default().with_length_unit(100.0),
764 /// ))
765 /// .run();
766 /// }
767 /// # #[cfg(not(feature = "2d"))]
768 /// # fn main() {} // Doc test needs main
769 /// ```
770 pub fn with_length_unit(mut self, unit: f32) -> Self {
771 self.length_unit = unit;
772 self
773 }
774}
775
776impl Default for PhysicsPlugins {
777 fn default() -> Self {
778 Self::new(FixedPostUpdate)
779 }
780}
781
782impl PluginGroup for PhysicsPlugins {
783 fn build(self) -> PluginGroupBuilder {
784 let builder = PluginGroupBuilder::start::<Self>()
785 .add(PhysicsSchedulePlugin::new(self.schedule))
786 .add(MassPropertyPlugin::new(self.schedule))
787 .add(ForcePlugin)
788 .add(ColliderHierarchyPlugin)
789 .add(ColliderTransformPlugin::new(self.schedule));
790
791 #[cfg(all(feature = "collider-from-mesh", feature = "default-collider"))]
792 let builder = builder.add(ColliderCachePlugin);
793
794 #[cfg(all(
795 feature = "default-collider",
796 any(feature = "parry-f32", feature = "parry-f64")
797 ))]
798 let builder = builder
799 .add(ColliderBackendPlugin::<Collider>::new(self.schedule))
800 .add(ColliderTreePlugin::<Collider>::default())
801 .add(NarrowPhasePlugin::<Collider>::default())
802 .add(BodySizeMetricsPlugin::<Collider>::default());
803
804 // Add solver plugins.
805 let builder = builder.add_group(SolverPlugins::new_with_length_unit(self.length_unit));
806
807 builder
808 .add(BroadPhaseCorePlugin)
809 .add(BvhBroadPhasePlugin::<()>::default())
810 .add(JointPlugin)
811 .add(SpatialQueryPlugin::new(self.schedule))
812 .add(PhysicsTransformPlugin::new(self.schedule))
813 .add(PhysicsInterpolationPlugin::default())
814 }
815}
816
817// This type is separate from `PhysicsPlugins` to avoid requiring users to use generics
818// like `PhysicsPlugins::<()>::default()` unless they actually want to use collision hooks.
819/// A [`PhysicsPlugins`] plugin group with [`CollisionHooks`] specified.
820pub struct PhysicsPluginsWithHooks<H: CollisionHooks> {
821 plugins: PhysicsPlugins,
822 _phantom: core::marker::PhantomData<H>,
823}
824
825impl<H: CollisionHooks> PhysicsPluginsWithHooks<H> {
826 /// Creates a new [`PhysicsPluginsWithHooks`] plugin group using the given [`CollisionHooks`]
827 /// and schedule for running the [`PhysicsSchedule`].
828 ///
829 /// The default schedule is [`FixedPostUpdate`].
830 pub fn new(schedule: impl ScheduleLabel) -> Self {
831 Self {
832 plugins: PhysicsPlugins::new(schedule),
833 _phantom: core::marker::PhantomData,
834 }
835 }
836
837 /// Sets the value used for the [`PhysicsLengthUnit`], a units-per-meter scaling factor
838 /// that adjusts the engine's internal properties to the scale of the world.
839 ///
840 /// See [`PhysicsPlugins::with_length_unit`] for more information.
841 pub fn with_length_unit(mut self, unit: f32) -> Self {
842 self.plugins.length_unit = unit;
843 self
844 }
845}
846
847impl<H: CollisionHooks> Default for PhysicsPluginsWithHooks<H> {
848 fn default() -> Self {
849 Self {
850 plugins: PhysicsPlugins::default(),
851 _phantom: core::marker::PhantomData,
852 }
853 }
854}
855
856impl<H: CollisionHooks + 'static> PluginGroup for PhysicsPluginsWithHooks<H>
857where
858 for<'w, 's> SystemParamItem<'w, 's, H>: CollisionHooks,
859{
860 fn build(self) -> PluginGroupBuilder {
861 // Replace the default collision hooks with the user-defined ones.
862 let builder = self
863 .plugins
864 .build()
865 .disable::<BvhBroadPhasePlugin>()
866 .add(BvhBroadPhasePlugin::<H>::default());
867
868 #[cfg(all(
869 feature = "default-collider",
870 any(feature = "parry-f32", feature = "parry-f64")
871 ))]
872 let builder = builder
873 .disable::<NarrowPhasePlugin<Collider>>()
874 .add(NarrowPhasePlugin::<Collider, H>::default());
875
876 builder
877 }
878}