processing/transform.rs
1use Screen;
2
3use {Matrix4, Vector3, Unit};
4
5impl<'a> Screen<'a> {
6 /// Pre-multiply the current MVP transformation matrix with a matrix formed
7 /// from the given values.
8 pub fn apply_matrix(
9 &mut self,
10 n00: f32,
11 n01: f32,
12 n02: f32,
13 n03: f32,
14 n10: f32,
15 n11: f32,
16 n12: f32,
17 n13: f32,
18 n20: f32,
19 n21: f32,
20 n22: f32,
21 n23: f32,
22 n30: f32,
23 n31: f32,
24 n32: f32,
25 n33: f32,
26 ) {
27 let m = Matrix4::new(
28 n00,
29 n01,
30 n02,
31 n03,
32 n10,
33 n11,
34 n12,
35 n13,
36 n20,
37 n21,
38 n22,
39 n23,
40 n30,
41 n31,
42 n32,
43 n33,
44 );
45
46 self.matrices.curr_matrix = m * self.matrices.curr_matrix;
47 }
48
49 /// Remove the current MVP transformation matrix from the stack and use the most
50 /// recently used one instead.
51 pub fn pop_matrix(&mut self) {
52 match self.matrices.matrix_stack.pop() {
53 Some(m) => self.matrices.curr_matrix = m,
54 None => {
55 self.matrices.curr_matrix = Matrix4::identity();
56 }
57 };
58 }
59
60 /// Push the current MVP transformation matrix onto the stack, so that it can be
61 /// saved for later. Useful for when you want to temporarily apply some rotation
62 /// or translation to a single object and don't want to disturb the rest of the
63 /// scene.
64 pub fn push_matrix(&mut self) {
65 self.matrices.matrix_stack.push(self.matrices.curr_matrix);
66 }
67
68 /// Remove the current MVP transfomation matrix and set it to the standard 4x4
69 /// identity matrix.
70 pub fn reset_matrix(&mut self) {
71 self.matrices.curr_matrix = Matrix4::identity();
72 }
73
74 /// Pre-multiply the current MVP transformation matrix by a rotation matrix which
75 /// is derived from a rotation angle about a vector in the direction (x, y, z).
76 pub fn rotate(&mut self, angle: f32, x: f32, y: f32, z: f32) {
77 // let m = Matrix4::new(
78 // angle.cos(),
79 // -angle.sin(),
80 // 0.,
81 // 0.,
82 // angle.sin(),
83 // angle.cos(),
84 // 0.,
85 // 0.,
86 // 0.,
87 // 0.,
88 // 1.,
89 // 0.,
90 // 0.,
91 // 0.,
92 // 0.,
93 // 1.,
94 // );
95 let m = Matrix4::from_axis_angle(&Unit::new_unchecked(Vector3::new(x, y, z)), angle);
96
97 self.matrices.curr_matrix = m * self.matrices.curr_matrix;
98 }
99
100 /// Apply a rotation matrix for a given angle around the x-axis to the current MVP
101 /// transformation matrix.
102 pub fn rotate_x(&mut self, angle: f32) {
103 let m = Matrix4::from_axis_angle(&Unit::new_unchecked(Vector3::new(1., 0., 0.)), angle);
104 self.matrices.curr_matrix = m * self.matrices.curr_matrix;
105 }
106
107 /// Apply a rotation matrix for a given angle around the y-axis to the current MVP
108 /// transformation matrix.
109 pub fn rotate_y(&mut self, angle: f32) {
110 let m = Matrix4::from_axis_angle(&Unit::new_unchecked(Vector3::new(0., 1., 0.)), angle);
111 self.matrices.curr_matrix = m * self.matrices.curr_matrix;
112 }
113
114 /// Apply a rotation matrix for a given angle around the z-axis to the current MVP
115 /// transformation matrix.
116 pub fn rotate_z(&mut self, angle: f32) {
117 let m = Matrix4::from_axis_angle(&Unit::new_unchecked(Vector3::new(0., 0., 1.)), angle);
118 self.matrices.curr_matrix = m * self.matrices.curr_matrix;
119 }
120
121 /// Scale the scene along the x-, y-, and z-axes by applying a matrix derived from
122 /// these values to the current MVP transformation matrix.
123 pub fn scale(&mut self, x: f32, y: f32, z: f32) {
124 // let m = Matrix4::new(x, 0., 0., 0., 0., y, 0., 0., 0., 0., z, 0., 0., 0., 0., 1.);
125
126 self.matrices.curr_matrix.append_nonuniform_scaling(
127 &Vector3::new(x, y, z),
128 ); //* self.matrices.curr_matrix;
129 }
130
131 /// Derive a matrix that applies shear for a given angle the scene about the x-axis
132 /// and apply it to the current MVP transformation matrix.
133 pub fn shear_x(&mut self, angle: f32) {
134 let m = Matrix4::new(
135 1.,
136 angle.tan(),
137 0.,
138 0.,
139 0.,
140 1.,
141 0.,
142 0.,
143 0.,
144 0.,
145 1.,
146 0.,
147 0.,
148 0.,
149 0.,
150 1.,
151 );
152
153 self.matrices.curr_matrix = m * self.matrices.curr_matrix;
154 }
155
156 /// Derive a matrix that applies shear for a given angle the scene about the y-axis
157 /// and apply it to the current MVP transformation matrix.
158 pub fn shear_y(&mut self, angle: f32) {
159 let m = Matrix4::new(
160 1.,
161 0.,
162 0.,
163 0.,
164 angle.tan(),
165 1.,
166 0.,
167 0.,
168 0.,
169 0.,
170 1.,
171 0.,
172 0.,
173 0.,
174 0.,
175 1.,
176 );
177
178 self.matrices.curr_matrix = m * self.matrices.curr_matrix;
179 }
180
181 /// Derive a translation matrix from the given (x, y, z) vector and apply it to the
182 /// current MVP transformation matrix.
183 pub fn translate(&mut self, x: f32, y: f32, z: f32) {
184 let m = Matrix4::new(1., 0., 0., x, 0., 1., 0., y, 0., 0., 1., z, 0., 0., 0., 1.);
185
186 self.matrices.curr_matrix = m * self.matrices.curr_matrix;
187 }
188
189 /// Print out the current MVP transformation matrix.
190 pub fn print_matrix(&self) {
191 println!("{:?}", self.matrices.curr_matrix);
192 }
193}