Skip to main content

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