mcube/
iter.rs

1use std::ops::*;
2use std::cmp::*;
3use cgmath::num_traits;
4use cgmath::num_traits::{one, zero};
5pub struct Enumerate3D<T>
6where
7    T: AddAssign + Copy + num_traits::One + num_traits::Zero + Ord
8{
9    size: T,
10    from: T,
11    current: Option<(T,T,T)>
12}
13impl<T> Enumerate3D<T>
14where 
15    T: AddAssign + Copy + num_traits::One + num_traits::Zero + Ord
16{
17    pub fn start_from_to(from: T, to: T) -> Enumerate3D<T> {
18        Enumerate3D{
19            size: to,from,
20            current: Some((from, from, from))
21        }
22    }
23    pub fn from_zero_to(size: T) -> Enumerate3D<T> {
24        Enumerate3D{
25            size,
26            from: zero(),
27            current: Some((zero(),zero(),zero()))
28        }
29    }
30    fn incr(&mut self) {
31        let current = self.current.as_mut().unwrap();
32        current.0+=one();
33        if current.0 >= self.size
34        {
35            current.0=self.from;
36            current.1+=one();
37            if current.1 >= self.size
38            {
39                current.1=self.from;
40                current.2+=one();
41                if current.2 >= self.size
42                {
43                    self.current=None;
44                }
45            }
46        }
47    }
48}
49impl<T> std::iter::Iterator for Enumerate3D<T>
50where 
51    T: AddAssign + Copy + num_traits::One + num_traits::Zero + Ord
52{
53    type Item = (T,T,T);
54    fn next(&mut self) -> Option<Self::Item>
55    {
56        let new = self.current.clone();
57        match new {
58            Some(_) => {
59                self.incr();
60                new
61            },
62            None => None
63        }
64    }
65}
66pub struct Enumerate3DValued<T>
67    where T: Iterator
68{
69    it: T,
70    size: usize,
71    current: (usize,usize,usize)
72    
73}
74impl<T> Enumerate3DValued<T>
75    where T: Iterator
76{
77    pub fn new(it: T, size: usize) -> Enumerate3DValued<T> {
78        Enumerate3DValued{
79            it,size,
80            current: (0,0,0)
81        }
82    }
83    fn incr(&mut self) {
84        self.current.0+=1;
85        if self.current.0 > self.size
86        {
87            self.current.0=0;
88            self.current.1+=1;
89            if self.current.1 > self.size
90            {
91                self.current.1=0;
92                self.current.2+=1
93            }
94        }
95    }
96}
97impl<T> std::iter::Iterator for Enumerate3DValued<T>
98    where T:Iterator
99{
100    type Item = ((usize,usize,usize), <T as Iterator>::Item);
101    fn next(&mut self) -> Option<Self::Item>
102    {
103        let result = match self.it.next() {
104            Some(v) => Some((self.current,v)),
105            None => None
106        };
107        self.incr();
108        result
109    }
110}
111
112use cgmath::{Vector4, Vector3, Point3, Matrix4};
113#[derive(Clone)]
114pub struct EnumMatrixData {
115    position: Point3<f32>,
116    id: Point3<usize>
117}
118pub struct EnumerateMatrix {
119    origin: Point3<f32>,
120    advance: [Vector3<f32>; 3],
121    size: usize,
122    current_data: Option<EnumMatrixData>,
123}
124impl EnumMatrixData {
125    pub fn get_position(&self) -> Point3<f32> {
126        self.position.clone()
127    }
128    pub fn get_id(&self) -> Point3<usize> {
129        self.id.clone()
130    }
131}
132impl EnumerateMatrix {
133    pub fn new(origin: Point3<f32>, modelmat: Matrix4<f32>, size: usize) -> EnumerateMatrix {
134        EnumerateMatrix{
135            origin,
136            advance: [
137                (modelmat * Vector4::unit_x()).truncate(),
138                (modelmat * Vector4::unit_y()).truncate(),
139                (modelmat * Vector4::unit_z()).truncate()
140            ],
141            size,
142            current_data: Some(EnumMatrixData{position: origin, id: Point3::new(0,0,0)}),
143        }
144    }
145    fn incr(&mut self) {
146        let mut is_none=false;
147        if let Some(data) = &mut self.current_data {
148            for i in 0..3 {
149                data.position+=self.advance[i];
150                data.id[i]+=1;
151                if data.id[i] < self.size{
152                    break;
153                }
154                if i==2 {
155                    is_none=true;
156                    break;
157                }
158                data.position-=self.advance[i]*(self.size as f32);
159                data.id[i]=0;
160            }
161        }
162        if is_none {
163            self.current_data = None;
164        }
165    }
166    fn reset(&mut self) {
167        self.current_data = Some(EnumMatrixData{position: self.origin, id: Point3::new(0,0,0)})
168    }
169    pub fn total(&self) -> usize {
170        self.size*self.size*self.size
171    }
172}
173impl std::iter::Iterator for EnumerateMatrix {
174    type Item = EnumMatrixData;
175    fn next(&mut self) -> Option<Self::Item> {
176        let result = self.current_data.clone();
177        self.incr();
178        result
179    }
180}