extern crate cgmath; extern crate collision; extern crate rhusics_core; extern crate rhusics_ecs; extern crate shrev; extern crate specs; use cgmath::{Point2, Rad, Rotation2, Transform, Vector2}; use collision::dbvt::query_ray_closest; use collision::Ray2; use shrev::EventChannel; use specs::prelude::{Builder, ReadExpect, System, World}; use rhusics_core::{PhysicalEntity, Pose}; use rhusics_ecs::physics2d::{ BodyPose2, CollisionMode, CollisionShape2, CollisionStrategy, ContactEvent2, ContactResolutionSystem2, CurrentFrameUpdateSystem2, DynamicBoundingVolumeTree2, Mass2, NextFrameSetupSystem2, Rectangle, SpatialCollisionSystem2, SpatialSortingSystem2, GJK2, }; use rhusics_ecs::WithPhysics; struct RayCastSystem; impl<'a> System<'a> for RayCastSystem { type SystemData = (ReadExpect<'a, DynamicBoundingVolumeTree2>,); fn run(&mut self, (tree,): Self::SystemData) { println!("{:?}", *tree); let ray = Ray2::new(Point2::new(-4., 10.), Vector2::new(0., -1.)); if let Some((v, p)) = query_ray_closest(&*tree, ray) { println!("hit bounding volume of {:?} at point {:?}", v.value, p); } } } pub fn main() { let mut world = World::new(); let mut sort = SpatialSortingSystem2::, ()>::new(); let mut collide = SpatialCollisionSystem2::, ()>::new().with_narrow_phase(GJK2::new()); let mut raycast = RayCastSystem; let mut impulse_solver = CurrentFrameUpdateSystem2::>::new(); let mut next_frame = NextFrameSetupSystem2::>::new(); let mut contact_resolution = ContactResolutionSystem2::>::new(); sort.setup(&mut world.res); collide.setup(&mut world.res); raycast.setup(&mut world.res); impulse_solver.setup(&mut world.res); next_frame.setup(&mut world.res); contact_resolution.setup(&mut world.res); world .create_entity() .with_static_physical_entity( CollisionShape2::, ()>::new_simple( CollisionStrategy::FullResolution, CollisionMode::Discrete, Rectangle::new(10., 10.).into(), ), BodyPose2::::one(), PhysicalEntity::default(), Mass2::new(1.), ).build(); world .create_entity() .with_static_physical_entity( CollisionShape2::, ()>::new_simple( CollisionStrategy::FullResolution, CollisionMode::Discrete, Rectangle::new(10., 10.).into(), ), BodyPose2::::new(Point2::new(2., 2.), Rotation2::from_angle(Rad(0.))), PhysicalEntity::default(), Mass2::new(1.), ).build(); let mut reader_1 = world .write_resource::>>() .register_reader(); { use specs::prelude::RunNow; sort.run_now(&world.res); collide.run_now(&world.res); println!( "Contacts: {:?}", world .read_resource::>>() .read(&mut reader_1) .collect::>() ); raycast.run_now(&world.res); impulse_solver.run_now(&world.res); next_frame.run_now(&world.res); contact_resolution.run_now(&world.res); } }