diff --git a/src/chunk_group.rs b/src/chunk_group.rs index 4fdc45a..a3c6150 100644 --- a/src/chunk_group.rs +++ b/src/chunk_group.rs @@ -1,11 +1,12 @@ use crate::prelude::*; use itertools::Itertools; +pub type ChunkCenter<'a> = Option<&'a mut [Atom; CHUNK_LEN]>; pub type ChunkCorners<'a> = [Option<[&'a mut Atom; QUARTER_CHUNK_LEN]>; 4]; pub type ChunkSides<'a> = [Option<[&'a mut Atom; HALF_CHUNK_LEN]>; 4]; pub struct ChunkGroup<'a> { - pub center: Option<&'a mut [Atom; CHUNK_LEN]>, + pub center: ChunkCenter<'a>, pub corners: ChunkCorners<'a>, pub sides: ChunkSides<'a>, /// Position of the center chunk. @@ -13,15 +14,6 @@ pub struct ChunkGroup<'a> { } impl<'a> ChunkGroup<'a> { - pub fn new(center: &'a mut [Atom; CHUNK_LEN], center_pos: IVec2) -> Self { - Self { - center: Some(center), - corners: [None, None, None, None], - sides: [None, None, None, None], - center_pos, - } - } - pub fn group_to_chunk(center_pos: IVec2, group_idx: i32) -> IVec2 { let x_diff = group_idx % 3 - 1; let y_diff = group_idx / 3 - 1; @@ -236,117 +228,14 @@ pub fn local_to_global(pos: (IVec2, i32)) -> IVec2 { IVec2::new(global_x, global_y) } -//Chunk References - -pub enum ChunkReference<'a> { - //Not chopped - Center(&'a mut [Atom; CHUNK_LEN]), - //Chopped in two - Side([Option<[&'a mut Atom; HALF_CHUNK_LEN]>; 2]), - //Chopped in four - Corner([Option<[&'a mut Atom; QUARTER_CHUNK_LEN]>; 4]), -} - -//This splits up our chunks for the update step, while also mutably borrowing them, making a `ChunkReference` -//Some chunks are not chopped others are chopped up/down, left/right, and also in four corners. -//We do this because each center chunk needs half of the adjacent chunks -//So it needs up/down/left/right halves, and also four corners -//TODO Decrease individual atoms iterations to get a &mut Atom; -pub fn get_mutable_references<'a>( - chunks: &'a mut HashMap, - mutable_references: &mut HashMap>, - (x_toff, y_toff): (i32, i32), - dirty_rects: &HashMap, - manager_pos: IVec2, -) { - puffin::profile_function!(); - - chunks - .iter_mut() - .filter(|(chunk_pos, _)| { - puffin::profile_scope!("Filtering."); - - let same_x = (chunk_pos.x + x_toff + manager_pos.x.abs() % 2) % 2 == 0; - let same_y = (chunk_pos.y + y_toff + manager_pos.y.abs() % 2) % 2 == 0; - let step_as_center = same_x && same_y; - if step_as_center && dirty_rects.contains_key(*chunk_pos) { - return true; - } else if !step_as_center { - let to_check = match (same_x, same_y) { - (false, false) => vec![ivec2(-1, -1), ivec2(-1, 1), ivec2(1, -1), ivec2(1, 1)], - (true, false) => vec![ivec2(0, -1), ivec2(0, 1)], - (false, true) => vec![ivec2(-1, 0), ivec2(1, 0)], - _ => unreachable!(), - }; - for vec in to_check { - if dirty_rects.contains_key(&(**chunk_pos + vec)) { - return true; - } - } - } - - false - }) - .for_each(|(chunk_pos, chunk)| { - let same_x = (chunk_pos.x + x_toff + manager_pos.x.abs() % 2) % 2 == 0; - let same_y = (chunk_pos.y + y_toff + manager_pos.y.abs() % 2) % 2 == 0; - - match (same_x, same_y) { - (true, true) => { - puffin::profile_scope!("Center reference chopping."); - - mutable_references.insert(*chunk_pos, ChunkReference::Center(&mut chunk.atoms)); - } - (true, false) => { - puffin::profile_scope!("Up/Down reference chopping."); - - let (up, down) = chunk.atoms.split_at_mut(HALF_CHUNK_LEN); - - mutable_references.insert( - *chunk_pos, - ChunkReference::Side([ - Some(up.iter_mut().collect::>().try_into().unwrap()), - Some(down.iter_mut().collect::>().try_into().unwrap()), - ]), - ); - } - (false, true) => { - puffin::profile_scope!("Left/Right reference chopping."); - - let (left, right) = split_left_right(&mut chunk.atoms); - - mutable_references - .insert(*chunk_pos, ChunkReference::Side([Some(left), Some(right)])); - } - - (false, false) => { - puffin::profile_scope!("Corner reference chopping."); - - let (up, down) = chunk.atoms.split_at_mut(HALF_CHUNK_LEN); - - let (up_left, up_right) = updown_to_leftright(up); - let (down_left, down_right) = updown_to_leftright(down); - - mutable_references.insert( - *chunk_pos, - ChunkReference::Corner([ - Some(up_left), - Some(up_right), - Some(down_left), - Some(down_right), - ]), - ); - } - } - }); -} - pub fn get_chunk_groups<'a>( chunks: &'a mut HashMap, (x_toff, y_toff): (i32, i32), dirty_rects: &HashMap, manager_pos: IVec2, ) -> Vec> { + puffin::profile_function!(); + let mut chunk_groups = vec![]; let mut indices = HashMap::new(); @@ -354,113 +243,115 @@ pub fn get_chunk_groups<'a>( let same_x = (chunk_pos.x + x_toff + manager_pos.x.abs() % 2) % 2 == 0; let same_y = (chunk_pos.y + y_toff + manager_pos.y.abs() % 2) % 2 == 0; - if same_x && same_y { - let mut chunk_group = ChunkGroup { - center: None, - sides: [None, None, None, None], - corners: [None, None, None, None], - center_pos: *chunk_pos, - }; - indices.insert(chunk_pos, chunk_groups.len()); - - for (x_off, y_off) in (-1..=1).cartesian_product(-1..=1) { - let off = ivec2(x_off, y_off); - unsafe { - match (x_off, y_off) { - (0, 0) => { /*CENTER*/ } - - (0, -1) | (0, 1) => { - // UP and DOWN - let Some(chunk) = chunks.get_mut(&(*chunk_pos + off)) else { - continue; - }; - - let mut start_ptr = chunk.atoms.as_mut_ptr(); - if y_off == -1 { - start_ptr = start_ptr.add(HALF_CHUNK_LEN); - } + if !same_x || !same_y || !chunks.contains_key(chunk_pos) { + continue; + } - let mut atoms = vec![]; - for i in 0..HALF_CHUNK_LEN { - atoms.push(start_ptr.add(i).as_mut().unwrap()); - } + let mut chunk_group = ChunkGroup { + center: None, + sides: [None, None, None, None], + corners: [None, None, None, None], + center_pos: *chunk_pos, + }; + indices.insert(chunk_pos, chunk_groups.len()); + + for (x_off, y_off) in (-1..=1).cartesian_product(-1..=1) { + let off = ivec2(x_off, y_off); + unsafe { + match (x_off, y_off) { + (0, 0) => { /*CENTER*/ } + + (0, -1) | (0, 1) => { + // UP and DOWN + let Some(chunk) = chunks.get_mut(&(*chunk_pos + off)) else { + continue; + }; + + let mut start_ptr = chunk.atoms.as_mut_ptr(); + if y_off == -1 { + start_ptr = start_ptr.add(HALF_CHUNK_LEN); + } - chunk_group.sides[if y_off == -1 { 0 } else { 3 }] = - Some(atoms.try_into().unwrap()); + let mut atoms = vec![]; + for i in 0..HALF_CHUNK_LEN { + atoms.push(start_ptr.add(i).as_mut().unwrap()); } - (-1, 0) | (1, 0) => { - //LEFT and RIGHT - let Some(chunk) = chunks.get_mut(&(*chunk_pos + off)) else { - continue; - }; + chunk_group.sides[if y_off == -1 { 0 } else { 3 }] = + Some(atoms.try_into().unwrap()); + } - let start_ptr = chunk.atoms.as_mut_ptr(); + (-1, 0) | (1, 0) => { + //LEFT and RIGHT + let Some(chunk) = chunks.get_mut(&(*chunk_pos + off)) else { + continue; + }; - let mut atoms = vec![]; - let mut add_off = match x_off { - -1 => HALF_CHUNK_LENGHT, - 1 => 0, - _ => unreachable!(), - }; + let start_ptr = chunk.atoms.as_mut_ptr(); - for i in 0..HALF_CHUNK_LEN { - if i % HALF_CHUNK_LENGHT == 0 && i != 0 { - add_off += HALF_CHUNK_LENGHT; - } + let mut atoms = vec![]; + let mut add_off = match x_off { + -1 => HALF_CHUNK_LENGHT, + 1 => 0, + _ => unreachable!(), + }; - atoms.push(start_ptr.add(i + add_off).as_mut().unwrap()); + for i in 0..HALF_CHUNK_LEN { + if i % HALF_CHUNK_LENGHT == 0 && i != 0 { + add_off += HALF_CHUNK_LENGHT; } - chunk_group.sides[if x_off == -1 { 1 } else { 2 }] = - Some(atoms.try_into().unwrap()); + atoms.push(start_ptr.add(i + add_off).as_mut().unwrap()); } - (-1, -1) | (1, -1) | (-1, 1) | (1, 1) => { - //CORNERS - let Some(chunk) = chunks.get_mut(&(*chunk_pos + off)) else { - continue; - }; + chunk_group.sides[if x_off == -1 { 1 } else { 2 }] = + Some(atoms.try_into().unwrap()); + } - let start_ptr = chunk.atoms.as_mut_ptr(); + (-1, -1) | (1, -1) | (-1, 1) | (1, 1) => { + //CORNERS + let Some(chunk) = chunks.get_mut(&(*chunk_pos + off)) else { + continue; + }; - let mut atoms = vec![]; - let mut add_off = match (x_off, y_off) { - (1, 1) => 0, - (-1, 1) => HALF_CHUNK_LENGHT, - (1, -1) => HALF_CHUNK_LEN, - (-1, -1) => HALF_CHUNK_LEN + HALF_CHUNK_LENGHT, + let start_ptr = chunk.atoms.as_mut_ptr(); - _ => unreachable!(), - }; + let mut atoms = vec![]; + let mut add_off = match (x_off, y_off) { + (1, 1) => 0, + (-1, 1) => HALF_CHUNK_LENGHT, + (1, -1) => HALF_CHUNK_LEN, + (-1, -1) => HALF_CHUNK_LEN + HALF_CHUNK_LENGHT, - for i in 0..QUARTER_CHUNK_LEN { - if i % HALF_CHUNK_LENGHT == 0 && i != 0 { - add_off += HALF_CHUNK_LENGHT; - } + _ => unreachable!(), + }; - atoms.push(start_ptr.add(i + add_off).as_mut().unwrap()); + for i in 0..QUARTER_CHUNK_LEN { + if i % HALF_CHUNK_LENGHT == 0 && i != 0 { + add_off += HALF_CHUNK_LENGHT; } - let corner_idx = match (x_off, y_off) { - (1, 1) => 3, - (-1, 1) => 2, - (1, -1) => 1, - (-1, -1) => 0, + atoms.push(start_ptr.add(i + add_off).as_mut().unwrap()); + } - _ => unreachable!(), - }; + let corner_idx = match (x_off, y_off) { + (1, 1) => 3, + (-1, 1) => 2, + (1, -1) => 1, + (-1, -1) => 0, - chunk_group.corners[corner_idx] = Some(atoms.try_into().unwrap()); - } + _ => unreachable!(), + }; - _ => unreachable!(), + chunk_group.corners[corner_idx] = Some(atoms.try_into().unwrap()); } + + _ => unreachable!(), } } - - chunk_groups.push(chunk_group); } + + chunk_groups.push(chunk_group); } for (chunk_pos, chunk) in chunks.iter_mut() { @@ -471,38 +362,3 @@ pub fn get_chunk_groups<'a>( chunk_groups } - -pub fn split_left_right( - array: &mut [Atom], -) -> ([&mut Atom; HALF_CHUNK_LEN], [&mut Atom; HALF_CHUNK_LEN]) { - puffin::profile_function!(); - - let (left, right): (Vec<_>, Vec<_>) = array - .chunks_mut(CHUNK_LENGHT) - .flat_map(|chunk| { - let (left, right) = chunk.split_at_mut(HALF_CHUNK_LENGHT); - left.iter_mut().zip(right.iter_mut()).collect::>() - }) - .unzip(); - - (left.try_into().unwrap(), right.try_into().unwrap()) -} - -pub fn updown_to_leftright( - array: &mut [Atom], -) -> ( - [&mut Atom; QUARTER_CHUNK_LEN], - [&mut Atom; QUARTER_CHUNK_LEN], -) { - puffin::profile_function!(); - - let (left, right): (Vec<_>, Vec<_>) = array - .chunks_mut(CHUNK_LENGHT) - .flat_map(|chunk| { - let (left, right) = chunk.split_at_mut(HALF_CHUNK_LENGHT); - left.iter_mut().zip(right.iter_mut()).collect::>() - }) - .unzip(); - - (left.try_into().unwrap(), right.try_into().unwrap()) -} diff --git a/src/chunk_manager.rs b/src/chunk_manager.rs index 3cde17e..0ba0a2a 100644 --- a/src/chunk_manager.rs +++ b/src/chunk_manager.rs @@ -235,15 +235,8 @@ pub fn chunk_manager_update( //Get materials let materials = &materials.0.get(materials.1 .0.clone()).unwrap(); - let first_x = chunk_manager.pos.x; - let first_y = chunk_manager.pos.y; - let last_x = chunk_manager.pos.x + LOAD_WIDTH; - let last_y = chunk_manager.pos.y + LOAD_HEIGHT; let manager_pos = ivec2(chunk_manager.pos.x, chunk_manager.pos.y); - let row_range = first_x..last_x; - let column_range = first_y..last_y; - let compute_pool = ComputeTaskPool::get(); // Create channel for sending dirty update rects @@ -321,97 +314,6 @@ pub fn chunk_manager_update( ) }); } - - /*OLD - //Get chopped chunks references - let mut mutable_references = HashMap::new(); - get_mutable_references( - &mut chunk_manager.chunks, - &mut mutable_references, - (x_toff, y_toff), - dirty_rects, - manager_pos, - ); - - //Iterate through the center chunks - let y_iter = ((y_toff + first_y)..last_y).step_by(2); - let x_iter = ((x_toff + first_x)..last_x).step_by(2); - for (x, y) in x_iter.cartesian_product(y_iter) { - let center_pos = ivec2(x, y); - let Some(rect) = dirty_rects.get(¢er_pos) else { - continue; - }; - let ChunkReference::Center(center) = - mutable_references.remove(¢er_pos).unwrap() - else { - unreachable!() - }; - let mut chunk_group = ChunkGroup::new(center, center_pos); - - // Get the rest of the 3x3 chunks to add to the chunk group - for (x_off, y_off) in (-1..=1).cartesian_product(-1..=1) { - //If it's the center chunk, or out of bounds continue - if (x_off == 0 && y_off == 0) - || !column_range.contains(&(y + y_off)) - || !row_range.contains(&(x + x_off)) - { - continue; - } - - let (group_idx, reference_idx) = match (x_off, y_off) { - // Left Right - (-1, 0) => (1, 1), - (1, 0) => (2, 0), - // Up Down - (0, -1) => (0, 1), - (0, 1) => (3, 0), - // Corners - (-1, -1) => (0, 3), - (1, -1) => (1, 2), - (-1, 1) => (2, 1), - (1, 1) => (3, 0), - - _ => unreachable!(), - }; - - if x_off.abs() != y_off.abs() { - // Side - let side = if let Some(ChunkReference::Side(ref mut side)) = - mutable_references.get_mut(&(center_pos + ivec2(x_off, y_off))) - { - side[reference_idx].take() - } else { - unreachable!() - }; - - chunk_group.sides[group_idx] = side; - } else { - // Corner - let corner = if let Some(ChunkReference::Corner(ref mut corner)) = - mutable_references.get_mut(&(center_pos + ivec2(x_off, y_off))) - { - corner[reference_idx].take() - } else { - unreachable!() - }; - - chunk_group.corners[group_idx] = corner; - } - } - - scope.spawn(async move { - update_chunks( - &mut UpdateChunksType { - group: chunk_group, - dirty_update_rect_send, - dirty_render_rect_send, - materials, - }, - dt, - rect, - ) - }); - }*/ }); }