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
use super::{ GenLayer, LayerLCG };
use std::rc::Rc;
use ::nalgebra::{ Vec2, Pnt2 };
use ::gen::unit::GenUnit2;
fn frequent_or_random<T>(rand: &mut LayerLCG, i1: T, i2: T, i3: T, i4: T) -> T where T: PartialEq {
if i2 == i3 && i3 == i4 { i2 }
else if i1 == i2 && i2 == i3 { i1 }
else if i1 == i2 && i2 == i4 { i1 }
else if i1 == i3 && i3 == i4 { i1 }
else if i1 == i2 && i3 != i4 { i1 }
else if i1 == i3 && i2 != i4 { i1 }
else if i1 == i4 && i2 != i3 { i1 }
else if i2 == i3 && i1 != i4 { i2 }
else if i2 == i4 && i1 != i3 { i2 }
else if i3 == i4 && i1 != i2 { i3 }
else { rand.random_from_4(i1, i2, i3, i4) }
}
#[derive(PartialEq, Clone)]
pub enum ZoomType {
MAJORITY,
FUZZY,
}
#[derive(Clone)]
pub struct GenZoom<I> {
source: Rc<GenLayer<I>>,
seed: i64,
zoom_type: ZoomType,
}
impl<I> GenZoom<I> {
pub fn new(seed: i64, zoom_type: ZoomType, source: Rc<GenLayer<I>>
) -> Rc<GenZoom<I>> {
Rc::new(GenZoom {
source: source,
seed: seed,
zoom_type: zoom_type,
})
}
}
impl<I> GenLayer<I> for GenZoom<I> where I: PartialEq + Copy {
fn gen(&self, seed: i64, pos: Pnt2<i32>, size: Vec2<u32>) -> GenUnit2<I> {
let mut lcg = LayerLCG::new(self.seed, seed);
let source_x = pos.x >> 1;
let source_y = pos.y >> 1;
let source_w = (size.x >> 1) + 2;
let source_h = (size.y >> 1) + 2;
let source_buf = self.source.gen(seed,
Pnt2::new(source_x, source_y),
Vec2::new(source_w, source_h));
let sink_unaligned_w = (source_w - 1) << 1;
let sink_unaligned_h = (source_h - 1) << 1;
let unaligned_len = (sink_unaligned_w * sink_unaligned_h) as usize;
let mut sink_unaligned_buf = Vec::with_capacity(unaligned_len);
unsafe { sink_unaligned_buf.set_len(unaligned_len) };
for sink_sample_y in 0..source_h-1 {
let mut sample00 =
source_buf[(0+0 + ((sink_sample_y+0) * source_w)) as usize];
let mut sample01 =
source_buf[(0+0 + ((sink_sample_y+1) * source_w)) as usize];
for sink_sample_x in 0..source_w-1 {
lcg.seed_pos((sink_sample_x as i32 + (source_x << 1)) as i64,
((sink_sample_y as i32 + source_y) << 1) as i64);
let sample10 = source_buf[
(sink_sample_x+1 + ((sink_sample_y+0) * source_w)) as usize];
let sample11 = source_buf[
(sink_sample_x+1 + ((sink_sample_y+1) * source_w)) as usize];
let base_x = sink_sample_x << 1;
let base_y = sink_sample_y << 1;
let base_idx = (sink_unaligned_w * base_y) + base_x;
sink_unaligned_buf[base_idx as usize] = sample00;
sink_unaligned_buf[(base_idx + 1) as usize] =
lcg.random_from_2(sample00, sample10);
sink_unaligned_buf[(base_idx + sink_unaligned_w) as usize] =
lcg.random_from_2(sample00, sample01);
if self.zoom_type == ZoomType::MAJORITY {
sink_unaligned_buf[(base_idx + sink_unaligned_w + 1) as usize] =
frequent_or_random(&mut lcg,
sample00, sample10,
sample01, sample11);
} else if self.zoom_type == ZoomType::FUZZY {
sink_unaligned_buf[(base_idx + sink_unaligned_w + 1) as usize] =
lcg.random_from_4(sample00, sample10,
sample01, sample11);
}
sample00 = sample10;
sample01 = sample11;
}
}
let mut final_buf = Vec::with_capacity((size.x * size.y) as usize);
for row in 0..size.y {
let source_start = (row as i32 + (pos.y & 1)) * sink_unaligned_w as i32 + (pos.x & 1);
let size = size.x;
for col in 0..size {
final_buf.push(sink_unaligned_buf[(source_start + col as i32) as usize])
}
}
GenUnit2::new2_from_vec(size, final_buf)
}
}