aboutsummaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-03-13 14:09:36 +0100
committermetamuffin <metamuffin@disroot.org>2025-03-13 14:09:36 +0100
commit664d54952323a52132377ce9ed3c4a552c0993fa (patch)
treedb6af4ac220e6fcfcdf7954b861b0a0762cf8579 /src/bin
parente4d1504b1d7e575702895d93781f3650ff190bb3 (diff)
downloadunity-tools-664d54952323a52132377ce9ed3c4a552c0993fa.tar
unity-tools-664d54952323a52132377ce9ed3c4a552c0993fa.tar.bz2
unity-tools-664d54952323a52132377ce9ed3c4a552c0993fa.tar.zst
can extract meshes
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/meshes.rs81
-rw-r--r--src/bin/textures.rs4
2 files changed, 83 insertions, 2 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(())
+}
diff --git a/src/bin/textures.rs b/src/bin/textures.rs
index d85f494..00f3596 100644
--- a/src/bin/textures.rs
+++ b/src/bin/textures.rs
@@ -19,7 +19,7 @@ fn main() -> anyhow::Result<()> {
let mut fs2 = UnityFS::open(file())?;
let mut i = 0;
- create_dir_all("/tmp/tex").unwrap();
+ create_dir_all("/tmp/a").unwrap();
let cabfile = fs
.nodes()
@@ -57,7 +57,7 @@ fn main() -> anyhow::Result<()> {
.read_to_end(&mut texture.image_data)?;
}
let path = format!(
- "/tmp/tex/{}_{i}.png",
+ "/tmp/a/{}_{i}.png",
texture.name.replace("/", "-").replace(".", "-")
);
match texture.to_image() {