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}