bevy_points/
mesh.rs

1use bevy::{
2    color::{ColorToComponents, Srgba},
3    prelude::{Color, Mesh, Vec3},
4    render::{
5        mesh::{Indices, VertexAttributeValues},
6        render_asset::RenderAssetUsages,
7        render_resource::PrimitiveTopology,
8    },
9};
10
11#[derive(Default)]
12pub struct PointsMesh {
13    pub vertices: Vec<Vec3>,
14    pub colors: Option<Vec<Color>>,
15}
16
17impl FromIterator<Vec3> for PointsMesh {
18    fn from_iter<T: IntoIterator<Item = Vec3>>(iter: T) -> Self {
19        Self {
20            vertices: iter.into_iter().collect(),
21            ..Default::default()
22        }
23    }
24}
25
26impl From<Mesh> for PointsMesh {
27    fn from(m: Mesh) -> Self {
28        if let Some(VertexAttributeValues::Float32x3(arr)) = m.attribute(Mesh::ATTRIBUTE_POSITION) {
29            let mut p = PointsMesh {
30                vertices: arr.iter().map(|item| Vec3::from_array(*item)).collect(),
31                ..Default::default()
32            };
33            if let Some(VertexAttributeValues::Float32x4(array)) =
34                m.attribute(Mesh::ATTRIBUTE_COLOR)
35            {
36                p.colors = Some(
37                    array
38                        .iter()
39                        .map(|item| Srgba::from_f32_array(*item).into())
40                        .collect(),
41                );
42            }
43            return p;
44        }
45        Self::default()
46    }
47}
48
49impl From<PointsMesh> for Mesh {
50    fn from(m: PointsMesh) -> Self {
51        let vertices: Vec<[f32; 3]> = m
52            .vertices
53            .iter()
54            .flat_map(|p| {
55                let arr = p.to_array();
56                [arr, arr, arr, arr]
57            })
58            .collect();
59        let uv_set = [[0., 0.], [1., 0.], [1., 1.], [0., 1.]];
60        let uvs: Vec<[f32; 2]> = m.vertices.iter().flat_map(|_| uv_set).collect();
61        let indices = Indices::U32(
62            m.vertices
63                .iter()
64                .enumerate()
65                .flat_map(|(i, _)| {
66                    let idx = (i * 4) as u32;
67                    [idx, idx + 1, idx + 3, idx + 2, idx + 3, idx + 1]
68                })
69                .collect(),
70        );
71        let mut mesh = Mesh::new(
72            PrimitiveTopology::TriangleList,
73            RenderAssetUsages::default(),
74        );
75        mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, vertices);
76        mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
77        if let Some(color) = m.colors {
78            mesh.insert_attribute(
79                Mesh::ATTRIBUTE_COLOR,
80                color
81                    .iter()
82                    .flat_map(|c| {
83                        let arr = c.to_srgba().to_f32_array();
84                        [arr, arr, arr, arr]
85                    })
86                    .collect::<Vec<[f32; 4]>>(),
87            );
88        }
89        mesh.insert_indices(indices);
90        mesh
91    }
92}