use crate::{io::RawAssets, volume::*, Error, Result};
use std::path::PathBuf;
pub fn deserialize_vol(raw_assets: &mut RawAssets, path: &PathBuf) -> Result<VoxelGrid> {
let name = path.to_str().unwrap().to_string();
let bytes = raw_assets.remove(path)?;
let width = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]);
let height = u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
let depth = u32::from_be_bytes([bytes[8], bytes[9], bytes[10], bytes[11]]);
let size = Vec3::new(
f32::from_be_bytes([bytes[16], bytes[17], bytes[18], bytes[19]]),
f32::from_be_bytes([bytes[20], bytes[21], bytes[22], bytes[23]]),
f32::from_be_bytes([bytes[24], bytes[25], bytes[26], bytes[27]]),
);
let bytes = &bytes[28..];
let data = match bytes.len() as u32 / (width * height * depth) {
1 => {
let data = bytes.to_vec();
TextureData::RU8(flip(data, width as usize, height as usize, depth as usize))
}
2 => {
let mut data = Vec::new();
for i in 0..bytes.len() / 2 {
data.push([bytes[i * 2], bytes[i * 2 + 1]]);
}
TextureData::RgU8(flip(data, width as usize, height as usize, depth as usize))
}
3 => {
let mut data = Vec::new();
for i in 0..bytes.len() / 3 {
data.push([bytes[i * 3], bytes[i * 3 + 1], bytes[i * 3 + 2]]);
}
TextureData::RgbU8(flip(data, width as usize, height as usize, depth as usize))
}
4 => {
let mut data = Vec::new();
for i in 0..bytes.len() / 4 {
data.push([
bytes[i * 4],
bytes[i * 4 + 1],
bytes[i * 4 + 2],
bytes[i * 4 + 3],
]);
}
TextureData::RgbaU8(flip(data, width as usize, height as usize, depth as usize))
}
_ => Err(Error::VolCorruptData)?,
};
Ok(VoxelGrid {
voxels: Texture3D {
data,
width: depth,
height: width,
depth: height,
..Default::default()
},
size: Vec3::new(size.z, size.x, size.y),
name,
})
}
fn flip<T: Default + Clone>(data: Vec<T>, width: usize, height: usize, depth: usize) -> Vec<T> {
let mut out_data = vec![T::default(); width * height * depth];
for x in 0..width {
for y in 0..height {
for z in 0..depth {
let id0 = x * depth * height + y * depth + z;
let id1 = y * width * depth + x * depth + z;
out_data[id1] = data[id0].clone();
}
}
}
out_data
}