Skip to content

Commit 34607ad

Browse files
committed
reorganize code in preparation for working on version 3
1 parent 88182b6 commit 34607ad

14 files changed

Lines changed: 157 additions & 152 deletions

File tree

src/lib.rs

Lines changed: 3 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -56,148 +56,7 @@
5656
//! * `bvh-arena` Integration with [bvh-arena](https://crates.io/crates/bvh-arena) bounding volumes
5757
//!
5858
59-
use crate::shapes::ShapeData;
60-
pub use crate::transform::Transform;
59+
mod v2;
60+
mod v3;
6161

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::*;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use bvh_arena::volumes::Aabb;
22
use glam::Vec2;
33

4-
use crate::{CollisionShape, Support};
4+
use crate::v2::{CollisionShape, Support};
55

66
impl From<&CollisionShape> for Aabb<2> {
77
fn from(shape: &CollisionShape) -> Self {

src/epa.rs renamed to src/v2/epa.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ use core::{
55

66
use smallvec::{smallvec, SmallVec};
77

8-
use crate::{gjk, math::*, Contact, Support};
8+
use super::{gjk, math::*, Contact, Support};
99

10-
pub(crate) fn generate_contact<S, V>(
10+
pub(super) fn generate_contact<S, V>(
1111
difference: &impl Support<V>,
1212
simplex: gjk::Simplex<V>,
1313
) -> Contact<S, V>

src/gjk.rs renamed to src/v2/gjk.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use core::ops::{Neg, Sub};
22

3-
use crate::{math::*, Support};
3+
use super::{math::*, Support};
44

5-
pub(crate) fn find_simplex_enclosing_origin<V>(
5+
pub(super) fn find_simplex_enclosing_origin<V>(
66
shape: &impl Support<V>,
77
initial_direction: V,
88
) -> Option<Simplex<V>>
File renamed without changes.
File renamed without changes.

src/minkowski.rs renamed to src/v2/minkowski.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::ops::{Neg, Sub};
22

3-
use crate::Support;
3+
use super::Support;
44

55
pub(crate) struct Difference<'a, S1, S2> {
66
pub(crate) shape1: &'a S1,

src/v2/mod.rs

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
mod broad_phase_interop;
2+
mod epa;
3+
mod gjk;
4+
mod math;
5+
mod minkowski;
6+
#[cfg(test)]
7+
mod ray;
8+
pub mod shapes;
9+
mod transform;
10+
11+
use shapes::ShapeData;
12+
pub use transform::Transform;
13+
14+
/// A collision shape
15+
///
16+
/// This is the entry point for collision detection.
17+
///
18+
/// See [crate](crate) level documentation for more info and examples.
19+
#[derive(Debug, Clone)]
20+
pub struct CollisionShape {
21+
transform: Transform,
22+
data: ShapeData,
23+
}
24+
25+
impl<S: Into<ShapeData>> From<S> for CollisionShape {
26+
fn from(shape: S) -> Self {
27+
Self {
28+
transform: Transform::default(),
29+
data: shape.into(),
30+
}
31+
}
32+
}
33+
34+
impl CollisionShape {
35+
/// Create a circle from its radius
36+
///
37+
/// The origin is in the center of the circle
38+
#[inline]
39+
#[must_use]
40+
pub fn new_circle(radius: f32) -> Self {
41+
shapes::Circle::new(radius).into()
42+
}
43+
44+
/// Create a rectangle from its width and height
45+
///
46+
/// The origin is in the center of the rectangle
47+
#[inline]
48+
#[must_use]
49+
pub fn new_rectangle(width: f32, height: f32) -> Self {
50+
shapes::Rectangle::new(width, height).into()
51+
}
52+
53+
/// Create a segment from two points
54+
#[inline]
55+
#[must_use]
56+
pub fn new_segment(p1: impl Into<[f32; 2]>, p2: impl Into<[f32; 2]>) -> Self {
57+
shapes::Segment::new(p1, p2).into()
58+
}
59+
60+
/// Set the transform (translation, rotation and scale)
61+
///
62+
/// This is equivalent to [`set_transform`](Self::set_transform), but in a builder style,
63+
/// useful to set the transform directly at creation
64+
#[inline]
65+
#[must_use]
66+
pub fn with_transform(mut self, transform: impl Into<Transform>) -> Self {
67+
self.set_transform(transform);
68+
self
69+
}
70+
71+
/// Set the transform (translation, rotation and scale)
72+
#[inline]
73+
pub fn set_transform(&mut self, transform: impl Into<Transform>) {
74+
self.transform = transform.into();
75+
}
76+
77+
/// Returns true if the two convex shapes geometries are overlapping
78+
#[must_use]
79+
pub fn is_collided_with(&self, other: &Self) -> bool {
80+
let difference = minkowski::Difference {
81+
shape1: self,
82+
shape2: other,
83+
};
84+
let initial_axis = other.transform.position() - self.transform.position();
85+
gjk::find_simplex_enclosing_origin(&difference, initial_axis).is_some()
86+
}
87+
88+
/// Returns contact data with the other shape if they collide. Returns `None` if they don't collide.
89+
///
90+
/// The normal of the contact data is pointing toward this shape.
91+
/// In other words, ff this shape is moved by `contact.normal * contact.penetration`
92+
/// the two shapes will no longer be inter-penetrating.
93+
#[must_use]
94+
pub fn contact_with(&self, other: &Self) -> Option<Contact> {
95+
let difference = minkowski::Difference {
96+
shape1: self,
97+
shape2: other,
98+
};
99+
let initial_axis = other.transform.position() - self.transform.position();
100+
let simplex = gjk::find_simplex_enclosing_origin(&difference, initial_axis)?;
101+
let Contact {
102+
normal,
103+
penetration,
104+
} = epa::generate_contact(&difference, simplex);
105+
Some(Contact::<f32, [f32; 2]> {
106+
normal: normal.into(),
107+
penetration,
108+
})
109+
}
110+
111+
/// Returns the shape data of the collider
112+
#[must_use]
113+
pub fn shape_data(&self) -> &ShapeData {
114+
&self.data
115+
}
116+
}
117+
118+
/// Contact data between two shapes
119+
///
120+
/// See [`CollisionShape::contact_with`]
121+
#[non_exhaustive]
122+
#[derive(Debug, Clone, PartialEq)]
123+
pub struct Contact<S = f32, V = [S; 2]> {
124+
/// Contact normal
125+
///
126+
/// This is the direction on which the first shape should be moved to resolve inter-penetration
127+
/// This is also on that direction that impulse should be applied to the first shape to resolve velocities
128+
pub normal: V,
129+
/// Penetration
130+
///
131+
/// This is "how much" the two shapes are inter-penetrating
132+
pub penetration: S,
133+
}
134+
135+
trait Support<V> {
136+
/// Returns the farthest point of the shape in the given direction.
137+
///
138+
/// More formaly: For a direction `v` return the point `p` of the shape that maximize the dot product `p . v`
139+
///
140+
/// If many points are equaly far in the given direction (have the same dot product `p . v`),
141+
/// then one of the is choosen arbitrarily.
142+
///
143+
/// Note the direction may not be normalized, and may have a magnitude of zero.
144+
fn support(&self, direction: V) -> V;
145+
}

0 commit comments

Comments
 (0)