|
56 | 56 | //! * `bvh-arena` Integration with [bvh-arena](https://crates.io/crates/bvh-arena) bounding volumes |
57 | 57 | //! |
58 | 58 |
|
59 | | -use crate::shapes::ShapeData; |
60 | | -pub use crate::transform::Transform; |
| 59 | +mod v2; |
| 60 | +mod v3; |
61 | 61 |
|
62 | | -mod broad_phase_interop; |
63 | | -mod epa; |
64 | | -mod gjk; |
65 | | -mod math; |
66 | | -mod minkowski; |
67 | | -#[cfg(test)] |
68 | | -mod ray; |
69 | | -pub mod shapes; |
70 | | -mod transform; |
71 | | - |
72 | | -/// A collision shape |
73 | | -/// |
74 | | -/// This is the entry point for collision detection. |
75 | | -/// |
76 | | -/// See [crate](crate) level documentation for more info and examples. |
77 | | -#[derive(Debug, Clone)] |
78 | | -pub struct CollisionShape { |
79 | | - transform: Transform, |
80 | | - data: ShapeData, |
81 | | -} |
82 | | - |
83 | | -impl<S: Into<ShapeData>> From<S> for CollisionShape { |
84 | | - fn from(shape: S) -> Self { |
85 | | - Self { |
86 | | - transform: Transform::default(), |
87 | | - data: shape.into(), |
88 | | - } |
89 | | - } |
90 | | -} |
91 | | - |
92 | | -impl CollisionShape { |
93 | | - /// Create a circle from its radius |
94 | | - /// |
95 | | - /// The origin is in the center of the circle |
96 | | - #[inline] |
97 | | - #[must_use] |
98 | | - pub fn new_circle(radius: f32) -> Self { |
99 | | - shapes::Circle::new(radius).into() |
100 | | - } |
101 | | - |
102 | | - /// Create a rectangle from its width and height |
103 | | - /// |
104 | | - /// The origin is in the center of the rectangle |
105 | | - #[inline] |
106 | | - #[must_use] |
107 | | - pub fn new_rectangle(width: f32, height: f32) -> Self { |
108 | | - shapes::Rectangle::new(width, height).into() |
109 | | - } |
110 | | - |
111 | | - /// Create a segment from two points |
112 | | - #[inline] |
113 | | - #[must_use] |
114 | | - pub fn new_segment(p1: impl Into<[f32; 2]>, p2: impl Into<[f32; 2]>) -> Self { |
115 | | - shapes::Segment::new(p1, p2).into() |
116 | | - } |
117 | | - |
118 | | - /// Set the transform (translation, rotation and scale) |
119 | | - /// |
120 | | - /// This is equivalent to [`set_transform`](Self::set_transform), but in a builder style, |
121 | | - /// useful to set the transform directly at creation |
122 | | - #[inline] |
123 | | - #[must_use] |
124 | | - pub fn with_transform(mut self, transform: impl Into<Transform>) -> Self { |
125 | | - self.set_transform(transform); |
126 | | - self |
127 | | - } |
128 | | - |
129 | | - /// Set the transform (translation, rotation and scale) |
130 | | - #[inline] |
131 | | - pub fn set_transform(&mut self, transform: impl Into<Transform>) { |
132 | | - self.transform = transform.into(); |
133 | | - } |
134 | | - |
135 | | - /// Returns true if the two convex shapes geometries are overlapping |
136 | | - #[must_use] |
137 | | - pub fn is_collided_with(&self, other: &Self) -> bool { |
138 | | - let difference = minkowski::Difference { |
139 | | - shape1: self, |
140 | | - shape2: other, |
141 | | - }; |
142 | | - let initial_axis = other.transform.position() - self.transform.position(); |
143 | | - gjk::find_simplex_enclosing_origin(&difference, initial_axis).is_some() |
144 | | - } |
145 | | - |
146 | | - /// Returns contact data with the other shape if they collide. Returns `None` if they don't collide. |
147 | | - /// |
148 | | - /// The normal of the contact data is pointing toward this shape. |
149 | | - /// In other words, ff this shape is moved by `contact.normal * contact.penetration` |
150 | | - /// the two shapes will no longer be inter-penetrating. |
151 | | - #[must_use] |
152 | | - pub fn contact_with(&self, other: &Self) -> Option<Contact> { |
153 | | - let difference = minkowski::Difference { |
154 | | - shape1: self, |
155 | | - shape2: other, |
156 | | - }; |
157 | | - let initial_axis = other.transform.position() - self.transform.position(); |
158 | | - let simplex = gjk::find_simplex_enclosing_origin(&difference, initial_axis)?; |
159 | | - let Contact { |
160 | | - normal, |
161 | | - penetration, |
162 | | - } = epa::generate_contact(&difference, simplex); |
163 | | - Some(Contact::<f32, [f32; 2]> { |
164 | | - normal: normal.into(), |
165 | | - penetration, |
166 | | - }) |
167 | | - } |
168 | | - |
169 | | - /// Returns the shape data of the collider |
170 | | - #[must_use] |
171 | | - pub fn shape_data(&self) -> &ShapeData { |
172 | | - &self.data |
173 | | - } |
174 | | -} |
175 | | - |
176 | | -/// Contact data between two shapes |
177 | | -/// |
178 | | -/// See [`CollisionShape::contact_with`] |
179 | | -#[non_exhaustive] |
180 | | -#[derive(Debug, Clone, PartialEq)] |
181 | | -pub struct Contact<S = f32, V = [S; 2]> { |
182 | | - /// Contact normal |
183 | | - /// |
184 | | - /// This is the direction on which the first shape should be moved to resolve inter-penetration |
185 | | - /// This is also on that direction that impulse should be applied to the first shape to resolve velocities |
186 | | - pub normal: V, |
187 | | - /// Penetration |
188 | | - /// |
189 | | - /// This is "how much" the two shapes are inter-penetrating |
190 | | - pub penetration: S, |
191 | | -} |
192 | | - |
193 | | -trait Support<V> { |
194 | | - /// Returns the farthest point of the shape in the given direction. |
195 | | - /// |
196 | | - /// More formaly: For a direction `v` return the point `p` of the shape that maximize the dot product `p . v` |
197 | | - /// |
198 | | - /// If many points are equaly far in the given direction (have the same dot product `p . v`), |
199 | | - /// then one of the is choosen arbitrarily. |
200 | | - /// |
201 | | - /// Note the direction may not be normalized, and may have a magnitude of zero. |
202 | | - fn support(&self, direction: V) -> V; |
203 | | -} |
| 62 | +pub use v2::*; |
0 commit comments