ranim_core/core_item/
vitem.rs1use color::{AlphaColor, Srgb};
2use glam::{DVec3, 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
14#[derive(Debug, Clone, Copy, PartialEq, ranim_macros::Interpolatable)]
16pub struct Basis2d {
17 u: DVec3,
19 v: DVec3,
21}
22
23impl Default for Basis2d {
24 fn default() -> Self {
25 Self::XY
26 }
27}
28
29impl Basis2d {
30 pub const XY: Self = Self {
32 u: DVec3::X,
33 v: DVec3::Y,
34 };
35 pub const XZ: Self = Self {
37 u: DVec3::X,
38 v: DVec3::Z,
39 };
40 pub const YZ: Self = Self {
42 u: DVec3::Y,
43 v: DVec3::Z,
44 };
45 pub fn new(u: DVec3, v: DVec3) -> Self {
47 Self {
48 u: u.normalize(),
49 v: v.normalize(),
50 }
51 }
52
53 pub fn u(&self) -> DVec3 {
55 self.u.normalize()
56 }
57 pub fn v(&self) -> DVec3 {
59 self.v.normalize()
60 }
61 pub fn uv(&self) -> (DVec3, DVec3) {
63 (self.u(), self.v())
64 }
65 pub fn corrected_u(&self) -> DVec3 {
68 self.u.normalize()
69 }
70 pub fn corrected_v(&self) -> DVec3 {
73 let normal = self.u.cross(self.v);
74 normal.cross(self.u).normalize()
75 }
76 pub fn corrected_uv(&self) -> (DVec3, DVec3) {
79 (self.corrected_u(), self.corrected_v())
80 }
81 #[inline]
83 pub fn normal(&self) -> DVec3 {
84 self.u.cross(self.v).normalize()
85 }
86 pub fn rotate_on_axis(&mut self, axis: DVec3, angle: f64) {
88 self.u = DVec3::rotate_axis(self.u, axis, angle).normalize();
89 self.v = DVec3::rotate_axis(self.v, axis, angle).normalize();
90 }
91}
92
93#[derive(Debug, Clone, PartialEq)]
94pub struct VItem {
96 pub origin: Vec3,
98 pub basis: Basis2d,
100 pub points: Vec<Vec4>,
103 pub fill_rgbas: Vec<Rgba>,
105 pub stroke_rgbas: Vec<Rgba>,
107 pub stroke_widths: Vec<Width>,
109}
110
111impl Default for VItem {
112 fn default() -> Self {
113 Self {
114 origin: Vec3::ZERO,
115 basis: Basis2d::default(),
116 points: vec![Vec4::ZERO; 3],
117 stroke_widths: vec![Width::default(); 2],
118 stroke_rgbas: vec![Rgba::default(); 2],
119 fill_rgbas: vec![Rgba::default(); 2],
120 }
121 }
122}
123
124impl Extract for VItem {
125 type Target = CoreItem;
126 fn extract_into(&self, buf: &mut Vec<Self::Target>) {
127 buf.push(CoreItem::VItem(self.clone()));
128 }
129}
130
131impl FillColor for VItem {
132 fn fill_color(&self) -> AlphaColor<Srgb> {
133 let Rgba(rgba) = self.fill_rgbas[0];
134 AlphaColor::new([rgba.x, rgba.y, rgba.z, rgba.w])
135 }
136 fn set_fill_color(&mut self, color: AlphaColor<Srgb>) -> &mut Self {
137 self.fill_rgbas.fill(color.into());
138 self
139 }
140 fn set_fill_opacity(&mut self, opacity: f32) -> &mut Self {
141 self.fill_rgbas
142 .iter_mut()
143 .for_each(|rgba| rgba.0.w = opacity);
144 self
145 }
146}