diff options
Diffstat (limited to 'src/sim/entity/mod.rs')
| -rw-r--r-- | src/sim/entity/mod.rs | 155 |
1 files changed, 133 insertions, 22 deletions
diff --git a/src/sim/entity/mod.rs b/src/sim/entity/mod.rs index ab10ea8..b648f1d 100644 --- a/src/sim/entity/mod.rs +++ b/src/sim/entity/mod.rs @@ -1,28 +1,139 @@ -// use glam::{IVec2, Vec2}; -// use rapier2d::{dynamics::RigidBodyHandle, geometry::ColliderHandle}; +use glam::{IVec2, Vec2}; +use rapier2d::{ + dynamics::{RigidBody, RigidBodyBuilder, RigidBodyHandle}, + geometry::{Collider, ColliderHandle}, +}; -// use crate::sim::cell::cell::Cell; +use crate::{ + config::CELLS_TO_METRES, + sim::{ + cell::{cell::Cell, materials::MaterialId}, + lib::marching_squares::Marchable, + rb_manager::RbManager, + sim_manager::SimManager, + }, +}; -// pub struct EntityCells { -// pub size: IVec2, -// pub cells: Vec<Cell>, -// } -// pub trait EntityBehaviour { -// fn update (&mut self) -> (); -// } +pub mod entities; -// pub struct Entity { -// pub rb_h: Option<RigidBodyHandle>, -// pub collider_h: Option<ColliderHandle>, -// pub cells: EntityCells, -// pub behaviour: -// } +pub struct EntityCells { + pub size: IVec2, + pub cells: Vec<Cell>, +} -// impl Entity { -// pub fn position(&self, rbsm:) -> Vec2 { +impl EntityCells { + #[inline] + pub fn get_cell_at_local_position(&self, pos: IVec2) -> Cell { + self.cells[pos.x as usize + pos.y as usize * self.size.x as usize] + } + #[inline] + pub fn set_cell_at_local_position(&mut self, pos: IVec2, cell: Cell) { + self.cells[pos.x as usize + pos.y as usize * self.size.x as usize] = cell; + } +} -// } -// pub fn destroy(&mut self) -> { +impl Marchable for EntityCells { + fn occupied(&self, pos: IVec2) -> bool { + if pos.x < 0 || pos.x >= self.size.x || pos.y < 0 || pos.y >= self.size.y { + false + } else { + self.get_cell_at_local_position(pos).material != MaterialId::Void + } + } + fn size(&self) -> IVec2 { + self.size + } +} -// } -// } +pub trait EntityBehaviour { + fn update(&mut self, sim: &mut SimManager, delta_time: f32) -> (); + fn physics_update(&mut self, sim: &mut SimManager, delta_time: f32) -> (); +} + +pub struct EntityDef { + pub position: Vec2, + pub rb: Option<RigidBody>, + pub collider: Option<Collider>, + pub cells: Option<EntityCells>, + pub behaviour: Option<Box<dyn EntityBehaviour>>, +} + +impl EntityDef { + pub fn from_cells( + position: Vec2, + cells: EntityCells, + behaviour: Option<Box<dyn EntityBehaviour>>, + ) -> Self { + let rb = RigidBodyBuilder::dynamic() + .translation(position / CELLS_TO_METRES) + .build(); + + let collider = RbManager::convex_hull_collider_from_marchable(&cells, None).build(); + + EntityDef { + position, + rb: Some(rb), + collider: Some(collider), + cells: Some(cells), + behaviour, + } + } +} + +pub struct Entity { + pub id: u32, + pub rb_h: Option<RigidBodyHandle>, + pub collider_h: Option<ColliderHandle>, + pub cells: Option<EntityCells>, + behaviour: Option<Box<dyn EntityBehaviour>>, +} + +impl Entity { + pub fn transform(&self, sim: &SimManager) -> Option<(Vec2, (f32, f32))> { + self.rb_h + .map(|rb_h| { + sim.rb_manager + .physics_manager + .rigid_body_set + .get(rb_h) + .map(|rb| { + ( + rb.translation() * CELLS_TO_METRES, + (rb.rotation().cos(), rb.rotation().sin()), + ) + }) + }) + .flatten() + } + + // TODO use drop? + pub fn destroy(&mut self, sim: &mut SimManager) -> () {} + + pub fn update(&mut self, sim: &mut SimManager, delta_time: f32) -> () { + if let Some(behaviour) = &mut self.behaviour { + behaviour.update(sim, delta_time); + } + } + + pub fn physics_update(&mut self, sim: &mut SimManager, delta_time: f32) -> () { + if let Some(behaviour) = &mut self.behaviour { + behaviour.physics_update(sim, delta_time); + } + } + + pub fn new( + id: u32, + rb_h: Option<RigidBodyHandle>, + collider_h: Option<ColliderHandle>, + cells: Option<EntityCells>, + behaviour: Option<Box<dyn EntityBehaviour>>, + ) -> Self { + Entity { + id, + rb_h, + collider_h, + cells, + behaviour, + } + } +} |
