make seperate struct for buffer
This commit is contained in:
parent
d887b13579
commit
af0b9f9222
11
src/agent.rs
11
src/agent.rs
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
grid::Grid,
|
||||
util::wrap,
|
||||
buffer::Buf,
|
||||
};
|
||||
|
||||
use rand::{seq::SliceRandom, Rng};
|
||||
@ -41,8 +41,9 @@ impl Agent {
|
||||
}
|
||||
}
|
||||
|
||||
// Tick an agent
|
||||
#[inline]
|
||||
pub fn tick(&mut self, grid: &Grid, sensor_distance: f32, sensor_angle: f32, rotation_angle: f32, step_distance: f32, width: usize, height: usize) {
|
||||
pub fn tick(&mut self, buf: &Buf, sensor_distance: f32, sensor_angle: f32, rotation_angle: f32, step_distance: f32, width: usize, height: usize) {
|
||||
let xc = self.x + cos(self.angle) * sensor_distance;
|
||||
let yc = self.y + sin(self.angle) * sensor_distance;
|
||||
|
||||
@ -55,9 +56,9 @@ impl Agent {
|
||||
let yr = self.y + sin(agent_add_sens) * sensor_distance;
|
||||
|
||||
// We sense from the buffer because this is where we previously combined data from all the grid.
|
||||
let center = grid.get_buf(xc, yc);
|
||||
let left = grid.get_buf(xl, yl);
|
||||
let right = grid.get_buf(xr, yr);
|
||||
let center = buf.get_buf(xc, yc);
|
||||
let left = buf.get_buf(xl, yl);
|
||||
let right = buf.get_buf(xr, yr);
|
||||
|
||||
// Rotate and move logic
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
39
src/buffer.rs
Normal file
39
src/buffer.rs
Normal file
@ -0,0 +1,39 @@
|
||||
#[derive(Debug)]
|
||||
pub struct Buf {
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
pub buf: Vec<f32>,
|
||||
}
|
||||
|
||||
impl Clone for Buf {
|
||||
fn clone(&self) -> Buf {
|
||||
Buf {
|
||||
width: self.width,
|
||||
height: self.height,
|
||||
buf: self.buf.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Buf {
|
||||
pub fn new(width: usize, height: usize, buf: Vec<f32>) -> Self {
|
||||
Buf {
|
||||
width,
|
||||
height,
|
||||
buf,
|
||||
}
|
||||
}
|
||||
|
||||
// Truncate x and y and return a corresponding index into the data slice.
|
||||
fn index(&self, x: f32, y: f32) -> usize {
|
||||
// x/y can come in negative, hence we shift them by width/height.
|
||||
let i = (x + self.width as f32) as usize & (self.width - 1);
|
||||
let j = (y + self.height as f32) as usize & (self.height - 1);
|
||||
j * self.width + i
|
||||
}
|
||||
|
||||
// Get the buffer value at a given position. The implementation effectively treats data as periodic, hence any finite position will produce a value.
|
||||
pub fn get_buf(&self, x: f32, y: f32) -> f32 {
|
||||
self.buf[self.index(x, y)]
|
||||
}
|
||||
}
|
||||
18
src/grid.rs
18
src/grid.rs
@ -1,6 +1,7 @@
|
||||
use crate::{
|
||||
blur::Blur,
|
||||
agent::Agent,
|
||||
buffer::Buf,
|
||||
};
|
||||
|
||||
use rand::{distributions::Uniform, Rng};
|
||||
@ -89,7 +90,8 @@ pub struct Grid {
|
||||
pub data: Vec<f32>,
|
||||
|
||||
// Scratch space for the blur operation.
|
||||
pub buf: Vec<f32>,
|
||||
// pub buf: Vec<f32>,
|
||||
pub buf: Buf,
|
||||
pub blur: Blur,
|
||||
pub agents: Vec<Agent>
|
||||
}
|
||||
@ -122,7 +124,7 @@ impl Grid {
|
||||
height,
|
||||
data,
|
||||
config: PopulationConfig::new(rng),
|
||||
buf: vec![0.0; width * height],
|
||||
buf: Buf::new(width, height, vec![0.0; width * height]),
|
||||
blur: Blur::new(width),
|
||||
agents,
|
||||
}
|
||||
@ -136,10 +138,12 @@ impl Grid {
|
||||
j * self.width + i
|
||||
}
|
||||
|
||||
/*
|
||||
// Get the buffer value at a given position. The implementation effectively treats data as periodic, hence any finite position will produce a value.
|
||||
pub fn get_buf(&self, x: f32, y: f32) -> f32 {
|
||||
self.buf[self.index(x, y)]
|
||||
self.buf.buf[self.index(x, y)]
|
||||
}
|
||||
*/
|
||||
|
||||
// Add a value to the grid data at a given position.
|
||||
pub fn deposit(&mut self, x: f32, y: f32) {
|
||||
@ -151,7 +155,7 @@ impl Grid {
|
||||
pub fn diffuse(&mut self, radius: usize) {
|
||||
self.blur.run(
|
||||
&mut self.data,
|
||||
&mut self.buf,
|
||||
&mut self.buf.buf,
|
||||
self.width,
|
||||
self.height,
|
||||
radius as f32,
|
||||
@ -170,10 +174,10 @@ impl Grid {
|
||||
..
|
||||
} = self.config;
|
||||
|
||||
let self_imut = self.clone(); // Create immutable copy of self before ticking agents (this is a very bad solution, needs to be improved)
|
||||
let buf = self.buf.clone();
|
||||
|
||||
self.agents.par_iter_mut().for_each(|agent| {
|
||||
agent.tick(&self_imut,
|
||||
agent.tick(&buf,
|
||||
sensor_distance, sensor_angle,
|
||||
rotation_angle, step_distance,
|
||||
width, height);
|
||||
@ -214,7 +218,7 @@ where
|
||||
T: AsRef<[f32]> + Sync,
|
||||
{
|
||||
let datas: Vec<_> = grids.iter().map(|grid| &grid.data).collect();
|
||||
let bufs: Vec<_> = grids.iter().map(|grid| &grid.buf).collect();
|
||||
let bufs: Vec<_> = grids.iter().map(|grid| &grid.buf.buf).collect();
|
||||
|
||||
// We mutate grid buffers and read grid data. We use unsafe because we need shared/unique borrows on different fields of the same Grid struct.
|
||||
bufs.iter().enumerate().for_each(|(i, buf)| unsafe {
|
||||
|
||||
@ -22,7 +22,7 @@ impl Clone for ThinGridData {
|
||||
|
||||
impl ThinGridData {
|
||||
// Convert Grid to ThinGridData
|
||||
pub fn from_grid(in_grid: &Grid) -> Self {
|
||||
pub fn new_from_grid(in_grid: &Grid) -> Self {
|
||||
ThinGridData {
|
||||
width: in_grid.width,
|
||||
height: in_grid.height,
|
||||
@ -31,9 +31,9 @@ impl ThinGridData {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn from_grid_vec(in_grids: Vec<Grid>) -> Vec<Self> {
|
||||
pub fn new_from_grid_vec(in_grids: Vec<Grid>) -> Vec<Self> {
|
||||
return in_grids.iter().map(|grid|{
|
||||
Self::from_grid(grid)
|
||||
Self::new_from_grid(grid)
|
||||
}).collect();
|
||||
}
|
||||
|
||||
|
||||
@ -5,3 +5,4 @@ pub mod model;
|
||||
mod palette;
|
||||
mod util; // for math things
|
||||
mod agent;
|
||||
mod buffer;
|
||||
@ -165,14 +165,8 @@ impl Model {
|
||||
);
|
||||
}
|
||||
|
||||
fn strip_grid_data(grids: Vec<Grid>) -> Vec<ThinGridData> {
|
||||
return grids.iter().map(|grid| {
|
||||
ThinGridData::from_grid(grid)
|
||||
}).collect();
|
||||
}
|
||||
|
||||
fn save_image_data(&mut self) {
|
||||
let grids = Self::strip_grid_data(self.grids.clone());
|
||||
let grids = ThinGridData::new_from_grid_vec(self.grids.clone());
|
||||
let img_data = ImgData::new(grids, self.palette, self.iteration);
|
||||
self.img_data_vec.push(img_data);
|
||||
if self.grids[0].width > 1024 && self.grids[0].height > 1024 && self.img_data_vec.len() > 100 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user