# HG changeset patch # User alfadur # Date 1541617307 -10800 # Node ID c24a76f131d6ad160e0b363c60d11e85fa324867 # Parent 0aeea29ef89087d3ed5aabaad4a8875db35d7f65 implement basic land texturing diff -r 0aeea29ef890 -r c24a76f131d6 rust/land2d/src/lib.rs --- a/rust/land2d/src/lib.rs Wed Nov 07 19:43:17 2018 +0100 +++ b/rust/land2d/src/lib.rs Wed Nov 07 22:01:47 2018 +0300 @@ -30,7 +30,7 @@ } pub fn raw_pixels(&self) -> &[T] { - &self.pixels.raw_data() + &self.pixels.as_slice() } #[inline] diff -r 0aeea29ef890 -r c24a76f131d6 rust/mapgen/Cargo.toml --- a/rust/mapgen/Cargo.toml Wed Nov 07 19:43:17 2018 +0100 +++ b/rust/mapgen/Cargo.toml Wed Nov 07 22:01:47 2018 +0300 @@ -5,6 +5,7 @@ edition = "2018" [dependencies] +vec2d = { path = "../vec2d" } land2d = { path = "../land2d" } landgen = { path = "../landgen" } lfprng = { path = "../lfprng" } diff -r 0aeea29ef890 -r c24a76f131d6 rust/mapgen/src/lib.rs --- a/rust/mapgen/src/lib.rs Wed Nov 07 19:43:17 2018 +0100 +++ b/rust/mapgen/src/lib.rs Wed Nov 07 22:01:47 2018 +0300 @@ -5,7 +5,6 @@ borrow::Borrow, mem::replace }; -use serde::{Deserialize}; use serde_derive::{Deserialize}; use serde_yaml; use integral_geometry::{Point, Size, Rect}; @@ -14,6 +13,7 @@ }; use rand::{thread_rng, Rng}; use land2d::Land2D; +use vec2d::Vec2D; use self::theme::Theme; #[derive(Deserialize)] @@ -106,11 +106,52 @@ self.templates.get(template_type).and_then(|t| thread_rng().choose(t)) } - pub fn make_texture(&self, land: &Land2D, theme: &Theme) { + pub fn make_texture(&self, land: &Land2D, theme: &Theme) -> Vec2D { + let mut texture = Vec2D::new(land.size(), 0); + if let Some(land_sprite) = theme.land_texture() { + for (row_index, (land_row, tex_row)) in land.rows() + .zip(texture.rows_mut()) + .enumerate() + { + let sprite_row = land_sprite.get_row(row_index % land_sprite.height()); + let mut x_offset = 0; + while sprite_row.len() < land.width() - x_offset { + let copy_range = x_offset..x_offset + sprite_row.len(); + tex_row_copy( + &land_row[copy_range.clone()], + &mut tex_row[copy_range], + sprite_row + ); + + x_offset += land_sprite.width() + } + if x_offset < land.width() { + let final_range = x_offset..land.width() - 1; + tex_row_copy( + &land_row[final_range.clone()], + &mut tex_row[final_range], + &sprite_row[..land.width() - x_offset] + ); + } + } + } + texture } } +fn tex_row_copy(land_row: &[u32], tex_row: &mut [u32], sprite_row: &[u32]) { + for ((land_v, tex_v), sprite_v) in + land_row.iter().zip(tex_row.iter_mut()).zip(sprite_row) + { + *tex_v = if *land_v == 0 { + *sprite_v + } else { + 0 + } + } +} + #[cfg(test)] mod tests { use crate::{ diff -r 0aeea29ef890 -r c24a76f131d6 rust/mapgen/src/theme.rs --- a/rust/mapgen/src/theme.rs Wed Nov 07 19:43:17 2018 +0100 +++ b/rust/mapgen/src/theme.rs Wed Nov 07 22:01:47 2018 +0300 @@ -6,25 +6,55 @@ path::Path }; use png::{ - BitDepth, ColorType, Decoder, DecodingError }; -use integral_geometry::{ - Rect, Size -}; +use integral_geometry::Size; +use vec2d::Vec2D; pub struct ThemeSprite { - bounds: Size, - pixels: Vec + pixels: Vec2D +} + +impl ThemeSprite { + #[inline] + pub fn width(&self) -> usize { + self.pixels.size().width + } + + #[inline] + pub fn height(&self) -> usize { + self.pixels.size().height + } + + #[inline] + pub fn bounds(&self) -> Size { + self.pixels.size() + } + + #[inline] + pub fn rows(&self) -> impl Iterator { + self.pixels.rows() + } + + #[inline] + pub fn get_row(&self, index: usize) -> &[u32] { + &self.pixels[index] + } } pub struct Theme { land_texture: Option } +impl Theme { + pub fn land_texture(&self) -> Option<&ThemeSprite> { + self.land_texture.as_ref() + } +} + pub enum ThemeLoadError { File(io::Error), Decoding(DecodingError), @@ -66,18 +96,17 @@ } let size = Size::new(info.width as usize, info.height as usize); - let mut buffer: Vec = Vec::with_capacity(size.area()); - let mut slice_u32 = buffer.as_mut_slice(); - let mut slice_u8 = unsafe { + let mut buffer: Vec2D = Vec2D::new(size, 0); + let slice_u32 = buffer.as_mut_slice(); + let slice_u8 = unsafe { from_raw_parts_mut::( slice_u32.as_mut_ptr() as *mut u8, slice_u32.len() / 4 ) }; - reader.next_frame(slice_u8); + reader.next_frame(slice_u8)?; let land_tex = ThemeSprite { - bounds: size, pixels: buffer }; theme.land_texture = Some(land_tex) diff -r 0aeea29ef890 -r c24a76f131d6 rust/vec2d/src/lib.rs --- a/rust/vec2d/src/lib.rs Wed Nov 07 19:43:17 2018 +0100 +++ b/rust/vec2d/src/lib.rs Wed Nov 07 22:01:47 2018 +0300 @@ -55,8 +55,14 @@ Self { size, data: vec![value; size.area()] } } - pub fn raw_data(&self) -> &[T] { - &self.data + #[inline] + pub fn as_slice(&self) -> &[T] { + self.data.as_slice() + } + + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [T] { + self.data.as_mut_slice() } #[inline] @@ -83,6 +89,24 @@ pub fn rows(&self) -> impl Iterator { self.data.chunks(self.width()) } + + #[inline] + pub fn rows_mut(&mut self) -> impl Iterator { + let width = self.width(); + self.data.chunks_mut(width) + } +} + +impl AsRef<[T]> for Vec2D { + fn as_ref(&self) -> &[T] { + self.as_slice() + } +} + +impl AsMut<[T]> for Vec2D { + fn as_mut(&mut self) -> &mut [T] { + self.as_mut_slice() + } } #[cfg(test)]