diff options
Diffstat (limited to 'exporter/src')
-rw-r--r-- | exporter/src/bin/gltf.rs | 234 |
1 files changed, 0 insertions, 234 deletions
diff --git a/exporter/src/bin/gltf.rs b/exporter/src/bin/gltf.rs deleted file mode 100644 index b8db13c..0000000 --- a/exporter/src/bin/gltf.rs +++ /dev/null @@ -1,234 +0,0 @@ -#![feature(array_chunks)] -use anyhow::{Result, anyhow}; -use glam::{Affine3A, Mat4}; -use gltf::{Glb, Semantic, mesh::Mode}; -use gltf_json::{ - Accessor, Index, Node, Root, Scene, - accessor::GenericComponentType, - mesh::Primitive, - validation::{Checked, USize64}, -}; -use log::warn; -use std::{borrow::Cow, collections::BTreeMap, env::args, fs::File, io::BufReader}; -use unity_tools::{ - classes::{ - gameobject::GameObject, - mesh::{Mesh, VertexDataChannel}, - renderer::SkinnedMeshRenderer, - transform::Transform, - }, - serialized_file::SerializedFile, - unityfs::UnityFS, -}; - -fn main() -> anyhow::Result<()> { - env_logger::init_from_env("LOG"); - let file = BufReader::new(File::open(args().nth(1).unwrap()).unwrap()); - let fs = UnityFS::open(file)?; - - let cabfile = fs - .find_main_file() - .ok_or(anyhow!("no CAB file found"))? - .to_owned(); - - let mut cab = fs.read(&cabfile)?; - let mut file = SerializedFile::read(&mut cab)?; - let gameobjects = file - .objects - .iter() - .filter(|ob| file.get_object_type_tree(ob).unwrap().type_string == "GameObject") - .cloned() - .collect::<Vec<_>>(); - - // let mut root_tr = Transform::from_value(file.read_object(ob)?)?; - // while !root_tr.father.is_null() { - // root_tr = root_tr.father.load(&mut file)?; - // } - // eprintln!("{root_tr:?}"); - - let mut root = gltf_json::Root::default(); - let mut nodes = Vec::new(); - let mut buffer = Vec::new(); - - for ob in gameobjects { - let go = file.read_object(ob)?.parse::<GameObject>()?; - let mut global_transform = Affine3A::default(); - for comp in go.components { - let ob = comp.load(&mut file, None)?; - match ob.class_name().unwrap().as_str() { - "Transform" => { - let mut tr = ob.parse::<Transform>()?; - let mut transforms = Vec::new(); - loop { - transforms.push( - Mat4::from_translation(tr.local_position) - * Mat4::from_scale(tr.local_scale) - * Mat4::from_quat(tr.local_rotation), - ); - if tr.father.is_null() { - break; - } else { - tr = tr.father.load(&mut file, None)?; - } - } - global_transform = - Affine3A::from_mat4(transforms.into_iter().reduce(|a, b| a * b).unwrap()) - } - "SkinnedMeshRenderer" => { - let smr = ob.parse::<SkinnedMeshRenderer>()?; - let mesh = import_mesh( - &mut root, - &mut buffer, - smr.mesh_renderer.mesh.load(&mut file, None)?, - )?; - nodes.push(root.push(Node { - mesh: Some(mesh), - ..Default::default() - })); - } - "MeshRenderer" => { - // let mr = ob.parse::<MeshRenderer>()?; - } - x => warn!("unknown component {x:?}"), - } - } - } - root.push(Scene { - extensions: Default::default(), - extras: Default::default(), - name: None, - nodes, - }); - - let json_string = gltf_json::serialize::to_string(&root).expect("Serialization error"); - let mut json_offset = json_string.len(); - align_to_multiple_of_four(&mut json_offset); - let glb = Glb { - header: gltf::binary::Header { - magic: *b"glTF", - version: 2, - length: json_offset as u32, - }, - bin: Some(Cow::Owned(buffer)), - json: Cow::Owned(json_string.into_bytes()), - }; - let writer = std::fs::File::create("/tmp/a.glb").expect("I/O error"); - glb.to_writer(writer).expect("glTF binary output error"); - - Ok(()) -} - -fn align_to_multiple_of_four(n: &mut usize) { - *n = (*n + 3) & !3; -} - -pub fn import_mesh( - root: &mut Root, - buffer: &mut Vec<u8>, - mesh: Mesh, -) -> Result<Index<gltf_json::Mesh>> { - let indicies = mesh.read_indecies(); - let (pdim, positions) = mesh - .vertex_data - .read_channel(VertexDataChannel::Position) - .ok_or(anyhow!("mesh has no positions"))?; - assert_eq!(pdim, 3); - - let positions = { - let buffer_length = positions.len() * size_of::<[f32; 3]>(); - let buffer = root.push(gltf_json::Buffer { - byte_length: USize64::from(buffer_length), - name: None, - uri: None, - extensions: Default::default(), - extras: Default::default(), - }); - let buffer_view = root.push(gltf_json::buffer::View { - buffer, - byte_length: USize64::from(buffer_length), - byte_offset: None, - byte_stride: Some(gltf_json::buffer::Stride(size_of::<[f32; 3]>())), - name: None, - target: Some(Checked::Valid(gltf_json::buffer::Target::ArrayBuffer)), - extensions: Default::default(), - extras: Default::default(), - }); - root.push(Accessor { - buffer_view: Some(buffer_view), - byte_offset: Some(USize64(0)), - count: USize64::from(positions.len()), - component_type: Checked::Valid(GenericComponentType( - gltf_json::accessor::ComponentType::F32, - )), - extensions: Default::default(), - extras: Default::default(), - type_: Checked::Valid(gltf_json::accessor::Type::Vec3), - max: None, - min: None, - name: None, - normalized: false, - sparse: None, - }) - }; - let indices = { - let offset = buffer.len(); - let num_indices = indicies.len(); - buffer.extend(indicies.into_iter().flatten().flat_map(u32::to_le_bytes)); - let buffer_length = num_indices * size_of::<u32>() * 3; - let buffer = root.push(gltf_json::Buffer { - byte_length: USize64::from(buffer_length), - name: None, - uri: None, - extensions: Default::default(), - extras: Default::default(), - }); - let buffer_view = root.push(gltf_json::buffer::View { - buffer, - byte_length: USize64::from(buffer_length), - byte_offset: Some(USize64::from(offset)), - byte_stride: Some(gltf_json::buffer::Stride(size_of::<u32>())), - name: None, - target: Some(Checked::Valid(gltf_json::buffer::Target::ArrayBuffer)), - extensions: Default::default(), - extras: Default::default(), - }); - root.push(Accessor { - buffer_view: Some(buffer_view), - byte_offset: Some(USize64(0)), - count: USize64::from(num_indices * 3), - component_type: Checked::Valid(GenericComponentType( - gltf_json::accessor::ComponentType::U32, - )), - extensions: Default::default(), - extras: Default::default(), - type_: Checked::Valid(gltf_json::accessor::Type::Vec3), - max: None, - min: None, - name: None, - normalized: false, - sparse: None, - }) - }; - - let primitive = Primitive { - attributes: { - let mut map = BTreeMap::new(); - map.insert(Checked::Valid(Semantic::Positions), positions); - map - }, - extensions: Default::default(), - extras: Default::default(), - indices: Some(indices), - material: None, - mode: Checked::Valid(Mode::Triangles), - targets: None, - }; - let mesh = root.push(gltf_json::Mesh { - extensions: Default::default(), - extras: Default::default(), - name: None, - primitives: vec![primitive], - weights: None, - }); - Ok(mesh) -} |