models_cv/gltf/
mod.rs

1extern crate nalgebra as na;
2mod byte_array_info;
3
4use na::Vector3;
5use byte_array_info::ByteArrayInfo;
6
7/**
8 * Returns a Vec<ByteArrayInfo> of position data
9 */
10fn find_position_buffer_data(document: &gltf::Document) -> Vec<ByteArrayInfo> { 
11    document.meshes().map(|mesh| {
12        mesh.primitives().map(|primitive| {
13            primitive.attributes().filter(|attribute| attribute.0 == gltf::Semantic::Positions).map(|attr| {
14                let buffer_view = attr.1.view().expect("Buffer is sparse. This is not implemented");
15                ByteArrayInfo::new (attr.1.data_type(),attr.1.dimensions(), buffer_view.buffer().index(),buffer_view.offset(), buffer_view.length(), buffer_view.stride())
16            })
17        }).flatten()
18    }).flatten().collect()
19}
20
21fn load_position_byte_data(position_buffer_info: Vec<ByteArrayInfo>, buffers: &Vec<gltf::buffer::Data>) -> Vec<&[u8]> {
22    position_buffer_info.into_iter().map(|info| {
23        let byte_end = info.get_byte_offset()+info.get_byte_length();
24        match info.get_byte_stride() {
25            None => &buffers[info.get_buffer_index()].0[info.get_byte_offset()..byte_end],
26            Some(_) => panic!("TODO Strided Position Loading") // After every read, continue for stide - size bytes
27        }
28    }).collect()
29}
30
31fn convert_byte_data_to_vec3(position_byte_data: Vec<&[u8]>) -> Vec<Vec<Vector3<f32>>> {
32    position_byte_data.into_iter().map(|byte_slice| {
33        let vec3_capacity = byte_slice.len() / 12;
34        let mut data_vector = Vec::<Vector3<f32>>::with_capacity(vec3_capacity);
35        for i in 0..vec3_capacity {
36            let x_s = 12*i;
37            let x_f = x_s + 4;
38            let y_s = x_f;
39            let y_f = x_s + 8;
40            let z_s = y_f;
41            let z_f = x_s + 12;
42            let x_raw_arr = byte_slice[x_s..x_f].try_into().expect("X: Could not convert 4 byte slice to array");
43            let y_raw_arr = byte_slice[y_s..y_f].try_into().expect("Y: Could not convert 4 byte slice to array");
44            let z_raw_arr = byte_slice[z_s..z_f].try_into().expect("Z: Could not convert 4 byte slice to array");
45            let x = f32::from_le_bytes(x_raw_arr);
46            let y = f32::from_le_bytes(y_raw_arr);
47            let z = f32::from_le_bytes(z_raw_arr);
48            data_vector.push(Vector3::<f32>::new(x, y, z));
49        }
50        data_vector
51    }).collect()
52}
53
54pub fn load(path: &str) -> (gltf::Document, Vec<gltf::buffer::Data>) {
55    let (document, buffers, _) = gltf::import(path).expect("Could not load gltf file");
56    (document, buffers)
57}
58
59pub fn load_vertex_positions(document: &gltf::Document, buffers: &Vec<gltf::buffer::Data>) -> Vec<Vec<Vector3<f32>>> {
60    let position_buffer_info = find_position_buffer_data(&document);
61    let positions_byte_data = load_position_byte_data(position_buffer_info, &buffers);
62    convert_byte_data_to_vec3(positions_byte_data)
63}
64
65pub fn load_mesh_names(document: &gltf::Document) -> Vec<String> {
66    document.meshes().into_iter().map(|m| m.name().expect("no name for mesh").to_string()).collect::<Vec<String>>()
67}