mesh-loader 0.0.1

Fast parser for 3D-model-formats.
Documentation
use super::*;
use crate::common;

pub(crate) fn build_meshes(doc: &Document) -> Vec<common::Mesh> {
    let mut meshes = Vec::with_capacity(doc.library_geometries.geometries.len());

    for mesh_ref in doc.meshes() {
        let mut mesh = common::Mesh {
            name: mesh_ref.xml.id.clone(),
            ..common::Mesh::default()
        };

        for prim in mesh_ref.primitives() {
            let prev_positions_len = mesh.vertices.len() as u32;
            let p: Vec<_> = prim.positions().collect();
            let n: Vec<_> = prim.normals().collect();
            let t: Vec<_> = prim.texcoords(0).collect();
            let positions_idx = prim.vertex_indices();
            let mut normal_idx = prim.normal_indices();
            let mut texcoord_idx = prim.texcoord_indices(0);
            let mut idx = 0;

            for i in positions_idx {
                if let iter::Face::Triangle(vertex) = i {
                    mesh.vertices.push([
                        p[vertex[0] as usize][0],
                        p[vertex[0] as usize][1],
                        p[vertex[0] as usize][2],
                    ]);
                    mesh.vertices.push([
                        p[vertex[1] as usize][0],
                        p[vertex[1] as usize][1],
                        p[vertex[1] as usize][2],
                    ]);
                    mesh.vertices.push([
                        p[vertex[2] as usize][0],
                        p[vertex[2] as usize][1],
                        p[vertex[2] as usize][2],
                    ]);
                    if !n.is_empty() {
                        if let Some(iter::Face::Triangle(normal)) = normal_idx.next() {
                            mesh.normals.push([
                                n[normal[0] as usize][0],
                                n[normal[0] as usize][1],
                                n[normal[0] as usize][2],
                            ]);
                            mesh.normals.push([
                                n[normal[1] as usize][0],
                                n[normal[1] as usize][1],
                                n[normal[1] as usize][2],
                            ]);
                            mesh.normals.push([
                                n[normal[2] as usize][0],
                                n[normal[2] as usize][1],
                                n[normal[2] as usize][2],
                            ]);
                        } else {
                            panic!()
                        }
                    }
                    if !t.is_empty() {
                        if let Some(iter::Face::Triangle(texcoord)) = texcoord_idx.next() {
                            mesh.texcoords[0]
                                .push([t[texcoord[0] as usize][0], t[texcoord[0] as usize][1]]);
                            mesh.texcoords[0]
                                .push([t[texcoord[1] as usize][0], t[texcoord[1] as usize][1]]);
                            mesh.texcoords[0]
                                .push([t[texcoord[2] as usize][0], t[texcoord[2] as usize][1]]);
                        } else {
                            panic!()
                        }
                    }
                    mesh.faces.push([
                        prev_positions_len + idx,
                        prev_positions_len + (idx + 1),
                        prev_positions_len + (idx + 2),
                    ]);
                    idx += 3;
                }
            }
        }

        meshes.push(mesh);
    }

    meshes
}