rust/hwphysics/src/lib.rs
author unc0rr
Tue, 13 Dec 2022 21:21:55 +0100
changeset 15899 73cdc306888f
parent 15829 d5e6c8c92d87
child 15935 cd3d16905e0e
permissions -rw-r--r--
Fix infinite loop in rendering of laser sight
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14716
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
     1
pub mod collision;
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
     2
pub mod common;
15305
0076bf602969 start gear data group implementation
alfadur
parents: 15281
diff changeset
     3
mod data;
14178
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents: 14144
diff changeset
     4
mod grid;
14716
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
     5
pub mod physics;
14144
165e43c3ed59 pull land into collision detector
alfadur
parents: 14059
diff changeset
     6
15828
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15780
diff changeset
     7
use integral_geometry::PotSize;
14144
165e43c3ed59 pull land into collision detector
alfadur
parents: 14059
diff changeset
     8
use land2d::Land2D;
15829
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
     9
use std::any::{Any, TypeId};
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    10
15829
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    11
use crate::collision::CollisionData;
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    12
use crate::physics::VelocityData;
14178
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents: 14144
diff changeset
    13
use crate::{
15381
52844baced17 add gravity
alfadur
parents: 15380
diff changeset
    14
    collision::CollisionProcessor,
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    15
    common::{GearAllocator, GearId, Millis},
15762
84c07aa94b61 start drawing gears
alfadur
parents: 15383
diff changeset
    16
    data::{DataIterator, GearDataManager, TypeIter},
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    17
    physics::PhysicsProcessor,
14178
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents: 14144
diff changeset
    18
};
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    19
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    20
pub struct World {
15274
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    21
    allocator: GearAllocator,
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    22
    data: GearDataManager,
14178
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents: 14144
diff changeset
    23
    physics: PhysicsProcessor,
a4c17cfaa4c9 split hwphysics into modules
alfadur
parents: 14144
diff changeset
    24
    collision: CollisionProcessor,
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    25
}
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    26
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    27
impl World {
15828
44b49f255e31 add type safe power of two sizes
alfadur
parents: 15780
diff changeset
    28
    pub fn new(world_size: PotSize) -> Self {
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    29
        let mut data = GearDataManager::new();
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    30
        PhysicsProcessor::register_components(&mut data);
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    31
        CollisionProcessor::register_components(&mut data);
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    32
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    33
        Self {
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    34
            data,
15274
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    35
            allocator: GearAllocator::new(),
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    36
            physics: PhysicsProcessor::new(),
14716
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
    37
            collision: CollisionProcessor::new(world_size),
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    38
        }
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    39
    }
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    40
15274
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    41
    #[inline]
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    42
    pub fn new_gear(&mut self) -> Option<GearId> {
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    43
        self.allocator.alloc()
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    44
    }
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    45
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    46
    #[inline]
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    47
    pub fn delete_gear(&mut self, gear_id: GearId) {
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    48
        self.data.remove_all(gear_id);
15274
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    49
        self.collision.remove(gear_id);
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    50
        self.allocator.free(gear_id)
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    51
    }
42b710b0f883 add gear allocator
alfadur
parents: 15270
diff changeset
    52
15275
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    53
    pub fn step(&mut self, time_step: Millis, land: &Land2D<u32>) {
15780
f4b563a9ac5e add const generics to physics step
alfadur
parents: 15775
diff changeset
    54
        let updates = self.physics.process(&mut self.data, time_step);
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    55
        let collisions = self.collision.process(land, &updates);
14144
165e43c3ed59 pull land into collision detector
alfadur
parents: 14059
diff changeset
    56
    }
165e43c3ed59 pull land into collision detector
alfadur
parents: 14059
diff changeset
    57
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    58
    pub fn add_gear_data<T: Clone + 'static>(&mut self, gear_id: GearId, data: &T) {
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    59
        self.data.add(gear_id, data);
15829
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    60
        if TypeId::of::<T>() == TypeId::of::<VelocityData>() {
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    61
            self.collision.remove(gear_id);
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    62
        }
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    63
    }
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    64
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    65
    pub fn remove_gear_data<T: Clone + 'static>(&mut self, gear_id: GearId) {
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    66
        self.data.remove::<T>(gear_id);
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    67
        if TypeId::of::<T>() == TypeId::of::<VelocityData>() {
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    68
            if let Some(collision_data) = self.data.get::<CollisionData>(gear_id) {
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    69
                self.collision.add(gear_id, *collision_data);
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    70
            }
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    71
        }
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    72
    }
15762
84c07aa94b61 start drawing gears
alfadur
parents: 15383
diff changeset
    73
84c07aa94b61 start drawing gears
alfadur
parents: 15383
diff changeset
    74
    #[inline]
84c07aa94b61 start drawing gears
alfadur
parents: 15383
diff changeset
    75
    pub fn iter_data<T: TypeIter + 'static>(&mut self) -> DataIterator<T> {
84c07aa94b61 start drawing gears
alfadur
parents: 15383
diff changeset
    76
        self.data.iter()
84c07aa94b61 start drawing gears
alfadur
parents: 15383
diff changeset
    77
    }
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    78
}
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    79
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    80
#[cfg(test)]
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    81
mod tests {
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    82
    use crate::{
14716
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
    83
        collision::{CircleBounds, CollisionData},
15353
35c331f9308e fix world test
alfadur
parents: 15305
diff changeset
    84
        common::Millis,
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    85
        physics::{PositionData, VelocityData},
14716
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
    86
        World,
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    87
    };
14716
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
    88
    use fpnum::{fp, FPNum, FPPoint};
15829
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    89
    use integral_geometry::{PotSize, Size};
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    90
    use land2d::Land2D;
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
    91
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    92
    #[test]
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    93
    fn data_flow() {
15829
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
    94
        let world_size = PotSize::new(2048, 2048).unwrap();
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    95
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
    96
        let mut world = World::new(world_size);
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    97
        let gear_id = world.new_gear().unwrap();
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    98
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
    99
        world.add_gear_data(gear_id, &PositionData(FPPoint::zero()));
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
   100
        world.add_gear_data(gear_id, &VelocityData(FPPoint::unit_y()));
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
   101
14716
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
   102
        world.add_gear_data(
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
   103
            gear_id,
15380
6e3e5be8b2e2 update hwphysics motion to use the new system
alfadur
parents: 15353
diff changeset
   104
            &CollisionData {
14716
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
   105
                bounds: CircleBounds {
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
   106
                    center: FPPoint::zero(),
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
   107
                    radius: fp!(10),
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
   108
                },
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
   109
            },
8e74d4eb89f5 add random falling stuff
alfadur
parents: 14179
diff changeset
   110
        );
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
   111
15829
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
   112
        let land = Land2D::new(
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
   113
            Size::new(world_size.width() - 2, world_size.height() - 2),
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
   114
            0,
d5e6c8c92d87 add direct access to gear data
alfadur
parents: 15828
diff changeset
   115
        );
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
   116
15353
35c331f9308e fix world test
alfadur
parents: 15305
diff changeset
   117
        world.step(Millis::new(1), &land);
14179
abbb74b9cb62 generalize adding data to World
alfadur
parents: 14178
diff changeset
   118
    }
14059
c6745a1c827a start a physics engine to try out this data oriented thing everyone seems to be talking about
alfadur
parents:
diff changeset
   119
}