ranim_core/core_item/
mesh_item.rs

1use glam::{Mat4, Vec3};
2
3use crate::{
4    Extract,
5    components::rgba::Rgba,
6    core_item::CoreItem,
7    traits::{FillColor, Interpolatable},
8};
9use color::{AlphaColor, Srgb};
10
11/// A primitive for rendering a mesh item.
12#[derive(Debug, Clone, PartialEq)]
13pub struct MeshItem {
14    /// The vertices of the mesh
15    pub points: Vec<Vec3>,
16    /// The triangle indices
17    pub triangle_indices: Vec<u32>,
18    /// The transform matrix
19    pub transform: Mat4,
20    /// Per-vertex colors
21    pub vertex_colors: Vec<Rgba>,
22    /// Per-vertex normals for smooth shading.
23    /// All-zero (or empty) → shader falls back to flat shading via `dpdx`/`dpdy`.
24    pub vertex_normals: Vec<Vec3>,
25}
26
27impl Interpolatable for MeshItem {
28    fn lerp(&self, target: &Self, t: f64) -> Self {
29        Self {
30            points: self.points.lerp(&target.points, t),
31            triangle_indices: if t < 0.5 {
32                self.triangle_indices.clone()
33            } else {
34                target.triangle_indices.clone()
35            },
36            transform: self.transform.lerp(&target.transform, t),
37            vertex_colors: self.vertex_colors.lerp(&target.vertex_colors, t),
38            vertex_normals: self.vertex_normals.lerp(&target.vertex_normals, t),
39        }
40    }
41}
42
43impl Default for MeshItem {
44    fn default() -> Self {
45        Self {
46            points: vec![Vec3::ZERO; 3],
47            triangle_indices: vec![0, 1, 2],
48            transform: Mat4::IDENTITY,
49            vertex_colors: vec![Rgba::default(); 3],
50            vertex_normals: vec![Vec3::ZERO; 3],
51        }
52    }
53}
54
55impl Extract for MeshItem {
56    type Target = CoreItem;
57    fn extract_into(&self, buf: &mut Vec<Self::Target>) {
58        buf.push(CoreItem::MeshItem(self.clone()));
59    }
60}
61
62impl FillColor for MeshItem {
63    fn fill_color(&self) -> AlphaColor<Srgb> {
64        let Rgba(rgba) = self.vertex_colors.first().cloned().unwrap_or_default();
65        AlphaColor::new([rgba.x, rgba.y, rgba.z, rgba.w])
66    }
67
68    fn set_fill_color(&mut self, color: AlphaColor<Srgb>) -> &mut Self {
69        if let Some(x) = self.vertex_colors.first_mut() {
70            *x = color.into();
71        }
72        self
73    }
74
75    fn set_fill_opacity(&mut self, opacity: f32) -> &mut Self {
76        if let Some(x) = self.vertex_colors.first_mut() {
77            x.0.w = opacity;
78        }
79        self
80    }
81}