mesh_graph/integrations/
mod.rs1use 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#[derive(Clone, Debug)]
17pub struct VertexIndexBuffers<T = ()> {
18 pub positions: Vec<Vec3>,
20 pub normals: Vec<Vec3>,
22 pub indices: Vec<u32>,
25 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}