pub struct SpatialCollisionSystem<P, T, D, B, Y = ()>{ /* private fields */ }
Expand description
Collision detection system for use with
specs
.
Will perform spatial sorting of the collision world.
Has support for both broad phase and narrow phase collision detection. Will only do narrow phase if both broad and narrow phase is activated. If no broad phase is set, it will use a DBVT based broad phase that has complexity O(m log^2 n), where m is the number of shapes that have a dirty pose.
Can handle any transform component type, as long as the type implements
Transform
, and as long as the
storage is wrapped in
FlaggedStorage
.
§Type parameters:
P
: Shape primitiveT
: TransformD
: Data accepted by broad phaseY
: Shape type, seeCollider
§System Function:
fn(Entities, T, NextFrame<T>, CollisionShape, DynamicBoundingVolumeTree<D>) -> (DynamicBoundingVolumeTree<D>, EventChannel<ContactEvent>)
Implementations§
Source§impl<P, T, D, B, Y> SpatialCollisionSystem<P, T, D, B, Y>where
P: Primitive + Send + Sync + 'static,
<P::Point as EuclideanSpace>::Diff: Debug,
<P::Point as EuclideanSpace>::Scalar: BaseFloat,
B: Clone + Debug + Send + Sync + 'static + Bound<Point = P::Point> + Union<B, Output = B> + Contains<B> + SurfaceArea<Scalar = <P::Point as EuclideanSpace>::Scalar>,
T: Transform<P::Point> + Component,
D: HasBound<Bound = B>,
impl<P, T, D, B, Y> SpatialCollisionSystem<P, T, D, B, Y>where
P: Primitive + Send + Sync + 'static,
<P::Point as EuclideanSpace>::Diff: Debug,
<P::Point as EuclideanSpace>::Scalar: BaseFloat,
B: Clone + Debug + Send + Sync + 'static + Bound<Point = P::Point> + Union<B, Output = B> + Contains<B> + SurfaceArea<Scalar = <P::Point as EuclideanSpace>::Scalar>,
T: Transform<P::Point> + Component,
D: HasBound<Bound = B>,
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new collision detection system, with no broad or narrow phase activated.
Examples found in repository?
35pub fn main() {
36 let mut world = World::new();
37 let mut sort = SpatialSortingSystem3::<f32, BodyPose3<f32>, ()>::new();
38 let mut collide =
39 SpatialCollisionSystem3::<f32, BodyPose3<f32>, ()>::new().with_narrow_phase(GJK3::new());
40 let mut raycast = RayCastSystem;
41 let mut impulse_solver = CurrentFrameUpdateSystem3::<f32, BodyPose3<f32>>::new();
42 let mut next_frame = NextFrameSetupSystem3::<f32, BodyPose3<f32>>::new();
43 let mut contact_resolution = ContactResolutionSystem3::<f32, BodyPose3<f32>>::new();
44
45 sort.setup(&mut world.res);
46 collide.setup(&mut world.res);
47 raycast.setup(&mut world.res);
48 impulse_solver.setup(&mut world.res);
49 next_frame.setup(&mut world.res);
50 contact_resolution.setup(&mut world.res);
51
52 world
53 .create_entity()
54 .with_static_physical_entity(
55 CollisionShape3::<f32, BodyPose3<f32>, ()>::new_simple(
56 CollisionStrategy::FullResolution,
57 CollisionMode::Discrete,
58 Cuboid::new(10., 10., 10.).into(),
59 ),
60 BodyPose3::one(),
61 PhysicalEntity::default(),
62 Mass3::new(1.),
63 ).build();
64
65 world
66 .create_entity()
67 .with_static_physical_entity(
68 CollisionShape3::<f32, BodyPose3<f32>, ()>::new_simple(
69 CollisionStrategy::FullResolution,
70 CollisionMode::Discrete,
71 Cuboid::new(10., 10., 10.).into(),
72 ),
73 BodyPose3::new(Point3::new(3., 2., 0.), Quaternion::from_angle_z(Rad(0.))),
74 PhysicalEntity::default(),
75 Mass3::new(1.),
76 ).build();
77
78 let mut reader_1 = world
79 .write_resource::<EventChannel<ContactEvent3<f32>>>()
80 .register_reader();
81 {
82 use specs::prelude::RunNow;
83 sort.run_now(&world.res);
84 collide.run_now(&world.res);
85 println!(
86 "Contacts: {:?}",
87 world
88 .read_resource::<EventChannel<ContactEvent3<f32>>>()
89 .read(&mut reader_1)
90 .collect::<Vec<_>>()
91 );
92 raycast.run_now(&world.res);
93
94 impulse_solver.run_now(&world.res);
95 next_frame.run_now(&world.res);
96 contact_resolution.run_now(&world.res);
97 }
98}
More examples
36pub fn main() {
37 let mut world = World::new();
38 let mut sort = SpatialSortingSystem2::<f32, BodyPose2<f32>, ()>::new();
39 let mut collide =
40 SpatialCollisionSystem2::<f32, BodyPose2<f32>, ()>::new().with_narrow_phase(GJK2::new());
41 let mut raycast = RayCastSystem;
42 let mut impulse_solver = CurrentFrameUpdateSystem2::<f32, BodyPose2<f32>>::new();
43 let mut next_frame = NextFrameSetupSystem2::<f32, BodyPose2<f32>>::new();
44 let mut contact_resolution = ContactResolutionSystem2::<f32, BodyPose2<f32>>::new();
45
46 sort.setup(&mut world.res);
47 collide.setup(&mut world.res);
48 raycast.setup(&mut world.res);
49 impulse_solver.setup(&mut world.res);
50 next_frame.setup(&mut world.res);
51 contact_resolution.setup(&mut world.res);
52
53 world
54 .create_entity()
55 .with_static_physical_entity(
56 CollisionShape2::<f32, BodyPose2<f32>, ()>::new_simple(
57 CollisionStrategy::FullResolution,
58 CollisionMode::Discrete,
59 Rectangle::new(10., 10.).into(),
60 ),
61 BodyPose2::<f32>::one(),
62 PhysicalEntity::default(),
63 Mass2::new(1.),
64 ).build();
65
66 world
67 .create_entity()
68 .with_static_physical_entity(
69 CollisionShape2::<f32, BodyPose2<f32>, ()>::new_simple(
70 CollisionStrategy::FullResolution,
71 CollisionMode::Discrete,
72 Rectangle::new(10., 10.).into(),
73 ),
74 BodyPose2::<f32>::new(Point2::new(2., 2.), Rotation2::from_angle(Rad(0.))),
75 PhysicalEntity::default(),
76 Mass2::new(1.),
77 ).build();
78
79 let mut reader_1 = world
80 .write_resource::<EventChannel<ContactEvent2<f32>>>()
81 .register_reader();
82
83 {
84 use specs::prelude::RunNow;
85 sort.run_now(&world.res);
86 collide.run_now(&world.res);
87
88 println!(
89 "Contacts: {:?}",
90 world
91 .read_resource::<EventChannel<ContactEvent2<f32>>>()
92 .read(&mut reader_1)
93 .collect::<Vec<_>>()
94 );
95
96 raycast.run_now(&world.res);
97 impulse_solver.run_now(&world.res);
98 next_frame.run_now(&world.res);
99 contact_resolution.run_now(&world.res);
100 }
101}
Sourcepub fn with_narrow_phase<N: NarrowPhase<P, T, B, Y> + 'static>(
self,
narrow: N,
) -> Self
pub fn with_narrow_phase<N: NarrowPhase<P, T, B, Y> + 'static>( self, narrow: N, ) -> Self
Specify what narrow phase algorithm to use
Examples found in repository?
35pub fn main() {
36 let mut world = World::new();
37 let mut sort = SpatialSortingSystem3::<f32, BodyPose3<f32>, ()>::new();
38 let mut collide =
39 SpatialCollisionSystem3::<f32, BodyPose3<f32>, ()>::new().with_narrow_phase(GJK3::new());
40 let mut raycast = RayCastSystem;
41 let mut impulse_solver = CurrentFrameUpdateSystem3::<f32, BodyPose3<f32>>::new();
42 let mut next_frame = NextFrameSetupSystem3::<f32, BodyPose3<f32>>::new();
43 let mut contact_resolution = ContactResolutionSystem3::<f32, BodyPose3<f32>>::new();
44
45 sort.setup(&mut world.res);
46 collide.setup(&mut world.res);
47 raycast.setup(&mut world.res);
48 impulse_solver.setup(&mut world.res);
49 next_frame.setup(&mut world.res);
50 contact_resolution.setup(&mut world.res);
51
52 world
53 .create_entity()
54 .with_static_physical_entity(
55 CollisionShape3::<f32, BodyPose3<f32>, ()>::new_simple(
56 CollisionStrategy::FullResolution,
57 CollisionMode::Discrete,
58 Cuboid::new(10., 10., 10.).into(),
59 ),
60 BodyPose3::one(),
61 PhysicalEntity::default(),
62 Mass3::new(1.),
63 ).build();
64
65 world
66 .create_entity()
67 .with_static_physical_entity(
68 CollisionShape3::<f32, BodyPose3<f32>, ()>::new_simple(
69 CollisionStrategy::FullResolution,
70 CollisionMode::Discrete,
71 Cuboid::new(10., 10., 10.).into(),
72 ),
73 BodyPose3::new(Point3::new(3., 2., 0.), Quaternion::from_angle_z(Rad(0.))),
74 PhysicalEntity::default(),
75 Mass3::new(1.),
76 ).build();
77
78 let mut reader_1 = world
79 .write_resource::<EventChannel<ContactEvent3<f32>>>()
80 .register_reader();
81 {
82 use specs::prelude::RunNow;
83 sort.run_now(&world.res);
84 collide.run_now(&world.res);
85 println!(
86 "Contacts: {:?}",
87 world
88 .read_resource::<EventChannel<ContactEvent3<f32>>>()
89 .read(&mut reader_1)
90 .collect::<Vec<_>>()
91 );
92 raycast.run_now(&world.res);
93
94 impulse_solver.run_now(&world.res);
95 next_frame.run_now(&world.res);
96 contact_resolution.run_now(&world.res);
97 }
98}
More examples
36pub fn main() {
37 let mut world = World::new();
38 let mut sort = SpatialSortingSystem2::<f32, BodyPose2<f32>, ()>::new();
39 let mut collide =
40 SpatialCollisionSystem2::<f32, BodyPose2<f32>, ()>::new().with_narrow_phase(GJK2::new());
41 let mut raycast = RayCastSystem;
42 let mut impulse_solver = CurrentFrameUpdateSystem2::<f32, BodyPose2<f32>>::new();
43 let mut next_frame = NextFrameSetupSystem2::<f32, BodyPose2<f32>>::new();
44 let mut contact_resolution = ContactResolutionSystem2::<f32, BodyPose2<f32>>::new();
45
46 sort.setup(&mut world.res);
47 collide.setup(&mut world.res);
48 raycast.setup(&mut world.res);
49 impulse_solver.setup(&mut world.res);
50 next_frame.setup(&mut world.res);
51 contact_resolution.setup(&mut world.res);
52
53 world
54 .create_entity()
55 .with_static_physical_entity(
56 CollisionShape2::<f32, BodyPose2<f32>, ()>::new_simple(
57 CollisionStrategy::FullResolution,
58 CollisionMode::Discrete,
59 Rectangle::new(10., 10.).into(),
60 ),
61 BodyPose2::<f32>::one(),
62 PhysicalEntity::default(),
63 Mass2::new(1.),
64 ).build();
65
66 world
67 .create_entity()
68 .with_static_physical_entity(
69 CollisionShape2::<f32, BodyPose2<f32>, ()>::new_simple(
70 CollisionStrategy::FullResolution,
71 CollisionMode::Discrete,
72 Rectangle::new(10., 10.).into(),
73 ),
74 BodyPose2::<f32>::new(Point2::new(2., 2.), Rotation2::from_angle(Rad(0.))),
75 PhysicalEntity::default(),
76 Mass2::new(1.),
77 ).build();
78
79 let mut reader_1 = world
80 .write_resource::<EventChannel<ContactEvent2<f32>>>()
81 .register_reader();
82
83 {
84 use specs::prelude::RunNow;
85 sort.run_now(&world.res);
86 collide.run_now(&world.res);
87
88 println!(
89 "Contacts: {:?}",
90 world
91 .read_resource::<EventChannel<ContactEvent2<f32>>>()
92 .read(&mut reader_1)
93 .collect::<Vec<_>>()
94 );
95
96 raycast.run_now(&world.res);
97 impulse_solver.run_now(&world.res);
98 next_frame.run_now(&world.res);
99 contact_resolution.run_now(&world.res);
100 }
101}
Sourcepub fn with_broad_phase<V: BroadPhase<D> + 'static>(self, broad: V) -> Self
pub fn with_broad_phase<V: BroadPhase<D> + 'static>(self, broad: V) -> Self
Specify what broad phase algorithm to use
Trait Implementations§
Source§impl<'a, P, T, Y, B, D> System<'a> for SpatialCollisionSystem<P, T, (usize, D), B, Y>where
P: Primitive + ComputeBound<B> + Send + Sync + 'static,
P::Point: EuclideanSpace + Debug + Send + Sync + 'static,
<P::Point as EuclideanSpace>::Scalar: BaseFloat + Send + Sync + 'static,
B: Clone + Debug + Send + Sync + 'static + Bound<Point = P::Point> + Union<B, Output = B> + Discrete<B> + Contains<B> + SurfaceArea<Scalar = <P::Point as EuclideanSpace>::Scalar>,
<P::Point as EuclideanSpace>::Diff: Debug + Send + Sync + 'static,
T: Component + Clone + Debug + Transform<P::Point> + Send + Sync + 'static,
T::Storage: Tracked,
Y: Default + Send + Sync + 'static,
D: Send + Sync + 'static + TreeValue<Bound = B> + HasBound<Bound = B> + GetId<Entity>,
impl<'a, P, T, Y, B, D> System<'a> for SpatialCollisionSystem<P, T, (usize, D), B, Y>where
P: Primitive + ComputeBound<B> + Send + Sync + 'static,
P::Point: EuclideanSpace + Debug + Send + Sync + 'static,
<P::Point as EuclideanSpace>::Scalar: BaseFloat + Send + Sync + 'static,
B: Clone + Debug + Send + Sync + 'static + Bound<Point = P::Point> + Union<B, Output = B> + Discrete<B> + Contains<B> + SurfaceArea<Scalar = <P::Point as EuclideanSpace>::Scalar>,
<P::Point as EuclideanSpace>::Diff: Debug + Send + Sync + 'static,
T: Component + Clone + Debug + Transform<P::Point> + Send + Sync + 'static,
T::Storage: Tracked,
Y: Default + Send + Sync + 'static,
D: Send + Sync + 'static + TreeValue<Bound = B> + HasBound<Bound = B> + GetId<Entity>,
Source§type SystemData = (Read<'a, EntitiesRes>, Storage<'a, T, Fetch<'a, MaskedStorage<T>>>, Storage<'a, NextFrame<T>, Fetch<'a, MaskedStorage<NextFrame<T>>>>, Storage<'a, CollisionShape<P, T, B, Y>, Fetch<'a, MaskedStorage<CollisionShape<P, T, B, Y>>>>, Write<'a, EventChannel<ContactEvent<Entity, <P as Primitive>::Point>>>, Write<'a, DynamicBoundingVolumeTree<D>>)
type SystemData = (Read<'a, EntitiesRes>, Storage<'a, T, Fetch<'a, MaskedStorage<T>>>, Storage<'a, NextFrame<T>, Fetch<'a, MaskedStorage<NextFrame<T>>>>, Storage<'a, CollisionShape<P, T, B, Y>, Fetch<'a, MaskedStorage<CollisionShape<P, T, B, Y>>>>, Write<'a, EventChannel<ContactEvent<Entity, <P as Primitive>::Point>>>, Write<'a, DynamicBoundingVolumeTree<D>>)
Source§fn run(&mut self, system_data: Self::SystemData)
fn run(&mut self, system_data: Self::SystemData)
Source§fn running_time(&self) -> RunningTime
fn running_time(&self) -> RunningTime
Source§fn accessor<'b>(&'b self) -> AccessorCow<'a, 'b, Self>
fn accessor<'b>(&'b self) -> AccessorCow<'a, 'b, Self>
SystemData
.Auto Trait Implementations§
impl<P, T, D, B, Y> Freeze for SpatialCollisionSystem<P, T, D, B, Y>
impl<P, T, D, B, Y = ()> !RefUnwindSafe for SpatialCollisionSystem<P, T, D, B, Y>
impl<P, T, D, B, Y> Send for SpatialCollisionSystem<P, T, D, B, Y>
impl<P, T, D, B, Y = ()> !Sync for SpatialCollisionSystem<P, T, D, B, Y>
impl<P, T, D, B, Y> Unpin for SpatialCollisionSystem<P, T, D, B, Y>
impl<P, T, D, B, Y = ()> !UnwindSafe for SpatialCollisionSystem<P, T, D, B, Y>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more