1extern crate nalgebra as na;
2mod byte_array_info;
3
4use na::Vector3;
5use byte_array_info::ByteArrayInfo;
6
7fn 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") }
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}