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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
use Screen;
use {Matrix4, Vector3, Unit};
impl<'a> Screen<'a> {
/// Pre-multiply the current MVP transformation matrix with a matrix formed
/// from the given values.
pub fn apply_matrix(
&mut self,
n00: f32,
n01: f32,
n02: f32,
n03: f32,
n10: f32,
n11: f32,
n12: f32,
n13: f32,
n20: f32,
n21: f32,
n22: f32,
n23: f32,
n30: f32,
n31: f32,
n32: f32,
n33: f32,
) {
let m = Matrix4::new(
n00,
n01,
n02,
n03,
n10,
n11,
n12,
n13,
n20,
n21,
n22,
n23,
n30,
n31,
n32,
n33,
);
self.matrices.curr_matrix = m * self.matrices.curr_matrix;
}
/// Remove the current MVP transformation matrix from the stack and use the most
/// recently used one instead.
pub fn pop_matrix(&mut self) {
match self.matrices.matrix_stack.pop() {
Some(m) => self.matrices.curr_matrix = m,
None => {
self.matrices.curr_matrix = Matrix4::identity();
}
};
}
/// Push the current MVP transformation matrix onto the stack, so that it can be
/// saved for later. Useful for when you want to temporarily apply some rotation
/// or translation to a single object and don't want to disturb the rest of the
/// scene.
pub fn push_matrix(&mut self) {
self.matrices.matrix_stack.push(self.matrices.curr_matrix);
}
/// Remove the current MVP transfomation matrix and set it to the standard 4x4
/// identity matrix.
pub fn reset_matrix(&mut self) {
self.matrices.curr_matrix = Matrix4::identity();
}
/// Pre-multiply the current MVP transformation matrix by a rotation matrix which
/// is derived from a rotation angle about a vector in the direction (x, y, z).
pub fn rotate(&mut self, angle: f32, x: f32, y: f32, z: f32) {
// let m = Matrix4::new(
// angle.cos(),
// -angle.sin(),
// 0.,
// 0.,
// angle.sin(),
// angle.cos(),
// 0.,
// 0.,
// 0.,
// 0.,
// 1.,
// 0.,
// 0.,
// 0.,
// 0.,
// 1.,
// );
let m = Matrix4::from_axis_angle(&Unit::new_unchecked(Vector3::new(x, y, z)), angle);
self.matrices.curr_matrix = m * self.matrices.curr_matrix;
}
/// Apply a rotation matrix for a given angle around the x-axis to the current MVP
/// transformation matrix.
pub fn rotate_x(&mut self, angle: f32) {
let m = Matrix4::from_axis_angle(&Unit::new_unchecked(Vector3::new(1., 0., 0.)), angle);
self.matrices.curr_matrix = m * self.matrices.curr_matrix;
}
/// Apply a rotation matrix for a given angle around the y-axis to the current MVP
/// transformation matrix.
pub fn rotate_y(&mut self, angle: f32) {
let m = Matrix4::from_axis_angle(&Unit::new_unchecked(Vector3::new(0., 1., 0.)), angle);
self.matrices.curr_matrix = m * self.matrices.curr_matrix;
}
/// Apply a rotation matrix for a given angle around the z-axis to the current MVP
/// transformation matrix.
pub fn rotate_z(&mut self, angle: f32) {
let m = Matrix4::from_axis_angle(&Unit::new_unchecked(Vector3::new(0., 0., 1.)), angle);
self.matrices.curr_matrix = m * self.matrices.curr_matrix;
}
/// Scale the scene along the x-, y-, and z-axes by applying a matrix derived from
/// these values to the current MVP transformation matrix.
pub fn scale(&mut self, x: f32, y: f32, z: f32) {
// let m = Matrix4::new(x, 0., 0., 0., 0., y, 0., 0., 0., 0., z, 0., 0., 0., 0., 1.);
self.matrices.curr_matrix.append_nonuniform_scaling(
&Vector3::new(x, y, z),
); //* self.matrices.curr_matrix;
}
/// Derive a matrix that applies shear for a given angle the scene about the x-axis
/// and apply it to the current MVP transformation matrix.
pub fn shear_x(&mut self, angle: f32) {
let m = Matrix4::new(
1.,
angle.tan(),
0.,
0.,
0.,
1.,
0.,
0.,
0.,
0.,
1.,
0.,
0.,
0.,
0.,
1.,
);
self.matrices.curr_matrix = m * self.matrices.curr_matrix;
}
/// Derive a matrix that applies shear for a given angle the scene about the y-axis
/// and apply it to the current MVP transformation matrix.
pub fn shear_y(&mut self, angle: f32) {
let m = Matrix4::new(
1.,
0.,
0.,
0.,
angle.tan(),
1.,
0.,
0.,
0.,
0.,
1.,
0.,
0.,
0.,
0.,
1.,
);
self.matrices.curr_matrix = m * self.matrices.curr_matrix;
}
/// Derive a translation matrix from the given (x, y, z) vector and apply it to the
/// current MVP transformation matrix.
pub fn translate(&mut self, x: f32, y: f32, z: f32) {
let m = Matrix4::new(1., 0., 0., x, 0., 1., 0., y, 0., 0., 1., z, 0., 0., 0., 1.);
self.matrices.curr_matrix = m * self.matrices.curr_matrix;
}
/// Print out the current MVP transformation matrix.
pub fn print_matrix(&self) {
println!("{:?}", self.matrices.curr_matrix);
}
}