1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
#![deny(future_incompatible, nonstandard_style)]
#![warn(missing_docs, rust_2018_idioms, clippy::pedantic)]
#![allow(clippy::needless_pass_by_value, clippy::needless_doctest_main)]
#![cfg(any(dim2, dim3))]
//! An ergonomic physics API for 2d and 3d [bevy] games. (powered by [rapier])
//!
//! [bevy]: https://bevyengine.org
//!
//! [rapier]: https://rapier.rs
//!
//! # Get started
//!
//! ## Add the dependency and choose to work with either 2d or 3d
//!
//! Add the library to `Cargo.toml`.
//!
//! For a 3d game:
//! ```toml
//! heron = { version = "0.12.0", features = ["3d"] }
//! ```
//!
//! For as 2d game:
//! ```toml
//! heron = { version = "0.12.0", features = ["2d"] }
//! ```
//!
//! ### Feature flags
//!
//! One must choose to use either `2d` or `3d`. If none of theses two features is enabled, the plugin won't be available.
//!
//! * `3d` Enable simulation on the 3 axes `x`, `y`, and `z`. Incompatible with the feature `2d`.
//! * `2d` Enable simulation only on the first 2 axes `x` and `y`. Incompatible with the feature `3d`, therefore require to disable the default features.
//! * `debug-2d` Render 2d collision shapes. Works only in 2d, support for 3d may be added later.
//!
//! ## Install the plugin
//!
//! The [`PhysicsPlugin`] should be installed to enable physics and collision detection.
//!
//! ```no_run
//! use bevy::prelude::*;
//! use heron::prelude::*;
//!
//! fn main() {
//! App::build()
//! .add_plugins(DefaultPlugins)
//! .add_plugin(PhysicsPlugin::default())
//! // ... Add your resources and systems
//! .run();
//! }
//! ```
//!
//! ## Create rigid bodies
//!
//! To create a rigid body, add the [`RigidBody`] to the entity and add a collision shapes with the
//! [`CollisionShape`] component.
//!
//! The position and rotation are defined by the bevy [`GlobalTransform`] component.
//!
//! [`GlobalTransform`]: bevy::prelude::GlobalTransform
//!
//! ```
//! # use bevy::prelude::*;
//! # use heron::prelude::*;
//! fn spawn(mut commands: Commands) {
//! commands
//!
//! // Spawn any bundle of your choice. Only make sure there is a `GlobalTransform`
//! .spawn_bundle(SpriteBundle::default())
//!
//! // Make it a rigid body
//! .insert(RigidBody::Dynamic)
//!
//! // Attach a collision shape
//! .insert(CollisionShape::Sphere { radius: 10.0 })
//!
//! // Optionally add other useful components...
//! .insert(Velocity::from_linear(Vec3::X * 2.0))
//! .insert(Acceleration::from_linear(Vec3::X * 1.0))
//! .insert(PhysicMaterial { friction: 1.0, density: 10.0, ..Default::default() })
//! .insert(RotationConstraints::lock());
//! }
//! ```
//!
//! ## Move rigid bodies programmatically
//!
//! When creating games, it is often useful to interact with the physics engine and move bodies
//! programmatically. For this, you have two options: Updating the [`Transform`] or applying a
//! [`Velocity`].
//!
//! [`Transform`]: bevy::prelude::Transform
//!
//! ### Option 1: Update the Transform
//!
//! For positional kinematic bodies ([`RigidBody::KinematicPositionBased`]), if the transform is
//! updated, the body is moved and get an automatically calculated velocity. Physics rules will be
//! applied normally. Updating the transform is a good way to move a kinematic body.
//!
//! For other types of bodies, if the transform is updated, the rigid body will be *teleported* to
//! the new position/rotation, **ignoring physic rules**.
//!
//! ### Option 2: Use the Velocity component
//!
//! For [`RigidBody::Dynamic`] and [`RigidBody::KinematicVelocityBased`] bodies **only**, one can
//! add a [`Velocity`] component to the entity, that will move the body over time. Physics rules
//! will be applied normally.
//!
//! Note that the velocity component is updated by heron to always reflects the current velocity.
//!
//! Defining/updating the velocity is a good way to interact with dynamic bodies.
//!
//! ## See also
//!
//! * How to define a [`RigidBody`]
//! * How to choose a [`CollisionShape`]
//! * How to define the world's [`Gravity`]
//! * How to define the world's [`PhysicsTime`]
//! * How to define the [`PhysicMaterial`]
//! * How to listen to [`CollisionEvent`]
//! * How to define [`RotationConstraints`]
use bevy::app::{AppBuilder, Plugin};
pub use heron_core::*;
pub use heron_macros::*;
use heron_rapier::RapierPlugin;
/// Physics behavior powered by [rapier](https://rapier.rs)
///
/// Allow access to the underlying physics world directly
pub mod rapier_plugin {
pub use heron_rapier::*;
}
/// Re-exports of the most commons/useful types
pub mod prelude {
pub use heron_macros::*;
#[allow(deprecated)]
pub use crate::{
ext::*, stage, Acceleration, AxisAngle, CollisionEvent, CollisionLayers, CollisionShape,
Gravity, PhysicMaterial, PhysicsLayer, PhysicsPlugin, PhysicsSystem, PhysicsTime,
RigidBody, RotationConstraints, Velocity,
};
}
/// Plugin to install to enable collision detection and physics behavior.
#[must_use]
#[derive(Debug, Copy, Clone, Default)]
pub struct PhysicsPlugin {
#[cfg(debug)]
debug: heron_debug::DebugPlugin,
}
impl Plugin for PhysicsPlugin {
fn build(&self, app: &mut AppBuilder) {
app.add_plugin(RapierPlugin);
#[cfg(debug)]
app.add_plugin(self.debug);
}
}