diff --git a/voxygen/src/bin/img-export.rs b/voxygen/src/bin/img-export.rs index 7005f92290..607d1d8cbf 100644 --- a/voxygen/src/bin/img-export.rs +++ b/voxygen/src/bin/img-export.rs @@ -1,11 +1,12 @@ -use clap::Parser; -use common::figure::Segment; -use common_assets::{AssetExt, DotVoxAsset}; use std::{fs, path::Path}; -use vek::{Mat4, Quaternion, Vec2, Vec3, Vec4}; + +use clap::Parser; +use vek::Vec2; + +use common_assets::AssetExt; use veloren_voxygen::{ hud::item_imgs::{ImageSpec, ItemImagesSpec}, - ui::graphic::renderer::{draw_vox, SampleStrat, Transform}, + ui::{graphic::renderer::draw_vox, Graphic}, }; #[derive(Parser)] @@ -18,108 +19,33 @@ struct Cli { pub fn main() { let args = Cli::parse(); let manifest = ItemImagesSpec::load_expect("voxygen.item_image_manifest"); + let image_size = Vec2 { + x: (10_u32 * args.scale) as u16, + y: (10_u32 * args.scale) as u16, + }; for (_, spec) in manifest.read().0.iter() { - match spec { - ImageSpec::Vox(specifier, model_index) => { - voxel_to_png(&specifier, Transform::default(), args.scale, *model_index as usize) + let graphic = spec.create_graphic(); + let img = match graphic { + Graphic::Voxel(segment, trans, sample_strat) => { + draw_vox(&segment, image_size, trans, sample_strat) }, - ImageSpec::VoxTrans(specifier, offset, [rot_x, rot_y, rot_z], zoom, model_index) => { - voxel_to_png( - &specifier, - Transform { - ori: Quaternion::rotation_x(rot_x * std::f32::consts::PI / 180.0) - .rotated_y(rot_y * std::f32::consts::PI / 180.0) - .rotated_z(rot_z * std::f32::consts::PI / 180.0), - offset: Vec3::from(*offset), - /* FIXME: This is a dirty workaround to not cut off the edges of some - * objects like ./img-export/weapon/component/ - * axe/poleaxe/bronze.vox more details here: https://gitlab.com/veloren/veloren/-/merge_requests/3494#note_1205030803 */ - zoom: *zoom * 0.8, - orth: true, - stretch: false, - }, - args.scale, - *model_index as usize, - ) - }, - ImageSpec::Png(specifier) => { - println!("Skip png image {}", specifier); - continue; - }, - } - } -} - -fn voxel_to_png(specifier: &String, transform: Transform, scale: u32, model_index: usize) { - let voxel = match DotVoxAsset::load(&format!("voxygen.{}", specifier)) { - Ok(dot_vox) => dot_vox, - Err(err) => { - println!("Coudn't load voxel: {}", err); + _ => continue, + }; + let specifier = match spec { + ImageSpec::Vox(specifier, _) => specifier, + ImageSpec::VoxTrans(specifier, _, _, _, _) => specifier, + _ => continue, + }; + let path = format!("img-export/{}.png", &specifier_to_path(specifier)); + let folder_path = path.rsplit_once('/').expect("Invalid path").0; + let full_path = Path::new(&path); + if let Err(e) = fs::create_dir_all(Path::new(folder_path)) { + println!("{}", e); return; - }, - }; - let dot_vox_data = &voxel.read().0; - let model_size = dot_vox_data - .models - .get(model_index) - .expect("Error getting model from voxel") - .size; - let ori_mat = Mat4::from(transform.ori); - let aabb_size = Vec3::new(model_size.x, model_size.y, model_size.z); - let projection_size = Vec2 { - x: (10u32 * scale) as u16, - y: (10u32 * scale) as u16, - }; - let segment = Segment::from_vox(dot_vox_data, false, model_index); - let path = format!("img-export/{}.png", &specifier_to_path(specifier)); - let folder_path = path.rsplit_once('/').expect("Invalid path").0; - let full_path = Path::new(&path); - if let Err(e) = fs::create_dir_all(Path::new(folder_path)) { - println!("{}", e); - return; - } + } - draw_vox(&segment, projection_size, transform, SampleStrat::None) - .save(full_path) - .unwrap_or_else(|_| panic!("Can't save file {}", full_path.to_str().expect(""))); -} - -fn calc_rotated_size(ori_mat: &Mat4, aabb_size: &Vec3) -> Vec3 { - let aabb_min = Vec3 { - x: 0f32, - y: 0f32, - z: 0f32, - }; - let aabb_max = Vec3 { - x: aabb_size.x as f32, - y: aabb_size.y as f32, - z: aabb_size.z as f32, - }; - let aabb_vertices: [Vec3; 8] = [ - Vec3::new(aabb_min.x, aabb_min.y, aabb_min.z), - Vec3::new(aabb_max.x, aabb_min.y, aabb_min.z), - Vec3::new(aabb_max.x, aabb_max.y, aabb_min.z), - Vec3::new(aabb_min.x, aabb_max.y, aabb_min.z), - Vec3::new(aabb_min.x, aabb_min.y, aabb_max.z), - Vec3::new(aabb_max.x, aabb_min.y, aabb_max.z), - Vec3::new(aabb_max.x, aabb_max.y, aabb_max.z), - Vec3::new(aabb_min.x, aabb_max.y, aabb_max.z), - ]; - let rotated_vertices = aabb_vertices.map(|c| (*ori_mat * Vec4::::from(c)).xyz()); - let max_xyz = rotated_vertices - .iter() - .copied() - .reduce(|acc, corner| Vec3::::partial_max(acc, corner)) - .expect("Failed find maximum"); - let min_xyz = rotated_vertices - .iter() - .copied() - .reduce(|acc, vertex| Vec3::::partial_min(acc, vertex)) - .expect("Failed find minimum"); - Vec3 { - x: max_xyz.x - min_xyz.x, - y: max_xyz.y - min_xyz.y, - z: max_xyz.z - min_xyz.z, + img.save(full_path) + .unwrap_or_else(|_| panic!("Can't save file {}", full_path.to_str().expect(""))); } } diff --git a/voxygen/src/hud/item_imgs.rs b/voxygen/src/hud/item_imgs.rs index 7d7234f80c..76cb844f8e 100644 --- a/voxygen/src/hud/item_imgs.rs +++ b/voxygen/src/hud/item_imgs.rs @@ -25,7 +25,7 @@ pub enum ImageSpec { VoxTrans(String, [f32; 3], [f32; 3], f32, #[serde(default)] u32), } impl ImageSpec { - fn create_graphic(&self) -> Graphic { + pub fn create_graphic(&self) -> Graphic { match self { ImageSpec::Png(specifier) => Graphic::Image(graceful_load_img(specifier), None), ImageSpec::Vox(specifier, model_index) => Graphic::Voxel(