make seperate struct for buffer
This commit is contained in:
parent
d887b13579
commit
af0b9f9222
13
src/agent.rs
13
src/agent.rs
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
grid::Grid,
|
|
||||||
util::wrap,
|
util::wrap,
|
||||||
|
buffer::Buf,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rand::{seq::SliceRandom, Rng};
|
use rand::{seq::SliceRandom, Rng};
|
||||||
@ -40,9 +40,10 @@ impl Agent {
|
|||||||
i,
|
i,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tick an agent
|
||||||
#[inline]
|
#[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 xc = self.x + cos(self.angle) * sensor_distance;
|
||||||
let yc = self.y + sin(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;
|
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.
|
// 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 center = buf.get_buf(xc, yc);
|
||||||
let left = grid.get_buf(xl, yl);
|
let left = buf.get_buf(xl, yl);
|
||||||
let right = grid.get_buf(xr, yr);
|
let right = buf.get_buf(xr, yr);
|
||||||
|
|
||||||
// Rotate and move logic
|
// Rotate and move logic
|
||||||
let mut rng = rand::thread_rng();
|
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::{
|
use crate::{
|
||||||
blur::Blur,
|
blur::Blur,
|
||||||
agent::Agent,
|
agent::Agent,
|
||||||
|
buffer::Buf,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rand::{distributions::Uniform, Rng};
|
use rand::{distributions::Uniform, Rng};
|
||||||
@ -89,7 +90,8 @@ pub struct Grid {
|
|||||||
pub data: Vec<f32>,
|
pub data: Vec<f32>,
|
||||||
|
|
||||||
// Scratch space for the blur operation.
|
// Scratch space for the blur operation.
|
||||||
pub buf: Vec<f32>,
|
// pub buf: Vec<f32>,
|
||||||
|
pub buf: Buf,
|
||||||
pub blur: Blur,
|
pub blur: Blur,
|
||||||
pub agents: Vec<Agent>
|
pub agents: Vec<Agent>
|
||||||
}
|
}
|
||||||
@ -122,7 +124,7 @@ impl Grid {
|
|||||||
height,
|
height,
|
||||||
data,
|
data,
|
||||||
config: PopulationConfig::new(rng),
|
config: PopulationConfig::new(rng),
|
||||||
buf: vec![0.0; width * height],
|
buf: Buf::new(width, height, vec![0.0; width * height]),
|
||||||
blur: Blur::new(width),
|
blur: Blur::new(width),
|
||||||
agents,
|
agents,
|
||||||
}
|
}
|
||||||
@ -136,10 +138,12 @@ impl Grid {
|
|||||||
j * self.width + i
|
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.
|
// 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 {
|
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.
|
// Add a value to the grid data at a given position.
|
||||||
pub fn deposit(&mut self, x: f32, y: f32) {
|
pub fn deposit(&mut self, x: f32, y: f32) {
|
||||||
@ -151,7 +155,7 @@ impl Grid {
|
|||||||
pub fn diffuse(&mut self, radius: usize) {
|
pub fn diffuse(&mut self, radius: usize) {
|
||||||
self.blur.run(
|
self.blur.run(
|
||||||
&mut self.data,
|
&mut self.data,
|
||||||
&mut self.buf,
|
&mut self.buf.buf,
|
||||||
self.width,
|
self.width,
|
||||||
self.height,
|
self.height,
|
||||||
radius as f32,
|
radius as f32,
|
||||||
@ -170,10 +174,10 @@ impl Grid {
|
|||||||
..
|
..
|
||||||
} = self.config;
|
} = 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| {
|
self.agents.par_iter_mut().for_each(|agent| {
|
||||||
agent.tick(&self_imut,
|
agent.tick(&buf,
|
||||||
sensor_distance, sensor_angle,
|
sensor_distance, sensor_angle,
|
||||||
rotation_angle, step_distance,
|
rotation_angle, step_distance,
|
||||||
width, height);
|
width, height);
|
||||||
@ -214,7 +218,7 @@ where
|
|||||||
T: AsRef<[f32]> + Sync,
|
T: AsRef<[f32]> + Sync,
|
||||||
{
|
{
|
||||||
let datas: Vec<_> = grids.iter().map(|grid| &grid.data).collect();
|
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.
|
// 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 {
|
bufs.iter().enumerate().for_each(|(i, buf)| unsafe {
|
||||||
|
|||||||
@ -22,7 +22,7 @@ impl Clone for ThinGridData {
|
|||||||
|
|
||||||
impl ThinGridData {
|
impl ThinGridData {
|
||||||
// Convert Grid to ThinGridData
|
// Convert Grid to ThinGridData
|
||||||
pub fn from_grid(in_grid: &Grid) -> Self {
|
pub fn new_from_grid(in_grid: &Grid) -> Self {
|
||||||
ThinGridData {
|
ThinGridData {
|
||||||
width: in_grid.width,
|
width: in_grid.width,
|
||||||
height: in_grid.height,
|
height: in_grid.height,
|
||||||
@ -31,9 +31,9 @@ impl ThinGridData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[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|{
|
return in_grids.iter().map(|grid|{
|
||||||
Self::from_grid(grid)
|
Self::new_from_grid(grid)
|
||||||
}).collect();
|
}).collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,4 +4,5 @@ mod imgdata; // for storing image data
|
|||||||
pub mod model;
|
pub mod model;
|
||||||
mod palette;
|
mod palette;
|
||||||
mod util; // for math things
|
mod util; // for math things
|
||||||
mod agent;
|
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) {
|
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);
|
let img_data = ImgData::new(grids, self.palette, self.iteration);
|
||||||
self.img_data_vec.push(img_data);
|
self.img_data_vec.push(img_data);
|
||||||
if self.grids[0].width > 1024 && self.grids[0].height > 1024 && self.img_data_vec.len() > 100 {
|
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