rapier2d/
lib.rs

1//! # Rapier
2//!
3//! Rapier is a set of two Rust crates `rapier2d` and `rapier3d` for efficient cross-platform
4//! physics simulation. It target application include video games, animation, robotics, etc.
5//!
6//! Rapier has some unique features for collaborative applications:
7//! - The ability to snapshot the state of the physics engine, and restore it later.
8//! - The ability to run a perfectly deterministic simulation on different machine, as long as they
9//!   are compliant with the IEEE 754-2008 floating point standard.
10//!
11//! User documentation for Rapier is on [the official Rapier site](https://rapier.rs/docs/).
12
13#![deny(bare_trait_objects)]
14#![warn(missing_docs)]
15#![allow(clippy::too_many_arguments)]
16#![allow(clippy::needless_range_loop)] // TODO: remove this? I find that in the math code using indices adds clarity.
17#![allow(clippy::module_inception)]
18#![cfg_attr(feature = "simd-nightly", feature(portable_simd))]
19
20#[cfg(all(feature = "dim2", feature = "f32"))]
21pub extern crate parry2d as parry;
22#[cfg(all(feature = "dim2", feature = "f64"))]
23pub extern crate parry2d_f64 as parry;
24#[cfg(all(feature = "dim3", feature = "f32"))]
25pub extern crate parry3d as parry;
26#[cfg(all(feature = "dim3", feature = "f64"))]
27pub extern crate parry3d_f64 as parry;
28
29pub extern crate nalgebra as na;
30#[cfg(feature = "serde-serialize")]
31#[macro_use]
32extern crate serde;
33extern crate num_traits as num;
34
35#[cfg(feature = "parallel")]
36pub use rayon;
37
38#[cfg(all(
39    feature = "simd-is-enabled",
40    not(feature = "simd-stable"),
41    not(feature = "simd-nightly")
42))]
43std::compile_error!(
44    "The `simd-is-enabled` feature should not be enabled explicitly. Please enable the `simd-stable` or the `simd-nightly` feature instead."
45);
46#[cfg(all(feature = "simd-is-enabled", feature = "enhanced-determinism"))]
47std::compile_error!(
48    "SIMD cannot be enabled when the `enhanced-determinism` feature is also enabled."
49);
50
51macro_rules! enable_flush_to_zero(
52    () => {
53        let _flush_to_zero = crate::utils::FlushToZeroDenormalsAreZeroFlags::flush_denormal_to_zero();
54    }
55);
56
57macro_rules! gather(
58    ($callback: expr) => {
59        {
60            #[inline(always)]
61            #[allow(dead_code)]
62            #[cfg(not(feature = "simd-is-enabled"))]
63            fn create_arr<T>(mut callback: impl FnMut(usize) -> T) -> T {
64                callback(0usize)
65            }
66
67            #[inline(always)]
68            #[allow(dead_code)]
69            #[cfg(feature = "simd-is-enabled")]
70            fn create_arr<T>(mut callback: impl FnMut(usize) -> T) -> [T; SIMD_WIDTH] {
71                [callback(0usize), callback(1usize), callback(2usize), callback(3usize)]
72            }
73
74
75            create_arr($callback)
76        }
77    }
78);
79
80macro_rules! array(
81    ($callback: expr) => {
82        {
83            #[inline(always)]
84            #[allow(dead_code)]
85            fn create_arr<T>(mut callback: impl FnMut(usize) -> T) -> [T; SIMD_WIDTH] {
86                #[cfg(not(feature = "simd-is-enabled"))]
87                return [callback(0usize)];
88                #[cfg(feature = "simd-is-enabled")]
89                return [callback(0usize), callback(1usize), callback(2usize), callback(3usize)];
90            }
91
92            create_arr($callback)
93        }
94    }
95);
96
97#[allow(unused_macros)]
98macro_rules! par_iter {
99    ($t: expr) => {{
100        #[cfg(not(feature = "parallel"))]
101        let it = $t.iter();
102
103        #[cfg(feature = "parallel")]
104        let it = $t.par_iter();
105        it
106    }};
107}
108
109macro_rules! par_iter_mut {
110    ($t: expr) => {{
111        #[cfg(not(feature = "parallel"))]
112        let it = $t.iter_mut();
113
114        #[cfg(feature = "parallel")]
115        let it = $t.par_iter_mut();
116        it
117    }};
118}
119
120// macro_rules! par_chunks_mut {
121//     ($t: expr, $sz: expr) => {{
122//         #[cfg(not(feature = "parallel"))]
123//         let it = $t.chunks_mut($sz);
124//
125//         #[cfg(feature = "parallel")]
126//         let it = $t.par_chunks_mut($sz);
127//         it
128//     }};
129// }
130
131#[allow(unused_macros)]
132macro_rules! try_ret {
133    ($val: expr) => {
134        try_ret!($val, ())
135    };
136    ($val: expr, $ret: expr) => {
137        if let Some(val) = $val {
138            val
139        } else {
140            return $ret;
141        }
142    };
143}
144
145// macro_rules! try_continue {
146//     ($val: expr) => {
147//         if let Some(val) = $val {
148//             val
149//         } else {
150//             continue;
151//         }
152//     };
153// }
154
155pub(crate) const INVALID_U32: u32 = u32::MAX;
156pub(crate) const INVALID_USIZE: usize = INVALID_U32 as usize;
157
158/// The string version of Rapier.
159pub const VERSION: &str = env!("CARGO_PKG_VERSION");
160
161pub mod control;
162pub mod counters;
163pub mod data;
164pub mod dynamics;
165pub mod geometry;
166pub mod pipeline;
167pub mod utils;
168
169/// Elementary mathematical entities (vectors, matrices, isometries, etc).
170pub mod math {
171    pub use parry::math::*;
172
173    /*
174     * 2D
175     */
176    /// Max number of pairs of contact points from the same
177    /// contact manifold that can be solved as part of a
178    /// single contact constraint.
179    #[cfg(feature = "dim2")]
180    pub const MAX_MANIFOLD_POINTS: usize = 2;
181
182    /// The type of a constraint Jacobian in twist coordinates.
183    #[cfg(feature = "dim2")]
184    pub type Jacobian<N> = na::Matrix3xX<N>;
185
186    /// The type of a slice of the constraint Jacobian in twist coordinates.
187    #[cfg(feature = "dim2")]
188    pub type JacobianView<'a, N> = na::MatrixView3xX<'a, N>;
189
190    /// The type of a mutable slice of the constraint Jacobian in twist coordinates.
191    #[cfg(feature = "dim2")]
192    pub type JacobianViewMut<'a, N> = na::MatrixViewMut3xX<'a, N>;
193
194    /// The type of impulse applied for friction constraints.
195    #[cfg(feature = "dim2")]
196    pub type TangentImpulse<N> = na::Vector1<N>;
197
198    /// The maximum number of possible rotations and translations of a rigid body.
199    #[cfg(feature = "dim2")]
200    pub const SPATIAL_DIM: usize = 3;
201
202    /// The maximum number of rotational degrees of freedom of a rigid-body.
203    #[cfg(feature = "dim2")]
204    pub const ANG_DIM: usize = 1;
205
206    /*
207     * 3D
208     */
209    /// Max number of pairs of contact points from the same
210    /// contact manifold that can be solved as part of a
211    /// single contact constraint.
212    #[cfg(feature = "dim3")]
213    pub const MAX_MANIFOLD_POINTS: usize = 4;
214
215    /// The type of a constraint Jacobian in twist coordinates.
216    #[cfg(feature = "dim3")]
217    pub type Jacobian<N> = na::Matrix6xX<N>;
218
219    /// The type of a slice of the constraint Jacobian in twist coordinates.
220    #[cfg(feature = "dim3")]
221    pub type JacobianView<'a, N> = na::MatrixView6xX<'a, N>;
222
223    /// The type of a mutable slice of the constraint Jacobian in twist coordinates.
224    #[cfg(feature = "dim3")]
225    pub type JacobianViewMut<'a, N> = na::MatrixViewMut6xX<'a, N>;
226
227    /// The type of impulse applied for friction constraints.
228    #[cfg(feature = "dim3")]
229    pub type TangentImpulse<N> = na::Vector2<N>;
230
231    /// The maximum number of possible rotations and translations of a rigid body.
232    #[cfg(feature = "dim3")]
233    pub const SPATIAL_DIM: usize = 6;
234
235    /// The maximum number of rotational degrees of freedom of a rigid-body.
236    #[cfg(feature = "dim3")]
237    pub const ANG_DIM: usize = 3;
238}
239
240/// Prelude containing the common types defined by Rapier.
241pub mod prelude {
242    pub use crate::dynamics::*;
243    pub use crate::geometry::*;
244    pub use crate::math::*;
245    pub use crate::pipeline::*;
246    pub use na::{DMatrix, DVector, point, vector};
247    pub extern crate nalgebra;
248}