From 3c85a6ac41397cf95199933c6a93909bc070a844 Mon Sep 17 00:00:00 2001 From: Sébastien Crozet Date: Tue, 8 Sep 2020 21:18:17 +0200 Subject: Start implementing ray-casting. This adds a QueryPipeline structure responsible for scene queries. Currently this structure is able to perform a brute-force ray-cast. This commit also includes the beginning of implementation of a SIMD-based acceleration structure which will be used for these scene queries in the future. --- src_testbed/testbed.rs | 77 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 28 deletions(-) (limited to 'src_testbed/testbed.rs') diff --git a/src_testbed/testbed.rs b/src_testbed/testbed.rs index 92aea5a..ba28a4b 100644 --- a/src_testbed/testbed.rs +++ b/src_testbed/testbed.rs @@ -21,9 +21,9 @@ use na::{self, Point2, Point3, Vector3}; use rapier::dynamics::{ ActivationStatus, IntegrationParameters, JointSet, RigidBodyHandle, RigidBodySet, }; -use rapier::geometry::{BroadPhase, ColliderSet, ContactEvent, NarrowPhase, ProximityEvent}; +use rapier::geometry::{BroadPhase, ColliderSet, ContactEvent, NarrowPhase, ProximityEvent, Ray}; use rapier::math::Vector; -use rapier::pipeline::{ChannelEventCollector, PhysicsPipeline}; +use rapier::pipeline::{ChannelEventCollector, PhysicsPipeline, QueryPipeline}; #[cfg(feature = "fluids")] use salva::{coupling::ColliderCouplingSet, object::FluidHandle, LiquidWorld}; @@ -179,6 +179,7 @@ pub struct PhysicsState { pub colliders: ColliderSet, pub joints: JointSet, pub pipeline: PhysicsPipeline, + pub query_pipeline: QueryPipeline, } impl PhysicsState { @@ -190,6 +191,7 @@ impl PhysicsState { colliders: ColliderSet::new(), joints: JointSet::new(), pipeline: PhysicsPipeline::new(), + query_pipeline: QueryPipeline::new(), } } } @@ -197,6 +199,7 @@ impl PhysicsState { pub struct TestbedState { pub running: RunMode, pub draw_colls: bool, + pub highlighted_body: Option, // pub grabbed_object: Option, // pub grabbed_object_constraint: Option, pub grabbed_object_plane: (Point3, Vector3), @@ -240,7 +243,7 @@ pub struct Testbed { hide_counters: bool, // persistant_contacts: HashMap, font: Rc, - // cursor_pos: Point2, + cursor_pos: Point2, events: PhysicsEvents, event_handler: ChannelEventCollector, ui: Option, @@ -301,6 +304,7 @@ impl Testbed { let state = TestbedState { running: RunMode::Running, draw_colls: false, + highlighted_body: None, // grabbed_object: None, // grabbed_object_constraint: None, grabbed_object_plane: (Point3::origin(), na::zero()), @@ -349,7 +353,7 @@ impl Testbed { hide_counters: true, // persistant_contacts: HashMap::new(), font: Font::default(), - // cursor_pos: Point2::new(0.0f32, 0.0), + cursor_pos: Point2::new(0.0f32, 0.0), ui, event_handler, events, @@ -408,6 +412,9 @@ impl Testbed { .set(TestbedActionFlags::RESET_WORLD_GRAPHICS, true); self.time = 0.0; self.state.timestep_id = 0; + self.state.highlighted_body = None; + self.physics.query_pipeline = QueryPipeline::new(); + self.physics.pipeline = PhysicsPipeline::new(); self.physics.pipeline.counters.enable(); #[cfg(all(feature = "dim2", feature = "other-backends"))] @@ -832,6 +839,10 @@ impl Testbed { ); } } + WindowEvent::CursorPos(x, y, _) => { + self.cursor_pos.x = x as f32; + self.cursor_pos.y = y as f32; + } _ => {} } @@ -1146,36 +1157,45 @@ impl Testbed { self.state.grabbed_object = None; self.state.grabbed_object_constraint = None; } - WindowEvent::CursorPos(x, y, modifiers) => { - self.cursor_pos.x = x as f32; - self.cursor_pos.y = y as f32; + _ => {} + } + */ + } - // update the joint - if let Some(joint) = self.state.grabbed_object_constraint { - let size = window.size(); - let (pos, dir) = self - .graphics - .camera() - .unproject(&self.cursor_pos, &na::convert(size)); - let (ref ppos, ref pdir) = self.state.grabbed_object_plane; + #[cfg(feature = "dim2")] + fn highlight_hovered_body(&mut self, window: &Window) { + // Do nothing for now. + } - if let Some(inter) = query::ray_toi_with_plane(ppos, pdir, &Ray::new(pos, dir)) - { - let joint = self - .constraints - .get_mut(joint) - .unwrap() - .downcast_mut::>() - .unwrap(); - joint.set_anchor_1(pos + dir * inter) - } + #[cfg(feature = "dim3")] + fn highlight_hovered_body(&mut self, window: &Window) { + if let Some(highlighted_body) = self.state.highlighted_body { + if let Some(nodes) = self.graphics.body_nodes_mut(highlighted_body) { + for node in nodes { + node.unselect() } + } + } - event.inhibited = modifiers.contains(Modifiers::Shift); + let size = window.size(); + let (pos, dir) = self + .graphics + .camera() + .unproject(&self.cursor_pos, &na::convert(size)); + let ray = Ray::new(pos, dir); + let hit = self + .physics + .query_pipeline + .cast_ray(&self.physics.colliders, &ray, f32::MAX); + + if let Some((_, collider, _)) = hit { + if self.physics.bodies[collider.parent()].is_dynamic() { + self.state.highlighted_body = Some(collider.parent()); + for node in self.graphics.body_nodes_mut(collider.parent()).unwrap() { + node.select() + } } - _ => {} } - */ } } @@ -1550,6 +1570,7 @@ impl State for Testbed { } } + self.highlight_hovered_body(window); self.graphics.draw(&self.physics.colliders, window); #[cfg(feature = "fluids")] -- cgit From 7b8e322446ffa36e3f47078e23eb61ef423175dc Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Mon, 21 Sep 2020 10:43:20 +0200 Subject: Make kinematic bodies properly wake up dynamic bodies. --- src_testbed/testbed.rs | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'src_testbed/testbed.rs') diff --git a/src_testbed/testbed.rs b/src_testbed/testbed.rs index ba28a4b..6c03ef4 100644 --- a/src_testbed/testbed.rs +++ b/src_testbed/testbed.rs @@ -824,7 +824,7 @@ impl Testbed { .physics .bodies .iter() - .filter(|e| e.1.is_dynamic()) + .filter(|e| !e.1.is_static()) .map(|e| e.0) .collect(); let num_to_delete = (dynamic_bodies.len() / 10).max(1); @@ -1367,7 +1367,7 @@ impl State for Testbed { } } else { for (_, mut body) in self.physics.bodies.iter_mut() { - body.wake_up(); + body.wake_up(true); body.activation.threshold = -1.0; } } @@ -1571,7 +1571,8 @@ impl State for Testbed { } self.highlight_hovered_body(window); - self.graphics.draw(&self.physics.colliders, window); + self.graphics + .draw(&self.physics.bodies, &self.physics.colliders, window); #[cfg(feature = "fluids")] { @@ -1648,26 +1649,35 @@ Fluids: {:.2}ms } if self.state.flags.contains(TestbedStateFlags::DEBUG) { - let hash_bf = md5::compute(&bincode::serialize(&self.physics.broad_phase).unwrap()); - let hash_nf = md5::compute(&bincode::serialize(&self.physics.narrow_phase).unwrap()); - let hash_bodies = md5::compute(&bincode::serialize(&self.physics.bodies).unwrap()); - let hash_colliders = - md5::compute(&bincode::serialize(&self.physics.colliders).unwrap()); - let hash_joints = md5::compute(&bincode::serialize(&self.physics.joints).unwrap()); + let bf = bincode::serialize(&self.physics.broad_phase).unwrap(); + let nf = bincode::serialize(&self.physics.narrow_phase).unwrap(); + let bs = bincode::serialize(&self.physics.bodies).unwrap(); + let cs = bincode::serialize(&self.physics.colliders).unwrap(); + let js = bincode::serialize(&self.physics.joints).unwrap(); + let hash_bf = md5::compute(&bf); + let hash_nf = md5::compute(&nf); + let hash_bodies = md5::compute(&bs); + let hash_colliders = md5::compute(&cs); + let hash_joints = md5::compute(&js); profile = format!( r#"{} Hashes at frame: {} -|_ Broad phase: {:?} -|_ Narrow phase: {:?} -|_ Bodies: {:?} -|_ Colliders: {:?} -|_ Joints: {:?}"#, +|_ Broad phase [{:.1}KB]: {:?} +|_ Narrow phase [{:.1}KB]: {:?} +|_ Bodies [{:.1}KB]: {:?} +|_ Colliders [{:.1}KB]: {:?} +|_ Joints [{:.1}KB]: {:?}"#, profile, self.state.timestep_id, + bf.len() as f32 / 1000.0, hash_bf, + nf.len() as f32 / 1000.0, hash_nf, + bs.len() as f32 / 1000.0, hash_bodies, + cs.len() as f32 / 1000.0, hash_colliders, + js.len() as f32 / 1000.0, hash_joints ); } -- cgit From a7d77a01447d2b77694b2a957d000790af60b383 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Tue, 22 Sep 2020 15:29:29 +0200 Subject: Add non-topological WQuadtree update. --- src_testbed/testbed.rs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src_testbed/testbed.rs') diff --git a/src_testbed/testbed.rs b/src_testbed/testbed.rs index 6c03ef4..9f63438 100644 --- a/src_testbed/testbed.rs +++ b/src_testbed/testbed.rs @@ -675,6 +675,10 @@ impl Testbed { &self.event_handler, ); + self.physics + .query_pipeline + .update(&self.physics.bodies, &self.physics.colliders); + #[cfg(feature = "fluids")] { fluids_time = instant::now(); @@ -1466,6 +1470,10 @@ impl State for Testbed { &self.event_handler, ); + self.physics + .query_pipeline + .update(&self.physics.bodies, &self.physics.colliders); + #[cfg(feature = "fluids")] { fluids_time = instant::now(); -- cgit From 93aa7b6e1e8cbfd73542ed10ad5c26ae0a8b9848 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Mon, 5 Oct 2020 19:04:18 +0200 Subject: Use the publish-subscribe mechanism to handle collider removals across pipelines. --- src_testbed/testbed.rs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'src_testbed/testbed.rs') diff --git a/src_testbed/testbed.rs b/src_testbed/testbed.rs index 9f63438..869fa41 100644 --- a/src_testbed/testbed.rs +++ b/src_testbed/testbed.rs @@ -813,13 +813,9 @@ impl Testbed { let num_to_delete = (colliders.len() / 10).max(1); for to_delete in &colliders[..num_to_delete] { - self.physics.pipeline.remove_collider( - to_delete[0], - &mut self.physics.broad_phase, - &mut self.physics.narrow_phase, - &mut self.physics.bodies, - &mut self.physics.colliders, - ); + self.physics + .colliders + .remove(to_delete[0], &mut self.physics.bodies); } } WindowEvent::Key(Key::D, Action::Release, _) => { @@ -833,11 +829,8 @@ impl Testbed { .collect(); let num_to_delete = (dynamic_bodies.len() / 10).max(1); for to_delete in &dynamic_bodies[..num_to_delete] { - self.physics.pipeline.remove_rigid_body( + self.physics.bodies.remove( *to_delete, - &mut self.physics.broad_phase, - &mut self.physics.narrow_phase, - &mut self.physics.bodies, &mut self.physics.colliders, &mut self.physics.joints, ); -- cgit From 5d95368bce1d18f0dbec295f8ee787c1b54be0ce Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Mon, 5 Oct 2020 19:13:09 +0200 Subject: Testbed: fix snapshot restoration. --- src_testbed/testbed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src_testbed/testbed.rs') diff --git a/src_testbed/testbed.rs b/src_testbed/testbed.rs index 869fa41..c145af5 100644 --- a/src_testbed/testbed.rs +++ b/src_testbed/testbed.rs @@ -1304,9 +1304,9 @@ impl State for Testbed { if let Ok(w) = snapshot.restore() { self.clear(window); self.graphics.clear(window); + self.set_world(w.3, w.4, w.5); self.physics.broad_phase = w.1; self.physics.narrow_phase = w.2; - self.set_world(w.3, w.4, w.5); self.state.timestep_id = w.0; } } -- cgit From e87b73a2a20fee1ed333d564ba46dbf1c3ca75e2 Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Tue, 6 Oct 2020 15:49:22 +0200 Subject: Fix compilation in 2D. --- src_testbed/testbed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src_testbed/testbed.rs') diff --git a/src_testbed/testbed.rs b/src_testbed/testbed.rs index c145af5..3d7fd7d 100644 --- a/src_testbed/testbed.rs +++ b/src_testbed/testbed.rs @@ -1160,7 +1160,7 @@ impl Testbed { } #[cfg(feature = "dim2")] - fn highlight_hovered_body(&mut self, window: &Window) { + fn highlight_hovered_body(&mut self, _window: &Window) { // Do nothing for now. } -- cgit