gltforge_unity/
unity_gltf.rs1use crate::{
2 convert, unity_image::UnityImage, unity_mesh::UnityMesh, unity_node::UnityNode,
3 unity_pbr_metallic_roughness::UnityPbrMetallicRoughness,
4};
5
6use std::{collections::HashMap, ffi::CStr, os::raw::c_char, path::Path, sync::Arc};
7
8pub struct UnityGltf {
11 pub scene_name: String,
14
15 pub root_nodes: Vec<u32>,
17
18 pub nodes: HashMap<u32, UnityNode>,
20
21 pub meshes: HashMap<u32, UnityMesh>,
24
25 pub images: HashMap<u32, UnityImage>,
27
28 pub pbr_metallic_roughness: HashMap<u32, UnityPbrMetallicRoughness>,
30}
31
32#[unsafe(no_mangle)]
37pub unsafe extern "C" fn gltforge_retain(ptr: *const UnityGltf) {
38 if !ptr.is_null() {
39 unsafe { Arc::increment_strong_count(ptr) };
40 }
41}
42
43#[unsafe(no_mangle)]
49pub unsafe extern "C" fn gltforge_release(ptr: *const UnityGltf) {
50 if !ptr.is_null() {
51 unsafe { drop(Arc::from_raw(ptr)) };
52 }
53}
54
55#[unsafe(no_mangle)]
63pub unsafe extern "C" fn gltforge_load(path: *const c_char) -> *const UnityGltf {
64 let result = std::panic::catch_unwind(|| {
65 let path_str = unsafe { CStr::from_ptr(path) }.to_str().ok()?;
66 let path = Path::new(path_str);
67 let base_dir = path.parent()?;
68
69 let file_stem = path
70 .file_stem()
71 .and_then(|s| s.to_str())
72 .unwrap_or("unknown");
73
74 let json = std::fs::read_to_string(path).ok()?;
75 let gltf = gltforge::parser::parse(&json).ok()?;
76 let buffers = gltforge::parser::load_buffers(&gltf, base_dir).ok()?;
77 let unity_gltf = convert::build_unity_gltf(&gltf, &buffers, file_stem).ok()?;
78
79 Some(Arc::into_raw(Arc::new(unity_gltf)))
80 });
81
82 result.ok().flatten().unwrap_or(std::ptr::null())
83}