Skip to content

Commit

Permalink
Merge pull request #49 from Jondolf/improved-docs
Browse files Browse the repository at this point in the history
Improve documentation
  • Loading branch information
Jondolf committed Jun 19, 2023
2 parents 0799738 + 4e0c03d commit 59b7c2a
Show file tree
Hide file tree
Showing 25 changed files with 1,315 additions and 155 deletions.
6 changes: 3 additions & 3 deletions src/collision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

use crate::prelude::*;

/// An event that is sent for each contact pair during the narrow phase.
/// A [collision event](Collider#collision-events) that is sent for each contact pair during the narrow phase.
#[derive(Clone, Debug, PartialEq)]
pub struct Collision(pub Contact);

/// An event that is sent when two entities start colliding.
/// A [collision event](Collider#collision-events) that is sent when two entities start colliding.
#[derive(Clone, Debug, PartialEq)]
pub struct CollisionStarted(pub Entity, pub Entity);

/// An event that is sent when two entities stop colliding.
/// A [collision event](Collider#collision-events) that is sent when two entities stop colliding.
#[derive(Clone, Debug, PartialEq)]
pub struct CollisionEnded(pub Entity, pub Entity);

Expand Down
108 changes: 103 additions & 5 deletions src/components/collider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,66 @@ use derive_more::From;
use parry::{bounding_volume::Aabb, shape::SharedShape};

/// A collider used for collision detection.
///
/// By default, colliders generate [collision events](#collision-events) and cause a collision response for
/// [rigid bodies](RigidBody). If you only want collision events, you can add a [`Sensor`] component.
///
/// ## Creation
///
/// `Collider` has tons of methods for creating colliders of various shapes.
/// For example, to add a ball collider to a [rigid body](RigidBody), use [`Collider::ball`](#method.ball):
///
/// ```
/// use bevy::prelude::*;
/// # #[cfg(feature = "2d")]
/// # use bevy_xpbd_2d::prelude::*;
/// # #[cfg(feature = "3d")]
/// use bevy_xpbd_3d::prelude::*;
///
/// fn setup(mut commands: Commands) {
/// commands.spawn((RigidBody::Dynamic, Collider::ball(0.5)));
/// }
/// ```
///
/// In addition, Bevy XPBD will automatically add some other components, like the following:
///
/// - [`ColliderAabb`]
/// - [`CollidingEntities`]
/// - [`ColliderMassProperties`]
///
/// ## Collision layers
///
/// You can use collsion layers to configure which entities can collide with each other.
///
/// See [`CollisionLayers`] for more information and examples.
///
/// ## Collision events
///
/// There are currently three different collision events: [`Collision`], [`CollisionStarted`] and [`CollisionEnded`].
/// You can listen to these events as you normally would.
///
/// For example, you could read [contacts](Contact) like this:
///
/// ```
/// use bevy::prelude::*;
/// # #[cfg(feature = "2d")]
/// # use bevy_xpbd_2d::prelude::*;
/// # #[cfg(feature = "3d")]
/// use bevy_xpbd_3d::prelude::*;
///
/// fn my_system(mut collision_event_reader: EventReader<Collision>) {
/// for Collision(contact) in collision_event_reader.iter() {
/// println!("{:?} and {:?} are colliding", contact.entity1, contact.entity2);
/// }
/// }
/// ```
///
/// ## Advanced usage
///
/// Internally, `Collider` uses the shapes provided by `parry`. If you want to create a collider
/// using these shapes, you can simply use `Collider::from(SharedShape::some_method())`.
///
/// To get a reference to the internal [`SharedShape`], you can use the [`get_shape`](#method.get_shape) method.
#[derive(Clone, Component, Deref, DerefMut, From)]
pub struct Collider(SharedShape);

Expand Down Expand Up @@ -246,8 +306,25 @@ fn extract_mesh_vertices_indices(mesh: &Mesh) -> Option<VerticesIndices> {
Some((vtx, idx))
}

/// Marks a [`Collider`] as a sensor collider. Sensor colliders send collision events but
/// don't cause a collision response. This is often used to detect when something enters or leaves an area.
/// A component that marks a [`Collider`] as a sensor collider.
///
/// Sensor colliders send [collision events](Collider#collision-events) but don't cause a collision response.
/// This is often used to detect when something enters or leaves an area.
///
/// ## Example
///
/// ```
/// use bevy::prelude::*;
/// # #[cfg(feature = "2d")]
/// # use bevy_xpbd_2d::prelude::*;
/// # #[cfg(feature = "3d")]
/// use bevy_xpbd_3d::prelude::*;
///
/// fn setup(mut commands: Commands) {
/// // Spawn a static ball that generates collision events but doesn't cause a collision response
/// commands.spawn((RigidBody::Static, Collider::ball(0.5), Sensor));
/// }
/// ```
#[derive(Reflect, Clone, Component, Debug, Default, PartialEq, Eq)]
pub struct Sensor;

Expand All @@ -256,7 +333,7 @@ pub struct Sensor;
pub struct ColliderAabb(pub Aabb);

impl ColliderAabb {
/// Creates a new collider from a given [`Shape`] with a default density of 1.0.
/// Creates a new collider from a given [`SharedShape`] with a default density of 1.0.
pub fn from_shape(shape: &SharedShape) -> Self {
Self(shape.compute_local_aabb())
}
Expand All @@ -268,8 +345,29 @@ impl Default for ColliderAabb {
}
}

/// Contains the entities that are colliding with an entity. These entities are added by the [`SolverPlugin`]
/// when collisions are detected during the constraint solve.
/// Contains the entities that are colliding with an entity.
///
/// This component is automatically added for all entities with a [`Collider`].
///
/// ## Example
///
/// ```
/// use bevy::prelude::*;
/// # #[cfg(feature = "2d")]
/// # use bevy_xpbd_2d::prelude::*;
/// # #[cfg(feature = "3d")]
/// use bevy_xpbd_3d::prelude::*;
///
/// fn my_system(query: Query<(Entity, &CollidingEntities)>) {
/// for (entity, colliding_entities) in &query {
/// println!(
/// "{:?} is colliding with the following entities: {:?}",
/// entity,
/// colliding_entities
/// );
/// }
/// }
/// ```
#[derive(Reflect, Clone, Component, Debug, Default, Deref, DerefMut, PartialEq, Eq)]
#[reflect(Component)]
pub struct CollidingEntities(pub HashSet<Entity>);
11 changes: 8 additions & 3 deletions src/components/layers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use bevy::prelude::*;
///
/// This trait can be derived for enums with `#[derive(PhysicsLayer)]`.
pub trait PhysicsLayer: Sized {
/// Converts the layer to a bitmask.
fn to_bits(&self) -> u32;
/// Creates a layer bitmask with all bits set to 1.
fn all_bits() -> u32;
}

Expand All @@ -32,7 +34,7 @@ impl<L: PhysicsLayer> PhysicsLayer for &L {
/// Colliders without this component can be considered as having all groups and masks, and they can
/// interact with everything that belongs on any layer.
///
/// ## Creating [`CollisionLayers`]
/// ## Creation
///
/// The easiest way to build a [`CollisionLayers`] configuration is to use the [`CollisionLayers::new()`](#method.new) method
/// that takes in a list of groups and masks. Additional groups and masks can be added and removed by calling methods like
Expand All @@ -47,9 +49,12 @@ impl<L: PhysicsLayer> PhysicsLayer for &L {
///
/// ## Example
///
/// ```ignore
/// ```
/// use bevy::prelude::*;
/// use bevy_xpbd::prelude::*; // 2D or 3D
/// # #[cfg(feature = "2d")]
/// # use bevy_xpbd_2d::prelude::*;
/// # #[cfg(feature = "3d")]
/// use bevy_xpbd_3d::prelude::*;
///
/// #[derive(PhysicsLayer)]
/// enum Layer {
Expand Down
30 changes: 30 additions & 0 deletions src/components/mass_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::utils::get_rotated_inertia_tensor;
pub struct Mass(pub Scalar);

impl Mass {
/// Zero mass.
pub const ZERO: Self = Self(0.0);
}

Expand All @@ -19,6 +20,7 @@ impl Mass {
pub struct InverseMass(pub Scalar);

impl InverseMass {
/// Zero inverse mass.
pub const ZERO: Self = Self(0.0);
}

Expand Down Expand Up @@ -47,8 +49,10 @@ impl Default for Inertia {
}

impl Inertia {
/// Zero angular inertia.
#[cfg(feature = "2d")]
pub const ZERO: Self = Self(0.0);
/// Zero angular inertia.
#[cfg(feature = "3d")]
pub const ZERO: Self = Self(Matrix3::ZERO);

Expand Down Expand Up @@ -103,8 +107,10 @@ impl Default for InverseInertia {
}

impl InverseInertia {
/// Zero inverse angular inertia.
#[cfg(feature = "2d")]
pub const ZERO: Self = Self(0.0);
/// Zero inverse angular inertia.
#[cfg(feature = "3d")]
pub const ZERO: Self = Self(Matrix3::ZERO);

Expand Down Expand Up @@ -145,9 +151,32 @@ impl From<Inertia> for InverseInertia {
pub struct CenterOfMass(pub Vector);

impl CenterOfMass {
/// A center of mass set at the local origin.
pub const ZERO: Self = Self(Vector::ZERO);
}

/// A bundle containing mass properties.
///
/// ## Example
///
/// The easiest way to create a new bundle is to use the [new_computed](#method.new_computed) method
/// that computes the mass properties based on a given [`Collider`] and density.
///
/// ```
/// use bevy::prelude::*;
/// # #[cfg(feature = "2d")]
/// # use bevy_xpbd_2d::prelude::*;
/// # #[cfg(feature = "3d")]
/// use bevy_xpbd_3d::prelude::*;
///
/// fn setup(mut commands: Commands) {
/// commands.spawn((
/// RigidBody::Dynamic,
/// MassPropertiesBundle::new_computed(&Collider::ball(0.5), 1.0)
/// ));
/// }
/// ```
#[allow(missing_docs)]
#[derive(Bundle, Debug, Default, Clone, PartialEq)]
pub struct MassPropertiesBundle {
pub mass: Mass,
Expand Down Expand Up @@ -202,6 +231,7 @@ pub struct ColliderMassProperties {
}

impl ColliderMassProperties {
/// The collider has no mass.
pub const ZERO: Self = Self {
mass: Mass::ZERO,
inverse_mass: InverseMass(Scalar::INFINITY),
Expand Down
Loading

0 comments on commit 59b7c2a

Please sign in to comment.