ranim_core/core_item/
vitem.rs1use color::{AlphaColor, Srgb};
2use glam::{Vec3, Vec4};
3
4use crate::{
5 Extract,
6 components::{rgba::Rgba, width::Width},
7 core_item::CoreItem,
8 traits::FillColor,
9};
10
11pub const DEFAULT_STROKE_WIDTH: f32 = 0.02;
13
14pub fn vitem_normal_from_points(points: &[Vec4]) -> Vec3 {
17 if points.len() < 3 {
18 return Vec3::Z;
19 }
20 let p0 = Vec3::new(points[0].x, points[0].y, points[0].z);
21 let p1 = Vec3::new(points[1].x, points[1].y, points[1].z);
22 let p2 = Vec3::new(points[2].x, points[2].y, points[2].z);
23 let n = (p1 - p0).cross(p2 - p0);
24 if n.length_squared() < 1e-6 {
25 Vec3::Z
26 } else {
27 n.normalize()
28 }
29}
30
31#[derive(Debug, Clone, PartialEq)]
32pub struct VItem {
34 pub normal: Option<Vec3>,
37 pub points: Vec<Vec4>,
40 pub fill_rgbas: Vec<Rgba>,
42 pub stroke_rgbas: Vec<Rgba>,
44 pub stroke_widths: Vec<Width>,
46}
47
48impl Default for VItem {
49 fn default() -> Self {
50 Self {
51 normal: None,
52 points: vec![Vec4::ZERO; 3],
53 stroke_widths: vec![Width::default(); 2],
54 stroke_rgbas: vec![Rgba::default(); 2],
55 fill_rgbas: vec![Rgba::default(); 2],
56 }
57 }
58}
59
60impl Extract for VItem {
61 type Target = CoreItem;
62 fn extract_into(&self, buf: &mut Vec<Self::Target>) {
63 buf.push(CoreItem::VItem(self.clone()));
64 }
65}
66
67impl FillColor for VItem {
68 fn fill_color(&self) -> AlphaColor<Srgb> {
69 let Rgba(rgba) = self.fill_rgbas[0];
70 AlphaColor::new([rgba.x, rgba.y, rgba.z, rgba.w])
71 }
72 fn set_fill_color(&mut self, color: AlphaColor<Srgb>) -> &mut Self {
73 self.fill_rgbas.fill(color.into());
74 self
75 }
76 fn set_fill_opacity(&mut self, opacity: f32) -> &mut Self {
77 self.fill_rgbas
78 .iter_mut()
79 .for_each(|rgba| rgba.0.w = opacity);
80 self
81 }
82}