1 // Copyright 2013-2014 The CGMath Developers.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Linear algebra types and functions.
16 //! Most of the code in this module was borrowed from the `cgmath` package.
17 
18 pub use num_traits::{cast, Float, One, Zero};
19 
20 /// 2D vector.
21 #[repr(C)]
22 #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
23 pub struct Vector2<S> {
24     pub x: S,
25     pub y: S,
26 }
27 
28 impl<S: Sized> Vector2<S> {
new(x: S, y: S) -> Self29     pub const fn new(x: S, y: S) -> Self {
30         Vector2 { x, y }
31     }
32 
33     /// Returns a vector with the same direction and a given magnitude.
34     #[inline]
normalize(self) -> Self where S: One + Float + std::ops::Div + std::ops::Mul,35     pub fn normalize(self) -> Self
36     where
37         S: One + Float + std::ops::Div + std::ops::Mul,
38     {
39         self * (S::one() / self.magnitude())
40     }
41 
42     /// The distance from the tail to the tip of the vector.
43     #[inline]
magnitude(self) -> S where S: Float,44     pub fn magnitude(self) -> S
45     where
46         S: Float,
47     {
48         Float::sqrt(Self::dot(self, self))
49     }
50 
51     /// Dot product of two vectors.
52     ///
53     /// ```
54     /// use rgx::math::*;
55     ///
56     /// let v1 = Vector4::new(1, 3, -5, 4);
57     /// let v2 = Vector4::new(4, -2, -1, 3);
58     ///
59     /// assert_eq!(v1 * v2, 15);
60     /// ```
61     #[inline]
dot(a: Self, b: Self) -> <S as std::ops::Add>::Output where S: std::ops::Mul<Output = S> + std::ops::Add,62     pub fn dot(a: Self, b: Self) -> <S as std::ops::Add>::Output
63     where
64         S: std::ops::Mul<Output = S> + std::ops::Add,
65     {
66         a.x * b.x + a.y * b.y
67     }
68 
69     /// Distance between two vectors.
70     #[inline]
distance(self, other: Self) -> S where S: Float,71     pub fn distance(self, other: Self) -> S
72     where
73         S: Float,
74     {
75         (other - self).magnitude()
76     }
77 
78     /// Extend vector to three dimensions.
extend(self, z: S) -> Vector3<S>79     pub fn extend(self, z: S) -> Vector3<S> {
80         Vector3::new(self.x, self.y, z)
81     }
82 
map<F, T>(self, mut f: F) -> Vector2<T> where F: FnMut(S) -> T,83     pub fn map<F, T>(self, mut f: F) -> Vector2<T>
84     where
85         F: FnMut(S) -> T,
86     {
87         Vector2::new(f(self.x), f(self.y))
88     }
89 }
90 
91 impl<S: Zero + Copy + PartialEq> Zero for Vector2<S> {
92     #[inline]
zero() -> Self93     fn zero() -> Self {
94         Vector2::new(S::zero(), S::zero())
95     }
96 
97     #[inline]
is_zero(&self) -> bool98     fn is_zero(&self) -> bool {
99         *self == Vector2::zero()
100     }
101 }
102 
103 impl<S> std::ops::Add<Vector2<S>> for Vector2<S>
104 where
105     S: std::ops::Add<Output = S> + Copy,
106 {
107     type Output = Self;
108 
add(self, other: Vector2<S>) -> Self109     fn add(self, other: Vector2<S>) -> Self {
110         Self {
111             x: self.x + other.x,
112             y: self.y + other.y,
113         }
114     }
115 }
116 
117 impl<S> std::ops::Sub<Vector2<S>> for Vector2<S>
118 where
119     S: std::ops::Sub<Output = S> + Copy,
120 {
121     type Output = Self;
122 
sub(self, other: Vector2<S>) -> Self123     fn sub(self, other: Vector2<S>) -> Self {
124         Self {
125             x: self.x - other.x,
126             y: self.y - other.y,
127         }
128     }
129 }
130 
131 impl<S> std::ops::Mul<S> for Vector2<S>
132 where
133     S: std::ops::Mul<Output = S> + Copy,
134 {
135     type Output = Self;
136 
mul(self, s: S) -> Self137     fn mul(self, s: S) -> Self {
138         Self {
139             x: self.x * s,
140             y: self.y * s,
141         }
142     }
143 }
144 
145 impl<S> From<Point2<S>> for Vector2<S> {
from(p: Point2<S>) -> Self146     fn from(p: Point2<S>) -> Self {
147         Self::new(p.x, p.y)
148     }
149 }
150 
151 /// 3D vector.
152 #[repr(C)]
153 #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
154 pub struct Vector3<S> {
155     pub x: S,
156     pub y: S,
157     pub z: S,
158 }
159 
160 impl<S> Vector3<S> {
new(x: S, y: S, z: S) -> Self161     pub const fn new(x: S, y: S, z: S) -> Self {
162         Vector3 { x, y, z }
163     }
164 
165     /// Extend vector to four dimensions.
extend(self, w: S) -> Vector4<S>166     pub fn extend(self, w: S) -> Vector4<S> {
167         Vector4::new(self.x, self.y, self.z, w)
168     }
169 }
170 
171 /// 4D vector.
172 #[repr(C)]
173 #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
174 pub struct Vector4<S> {
175     pub x: S,
176     pub y: S,
177     pub z: S,
178     pub w: S,
179 }
180 
181 impl From<Vector4<f32>> for [f32; 4] {
from(mat: Vector4<f32>) -> Self182     fn from(mat: Vector4<f32>) -> Self {
183         unsafe { std::mem::transmute(mat) }
184     }
185 }
186 
187 impl<S> Vector4<S> {
new(x: S, y: S, z: S, w: S) -> Self188     pub const fn new(x: S, y: S, z: S, w: S) -> Self {
189         Vector4 { x, y, z, w }
190     }
191 }
192 
193 impl<S> std::ops::Mul<S> for Vector4<S>
194 where
195     S: std::ops::Mul<Output = S> + Copy,
196 {
197     type Output = Self;
198 
mul(self, s: S) -> Self199     fn mul(self, s: S) -> Self {
200         Self {
201             x: self.x * s,
202             y: self.y * s,
203             z: self.z * s,
204             w: self.w * s,
205         }
206     }
207 }
208 
209 impl<S> std::ops::Mul<Vector4<S>> for Vector4<S>
210 where
211     S: std::ops::Mul<Output = S> + std::ops::Add<Output = S> + Copy,
212 {
213     type Output = S;
214 
mul(self, other: Vector4<S>) -> S215     fn mul(self, other: Vector4<S>) -> S {
216         other.x * self.x + other.y * self.y + other.z * self.z + other.w * self.w
217     }
218 }
219 
220 impl<S> std::ops::Add<Vector4<S>> for Vector4<S>
221 where
222     S: std::ops::Add<Output = S> + Copy,
223 {
224     type Output = Self;
225 
add(self, other: Vector4<S>) -> Self226     fn add(self, other: Vector4<S>) -> Self {
227         Self {
228             x: self.x + other.x,
229             y: self.y + other.y,
230             z: self.z + other.z,
231             w: self.w + other.w,
232         }
233     }
234 }
235 
236 #[repr(C)]
237 #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
238 pub struct Point2<S> {
239     pub x: S,
240     pub y: S,
241 }
242 
243 impl<S> Point2<S> {
new(x: S, y: S) -> Self244     pub const fn new(x: S, y: S) -> Self {
245         Point2 { x, y }
246     }
247 
map<F, T>(self, mut f: F) -> Point2<T> where F: FnMut(S) -> T,248     pub fn map<F, T>(self, mut f: F) -> Point2<T>
249     where
250         F: FnMut(S) -> T,
251     {
252         Point2::new(f(self.x), f(self.y))
253     }
254 }
255 
256 impl<S> From<Vector2<S>> for Point2<S> {
from(v: Vector2<S>) -> Self257     fn from(v: Vector2<S>) -> Self {
258         Self::new(v.x, v.y)
259     }
260 }
261 
262 impl<S> std::ops::Div<S> for Point2<S>
263 where
264     S: std::ops::Div<Output = S> + Copy,
265 {
266     type Output = Self;
267 
div(self, s: S) -> Self268     fn div(self, s: S) -> Self {
269         Self {
270             x: self.x / s,
271             y: self.y / s,
272         }
273     }
274 }
275 
276 impl<S> std::ops::Mul<S> for Point2<S>
277 where
278     S: std::ops::Mul<Output = S> + Copy,
279 {
280     type Output = Self;
281 
mul(self, s: S) -> Self282     fn mul(self, s: S) -> Self {
283         Self {
284             x: self.x * s,
285             y: self.y * s,
286         }
287     }
288 }
289 
290 impl<S> std::ops::Add<Vector2<S>> for Point2<S>
291 where
292     S: std::ops::Add<Output = S> + Copy,
293 {
294     type Output = Self;
295 
add(self, other: Vector2<S>) -> Self296     fn add(self, other: Vector2<S>) -> Self {
297         Self {
298             x: self.x + other.x,
299             y: self.y + other.y,
300         }
301     }
302 }
303 
304 impl<S> std::ops::Sub<Vector2<S>> for Point2<S>
305 where
306     S: std::ops::Sub<Output = S> + Copy,
307 {
308     type Output = Self;
309 
sub(self, other: Vector2<S>) -> Self310     fn sub(self, other: Vector2<S>) -> Self {
311         Self {
312             x: self.x - other.x,
313             y: self.y - other.y,
314         }
315     }
316 }
317 
318 impl<S> std::ops::Sub<Point2<S>> for Point2<S>
319 where
320     S: std::ops::Sub<Output = S> + Copy,
321 {
322     type Output = Vector2<S>;
323 
sub(self, other: Point2<S>) -> Vector2<S>324     fn sub(self, other: Point2<S>) -> Vector2<S> {
325         Vector2 {
326             x: self.x - other.x,
327             y: self.y - other.y,
328         }
329     }
330 }
331 
332 /// A 4 x 4, column major matrix
333 ///
334 /// This type is marked as `#[repr(C)]`.
335 #[repr(C)]
336 #[derive(Debug, Copy, Clone, PartialEq)]
337 pub struct Matrix4<S> {
338     /// The first column of the matrix.
339     pub x: Vector4<S>,
340     /// The second column of the matrix.
341     pub y: Vector4<S>,
342     /// The third column of the matrix.
343     pub z: Vector4<S>,
344     /// The fourth column of the matrix.
345     pub w: Vector4<S>,
346 }
347 
348 impl From<Matrix4<f32>> for [[f32; 4]; 4] {
from(mat: Matrix4<f32>) -> Self349     fn from(mat: Matrix4<f32>) -> Self {
350         unsafe { std::mem::transmute(mat) }
351     }
352 }
353 
354 impl<S: Copy + Zero + One> Matrix4<S> {
355     /// Create a new matrix, providing values for each index.
356     #[inline]
357     #[rustfmt::skip]
new( c0r0: S, c0r1: S, c0r2: S, c0r3: S, c1r0: S, c1r1: S, c1r2: S, c1r3: S, c2r0: S, c2r1: S, c2r2: S, c2r3: S, c3r0: S, c3r1: S, c3r2: S, c3r3: S, ) -> Self358     pub fn new(
359         c0r0: S, c0r1: S, c0r2: S, c0r3: S,
360         c1r0: S, c1r1: S, c1r2: S, c1r3: S,
361         c2r0: S, c2r1: S, c2r2: S, c2r3: S,
362         c3r0: S, c3r1: S, c3r2: S, c3r3: S,
363     ) -> Self {
364         Self {
365             x: Vector4::new(c0r0, c0r1, c0r2, c0r3),
366             y: Vector4::new(c1r0, c1r1, c1r2, c1r3),
367             z: Vector4::new(c2r0, c2r1, c2r2, c2r3),
368             w: Vector4::new(c3r0, c3r1, c3r2, c3r3),
369         }
370     }
371 
372     #[inline]
373     #[rustfmt::skip]
identity() -> Self374     pub fn identity() -> Self {
375         Matrix4::new(
376             S::one(), S::zero(), S::zero(), S::zero(),
377             S::zero(), S::one(), S::zero(), S::zero(),
378             S::zero(), S::zero(), S::one(), S::zero(),
379             S::zero(), S::zero(), S::zero(), S::one(),
380         )
381     }
382 
383     /// Create a homogeneous transformation matrix from a translation vector.
384     #[inline]
from_translation(v: Vector3<S>) -> Self385     pub fn from_translation(v: Vector3<S>) -> Self {
386         #[cfg_attr(rustfmt, rustfmt_skip)]
387         Matrix4::new(
388             S::one(), S::zero(), S::zero(), S::zero(),
389             S::zero(), S::one(), S::zero(), S::zero(),
390             S::zero(), S::zero(), S::one(), S::zero(),
391             v.x, v.y, v.z, S::one(),
392         )
393     }
394 
395     #[inline]
row(&self, n: usize) -> Vector4<S>396     pub fn row(&self, n: usize) -> Vector4<S> {
397         match n {
398             0 => Vector4::new(self.x.x, self.y.x, self.z.x, self.w.x),
399             1 => Vector4::new(self.x.y, self.y.y, self.z.y, self.w.y),
400             2 => Vector4::new(self.x.z, self.y.z, self.z.z, self.w.z),
401             3 => Vector4::new(self.x.w, self.y.w, self.z.w, self.w.w),
402             _ => panic!("Matrix4::row: invalid row number: {}", n),
403         }
404     }
405 
406     /// Create a homogeneous transformation matrix from a scale value.
407     #[inline]
from_scale(value: S) -> Matrix4<S>408     pub fn from_scale(value: S) -> Matrix4<S> {
409         Matrix4::from_nonuniform_scale(value, value, value)
410     }
411 
412     /// Create a homogeneous transformation matrix from a set of scale values.
413     #[inline]
414     #[rustfmt::skip]
from_nonuniform_scale(x: S, y: S, z: S) -> Matrix4<S>415     pub fn from_nonuniform_scale(x: S, y: S, z: S) -> Matrix4<S> {
416         Matrix4::new(
417             x,         S::zero(), S::zero(), S::zero(),
418             S::zero(), y,         S::zero(), S::zero(),
419             S::zero(), S::zero(), z,         S::zero(),
420             S::zero(), S::zero(), S::zero(), S::one(),
421         )
422     }
423 }
424 
425 impl<S> std::ops::Mul<Matrix4<S>> for Matrix4<S>
426 where
427     S: std::ops::Mul<Output = S> + std::ops::Add<Output = S> + Copy,
428 {
429     type Output = Self;
430 
431     #[rustfmt::skip]
mul(self, rhs: Matrix4<S>) -> Matrix4<S>432     fn mul(self, rhs: Matrix4<S>) -> Matrix4<S> {
433         let a = self.x;
434         let b = self.y;
435         let c = self.z;
436         let d = self.w;
437 
438         #[cfg_attr(rustfmt, rustfmt_skip)]
439         Matrix4 {
440             x: a * rhs.x.x + b * rhs.x.y + c * rhs.x.z + d * rhs.x.w,
441             y: a * rhs.y.x + b * rhs.y.y + c * rhs.y.z + d * rhs.y.w,
442             z: a * rhs.z.x + b * rhs.z.y + c * rhs.z.z + d * rhs.z.w,
443             w: a * rhs.w.x + b * rhs.w.y + c * rhs.w.z + d * rhs.w.w,
444         }
445     }
446 }
447 
448 /// Transform a [`Vector3`] with a [`Matrix4`].
449 ///
450 /// ```
451 /// use rgx::math::*;
452 /// let m = Matrix4::from_translation(Vector3::new(8., 8., 0.));
453 /// let v = Vector3::new(1., 1., 0.);
454 ///
455 /// assert_eq!(m * v, Vector3::new(9., 9., 0.));
456 /// ```
457 impl std::ops::Mul<Vector3<f32>> for Matrix4<f32> {
458     type Output = Vector3<f32>;
459 
mul(self, vec: Vector3<f32>) -> Vector3<f32>460     fn mul(self, vec: Vector3<f32>) -> Vector3<f32> {
461         let vec = vec.extend(1.);
462         Vector3::new(self.row(0) * vec, self.row(1) * vec, self.row(2) * vec)
463     }
464 }
465 
466 /// Transform a [`Point2`] with a [`Matrix4`].
467 ///
468 /// ```
469 /// use rgx::math::*;
470 /// let m = Matrix4::from_translation(Vector3::new(8., 8., 0.));
471 /// let p = Point2::new(1., 1.);
472 ///
473 /// assert_eq!(m * p, Point2::new(9., 9.));
474 /// ```
475 impl std::ops::Mul<Point2<f32>> for Matrix4<f32> {
476     type Output = Point2<f32>;
477 
mul(self, p: Point2<f32>) -> Point2<f32>478     fn mul(self, p: Point2<f32>) -> Point2<f32> {
479         let vec = Vector4::new(p.x, p.y, 0., 1.);
480         Point2::new(self.row(0) * vec, self.row(1) * vec)
481     }
482 }
483 
484 /// An orthographic projection with arbitrary left/right/bottom/top distances
485 #[derive(Copy, Clone, Debug, PartialEq)]
486 pub struct Ortho<S> {
487     pub left: S,
488     pub right: S,
489     pub bottom: S,
490     pub top: S,
491     pub near: S,
492     pub far: S,
493 }
494 
495 impl<S: Float> From<Ortho<S>> for Matrix4<S> {
from(ortho: Ortho<S>) -> Matrix4<S>496     fn from(ortho: Ortho<S>) -> Matrix4<S> {
497         let two: S = cast(2).unwrap();
498 
499         let c0r0 = two / (ortho.right - ortho.left);
500         let c0r1 = S::zero();
501         let c0r2 = S::zero();
502         let c0r3 = S::zero();
503 
504         let c1r0 = S::zero();
505         let c1r1 = two / (ortho.top - ortho.bottom);
506         let c1r2 = S::zero();
507         let c1r3 = S::zero();
508 
509         let c2r0 = S::zero();
510         let c2r1 = S::zero();
511         let c2r2 = -two / (ortho.far - ortho.near);
512         let c2r3 = S::zero();
513 
514         let c3r0 = -(ortho.right + ortho.left) / (ortho.right - ortho.left);
515         let c3r1 = -(ortho.top + ortho.bottom) / (ortho.top - ortho.bottom);
516         let c3r2 = -(ortho.far + ortho.near) / (ortho.far - ortho.near);
517         let c3r3 = S::one();
518 
519         #[cfg_attr(rustfmt, rustfmt_skip)]
520         Matrix4::new(
521             c0r0, c0r1, c0r2, c0r3,
522             c1r0, c1r1, c1r2, c1r3,
523             c2r0, c2r1, c2r2, c2r3,
524             c3r0, c3r1, c3r2, c3r3,
525         )
526     }
527 }
528