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}