Skip to main content

mesh_graph/integrations/
mod.rs

1use std::iter::repeat_n;
2
3use glam::Vec3;
4use hashbrown::HashMap;
5use slotmap::SecondaryMap;
6use tracing::{error, instrument};
7
8use crate::{MeshGraph, VertexId};
9
10#[cfg(feature = "bevy")]
11pub mod bevy;
12#[cfg(feature = "gltf")]
13pub mod gltf;
14
15/// Classical indexed mesh representation
16#[derive(Clone, Debug)]
17pub struct VertexIndexBuffers<T = ()> {
18    /// Vertex positions, one per vertex.
19    pub positions: Vec<Vec3>,
20    /// Vertex normals, one per vertex.
21    pub normals: Vec<Vec3>,
22    /// Indices: 3*N where N is the number of triangles. Indices point to
23    /// elements of `positions` and `normals`.
24    pub indices: Vec<u32>,
25    /// Potential custom vertex attribute(s)
26    pub custom_vertex_attribute: Vec<T>,
27}
28
29impl<T> VertexIndexBuffers<T>
30where
31    T: Clone + Default,
32{
33    pub fn with_attr_from_map(mesh_graph: &MeshGraph, attr: &HashMap<VertexId, T>) -> Self {
34        let (positions, normals, indices, vertex_id_to_index) =
35            Self::attrs_from_mesh_graph(mesh_graph);
36
37        let mut custom_vertex_attribute =
38            repeat_n(T::default(), positions.len()).collect::<Vec<T>>();
39
40        for (vertex_id, value) in attr {
41            if let Some(index) = vertex_id_to_index.get(*vertex_id) {
42                custom_vertex_attribute[*index as usize] = value.clone();
43            }
44        }
45
46        Self {
47            positions,
48            normals,
49            indices,
50            custom_vertex_attribute,
51        }
52    }
53
54    fn attrs_from_mesh_graph(
55        mesh_graph: &MeshGraph,
56    ) -> (Vec<Vec3>, Vec<Vec3>, Vec<u32>, SecondaryMap<VertexId, u32>) {
57        let mut vertex_id_to_index = SecondaryMap::default();
58
59        let mut positions = vec![];
60        let mut normals = vec![];
61        let mut indices = vec![];
62
63        for (vertex_id, pos) in &mesh_graph.positions {
64            vertex_id_to_index.insert(vertex_id, positions.len() as u32);
65            positions.push(*pos);
66
67            if let Some(vertex_normals) = mesh_graph.vertex_normals.as_ref() {
68                normals.push(vertex_normals.get(vertex_id).copied().unwrap_or_else(|| {
69                    error!("Normal not found");
70                    Vec3::ZERO
71                }));
72            }
73        }
74
75        'outer: for face in mesh_graph.faces.values() {
76            let mut face_indices = Vec::with_capacity(3);
77
78            for vertex in face.vertices(mesh_graph) {
79                let Some(&index) = vertex_id_to_index.get(vertex) else {
80                    error!("Vertex {vertex:?} not found in mapped vertices");
81                    continue 'outer;
82                };
83                face_indices.push(index);
84            }
85
86            indices.extend(face_indices);
87        }
88
89        (positions, normals, indices, vertex_id_to_index)
90    }
91}
92
93impl From<&MeshGraph> for VertexIndexBuffers {
94    #[instrument(skip(mesh_graph))]
95    fn from(mesh_graph: &MeshGraph) -> VertexIndexBuffers {
96        let (positions, normals, indices, _) = Self::attrs_from_mesh_graph(mesh_graph);
97
98        VertexIndexBuffers {
99            indices,
100            positions,
101            normals,
102            custom_vertex_attribute: vec![],
103        }
104    }
105}