spatial3d/
spatial3d.rs

1extern crate cgmath;
2extern crate collision;
3extern crate rhusics_core;
4extern crate rhusics_ecs;
5extern crate shrev;
6extern crate specs;
7
8use cgmath::{Point3, Quaternion, Rad, Rotation3, Transform, Vector3};
9use collision::dbvt::query_ray_closest;
10use collision::Ray3;
11use shrev::EventChannel;
12use specs::prelude::{Builder, ReadExpect, System, World};
13
14use rhusics_core::{PhysicalEntity, Pose};
15use rhusics_ecs::physics3d::{
16    BodyPose3, CollisionMode, CollisionShape3, CollisionStrategy, ContactEvent3,
17    ContactResolutionSystem3, Cuboid, CurrentFrameUpdateSystem3, DynamicBoundingVolumeTree3, Mass3,
18    NextFrameSetupSystem3, SpatialCollisionSystem3, SpatialSortingSystem3, GJK3,
19};
20use rhusics_ecs::WithPhysics;
21
22struct RayCastSystem;
23
24impl<'a> System<'a> for RayCastSystem {
25    type SystemData = (ReadExpect<'a, DynamicBoundingVolumeTree3<f32>>,);
26
27    fn run(&mut self, (tree,): Self::SystemData) {
28        let ray = Ray3::new(Point3::new(-4., 10., 0.), Vector3::new(0., -1., 0.));
29        if let Some((v, p)) = query_ray_closest(&*tree, ray) {
30            println!("hit bounding volume of {:?} at point {:?}", v.value, p);
31        }
32    }
33}
34
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}