spatial2d/
spatial2d.rs

1extern crate cgmath;
2extern crate collision;
3extern crate rhusics_core;
4extern crate rhusics_ecs;
5extern crate shrev;
6extern crate specs;
7
8use cgmath::{Point2, Rad, Rotation2, Transform, Vector2};
9use collision::dbvt::query_ray_closest;
10use collision::Ray2;
11use shrev::EventChannel;
12use specs::prelude::{Builder, ReadExpect, System, World};
13
14use rhusics_core::{PhysicalEntity, Pose};
15use rhusics_ecs::physics2d::{
16    BodyPose2, CollisionMode, CollisionShape2, CollisionStrategy, ContactEvent2,
17    ContactResolutionSystem2, CurrentFrameUpdateSystem2, DynamicBoundingVolumeTree2, Mass2,
18    NextFrameSetupSystem2, Rectangle, SpatialCollisionSystem2, SpatialSortingSystem2, GJK2,
19};
20use rhusics_ecs::WithPhysics;
21
22struct RayCastSystem;
23
24impl<'a> System<'a> for RayCastSystem {
25    type SystemData = (ReadExpect<'a, DynamicBoundingVolumeTree2<f32>>,);
26
27    fn run(&mut self, (tree,): Self::SystemData) {
28        println!("{:?}", *tree);
29        let ray = Ray2::new(Point2::new(-4., 10.), Vector2::new(0., -1.));
30        if let Some((v, p)) = query_ray_closest(&*tree, ray) {
31            println!("hit bounding volume of {:?} at point {:?}", v.value, p);
32        }
33    }
34}
35
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}