From bdad89910dcf3a56790dba60ed1f0db679432323 Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Sat, 22 Aug 2026 16:49:56 -0700 Subject: refactor entities --- src/sim/entity/mod.rs | 167 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 139 insertions(+), 28 deletions(-) (limited to 'src/sim/entity/mod.rs') 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 crate::sim::cell::cell::Cell; - -// pub struct EntityCells { -// pub size: IVec2, -// pub cells: Vec, -// } -// pub trait EntityBehaviour { -// fn update (&mut self) -> (); -// } - -// pub struct Entity { -// pub rb_h: Option, -// pub collider_h: Option, -// pub cells: EntityCells, -// pub behaviour: -// } - -// impl Entity { -// pub fn position(&self, rbsm:) -> Vec2 { - -// } -// pub fn destroy(&mut self) -> { - -// } -// } +use glam::{IVec2, Vec2}; +use rapier2d::{ + dynamics::{RigidBody, RigidBodyBuilder, RigidBodyHandle}, + geometry::{Collider, ColliderHandle}, +}; + +use crate::{ + config::CELLS_TO_METRES, + sim::{ + cell::{cell::Cell, materials::MaterialId}, + lib::marching_squares::Marchable, + rb_manager::RbManager, + sim_manager::SimManager, + }, +}; + +pub mod entities; + +pub struct EntityCells { + pub size: IVec2, + pub cells: Vec, +} + +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; + } +} + +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, + pub collider: Option, + pub cells: Option, + pub behaviour: Option>, +} + +impl EntityDef { + pub fn from_cells( + position: Vec2, + cells: EntityCells, + behaviour: Option>, + ) -> 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, + pub collider_h: Option, + pub cells: Option, + behaviour: Option>, +} + +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, + collider_h: Option, + cells: Option, + behaviour: Option>, + ) -> Self { + Entity { + id, + rb_h, + collider_h, + cells, + behaviour, + } + } +} -- cgit v1.3.1