1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use std::ops::Range;
use super::primitive::Polygonal;
pub struct Generate<'a, G, P>
where
G: 'a,
{
generator: &'a G,
range: Range<usize>,
f: fn(&'a G, usize) -> P,
}
impl<'a, G, P> Generate<'a, G, P>
where
G: 'a,
{
pub(super) fn new(generator: &'a G, range: Range<usize>, f: fn(&'a G, usize) -> P) -> Self {
Generate {
generator: generator,
range: range,
f: f,
}
}
}
impl<'a, G, P> Iterator for Generate<'a, G, P>
where
G: 'a,
{
type Item = P;
fn next(&mut self) -> Option<Self::Item> {
self.range
.next()
.map(|index| (self.f)(self.generator, index))
}
}
pub trait ConjointPointGenerator {
type Output;
fn conjoint_point(&self, index: usize) -> Self::Output;
fn conjoint_point_count(&self) -> usize;
}
pub trait ConjointPoints<P>: Sized {
fn conjoint_points(&self) -> Generate<Self, P>;
}
impl<G, P> ConjointPoints<P> for G
where
G: ConjointPointGenerator<Output = P>,
{
fn conjoint_points(&self) -> Generate<Self, P> {
Generate::new(self, 0..self.conjoint_point_count(), G::conjoint_point)
}
}
pub trait PolygonGenerator {
type Output: Polygonal;
fn polygon(&self, index: usize) -> Self::Output;
fn polygon_count(&self) -> usize;
}
pub trait Polygons<P>: Sized {
fn polygons(&self) -> Generate<Self, P>;
}
impl<G, P> Polygons<P> for G
where
G: PolygonGenerator<Output = P>,
P: Polygonal,
{
fn polygons(&self) -> Generate<Self, P> {
Generate::new(self, 0..self.polygon_count(), G::polygon)
}
}
pub trait IndexPolygonGenerator: ConjointPointGenerator + PolygonGenerator {
type Output: Polygonal;
fn index_polygon(&self, index: usize) -> <Self as IndexPolygonGenerator>::Output;
}
pub trait IndexPolygons<P>: Sized {
fn index_polygons(&self) -> Generate<Self, P>;
}
impl<G, P> IndexPolygons<P> for G
where
G: IndexPolygonGenerator<Output = P> + ConjointPointGenerator + PolygonGenerator,
P: Polygonal,
{
fn index_polygons(&self) -> Generate<Self, P> {
Generate::new(self, 0..self.polygon_count(), G::index_polygon)
}
}
pub trait TexturePolygonGenerator: PolygonGenerator {
type Output: Polygonal;
fn texture_polygon(&self, index: usize) -> <Self as TexturePolygonGenerator>::Output;
}
pub trait TexturePolygons<P>: Sized {
fn texture_polygons(&self) -> Generate<Self, P>;
}
impl<G, P> TexturePolygons<P> for G
where
G: PolygonGenerator + TexturePolygonGenerator<Output = P>,
P: Polygonal,
{
fn texture_polygons(&self) -> Generate<Self, P> {
Generate::new(self, 0..self.polygon_count(), G::texture_polygon)
}
}