diff options
Diffstat (limited to 'src/bin/meshes.rs')
-rw-r--r-- | src/bin/meshes.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/bin/meshes.rs b/src/bin/meshes.rs new file mode 100644 index 0000000..64fe91c --- /dev/null +++ b/src/bin/meshes.rs @@ -0,0 +1,81 @@ +#![feature(array_chunks)] +use anyhow::anyhow; +use std::{ + env::args, + fs::{File, create_dir_all}, + io::{BufReader, BufWriter, Seek, SeekFrom, Write}, +}; +use unity_tools::{ + classes::mesh::{Mesh, VertexDataChannel}, + object::{parser::FromValue, read::read_value}, + serialized_file::read_serialized_file, + unityfs::UnityFS, +}; + +fn main() -> anyhow::Result<()> { + env_logger::init_from_env("LOG"); + let file = || BufReader::new(File::open(args().nth(1).unwrap()).unwrap()); + let mut fs = UnityFS::open(file())?; + // let mut fs2 = UnityFS::open(file())?; + + let mut i = 0; + create_dir_all("/tmp/a").unwrap(); + + let cabfile = fs + .nodes() + .iter() + .find(|n| !n.name.ends_with(".resource") && !n.name.ends_with(".resS")) + .ok_or(anyhow!("no CAB file found"))? + .to_owned(); + // let ressfile = fs2 + // .nodes() + // .iter() + // .find(|n| n.name.ends_with(".resS")) + // .cloned(); + + let mut cab = fs.read(&cabfile)?; + // let mut ress = ressfile.map(|p| fs2.read(&p)).transpose()?; + let file = read_serialized_file(&mut cab)?; + for ob in file.objects { + cab.seek(SeekFrom::Start(ob.data_offset))?; + let typetree = if ob.type_id < 0 { + unimplemented!() + } else { + &file.types[ob.type_id as usize] + }; + if let Some(typetree) = &typetree.type_tree { + if typetree.type_string != "Mesh" { + continue; + } + let value = read_value(typetree, file.endianness, &mut cab)?; + let mesh = Mesh::from_value(value).unwrap(); + // if mesh.stream_data.len() == 0 { + // let ress = ress.as_mut().unwrap(); + // ress.seek(SeekFrom::Start(mesh.stream_data.offset))?; + // ress.by_ref() + // .take(mesh.stream_data.size as u64) + // .read_to_end(&mut mesh.)?; + // } + let mut obj = BufWriter::new(File::create(format!( + "/tmp/a/{}_{i}.obj", + mesh.name.replace("/", "-").replace(".", "-") + ))?); + + let (pos_dims, positions) = mesh + .vertex_data + .read_channel(VertexDataChannel::Position) + .unwrap(); + assert_eq!(pos_dims, 3); + + for [x, y, z] in positions.array_chunks() { + writeln!(obj, "v {x} {y} {z}")?; + } + for [a, b, c] in mesh.read_indecies() { + writeln!(obj, "f {a} {b} {c}")?; + } + i += 1; + } + } + + Ok(()) +} |