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
use std::ops::{Add, Mul};
use film::Colorf;
pub use self::image::Image;
pub use self::animated_image::AnimatedImage;
pub mod image;
pub mod animated_image;
pub trait Texture {
fn sample_f32(&self, u: f32, v: f32, time: f32) -> f32;
fn sample_color(&self, u: f32, v: f32, time: f32) -> Colorf;
}
fn bilinear_interpolate<T, F>(x: f32, y: f32, get: F) -> T
where T: Copy + Add<T, Output=T> + Mul<f32, Output=T>,
F: Fn(u32, u32) -> T
{
let p00 = (x as u32, y as u32);
let p10 = (p00.0 + 1, p00.1);
let p01 = (p00.0, p00.1 + 1);
let p11 = (p00.0 + 1, p00.1 + 1);
let s00 = get(p00.0, p00.1);
let s10 = get(p10.0, p10.1);
let s01 = get(p01.0, p01.1);
let s11 = get(p11.0, p11.1);
let sx = x - p00.0 as f32;
let sy = y - p00.1 as f32;
s00 * (1.0 - sx) * (1.0 - sy) + s10 * sx * (1.0 - sy)
+ s01 * (1.0 - sx) * sy + s11 * sx * sy
}
pub struct ConstantScalar {
val: f32,
}
impl ConstantScalar {
pub fn new(val: f32) -> ConstantScalar {
ConstantScalar { val: val }
}
}
impl Texture for ConstantScalar {
fn sample_f32(&self, _: f32, _: f32, _: f32) -> f32 {
self.val
}
fn sample_color(&self, _: f32, _: f32, _: f32) -> Colorf {
Colorf::broadcast(self.val)
}
}
pub struct ConstantColor {
val: Colorf,
}
impl ConstantColor {
pub fn new(val: Colorf) -> ConstantColor {
ConstantColor { val: val }
}
}
impl Texture for ConstantColor {
fn sample_f32(&self, _: f32, _: f32, _: f32) -> f32 {
self.val.luminance()
}
fn sample_color(&self, _: f32, _: f32, _: f32) -> Colorf {
self.val
}
}
pub struct UVColor;
impl Texture for UVColor {
fn sample_f32(&self, u: f32, v: f32, _: f32) -> f32 {
Colorf::new(u, v, 0.0).luminance()
}
fn sample_color(&self, u: f32, v: f32, _: f32) -> Colorf {
Colorf::new(u, v, 0.0)
}
}