physics.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. use crate::com::{Blocking, Collision, Velocity, Position};
  2. use crate::types::{NPhase,BPhase};
  3. use crate::game::MyGame;
  4. use nalgebra::{Isometry2, Vector2};
  5. use ncollide2d::broad_phase::{
  6. ProxyHandle,
  7. broad_phase::BroadPhase,
  8. BroadPhaseInterferenceHandler,
  9. };
  10. use specs::{Join,RunNow};
  11. struct InterferenceHandler<'a> {
  12. collisions: specs::WriteStorage<'a, Collision>,
  13. }
  14. impl<'a> BroadPhaseInterferenceHandler<specs::Entity> for InterferenceHandler<'a> {
  15. fn is_interference_allowed(&mut self, a: &specs::Entity, b: &specs::Entity) -> bool {
  16. // Prevent self-collision.
  17. *a != *b
  18. }
  19. fn interference_started(&mut self, a: &specs::Entity, b: &specs::Entity) {
  20. self.collisions.get_mut(*a).map (|r| r.has_collision = true );
  21. self.collisions.get_mut(*b).map (|r| r.has_collision = true );
  22. }
  23. fn interference_stopped(&mut self, _: &specs::Entity, _: &specs::Entity) {
  24. }
  25. }
  26. struct Collide;
  27. impl<'a> specs::System<'a> for Collide {
  28. type SystemData = (
  29. specs::Entities<'a>,
  30. specs::ReadStorage<'a, Position>,
  31. specs::ReadStorage<'a, Velocity>,
  32. specs::ReadStorage<'a, Blocking>,
  33. specs::WriteStorage<'a, Collision>,
  34. specs::WriteExpect<'a, BPhase>,
  35. specs::WriteExpect<'a, NPhase>,
  36. );
  37. fn run(&mut self, (entities, position, velocity, blocking, mut collisions, mut bf, _narrow): Self::SystemData) {
  38. let _: Vec<()> = (&mut collisions).join().map( |c| c.has_collision = false ).collect();
  39. let handles: Vec<ProxyHandle> =
  40. (&entities, &position, &blocking).join().map( |(e, pos, bl)| {
  41. let np = if let Some(vel) = velocity.get(e) {
  42. pos.moved(vel)
  43. } else {
  44. pos.clone()
  45. };
  46. bf.create_proxy(
  47. { let v = bl.volume.aabb(&Isometry2::new(Vector2::new(np.x, np.y), nalgebra::zero()));
  48. println!("{:?}", v);
  49. v
  50. },
  51. e,
  52. )
  53. }).collect();
  54. bf.update(&mut InterferenceHandler {
  55. collisions: collisions,
  56. });
  57. bf.remove(&handles, &mut |_, _| {});
  58. }
  59. }
  60. struct Intersection;
  61. impl<'a> specs::System<'a> for Intersection {
  62. type SystemData = (
  63. specs::Entities<'a>,
  64. specs::ReadStorage<'a, Position>,
  65. specs::ReadStorage<'a, Velocity>,
  66. specs::ReadStorage<'a, Blocking>,
  67. specs::WriteStorage<'a, Collision>,
  68. );
  69. fn run(&mut self, (entity, position, velocity, blocking, mut collision): Self::SystemData) {
  70. let mut spacemap = std::collections::HashMap::new();
  71. for (e, pos, _) in (&entity, &position, &blocking).join() {
  72. spacemap.insert(pos.to_grid(), e);
  73. }
  74. for (pos, vel, col) in (&position, &velocity, &mut collision).join() {
  75. if let Some(_) = spacemap.get(&pos.moved(vel).to_grid()) {
  76. col.has_collision = true;
  77. }
  78. }
  79. }
  80. }
  81. struct Physics;
  82. impl <'a> specs::System<'a> for Physics {
  83. type SystemData = (
  84. specs::ReadStorage<'a, Velocity>,
  85. specs::ReadStorage<'a, Collision>,
  86. specs::WriteStorage<'a, Position>,
  87. );
  88. fn run(&mut self, (velocity, collision, mut position): Self::SystemData) {
  89. for (vel, col, pos) in (&velocity, &collision, &mut position).join() {
  90. if !col.has_collision {
  91. pos.x += vel.dx;
  92. pos.y += vel.dy;
  93. }
  94. }
  95. }
  96. }
  97. struct ResetCollision;
  98. impl<'a> specs::System<'a> for ResetCollision {
  99. type SystemData =
  100. specs::WriteStorage<'a, Collision>;
  101. fn run(&mut self, mut collision: Self::SystemData) {
  102. for mut e in (&mut collision).join() {
  103. e.has_collision = false;
  104. }
  105. }
  106. }
  107. pub fn systems(game: &mut MyGame) {
  108. Collide.run_now(&game.world.res);
  109. // Intersection.run_now(&game.world.res);
  110. Physics.run_now(&game.world.res);
  111. ResetCollision.run_now(&game.world.res);
  112. }