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
127
128
129
130
131
use vecmath::{
Vector3,
Matrix4,
vec3_normalized_sub,
vec3_cross,
vec3_dot,
};
use vecmath::col_mat4_mul as mul;
use vecmath::traits::*;
use quaternion::{Quaternion, rotate_vector};
pub fn model_view_projection<T: Float + Copy>(
model: Matrix4<T>,
view: Matrix4<T>,
projection: Matrix4<T>
) -> Matrix4<T> {
mul(mul(projection, view), model)
}
pub struct Camera<T=f32> {
pub position: Vector3<T>,
pub up: Vector3<T>,
pub right: Vector3<T>,
pub forward: Vector3<T>
}
pub struct CameraPerspective<T=f32> {
pub fov: T,
pub near_clip: T,
pub far_clip: T,
pub aspect_ratio: T,
}
impl<T: Float + Copy> Camera<T> {
pub fn new(position: Vector3<T>) -> Camera<T> {
let _0 = Zero::zero();
let _1 = One::one();
Camera {
position: position,
right: [_1, _0, _0],
up: [_0, _1, _0],
forward: [_0, _0, _1]
}
}
pub fn orthogonal(&self) -> Matrix4<T> {
let p = self.position;
let r = self.right;
let u = self.up;
let f = self.forward;
let _0 = Zero::zero();
[
[r[0], u[0], f[0], _0],
[r[1], u[1], f[1], _0],
[r[2], u[2], f[2], _0],
[-vec3_dot(r, p), -vec3_dot(u, p), -vec3_dot(f, p), One::one()]
]
}
pub fn look_at(&mut self, point: Vector3<T>) {
self.forward = vec3_normalized_sub(self.position, point);
self.update_right();
}
pub fn set_yaw_pitch(&mut self, yaw: T, pitch: T) {
let (y_s, y_c, p_s, p_c) = (yaw.sin(), yaw.cos(), pitch.sin(), pitch.cos());
self.forward = [y_s * p_c, p_s, y_c * p_c];
self.up = [y_s * -p_s, p_c, y_c * -p_s];
self.update_right();
}
pub fn set_rotation(&mut self, rotation: Quaternion<T>)
{
let _0: T = Zero::zero();
let _1: T = One::one();
let forward: Vector3<T> = [_0, _0, _1];
let up: Vector3<T> = [_0, _1, _0];
self.forward = rotate_vector(rotation, forward);
self.up = rotate_vector(rotation, up);
self.update_right();
}
fn update_right(&mut self) {
self.right = vec3_cross(self.up, self.forward);
}
}
impl<T: Float> CameraPerspective<T>
where f64: Cast<T>
{
pub fn projection(&self) -> Matrix4<T> {
let _0: T = Zero::zero();
let _1: T = One::one();
let _2: T = _1 + _1;
let pi: T = Radians::_180();
let _360: T = Cast::cast(360.0f64);
let f = _1 / (self.fov * (pi / _360)).tan();
let (far, near) = (self.far_clip, self.near_clip);
[
[f / self.aspect_ratio, _0, _0, _0],
[_0, f, _0, _0],
[_0, _0, (far + near) / (near - far), -_1],
[_0, _0, (_2 * far * near) / (near - far), _0]
]
}
}