gltforge_unity/
unity_gltf.rs1use crate::convert;
2use gltforge_unity_core::{UnityGameObject, UnityImage, UnityMesh, UnityPbrMetallicRoughness};
3
4use std::{collections::HashMap, ffi::CStr, os::raw::c_char, path::Path, sync::Arc};
5
6pub struct UnityGltf {
9 pub scene_name: String,
12
13 pub root_game_objects: Vec<u32>,
15
16 pub game_objects: HashMap<u32, UnityGameObject>,
18
19 pub meshes: HashMap<u32, UnityMesh>,
22
23 pub images: HashMap<u32, UnityImage>,
25
26 pub pbr_metallic_roughness: HashMap<u32, UnityPbrMetallicRoughness>,
28}
29
30#[unsafe(no_mangle)]
35pub unsafe extern "C" fn gltforge_retain(ptr: *const UnityGltf) {
36 if !ptr.is_null() {
37 unsafe { Arc::increment_strong_count(ptr) };
38 }
39}
40
41#[unsafe(no_mangle)]
47pub unsafe extern "C" fn gltforge_release(ptr: *const UnityGltf) {
48 if !ptr.is_null() {
49 unsafe { drop(Arc::from_raw(ptr)) };
50 }
51}
52
53#[unsafe(no_mangle)]
61pub unsafe extern "C" fn gltforge_load(path: *const c_char) -> *const UnityGltf {
62 let result = std::panic::catch_unwind(|| {
63 let path_str = unsafe { CStr::from_ptr(path) }.to_str().ok()?;
64 let path = Path::new(path_str);
65 let base_dir = path.parent()?;
66
67 let file_stem = path
68 .file_stem()
69 .and_then(|s| s.to_str())
70 .unwrap_or("unknown");
71
72 let data = std::fs::read(path).ok()?;
73 let (gltf, buffers) = if data.starts_with(b"glTF") {
74 gltforge::parser::parse_glb(&data).ok()?
75 } else {
76 let json = std::str::from_utf8(&data).ok()?;
77 let gltf = gltforge::parser::parse(json).ok()?;
78 let buffers = gltforge::parser::load_buffers(&gltf, base_dir).ok()?;
79 (gltf, buffers)
80 };
81 let unity_gltf = convert::build_unity_gltf(&gltf, &buffers, file_stem).ok()?;
82
83 Some(Arc::into_raw(Arc::new(unity_gltf)))
84 });
85
86 result.ok().flatten().unwrap_or(std::ptr::null())
87}