1use prelude::*;
2use super::{Vec2, Vec3, Rect, Vector, Matrix};
3use super::matrix::Mat4 as Mat4Type;
4
5#[derive(Copy, Clone)]
7#[cfg_attr(feature = "serialize-serde", derive(Deserialize, Serialize))]
8pub struct Mat4<T = f32>(pub [ [ T; 4 ]; 4 ]);
9
10impl<T> Mat4<T> where T: Float {
11 pub fn new() -> Mat4<T> {
13 Mat4([ [ T::zero(); 4]; 4 ])
14 }
15 pub fn identity() -> Mat4<T> {
17 Mat4([
18 [ T::one(), T::zero(), T::zero(), T::zero() ],
19 [ T::zero(), T::one(), T::zero(), T::zero(), ],
20 [ T::zero(), T::zero(), T::one(), T::zero(), ],
21 [ T::zero(), T::zero(), T::zero(), T::one(), ],
22 ])
23 }
24 pub fn viewport(width: T, height: T) -> Mat4<T> {
26 #[allow(non_snake_case)]
28 let TWO = T::one() + T::one();
29 Mat4([
30 [ TWO/width, T::zero(), T::zero(), T::zero() ],
31 [ T::zero(), -TWO/height, T::zero(), T::zero() ],
32 [ T::zero(), T::zero(), T::one(), T::zero() ],
33 [ -T::one(), T::one(), T::zero(), T::one() ],
34 ])
35 }
36 pub fn look_at<E, C, U>(eye: E, target: C, up: U) -> Mat4<T> where E: Vector<T>, C: Vector<T>, U: Vector<T> {
38
39 let eye = eye.as_vec3(T::zero());
40 let target = target.as_vec3(T::zero());
41 let up = up.as_vec3(T::zero());
42 let zero = T::zero();
43 let one = T::one();
44
45 if (eye.0 - target.0).abs() < T::epsilon() && (eye.1 - target.1).abs() < T::epsilon() && (eye.2 - target.2).abs() < T::epsilon() {
46 return Self::identity();
47 }
48
49 let mut z0 = eye.0 - target.0;
50 let mut z1 = eye.1 - target.1;
51 let mut z2 = eye.2 - target.2;
52
53 let recip_len = (z0 * z0 + z1 * z1 + z2 * z2).sqrt().recip();
54 z0 = z0 * recip_len;
55 z1 = z1 * recip_len;
56 z2 = z2 * recip_len;
57
58 let mut x0 = up.1 * z2 - up.2 * z1;
59 let mut x1 = up.2 * z0 - up.0 * z2;
60 let mut x2 = up.0 * z1 - up.1 * z0;
61 let len = (x0 * x0 + x1 * x1 + x2 * x2).sqrt();
62
63 if len < T::epsilon() {
64 x0 = zero;
65 x1 = zero;
66 x2 = zero;
67 } else {
68 let recip_len = len.recip();
69 x0 = x0 * recip_len;
70 x1 = x1 * recip_len;
71 x2 = x2 * recip_len;
72 }
73
74 let mut y0 = z1 * x2 - z2 * x1;
75 let mut y1 = z2 * x0 - z0 * x2;
76 let mut y2 = z0 * x1 - z1 * x0;
77 let len = (y0 * y0 + y1 * y1 + y2 * y2).sqrt();
78
79 if len < T::epsilon() {
80 y0 = zero;
81 y1 = zero;
82 y2 = zero;
83 } else {
84 let recip_len = len.recip();
85 y0 = y0 * recip_len;
86 y1 = y1 * recip_len;
87 y2 = y2 * recip_len;
88 }
89
90 Mat4([
91 [ x0, y0, z0, zero ],
92 [ x1, y1, z1, zero ],
93 [ x2, y2, z2, zero ],
94 [
95 -(x0 * eye.0 + x1 * eye.1 + x2 * eye.2),
96 -(y0 * eye.0 + y1 * eye.1 + y2 * eye.2),
97 -(z0 * eye.0 + z1 * eye.1 + z2 * eye.2),
98 one
99 ]
100 ])
101 }
102 pub fn ortho<R>(rectangle: R, near: T, far: T) -> Mat4<T> where Rect<T>: From<R> {
105 let ((left, top), (right, bottom)) = rectangle.into();
106 let two = T::one() + T::one();
107 let zero = T::zero();
108 let lr = T::one() / (left - right);
109 let bt = T::one() / (bottom - top);
110 let nf = T::one() / (near - far);
111 Mat4([
112 [ -two * lr, zero, zero, zero ],
113 [ zero, -two * bt, zero, zero ],
114 [ zero, zero, two * nf, zero ],
115 [ (left + right) * lr, (top + bottom) * bt, (far + near) * nf, T::one() ],
116 ])
117 }
118 pub fn frustum<R>(rectangle: R, near: T, far: T) -> Mat4<T> where Rect<T>: From<R> {
121 let ((left, top), (right, bottom)) = rectangle.into();
122 let two = T::one() + T::one();
123 let zero = T::zero();
124 let rl = (right - left).recip();
125 let tb = (top - bottom).recip();
126 let nf = (near - far).recip();
127 Mat4([
128 [ (near * two) * rl, zero, zero, zero ],
129 [ zero, (near * two) * tb, zero, zero ],
130 [ (right + left) * rl, (top + bottom) * tb, (far + near) * nf, -T::one() ],
131 [ zero, zero, (far * near * two) * nf, zero ]
132 ])
133 }
134 pub fn perspective(fov_y: T, aspect: T, near: T, far: T) -> Mat4<T> {
137 let two = T::one() + T::one();
138 let f = (fov_y / two).tan().recip();
139 let nf = (near - far).recip();
140 Mat4([
141 [ f / aspect, T::zero(), T::zero(), T::zero() ],
142 [ T::zero(), f, T::zero(), T::zero() ],
143 [ T::zero(), T::zero(), (far + near) * nf, -T::one() ],
144 [ T::zero(), T::zero(), two * far * near * nf, T::zero() ],
145 ])
146 }
147}
148
149impl<T> Matrix<T> for Mat4<T> where T: Float {
151 fn set<M>(self: &mut Self, other: M) -> &mut Self where Mat4Type<T>: From<M> {
152 self.0 = other.into();
153 self
154 }
155 fn translate<V>(self: &mut Self, translation_vector: V) -> &mut Self where V: Vector<T> {
156 self.0.translate(translation_vector);
157 self
158 }
159 fn scale<V>(self: &mut Self, scaling_vector: V) -> &mut Self where V: Vector<T> {
160 self.0.scale(scaling_vector);
161 self
162 }
163 fn scale_at<P, V>(self: &mut Self, position: P, scaling_vector: V) -> &mut Self where P: Vector<T>, V: Vector<T> {
164 self.0.scale_at(position, scaling_vector);
165 self
166 }
167 fn rotate(self: &mut Self, radians: T) -> &mut Self {
168 self.0.rotate(radians);
169 self
170 }
171 fn rotate_at<P>(self: &mut Self, position: P, radians: T) -> &mut Self where P: Vector<T> {
172 self.0.rotate_at(position, radians);
173 self
174 }
175 fn rotate_axis<V>(self: &mut Self, radians: T, axis: V) -> &mut Self where Vec3<T>: From<V> {
176 self.0.rotate_axis(radians, axis);
177 self
178 }
179 fn rotate_axis_at<P, V>(self: &mut Self, position: P, radians: T, axis: V) -> &mut Self where P: Vector<T>, Vec3<T>: From<V> {
180 self.0.rotate_axis_at(position, radians, axis);
181 self
182 }
183 fn get_rotation(self: &Self) -> Self {
184 let rot = self.0.get_rotation();
185 Mat4(rot)
186 }
187 fn get_translation(self: &Self) -> Vec3<T> {
188 self.0.get_translation()
189 }
190 fn get_scale(self: &Self) -> Vec3<T> {
191 self.0.get_scale()
192 }
193 fn get_euler(self: &Self) -> Vec3<T> {
194 self.0.get_euler()
195 }
196}
197
198impl<T> From<Mat4Type<T>> for Mat4<T> where T: Copy {
201 fn from(source: Mat4Type<T>) -> Self {
202 Mat4(source)
203 }
204}
205
206impl<T> Default for Mat4<T> where T: Float {
209 fn default() -> Self {
210 Mat4::new()
211 }
212}
213
214impl<T> Mul<T> for Mat4<T> where T: Float {
217 type Output = Mat4<T>;
218 fn mul(self, other: T) -> Mat4<T> {
219 let a = self.0;
220 let b = other;
221 Mat4([
222 [ a[0][0] * b, a[0][1] * b, a[0][2] * b, a[0][3] * b ],
223 [ a[1][0] * b, a[1][1] * b, a[1][2] * b, a[1][3] * b ],
224 [ a[2][0] * b, a[2][1] * b, a[2][2] * b, a[2][3] * b ],
225 [ a[3][0] * b, a[3][1] * b, a[3][2] * b, a[3][3] * b ],
226 ])
227 }
228}
229
230impl<T> Mul<Vec2<T>> for Mat4<T> where T: Float {
231 type Output = Vec2<T>;
232 fn mul(self, other: Vec2<T>) -> Vec2<T> {
234 let mat = self.0;
235 Vec2(
236 other.0 * mat[0][0] + other.1 * mat[1][0] + mat[2][0] + mat[3][0],
237 other.0 * mat[0][1] + other.1 * mat[1][1] + mat[2][0] + mat[3][1]
238 )
239 }
240}
241
242impl<T> Mul<Vec3<T>> for Mat4<T> where T: Float {
243 type Output = Vec3<T>;
244 fn mul(self, other: Vec3<T>) -> Vec3<T> {
246 let mat = self.0;
247 Vec3::<T>(
248 other.0 * mat[0][0] + other.1 * mat[1][0] + other.2 * mat[2][0] + mat[3][0],
249 other.0 * mat[0][1] + other.1 * mat[1][1] + other.2 * mat[2][1] + mat[3][1],
250 other.0 * mat[0][2] + other.1 * mat[1][2] + other.2 * mat[2][2] + mat[3][2]
251 )
252 }
253}
254
255impl<T> Mul<Mat4<T>> for Mat4<T> where T: Float {
256 type Output = Mat4<T>;
257 fn mul(self, other: Mat4<T>) -> Mat4<T> {
258 let a = self.0;
259 let b = other.0;
260 Mat4([
261 [
262 a[0][0]*b[0][0] + a[1][0]*b[0][1] + a[2][0]*b[0][2] + a[3][0]*b[0][3],
263 a[0][1]*b[0][0] + a[1][1]*b[0][1] + a[2][1]*b[0][2] + a[3][1]*b[0][3],
264 a[0][2]*b[0][0] + a[1][2]*b[0][1] + a[2][2]*b[0][2] + a[3][2]*b[0][3],
265 a[0][3]*b[0][0] + a[1][3]*b[0][1] + a[2][3]*b[0][2] + a[3][3]*b[0][3],
266 ],
267 [
268 a[0][0]*b[1][0] + a[1][0]*b[1][1] + a[2][0]*b[1][2] + a[3][0]*b[1][3],
269 a[0][1]*b[1][0] + a[1][1]*b[1][1] + a[2][1]*b[1][2] + a[3][1]*b[1][3],
270 a[0][2]*b[1][0] + a[1][2]*b[1][1] + a[2][2]*b[1][2] + a[3][2]*b[1][3],
271 a[0][3]*b[1][0] + a[1][3]*b[1][1] + a[2][3]*b[1][2] + a[3][3]*b[1][3],
272 ],
273 [
274 a[0][0]*b[2][0] + a[1][0]*b[2][1] + a[2][0]*b[2][2] + a[3][0]*b[2][3],
275 a[0][1]*b[2][0] + a[1][1]*b[2][1] + a[2][1]*b[2][2] + a[3][1]*b[2][3],
276 a[0][2]*b[2][0] + a[1][2]*b[2][1] + a[2][2]*b[2][2] + a[3][2]*b[2][3],
277 a[0][3]*b[2][0] + a[1][3]*b[2][1] + a[2][3]*b[2][2] + a[3][3]*b[2][3],
278 ],
279 [
280 a[0][0]*b[3][0] + a[1][0]*b[3][1] + a[2][0]*b[3][2] + a[3][0]*b[3][3],
281 a[0][1]*b[3][0] + a[1][1]*b[3][1] + a[2][1]*b[3][2] + a[3][1]*b[3][3],
282 a[0][2]*b[3][0] + a[1][2]*b[3][1] + a[2][2]*b[3][2] + a[3][2]*b[3][3],
283 a[0][3]*b[3][0] + a[1][3]*b[3][1] + a[2][3]*b[3][2] + a[3][3]*b[3][3],
284 ],
285 ])
286 }
287}
288
289#[cfg(feature = "uniforms")]
292use radiant_rs::{Uniform, AsUniform};
293
294#[cfg(feature = "uniforms")]
295impl AsUniform for Mat4<f32> {
296 fn as_uniform(&self) -> Uniform {
297 let a = &self.0;
298 Uniform::Mat4([
299 [ a[0][0], a[0][1], a[0][2], a[0][3] ],
300 [ a[1][0], a[1][1], a[1][2], a[1][3] ],
301 [ a[2][0], a[2][1], a[2][2], a[2][3] ],
302 [ a[3][0], a[3][1], a[3][2], a[3][3] ],
303 ])
304 }
305}
306
307#[cfg(feature = "uniforms")]
308impl AsUniform for Mat4<f64> {
309 fn as_uniform(&self) -> Uniform {
310 let a = &self.0;
311 Uniform::DoubleMat4([
312 [ a[0][0], a[0][1], a[0][2], a[0][3] ],
313 [ a[1][0], a[1][1], a[1][2], a[1][3] ],
314 [ a[2][0], a[2][1], a[2][2], a[2][3] ],
315 [ a[3][0], a[3][1], a[3][2], a[3][3] ],
316 ])
317 }
318}
319
320impl<T> Debug for Mat4<T> where T: Debug {
323 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
324 let a = &self.0;
325 write!(f, "Mat4(
326 {:?}, {:?}, {:?}, {:?}
327 {:?}, {:?}, {:?}, {:?}
328 {:?}, {:?}, {:?}, {:?}
329 {:?}, {:?}, {:?}, {:?}
330)",
331a[0][0], a[0][1], a[0][2], a[0][3],
332a[1][0], a[1][1], a[1][2], a[1][3],
333a[2][0], a[2][1], a[2][2], a[2][3],
334a[3][0], a[3][1], a[3][2], a[3][3])
335 }
336}