use bevy::prelude::*;
use bevy::render::render_asset::RenderAssetUsages;
use bevy::render::render_resource::{Extent3d, TextureDimension, TextureFormat};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum RegionMapError {
#[error("failed to load the image")]
LoadingError,
}
pub type RegionMapU8 = Vec<Vec<u8>>;
pub struct SubRegionMapU8(pub Vec<Vec<u8>>);
impl SubRegionMapU8 {
pub fn append_x_row(&mut self, row: Vec<u8>) {
self.0.push(row);
}
pub fn append_y_col(&mut self, col: Vec<u8>) {
if col.len() != self.0.len() {
println!("WARN: cannot append y col "); panic!("Column length does not match the number of rows in height data.");
}
for (row, &value) in self.0.iter_mut().zip(col.iter()) {
row.push(value);
}
}
}
pub trait RegionMap {
fn load_from_image(image: &Image) -> Result<Box<Self>, RegionMapError>;
fn to_image(&self) -> Image;
}
impl RegionMap for RegionMapU8 {
fn to_image(&self) -> Image {
let raw_data = self ;
let height = raw_data.len();
let width = if height > 0 {
raw_data[0].len()
} else {
0
};
let mut modified_data = Vec::with_capacity(height * width * 4);
for row in raw_data {
for &value in row {
modified_data.extend_from_slice(&[value, value, value, 255]);
}
}
let size = Extent3d {
width: width as u32,
height: height as u32,
depth_or_array_layers: 1,
};
let dimension = TextureDimension::D2;
Image::new(
size,
dimension,
modified_data,
TextureFormat::Rgba8Uint,
RenderAssetUsages::default(),
)
}
fn load_from_image(image: &Image) -> Result<Box<Self>, RegionMapError> {
let width = image.size().x as usize;
let height = image.size().y as usize;
let format = image.texture_descriptor.format;
if format != TextureFormat::R8Uint {
println!("regionmap: wrong format {:?}", format);
return Err(RegionMapError::LoadingError);
}
let mut region_map = Vec::with_capacity(height);
for y in 0..height {
let mut row = Vec::with_capacity(width);
for x in 0..width {
let index = y * width + x;
let height_value = image.data[index];
row.push(height_value);
}
region_map.push(row);
}
Ok(Box::new(region_map))
}
}