bevy_heavy/lib.rs
1//! `bevy_heavy` is a crate for computing mass properties ([mass], [angular inertia], and [center of mass])
2//! for the [geometric primitives] in the [Bevy game engine][Bevy]. This is typically required
3//! for things like physics simulations.
4//!
5//! [mass]: #mass
6//! [angular inertia]: #angular-inertia
7//! [center of mass]: #center-of-mass
8//! [geometric primitives]: bevy_math::primitives
9//! [Bevy]: https://bevyengine.org
10//!
11//! # Usage
12//!
13//! Mass properties can be computed individually for shapes using the [`mass`], [`angular_inertia`],
14//! and [`center_of_mass`] methods:
15//!
16//! [`mass`]: ComputeMassProperties2d::mass
17//! [`angular_inertia`]: ComputeMassProperties2d::angular_inertia
18//! [`center_of_mass`]: ComputeMassProperties2d::center_of_mass
19//!
20//! ```
21//! use bevy_heavy::{ComputeMassProperties2d, MassProperties2d};
22//! use bevy_math::{primitives::Rectangle, Vec2};
23//!
24//! let rectangle = Rectangle::new(2.0, 1.0);
25//! let density = 2.0;
26//!
27//! let mass = rectangle.mass(density);
28//! let angular_inertia = rectangle.angular_inertia(mass);
29//! let center_of_mass = rectangle.center_of_mass();
30//! ```
31//!
32//! You can also compute all mass properties at once, returning [`MassProperties2d`] for 2D shapes,
33//! or [`MassProperties3d`] for 3D shapes. This can be more efficient when more than one property is needed.
34//!
35//! ```
36//! # use bevy_heavy::{ComputeMassProperties2d, MassProperties2d};
37//! # use bevy_math::{primitives::Rectangle, Vec2};
38//! #
39//! # let rectangle = Rectangle::new(2.0, 1.0);
40//! # let density = 2.0;
41//! #
42//! let mass_props = rectangle.mass_properties(density);
43//! ```
44//!
45//! The mass property types have several helper methods for various transformations and operations:
46//!
47//! ```
48//! # use bevy_heavy::{ComputeMassProperties2d, MassProperties2d};
49//! # use bevy_math::{primitives::Rectangle, Vec2};
50//! #
51//! # let rectangle = Rectangle::new(2.0, 1.0);
52//! # let density = 2.0;
53//! #
54//! # let mass_props = rectangle.mass_properties(density);
55//! #
56//! let shifted_inertia = mass_props.shifted_angular_inertia(Vec2::new(-3.5, 1.0));
57//! let global_center_of_mass = mass_props.global_center_of_mass(Vec2::new(5.0, 7.5));
58//! ```
59//!
60//! You can also add and subtract mass properties:
61//!
62//! ```
63//! # use bevy_heavy::{ComputeMassProperties2d, MassProperties2d};
64//! # use bevy_math::{primitives::Rectangle, Vec2};
65//! #
66//! # let rectangle = Rectangle::new(2.0, 1.0);
67//! # let density = 2.0;
68//! #
69//! # let mass = rectangle.mass(density);
70//! # let angular_inertia = rectangle.angular_inertia(mass);
71//! #
72//! # let mass_props = rectangle.mass_properties(density);
73//! #
74//! let mass_props_2 = MassProperties2d::new(mass, angular_inertia, Vec2::new(0.0, 1.0));
75//! let sum = mass_props + mass_props_2;
76//! approx::assert_relative_eq!(sum - mass_props_2, mass_props);
77//! ```
78//!
79//! To support mass property computation for custom shapes, implement [`ComputeMassProperties2d`]
80//! or [`ComputeMassProperties3d`] for them.
81//!
82//! # Terminology
83//!
84//! ## Mass
85//!
86//! **[Mass](https://en.wikipedia.org/wiki/Mass)** is a scalar value representing resistance
87//! to linear acceleration when a force is applied.
88//!
89//! Mass is commonly measured in kilograms (kg).
90//!
91//! ## Angular Inertia
92//!
93//! **[Angular inertia](https://en.wikipedia.org/wiki/Moment_of_inertia)**, also known as
94//! the **moment of inertia** or **rotational inertia**, is the rotational analog of mass.
95//! It represents resistance to angular acceleration when a torque is applied.
96//!
97//! An object's angular inertia depends on its mass, shape, and how the mass is distributed
98//! relative to a rotational axis. It increases with mass and distance from the axis.
99//!
100//! In 2D, angular inertia can be treated as a scalar value, as it is only defined
101//! relative to the Z axis.
102//!
103//! In 3D, angular inertia can be represented with a [symmetric], [positive-semidefinite] 3x3 [tensor]
104//! ([`AngularInertiaTensor`]) that describes the moment of inertia for rotations about the X, Y, and Z axes.
105//! By [diagonalizing] this matrix, it is possible to extract the [principal axes of inertia] (a [`Vec3`])
106//! and a local inertial frame (a [`Quat`]) that defines the XYZ axes.
107//!
108//! The latter diagonalized representation is more compact and often easier to work with,
109//! but the full tensor can be more efficient for computations using the angular inertia.
110//!
111//! Angular inertia is commonly measured in kilograms times meters squared (kg⋅m²).
112//!
113//! [symmetric]: https://en.wikipedia.org/wiki/Symmetric_matrix
114//! [positive-semidefinite]: https://en.wikipedia.org/wiki/Definite_matrix
115//! [tensor]: https://en.wikipedia.org/wiki/Moment_of_inertia#Inertia_tensor
116//! [diagonalizing]: https://en.wikipedia.org/wiki/Diagonalizable_matrix#Diagonalization
117//! [principal axes of inertia]: https://en.wikipedia.org/wiki/Moment_of_inertia#Principal_axes
118//! [`Vec3`]: bevy_math::Vec3
119//! [`Quat`]: bevy_math::Quat
120//!
121//! ## Center of Mass
122//!
123//! The **[center of mass](https://en.wikipedia.org/wiki/Center_of_mass)** is the average position
124//! of mass in an object. Applying a force at the center of mass causes linear acceleration
125//! without angular acceleration.
126//!
127//! If an object has uniform density, mass is evenly distributed,
128//! and the center of mass is at the [geometric center], also known as the [centroid].
129//!
130//! The center of mass is commonly measured in meters (m).
131//!
132//! [geometric center]: https://en.wikipedia.org/wiki/Centroid
133//! [centroid]: https://en.wikipedia.org/wiki/Centroid
134
135#![warn(missing_docs)]
136#![no_std]
137
138#[cfg(any(feature = "2d", feature = "3d"))]
139extern crate alloc;
140
141#[cfg(feature = "2d")]
142mod dim2;
143#[cfg(feature = "3d")]
144mod dim3;
145mod math_ext;
146
147#[cfg(feature = "2d")]
148pub use dim2::{ComputeMassProperties2d, MassProperties2d};
149#[cfg(feature = "3d")]
150pub use dim3::{
151 AngularInertiaTensor, AngularInertiaTensorError, ComputeMassProperties3d, MassProperties3d,
152 SymmetricEigen3,
153};
154pub use math_ext::{MatExt, RecipOrZero};