Skip to main content

rscad_core/transformations/
pattern.rs

1use crate::prelude_::*;
2
3#[derive(Debug, Clone, Copy, PartialEq)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5#[cfg_attr(feature = "reflect", derive(bevy_reflect::Reflect))]
6pub struct Pattern<T: Object + Clone, const N: usize> {
7    pub object: T,
8    pub pattern_type: PatternType,
9}
10
11#[derive(Debug, Clone, Copy, PartialEq)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13#[cfg_attr(feature = "reflect", derive(bevy_reflect::Reflect))]
14pub struct PatternRuntime<T: Object + Clone> {
15    pub times: usize,
16    pub object: T,
17    pub pattern_type: PatternType,
18}
19
20impl<T: Object + Clone, const N: usize> Pattern<T, N> {
21    pub fn new(object: T, pattern_type: PatternType) -> Self {
22        Self {
23            object,
24            pattern_type,
25        }
26    }
27}
28
29#[derive(Debug, Clone, Copy, PartialEq)]
30#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31#[cfg_attr(feature = "reflect", derive(bevy_reflect::Reflect))]
32pub enum PatternType {
33    Circular(PatternCircular),
34    Linear(PatternLinear),
35}
36
37impl PatternType {
38    pub fn translation(&self) -> DVec3 {
39        match self {
40            PatternType::Circular(_) => DVec3::ZERO,
41            PatternType::Linear(pattern) => pattern.translation(),
42        }
43    }
44}
45
46#[derive(Debug, Clone, Copy, PartialEq)]
47#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
48#[cfg_attr(feature = "reflect", derive(bevy_reflect::Reflect))]
49pub struct PatternCircular {
50    axis: DVec3,
51}
52
53#[derive(Debug, Clone, Copy, PartialEq)]
54#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
55#[cfg_attr(feature = "reflect", derive(bevy_reflect::Reflect))]
56pub struct PatternLinear {
57    offset: f64,
58    direction: DVec3,
59}
60
61impl PatternLinear {
62    pub fn translation(&self) -> DVec3 {
63        self.direction * self.offset
64    }
65}
66
67pub trait LinearPatternObject: Object + Clone {
68    fn repeat<const N: usize>(self, offset: impl Number, direction: DVec3) -> Pattern<Self, N>
69    where
70        Self: Sized,
71    {
72        Pattern::new(
73            self,
74            PatternType::Linear(PatternLinear {
75                offset: offset.to_f64(),
76                direction: direction.normalize_or_zero(),
77            }),
78        )
79    }
80
81    fn repeated(self, offset: impl Number, direction: DVec3, times: usize) -> PatternRuntime<Self>
82    where
83        Self: Sized,
84    {
85        PatternRuntime {
86            times,
87            object: self,
88            pattern_type: PatternType::Linear(PatternLinear {
89                offset: offset.to_f64(),
90                direction: direction.normalize_or_zero(),
91            }),
92        }
93    }
94}
95
96impl<T: Object + Clone> LinearPatternObject for T {}
97
98impl<T: Object + Clone, const N: usize> Object for Pattern<T, N> {}
99impl<T: Object + Clone> Object for PatternRuntime<T> {}