1use scenix_core::Color;
2
3use crate::{
4 AlphaMode, FEATURE_DASHED, FEATURE_WORLD_SPACE, Material, PipelineAlphaMode, PipelineKey,
5 ShaderKind,
6};
7
8#[derive(Clone, Copy, Debug, PartialEq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct LineMaterial {
12 pub color: Color,
14 pub width: f32,
16 pub dash_size: f32,
18 pub gap_size: f32,
20 pub world_units: bool,
22 pub alpha_mode: AlphaMode,
24}
25
26impl LineMaterial {
27 #[inline]
29 pub const fn new() -> Self {
30 Self {
31 color: Color::WHITE,
32 width: 1.0,
33 dash_size: 0.0,
34 gap_size: 0.0,
35 world_units: false,
36 alpha_mode: AlphaMode::Opaque,
37 }
38 }
39
40 #[inline]
42 pub fn dashed(mut self, dash_size: f32, gap_size: f32) -> Self {
43 self.dash_size = dash_size.max(0.0);
44 self.gap_size = gap_size.max(0.0);
45 self
46 }
47}
48
49impl Default for LineMaterial {
50 #[inline]
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56impl Material for LineMaterial {
57 #[inline]
58 fn pipeline_key(&self) -> PipelineKey {
59 let mut bits = 0;
60 if self.dash_size > 0.0 && self.gap_size > 0.0 {
61 bits |= FEATURE_DASHED;
62 }
63 if self.world_units {
64 bits |= FEATURE_WORLD_SPACE;
65 }
66 let alpha = if self.color.a < 1.0 {
67 PipelineAlphaMode::Blend
68 } else {
69 self.alpha_mode.pipeline_alpha()
70 };
71 PipelineKey::new(ShaderKind::Line, alpha, bits)
72 }
73
74 #[inline]
75 fn is_transparent(&self) -> bool {
76 self.alpha_mode.is_transparent() || self.color.a < 1.0
77 }
78
79 #[inline]
80 fn double_sided(&self) -> bool {
81 true
82 }
83
84 #[inline]
85 fn alpha_cutoff(&self) -> Option<f32> {
86 self.alpha_mode.cutoff()
87 }
88}