add random falling stuff
authoralfadur
Sat, 23 Mar 2019 01:07:23 +0300
changeset 14716 8e74d4eb89f5
parent 14715 e519802076e9
child 14717 16024046d458
add random falling stuff
rust/hwphysics/src/collision.rs
rust/hwphysics/src/grid.rs
rust/hwphysics/src/lib.rs
rust/hwphysics/src/physics.rs
rust/hwrunner/src/main.rs
rust/lib-hedgewars-engine/src/world.rs
--- a/rust/hwphysics/src/collision.rs	Fri Mar 22 23:46:48 2019 +0300
+++ b/rust/hwphysics/src/collision.rs	Sat Mar 23 01:07:23 2019 +0300
@@ -1,17 +1,13 @@
-use std::{
-    ops::RangeInclusive
-};
+use std::ops::RangeInclusive;
 
 use crate::{
-    common::{GearId, GearData, GearDataProcessor},
+    common::{GearData, GearDataProcessor, GearId},
+    grid::Grid,
     physics::PhysicsData,
-    grid::Grid
 };
 
 use fpnum::*;
-use integral_geometry::{
-    Point, Size, GridIndex
-};
+use integral_geometry::{GridIndex, Point, Size};
 use land2d::Land2D;
 
 pub fn fppoint_round(point: &FPPoint) -> Point {
@@ -21,7 +17,7 @@
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 pub struct CircleBounds {
     pub center: FPPoint,
-    pub radius: FPNum
+    pub radius: FPNum,
 }
 
 impl CircleBounds {
@@ -39,7 +35,7 @@
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 pub struct CollisionData {
-    pub bounds: CircleBounds
+    pub bounds: CircleBounds,
 }
 
 impl GearData for CollisionData {}
@@ -47,21 +43,21 @@
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 pub struct ContactData {
     pub elasticity: FPNum,
-    pub friction: FPNum
+    pub friction: FPNum,
 }
 
 impl GearData for ContactData {}
 
 struct EnabledCollisionsCollection {
     gear_ids: Vec<GearId>,
-    collisions: Vec<CollisionData>
+    collisions: Vec<CollisionData>,
 }
 
 impl EnabledCollisionsCollection {
     fn new() -> Self {
         Self {
             gear_ids: Vec::new(),
-            collisions: Vec::new()
+            collisions: Vec::new(),
         }
     }
 
@@ -84,7 +80,7 @@
 
 pub struct DetectedCollisions {
     pub pairs: Vec<(GearId, GearId)>,
-    pub positions: Vec<Point>
+    pub positions: Vec<Point>,
 }
 
 impl DetectedCollisions {
@@ -106,7 +102,7 @@
         Self {
             grid: Grid::new(size),
             enabled_collisions: EnabledCollisionsCollection::new(),
-            detected_collisions: DetectedCollisions::new(0)
+            detected_collisions: DetectedCollisions::new(0),
         }
     }
 
@@ -114,8 +110,13 @@
         self.grid.check_collisions(&mut self.detected_collisions);
 
         for (gear_id, collision) in self.enabled_collisions.iter() {
-            if collision.bounds.rows().any(|(y, r)| (&land[y][r]).iter().any(|v| *v != 0)) {
-                self.detected_collisions.push(gear_id, 0, &collision.bounds.center)
+            if collision
+                .bounds
+                .rows()
+                .any(|(y, r)| (&land[y][r]).iter().any(|v| *v != 0))
+            {
+                self.detected_collisions
+                    .push(gear_id, 0, &collision.bounds.center)
             }
         }
     }
--- a/rust/hwphysics/src/grid.rs	Fri Mar 22 23:46:48 2019 +0300
+++ b/rust/hwphysics/src/grid.rs	Sat Mar 23 01:07:23 2019 +0300
@@ -1,23 +1,15 @@
 use crate::{
+    collision::{fppoint_round, CircleBounds, DetectedCollisions},
     common::GearId,
-    collision::{
-        fppoint_round,
-        CircleBounds,
-        DetectedCollisions
-    }
 };
 
-use integral_geometry::{
-    Point,
-    Size,
-    GridIndex
-};
 use fpnum::FPPoint;
+use integral_geometry::{GridIndex, Point, Size};
 
 struct GridBin {
     refs: Vec<GearId>,
     static_entries: Vec<CircleBounds>,
-    dynamic_entries: Vec<CircleBounds>
+    dynamic_entries: Vec<CircleBounds>,
 }
 
 impl GridBin {
@@ -25,7 +17,7 @@
         Self {
             refs: vec![],
             static_entries: vec![],
-            dynamic_entries: vec![]
+            dynamic_entries: vec![],
         }
     }
 }
@@ -36,21 +28,19 @@
     bins: Vec<GridBin>,
     space_size: Size,
     bins_count: Size,
-    index: GridIndex
+    index: GridIndex,
 }
 
 impl Grid {
     pub fn new(size: Size) -> Self {
         assert!(size.is_power_of_two());
-        let bins_count =
-            Size::new(size.width / GRID_BIN_SIZE,
-                      size.height / GRID_BIN_SIZE);
+        let bins_count = Size::new(size.width / GRID_BIN_SIZE, size.height / GRID_BIN_SIZE);
 
         Self {
             bins: (0..bins_count.area()).map(|_| GridBin::new()).collect(),
             space_size: size,
             bins_count,
-            index: Size::square(GRID_BIN_SIZE).to_grid_index()
+            index: Size::square(GRID_BIN_SIZE).to_grid_index(),
         }
     }
 
@@ -68,7 +58,9 @@
     }
 
     pub fn insert_dynamic(&mut self, gear_id: GearId, bounds: &CircleBounds) {
-        self.lookup_bin(&bounds.center).dynamic_entries.push(*bounds)
+        self.lookup_bin(&bounds.center)
+            .dynamic_entries
+            .push(*bounds)
     }
 
     pub fn check_collisions(&self, collisions: &mut DetectedCollisions) {
@@ -88,4 +80,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
--- a/rust/hwphysics/src/lib.rs	Fri Mar 22 23:46:48 2019 +0300
+++ b/rust/hwphysics/src/lib.rs	Sat Mar 23 01:07:23 2019 +0300
@@ -1,35 +1,23 @@
-mod common;
-mod physics;
+pub mod collision;
+pub mod common;
 mod grid;
-mod collision;
+pub mod physics;
 
 use fpnum::FPNum;
 use integral_geometry::Size;
 use land2d::Land2D;
 
 use crate::{
-    common::{
-        GearId,
-        GearData,
-        GearDataAggregator,
-        GearDataProcessor
-    },
-    physics::{
-        PhysicsProcessor,
-        PhysicsData
-    },
-    collision::{
-        CollisionProcessor,
-        CollisionData,
-        ContactData
-    }
+    collision::{CollisionData, CollisionProcessor, ContactData},
+    common::{GearData, GearDataAggregator, GearDataProcessor, GearId},
+    physics::{PhysicsData, PhysicsProcessor},
 };
 
 pub struct JoinedData {
     gear_id: GearId,
     physics: PhysicsData,
     collision: CollisionData,
-    contact: ContactData
+    contact: ContactData,
 }
 
 pub struct World {
@@ -44,7 +32,7 @@
                 &mut self.$field
             }
         }
-    }
+    };
 }
 
 processor_map!(PhysicsData => physics);
@@ -54,7 +42,7 @@
     pub fn new(world_size: Size) -> Self {
         Self {
             physics: PhysicsProcessor::new(),
-            collision: CollisionProcessor::new(world_size)
+            collision: CollisionProcessor::new(world_size),
         }
     }
 
@@ -64,8 +52,9 @@
     }
 
     pub fn add_gear_data<T>(&mut self, gear_id: GearId, data: T)
-        where T: GearData,
-              Self: GearDataAggregator<T>
+    where
+        T: GearData,
+        Self: GearDataAggregator<T>,
     {
         self.find_processor().add(gear_id, data);
     }
@@ -74,11 +63,11 @@
 #[cfg(test)]
 mod tests {
     use crate::{
-        World,
+        collision::{CircleBounds, CollisionData},
         physics::PhysicsData,
-        collision::{CollisionData, CircleBounds}
+        World,
     };
-    use fpnum::{FPNum, FPPoint, fp};
+    use fpnum::{fp, FPNum, FPPoint};
     use integral_geometry::Size;
     use land2d::Land2D;
 
@@ -89,17 +78,23 @@
         let mut world = World::new(world_size);
         let gear_id = 46631;
 
-        world.add_gear_data(gear_id, PhysicsData {
-            position: FPPoint::zero(),
-            velocity: FPPoint::unit_y()
-        });
+        world.add_gear_data(
+            gear_id,
+            PhysicsData {
+                position: FPPoint::zero(),
+                velocity: FPPoint::unit_y(),
+            },
+        );
 
-        world.add_gear_data(gear_id, CollisionData {
-            bounds: CircleBounds {
-                center: FPPoint::zero(),
-                radius: fp!(10)
-            }
-        });
+        world.add_gear_data(
+            gear_id,
+            CollisionData {
+                bounds: CircleBounds {
+                    center: FPPoint::zero(),
+                    radius: fp!(10),
+                },
+            },
+        );
 
         let land = Land2D::new(Size::new(world_size.width - 2, world_size.height - 2), 0);
 
--- a/rust/hwphysics/src/physics.rs	Fri Mar 22 23:46:48 2019 +0300
+++ b/rust/hwphysics/src/physics.rs	Sat Mar 23 01:07:23 2019 +0300
@@ -1,10 +1,6 @@
-use crate::{
-    common::{GearId, GearData, GearDataProcessor}
-};
+use crate::common::{GearData, GearDataProcessor, GearId};
 use fpnum::*;
-use integral_geometry::{
-    Point, Size, GridIndex
-};
+use integral_geometry::{GridIndex, Point, Size};
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 pub struct PhysicsData {
@@ -14,6 +10,12 @@
 
 impl GearData for PhysicsData {}
 
+impl PhysicsData {
+    pub fn new(position: FPPoint, velocity: FPPoint) -> Self {
+        Self { position, velocity }
+    }
+}
+
 pub struct DynamicPhysicsCollection {
     gear_ids: Vec<GearId>,
     positions: Vec<FPPoint>,
@@ -25,7 +27,7 @@
         Self {
             gear_ids: Vec::new(),
             positions: Vec::new(),
-            velocities: Vec::new()
+            velocities: Vec::new(),
         }
     }
 
@@ -40,22 +42,23 @@
     }
 
     fn iter_pos_update(&mut self) -> impl Iterator<Item = (GearId, (&mut FPPoint, &FPPoint))> {
-        self.gear_ids.iter().cloned()
-            .zip(self.positions.iter_mut()
-                .zip(self.velocities.iter()))
+        self.gear_ids
+            .iter()
+            .cloned()
+            .zip(self.positions.iter_mut().zip(self.velocities.iter()))
     }
 }
 
 pub struct StaticPhysicsCollection {
     gear_ids: Vec<GearId>,
-    positions: Vec<FPPoint>
+    positions: Vec<FPPoint>,
 }
 
 impl StaticPhysicsCollection {
     fn new() -> Self {
         Self {
             gear_ids: Vec::new(),
-            positions: Vec::new()
+            positions: Vec::new(),
         }
     }
 
@@ -70,12 +73,12 @@
     static_physics: StaticPhysicsCollection,
 
     physics_cleanup: Vec<GearId>,
-    position_updates: PositionUpdates
+    position_updates: PositionUpdates,
 }
 
 pub struct PositionUpdates {
     pub gear_ids: Vec<GearId>,
-    pub positions: Vec<FPPoint>
+    pub positions: Vec<FPPoint>,
 }
 
 impl PositionUpdates {
@@ -98,7 +101,7 @@
             dynamic_physics: DynamicPhysicsCollection::new(),
             static_physics: StaticPhysicsCollection::new(),
             physics_cleanup: Vec::new(),
-            position_updates: PositionUpdates::new(0)
+            position_updates: PositionUpdates::new(0),
         }
     }
 
@@ -131,4 +134,4 @@
             self.dynamic_physics.push(gear_id, gear_data);
         }
     }
-}
\ No newline at end of file
+}
--- a/rust/hwrunner/src/main.rs	Fri Mar 22 23:46:48 2019 +0300
+++ b/rust/hwrunner/src/main.rs	Sat Mar 23 01:07:23 2019 +0300
@@ -6,6 +6,7 @@
 use hedgewars_engine::instance::EngineInstance;
 
 use integral_geometry::Point;
+use std::time::Duration;
 
 fn init(event_loop: &EventsLoop, size: dpi::LogicalSize) -> WindowedContext {
     use glutin::{ContextBuilder, WindowBuilder};
@@ -48,6 +49,7 @@
     use std::time::Instant;
 
     let mut now = Instant::now();
+    let mut update = Instant::now();
 
     let mut is_running = true;
     while is_running {
@@ -57,6 +59,11 @@
         let ms = delta.as_secs() as f64 * 1000.0 + delta.subsec_millis() as f64;
         window.set_title(&format!("hwengine {:.3}ms", ms));
 
+        if update.elapsed() > Duration::from_millis(10) {
+            update = curr;
+            engine.world.step()
+        }
+
         event_loop.poll_events(|event| match event {
             Event::WindowEvent { event, .. } => match event {
                 WindowEvent::CloseRequested => {
--- a/rust/lib-hedgewars-engine/src/world.rs	Fri Mar 22 23:46:48 2019 +0300
+++ b/rust/lib-hedgewars-engine/src/world.rs	Sat Mar 23 01:07:23 2019 +0300
@@ -1,5 +1,5 @@
-use fpnum::{fp, FPNum};
-use hwphysics as hwp;
+use fpnum::{fp, FPNum, FPPoint};
+use hwphysics::{self as hwp, common::GearId};
 use integral_geometry::{Point, Rect, Size};
 use land2d::Land2D;
 use landgen::{
@@ -27,6 +27,7 @@
     game_state: Option<GameState>,
     renderer: Option<MapRenderer>,
     camera: Camera,
+    last_gear_id: GearId,
 }
 
 impl World {
@@ -37,6 +38,7 @@
             game_state: None,
             renderer: None,
             camera: Camera::new(),
+            last_gear_id: GearId::default(),
         }
     }
 
@@ -120,8 +122,36 @@
         }
     }
 
+    fn get_unused_gear_id(&mut self) -> GearId {
+        let id = self.last_gear_id;
+        self.last_gear_id += 1;
+        id
+    }
+
+    fn create_gear(&mut self, position: Point) {
+        let id = self.get_unused_gear_id();
+        if let Some(ref mut state) = self.game_state {
+            let fp_position = FPPoint::new(position.x.into(), position.y.into());
+            state.physics.add_gear_data(
+                id,
+                hwp::physics::PhysicsData::new(fp_position, FPPoint::zero()),
+            )
+        }
+    }
+
     pub fn step(&mut self) {
         if let Some(ref mut state) = self.game_state {
+            let next = self.random_numbers_gen.next().unwrap();
+            if next % 32 == 0 {
+                let position = Point::new(
+                    (self.random_numbers_gen.next().unwrap() % state.land.width() as u32) as i32,
+                    0,
+                );
+                self.create_gear(position);
+            }
+        }
+
+        if let Some(ref mut state) = self.game_state {
             state.physics.step(fp!(1), &state.land);
         }
     }