rust/hwphysics/src/physics.rs
author Wuzzy <Wuzzy2@mail.ru>
Mon, 14 Jan 2019 00:34:56 +0100
changeset 14605 ab79cd4a7382
parent 14200 abbb74b9cb62
child 14737 8e74d4eb89f5
permissions -rw-r--r--
Reverse order of visual gears linked list Now vgears will render in the order they have been added. Older visual gears are rendered earlier, so they are "behind" newer visual gears. This has been primarily done to fix the render order of speech bubbles (bug #287).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14199
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     1
use crate::{
14200
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
     2
    common::{GearId, GearData, GearDataProcessor}
14199
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     3
};
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     4
use fpnum::*;
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     5
use integral_geometry::{
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     6
    Point, Size, GridIndex
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     7
};
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     8
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
     9
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    10
pub struct PhysicsData {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    11
    pub position: FPPoint,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    12
    pub velocity: FPPoint,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    13
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    14
14200
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    15
impl GearData for PhysicsData {}
14199
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    16
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    17
pub struct DynamicPhysicsCollection {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    18
    gear_ids: Vec<GearId>,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    19
    positions: Vec<FPPoint>,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    20
    velocities: Vec<FPPoint>,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    21
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    22
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    23
impl DynamicPhysicsCollection {
14200
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    24
    fn new() -> Self {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    25
        Self {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    26
            gear_ids: Vec::new(),
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    27
            positions: Vec::new(),
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    28
            velocities: Vec::new()
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    29
        }
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    30
    }
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    31
14199
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    32
    fn len(&self) -> usize {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    33
        self.gear_ids.len()
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    34
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    35
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    36
    fn push(&mut self, id: GearId, physics: PhysicsData) {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    37
        self.gear_ids.push(id);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    38
        self.positions.push(physics.position);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    39
        self.velocities.push(physics.velocity);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    40
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    41
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    42
    fn iter_pos_update(&mut self) -> impl Iterator<Item = (GearId, (&mut FPPoint, &FPPoint))> {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    43
        self.gear_ids.iter().cloned()
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    44
            .zip(self.positions.iter_mut()
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    45
                .zip(self.velocities.iter()))
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    46
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    47
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    48
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    49
pub struct StaticPhysicsCollection {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    50
    gear_ids: Vec<GearId>,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    51
    positions: Vec<FPPoint>
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    52
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    53
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    54
impl StaticPhysicsCollection {
14200
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    55
    fn new() -> Self {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    56
        Self {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    57
            gear_ids: Vec::new(),
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    58
            positions: Vec::new()
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    59
        }
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    60
    }
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    61
14199
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    62
    fn push(&mut self, gear_id: GearId, physics: PhysicsData) {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    63
        self.gear_ids.push(gear_id);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    64
        self.positions.push(physics.position);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    65
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    66
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    67
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    68
pub struct PhysicsProcessor {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    69
    dynamic_physics: DynamicPhysicsCollection,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    70
    static_physics: StaticPhysicsCollection,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    71
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    72
    physics_cleanup: Vec<GearId>,
14200
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    73
    position_updates: PositionUpdates
14199
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    74
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    75
14200
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    76
pub struct PositionUpdates {
14199
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    77
    pub gear_ids: Vec<GearId>,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    78
    pub positions: Vec<FPPoint>
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    79
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    80
14200
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    81
impl PositionUpdates {
14199
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    82
    pub fn new(capacity: usize) -> Self {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    83
        Self {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    84
            gear_ids: Vec::with_capacity(capacity),
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    85
            positions: Vec::with_capacity(capacity),
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    86
        }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    87
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    88
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    89
    pub fn push(&mut self, gear_id: GearId, position: &FPPoint) {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    90
        self.gear_ids.push(gear_id);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    91
        self.positions.push(*position);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    92
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    93
}
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    94
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
    95
impl PhysicsProcessor {
14200
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    96
    pub fn new() -> Self {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    97
        PhysicsProcessor {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    98
            dynamic_physics: DynamicPhysicsCollection::new(),
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
    99
            static_physics: StaticPhysicsCollection::new(),
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   100
            physics_cleanup: Vec::new(),
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   101
            position_updates: PositionUpdates::new(0)
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   102
        }
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   103
    }
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   104
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   105
    pub fn process(&mut self, time_step: FPNum) -> &PositionUpdates {
14199
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   106
        for (gear_id, (pos, vel)) in self.dynamic_physics.iter_pos_update() {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   107
            *pos += *vel * time_step;
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   108
            if !vel.is_zero() {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   109
                self.position_updates.push(gear_id, pos)
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   110
            } else {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   111
                self.physics_cleanup.push(gear_id)
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   112
            }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   113
        }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   114
        &self.position_updates
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   115
    }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   116
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   117
    pub fn push(&mut self, gear_id: GearId, physics_data: PhysicsData) {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   118
        if physics_data.velocity.is_zero() {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   119
            self.static_physics.push(gear_id, physics_data);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   120
        } else {
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   121
            self.dynamic_physics.push(gear_id, physics_data);
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   122
        }
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   123
    }
14200
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   124
}
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   125
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   126
impl GearDataProcessor<PhysicsData> for PhysicsProcessor {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   127
    fn add(&mut self, gear_id: GearId, gear_data: PhysicsData) {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   128
        if gear_data.velocity.is_zero() {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   129
            self.static_physics.push(gear_id, gear_data);
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   130
        } else {
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   131
            self.dynamic_physics.push(gear_id, gear_data);
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   132
        }
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14199
diff changeset
   133
    }
14199
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents:
diff changeset
   134
}