2025-06-27 23:23:49 -04:00
|
|
|
use crate::chunk::{CellType, Chunk, ChunkPos};
|
2025-06-27 14:11:41 -04:00
|
|
|
use crate::{CHUNK_SIZE, State};
|
|
|
|
#[derive(Default, Debug)]
|
2025-06-27 10:26:09 -04:00
|
|
|
pub struct Pos {
|
|
|
|
x: f64,
|
|
|
|
y: f64,
|
|
|
|
}
|
|
|
|
impl Pos {
|
|
|
|
pub fn new(x: f64, y: f64) -> Self {
|
|
|
|
Self { x, y }
|
|
|
|
}
|
2025-06-27 14:11:41 -04:00
|
|
|
pub fn to_chunk(&self) -> ChunkPos {
|
|
|
|
ChunkPos::new(self.x as i32, self.y as i32)
|
|
|
|
}
|
|
|
|
pub fn to_chunk_inner(&self) -> usize {
|
2025-06-28 15:20:06 -04:00
|
|
|
self.x.rem_euclid(CHUNK_SIZE as f64) as usize * CHUNK_SIZE
|
|
|
|
+ self.y.rem_euclid(CHUNK_SIZE as f64) as usize
|
2025-06-27 14:11:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
impl State {
|
2025-06-27 23:23:49 -04:00
|
|
|
pub fn update(&mut self) -> eyre::Result<()> {
|
|
|
|
if self.blobs.is_empty() {
|
2025-06-29 13:09:01 -04:00
|
|
|
self.blobs.push(Blob::new(0.0, -64.0))
|
2025-06-27 23:23:49 -04:00
|
|
|
}
|
2025-06-27 14:11:41 -04:00
|
|
|
if let Some(pws) = self.particle_world_state.as_mut() {
|
2025-06-27 23:23:49 -04:00
|
|
|
'upper: for blob in self.blobs.iter_mut() {
|
2025-06-27 14:11:41 -04:00
|
|
|
let c = blob.pos.to_chunk();
|
2025-06-27 23:23:49 -04:00
|
|
|
let mut k = 0;
|
|
|
|
for x in -1..=1 {
|
|
|
|
for y in -1..=1 {
|
|
|
|
if unsafe { !pws.encode_area(c.x + x, c.y + y, &mut self.world[k]) } {
|
|
|
|
continue 'upper;
|
|
|
|
}
|
|
|
|
k += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
blob.update(&mut self.world);
|
|
|
|
let mut k = 0;
|
|
|
|
for x in -1..=1 {
|
|
|
|
for y in -1..=1 {
|
|
|
|
if unsafe { !pws.decode_area(c.x + x, c.y + y, &self.world[k]) } {
|
|
|
|
continue 'upper;
|
2025-06-27 14:11:41 -04:00
|
|
|
}
|
2025-06-27 23:23:49 -04:00
|
|
|
k += 1;
|
2025-06-27 14:11:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-06-27 23:23:49 -04:00
|
|
|
Ok(())
|
2025-06-27 14:11:41 -04:00
|
|
|
}
|
2025-06-27 10:26:09 -04:00
|
|
|
}
|
2025-06-28 15:20:06 -04:00
|
|
|
const SIZE: usize = 8;
|
2025-06-27 10:26:09 -04:00
|
|
|
pub struct Blob {
|
|
|
|
pub pos: Pos,
|
2025-06-27 14:11:41 -04:00
|
|
|
pixels: [Pos; SIZE * SIZE],
|
2025-06-27 10:26:09 -04:00
|
|
|
}
|
|
|
|
impl Blob {
|
2025-06-27 23:23:49 -04:00
|
|
|
pub fn update(&mut self, map: &mut [Chunk; 9]) {
|
2025-06-27 14:11:41 -04:00
|
|
|
let mut last = ChunkPos::new(i32::MAX, i32::MAX);
|
2025-06-27 23:23:49 -04:00
|
|
|
let mut k = 0;
|
|
|
|
let start = self.pos.to_chunk();
|
2025-06-27 14:11:41 -04:00
|
|
|
for p in &self.pixels {
|
|
|
|
let c = p.to_chunk();
|
|
|
|
if c != last {
|
2025-06-27 23:23:49 -04:00
|
|
|
k = ((c.x - start.x + 1) * 3 + c.y - start.y + 1) as usize;
|
2025-06-27 14:11:41 -04:00
|
|
|
last = c;
|
|
|
|
}
|
2025-06-27 23:23:49 -04:00
|
|
|
let n = p.to_chunk_inner();
|
2025-06-28 15:20:06 -04:00
|
|
|
|
|
|
|
map[k][n] = if matches!(map[k][n], CellType::Remove) {
|
|
|
|
CellType::Ignore
|
|
|
|
} else {
|
|
|
|
CellType::Blob
|
|
|
|
}
|
2025-06-27 14:11:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
pub fn new(x: f64, y: f64) -> Self {
|
|
|
|
Blob {
|
|
|
|
pos: Pos::new(x, y),
|
|
|
|
pixels: std::array::from_fn(|i| {
|
2025-06-28 15:20:06 -04:00
|
|
|
let a = (i / SIZE) as f64 - SIZE as f64 / 2.0 + 0.5;
|
|
|
|
let b = (i % SIZE) as f64 - SIZE as f64 / 2.0 + 0.5;
|
2025-06-27 14:11:41 -04:00
|
|
|
Pos::new(x + a, y + b)
|
|
|
|
}),
|
|
|
|
}
|
2025-06-27 10:26:09 -04:00
|
|
|
}
|
|
|
|
}
|