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
use linalg::lerp;
use film::Colorf;
use texture::{Texture, Image};
pub struct AnimatedImage {
frames: Vec<(f32, Image)>,
}
impl AnimatedImage {
pub fn new(frames: Vec<(f32, Image)>) -> AnimatedImage {
assert!(frames.len() >= 2);
AnimatedImage { frames: frames }
}
pub fn active_keyframes(&self, time: f32) -> (usize, Option<usize>) {
match self.frames.binary_search_by(|&(t, _)| t.partial_cmp(&time).unwrap()) {
Ok(i) => (i, None),
Err(i) => {
if i == self.frames.len() {
(i - 1, None)
} else if i == 0 {
(0, None)
} else {
(i - 1, Some(i))
}
},
}
}
}
impl Texture for AnimatedImage {
fn sample_f32(&self, u: f32, v: f32, time: f32) -> f32 {
match self.active_keyframes(time) {
(lo, None) => self.frames[lo].1.sample_f32(u, v, time),
(lo, Some(hi)) => {
let x = (time - self.frames[lo].0)
/ (self.frames[hi].0 - self.frames[lo].0);
lerp(x, &self.frames[lo].1.sample_f32(u, v, time),
&self.frames[hi].1.sample_f32(u, v, time))
}
}
}
fn sample_color(&self, u: f32, v: f32, time: f32) -> Colorf {
match self.active_keyframes(time) {
(lo, None) => self.frames[lo].1.sample_color(u, v, time),
(lo, Some(hi)) => {
let x = (time - self.frames[lo].0)
/ (self.frames[hi].0 - self.frames[lo].0);
lerp(x, &self.frames[lo].1.sample_color(u, v, time),
&self.frames[hi].1.sample_color(u, v, time))
}
}
}
}