|
- #![allow(dead_code)]
-
- use std::borrow::Borrow;
- use std::convert::{AsMut, AsRef};
- use std::fmt::{Debug, Formatter, Result as FmtResult};
- use std::ops::{Deref, DerefMut, Mul};
-
- #[cfg(feature = "serde")]
- use serde::{
- de::{Deserializer, Error, MapAccess, SeqAccess, Visitor},
- ser::{SerializeStruct, Serializer},
- Deserialize, Serialize,
- };
-
- use super::vector::{Vector2, Vector3, Vector4};
-
- pub use super::{
- angle::Angle,
- numeric::{Float, Numeric},
- };
-
- macro_rules! first_ptr {
- ($this:ident, $first:ident $(, $other:ident)*) => {
- unsafe { $this.$first.as_ptr() }
- };
- }
-
- macro_rules! define_mat {
- ($Name:ident, $Vector:ident, $size:tt, $($T:ident => $i:tt => $f:ident),*) => {
- #[repr(C, packed)]
- pub struct $Name<T> {
- $(pub $f: $Vector<T>,)+
- }
-
- impl<T> $Name<T> {
- #[inline]
- pub fn new($($f: $Vector<T>,)+) -> Self {
- Self { $($f,)+ }
- }
-
- pub fn as_ptr(&self) -> * const T {
- first_ptr!(self $(,$f)+)
- }
- }
-
- impl<T> Default for $Name<T>
- where
- T: Numeric
- {
- #[inline]
- fn default() -> Self {
- Self::identity()
- }
- }
-
- impl<T> Debug for $Name<T>
- where
- T: Debug
- {
- fn fmt(&self, fmt: &mut Formatter<'_>) -> FmtResult {
- fmt.debug_list().entries(self.as_ref().iter()).finish()
- }
- }
-
- impl<T, S> PartialEq<$Name<S>> for $Name<T>
- where
- $Vector<S>: PartialEq<$Vector<T>>,
- {
- fn eq(&self, other: &$Name<S>) -> bool {
- unsafe { true $(&& other.$f.eq(&self.$f))+ }
- }
- }
-
- impl<T> Eq for $Name<T>
- where
- T: Eq
- { }
-
- impl<T> Deref for $Name<T> {
- type Target = [$Vector<T>; $size];
-
- #[inline]
- fn deref(&self) -> &Self::Target {
- self.as_ref()
- }
- }
-
- impl<T> DerefMut for $Name<T> {
- #[inline]
- fn deref_mut(&mut self) -> &mut Self::Target {
- self.as_mut()
- }
- }
-
- impl<T> AsRef<[$Vector<T>; $size]> for $Name<T> {
- #[inline]
- fn as_ref(&self) -> &[$Vector<T>; $size] {
- unsafe {
- let raw: * const _ = self;
- let raw = raw as * const [$Vector<T>; $size];
-
- &*raw
- }
- }
- }
-
- impl<T> AsMut<[$Vector<T>; $size]> for $Name<T> {
- #[inline]
- fn as_mut(&mut self) -> &mut [$Vector<T>; $size] {
- unsafe {
- let raw: * mut _ = self;
- let raw = raw as * mut [$Vector<T>; $size];
-
- &mut *raw
- }
- }
- }
-
- impl<T> Clone for $Name<T>
- where
- T: Clone
- {
- #[inline]
- fn clone(&self) -> Self {
- unsafe {
- Self {
- $($f: self.$f.clone(),)+
- }
- }
- }
- }
-
- impl<T> Copy for $Name<T>
- where
- T: Copy
- { }
-
- impl<T> From<[$Vector<T>; $size]> for $Name<T>
- where
- T: Copy,
- {
- #[inline]
- fn from(arr: [$Vector<T>; $size]) -> Self {
- Self {
- $($f: arr[$i],)+
- }
- }
- }
-
- impl<T> From<($($Vector<$T>,)+)> for $Name<T> {
- #[inline]
- fn from(($($f,)+): ($($Vector<$T>,)+)) -> Self {
- Self {
- $($f,)+
- }
- }
- }
-
- #[cfg(feature = "serde")]
- impl<T> Serialize for $Name<T>
- where
- T: Serialize,
- {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: Serializer
- {
- let mut s = serializer.serialize_struct(stringify!($Name), $size)?;
- unsafe { $(s.serialize_field(stringify!($f), &self.$f)?;)+ }
- s.end()
- }
- }
-
- #[cfg(feature = "serde")]
- impl<'de, T> Deserialize<'de> for $Name<T>
- where
- T: Deserialize<'de>,
- {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>
- {
- struct MatrixVisitor<T>(std::marker::PhantomData<T>);
-
- impl<'de, X> Visitor<'de> for MatrixVisitor<X>
- where X: Deserialize<'de>,
- {
- type Value = $Name<X>;
-
- fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
- formatter.write_fmt(format_args!("struct {}", stringify!($Name)))
- }
-
- fn visit_seq<V>(self, mut seq: V) -> Result<$Name<X>, V::Error>
- where
- V: SeqAccess<'de>,
- {
- Ok($Name {
- $($f: seq.next_element()?.ok_or_else(|| Error::invalid_length($i, &self))?,)+
- })
- }
-
- fn visit_map<V>(self, mut map: V) -> Result<$Name<X>, V::Error>
- where
- V: MapAccess<'de>,
- {
- $(let mut $f = None;)+
-
- while let Some(key) = map.next_key()? {
- match key {
- $(
- stringify!($f) => {
- if $f.is_some() {
- return Err(Error::duplicate_field(stringify!($f)));
- }
- $f = Some(map.next_value()?);
- }
- )+
- value => return Err(Error::unknown_field(value, FIELDS)),
- }
- }
-
- Ok($Name {
- $($f: $f.ok_or_else(|| Error::missing_field(stringify!($f)))?,)+
- })
- }
- }
-
- const FIELDS: &'static [&'static str] = &[$(stringify!($f),)+];
-
- deserializer.deserialize_struct(stringify!($Name), FIELDS, MatrixVisitor::<T>(std::marker::PhantomData))
- }
- }
- };
- }
-
- define_mat!(Matrix2, Vector2, 2, T => 0 => axis_x, T => 1 => axis_y);
- define_mat!(Matrix3, Vector3, 3, T => 0 => axis_x, T => 1 => axis_y, T => 2 => axis_z);
- define_mat!(Matrix4, Vector4, 4, T => 0 => axis_x, T => 1 => axis_y, T => 2 => axis_z, T => 3 => position);
-
- pub type Matrix2f = Matrix2<gl::GLfloat>;
- pub type Matrix3f = Matrix3<gl::GLfloat>;
- pub type Matrix4f = Matrix4<gl::GLfloat>;
-
- pub type Matrix2d = Matrix2<gl::GLdouble>;
- pub type Matrix3d = Matrix3<gl::GLdouble>;
- pub type Matrix4d = Matrix4<gl::GLdouble>;
-
- pub type Matrix2i = Matrix2<gl::GLint>;
- pub type Matrix3i = Matrix3<gl::GLint>;
- pub type Matrix4i = Matrix4<gl::GLint>;
-
- /* Matrix2 */
-
- impl<T> Matrix2<T>
- where
- T: Numeric,
- {
- #[inline]
- pub fn identity() -> Self {
- let one = T::one();
- let zero = T::zero();
-
- Self::new(Vector2::new(one, zero), Vector2::new(zero, one))
- }
- }
-
- /* Matrix3 */
-
- impl<T> Matrix3<T>
- where
- T: Numeric,
- {
- #[inline]
- pub fn identity() -> Self {
- let one = T::one();
- let zero = T::zero();
-
- Self::new(
- Vector3::new(one, zero, zero),
- Vector3::new(zero, one, zero),
- Vector3::new(zero, zero, one),
- )
- }
-
- #[inline]
- pub fn translate(v: Vector2<T>) -> Self {
- let one = T::one();
- let zro = T::zero();
-
- Self::new(
- Vector3::new(one, zro, zro),
- Vector3::new(zro, one, zro),
- Vector3::new(v.x, v.y, one),
- )
- }
-
- #[inline]
- pub fn determinant(&self) -> T {
- let m = self;
-
- m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2]
- - m[2][0] * m[1][1] * m[0][2]
- - m[1][0] * m[0][1] * m[2][2]
- - m[0][0] * m[2][1] * m[1][2]
- }
-
- #[inline]
- pub fn multiply(&self, other: &Self) -> Self {
- let m1 = self;
- let m2 = other;
-
- macro_rules! mul {
- ($x:tt, $y:tt) => {
- m1[0][$y] * m2[$x][0] + m1[1][$y] * m2[$x][1] + m1[2][$y] * m2[$x][2]
- };
- }
-
- Self::new(
- Vector3::new(mul!(0, 0), mul!(0, 1), mul!(0, 2)),
- Vector3::new(mul!(1, 0), mul!(1, 1), mul!(1, 2)),
- Vector3::new(mul!(2, 0), mul!(2, 1), mul!(2, 2)),
- )
- }
- }
-
- impl<T> Matrix3<T>
- where
- T: Float,
- {
- #[inline]
- pub fn rotate(a: Angle<T>) -> Self {
- let one = T::one();
- let zro = T::zero();
-
- Self::new(
- Vector3::new(a.cos(), -a.sin(), zro),
- Vector3::new(a.sin(), a.cos(), zro),
- Vector3::new(zro, zro, one),
- )
- }
- }
-
- impl<T, M> Mul<M> for Matrix3<T>
- where
- T: Float,
- M: Borrow<Matrix3<T>>,
- {
- type Output = Self;
-
- fn mul(self, rhs: M) -> Self::Output {
- self.multiply(rhs.borrow())
- }
- }
-
- /* Matrix4 */
-
- impl<T> Matrix4<T>
- where
- T: Numeric,
- {
- #[inline]
- pub fn identity() -> Self {
- let one = T::one();
- let zero = T::zero();
-
- Self::new(
- Vector4::new(one, zero, zero, zero),
- Vector4::new(zero, one, zero, zero),
- Vector4::new(zero, zero, one, zero),
- Vector4::new(zero, zero, zero, one),
- )
- }
- }
-
- impl<T> Matrix4<T>
- where
- T: Float,
- {
- #[inline]
- pub fn translate(v: Vector3<T>) -> Self {
- let one = T::one();
- let zero = T::zero();
-
- Self::new(
- Vector4::new(one, zero, zero, zero),
- Vector4::new(zero, one, zero, zero),
- Vector4::new(zero, zero, one, zero),
- Vector4::new(v.x, v.y, v.z, one),
- )
- }
-
- #[inline]
- pub fn scale(v: Vector3<T>) -> Self {
- let one = T::one();
- let zero = T::zero();
-
- Self::new(
- Vector4::new(v.x, zero, zero, zero),
- Vector4::new(zero, v.y, zero, zero),
- Vector4::new(zero, zero, v.z, zero),
- Vector4::new(zero, zero, zero, one),
- )
- }
-
- #[inline]
- #[allow(clippy::many_single_char_names)]
- pub fn rotate(axis: Vector3<T>, angle: Angle<T>) -> Self {
- let axis = axis.normalize();
- let x = axis.x;
- let y = axis.y;
- let z = axis.z;
- let angle = angle.into_rad().into_inner();
- let s = T::sin(angle);
- let c = T::cos(angle);
- let one = T::one();
- let zero = T::zero();
-
- Self::new(
- Vector4::new(
- x * x + (one - y * y) * c,
- x * y * (one - c) + z * s,
- x * z * (one - c) - y * s,
- zero,
- ),
- Vector4::new(
- x * y * (one - c) - z * s,
- y * y + (one - y * y) * c,
- y * z * (one - c) + x * s,
- zero,
- ),
- Vector4::new(
- x * z * (one - c) + y * s,
- y * z * (one - c) - x * s,
- z * z + (one - z * z) * c,
- zero,
- ),
- Vector4::new(zero, zero, zero, one),
- )
- }
-
- #[inline]
- pub fn multiply(&self, other: &Self) -> Self {
- let m1 = self;
- let m2 = other;
-
- macro_rules! mul {
- ($x:tt, $y:tt) => {
- m1[0][$y] * m2[$x][0]
- + m1[1][$y] * m2[$x][1]
- + m1[2][$y] * m2[$x][2]
- + m1[3][$y] * m2[$x][3]
- };
- }
-
- Self::new(
- Vector4::new(mul!(0, 0), mul!(0, 1), mul!(0, 2), mul!(0, 3)),
- Vector4::new(mul!(1, 0), mul!(1, 1), mul!(1, 2), mul!(1, 3)),
- Vector4::new(mul!(2, 0), mul!(2, 1), mul!(2, 2), mul!(2, 3)),
- Vector4::new(mul!(3, 0), mul!(3, 1), mul!(3, 2), mul!(3, 3)),
- )
- }
-
- #[inline]
- pub fn transform(&self, v: &Vector4<T>) -> Vector4<T> {
- let m = self;
-
- macro_rules! mul {
- ($i:tt) => {
- m[0][$i] * v[0] + m[1][$i] * v[1] + m[2][$i] * v[2] + m[3][$i] * v[3]
- };
- }
-
- Vector4::new(mul!(0), mul!(1), mul!(2), mul!(3))
- }
-
- #[inline]
- pub fn transpose(&self) -> Self {
- let m = self;
-
- Self::new(
- Vector4::new(m[0][0], m[1][0], m[2][0], m[3][0]),
- Vector4::new(m[0][1], m[1][1], m[2][1], m[3][1]),
- Vector4::new(m[0][2], m[1][2], m[2][2], m[3][2]),
- Vector4::new(m[0][3], m[1][3], m[2][3], m[3][3]),
- )
- }
-
- #[inline]
- pub fn submatrix(&self, s: usize, z: usize) -> Matrix3<T> {
- let mut ret = Matrix3::identity();
-
- for i in 0..=2 {
- for j in 0..=2 {
- let x = if i >= s { i + 1 } else { i };
- let y = if j >= z { j + 1 } else { j };
-
- ret[i][j] = self[x][y];
- }
- }
-
- ret
- }
-
- #[inline]
- pub fn determinant(&self) -> T {
- let m = self;
-
- m[0][0] * m.submatrix(0, 0).determinant() - m[1][0] * m.submatrix(1, 0).determinant()
- + m[2][0] * m.submatrix(2, 0).determinant()
- + m[3][0] * m.submatrix(3, 0).determinant()
- }
-
- #[inline]
- pub fn adjoint(&self) -> Self {
- let m = self;
-
- Self::new(
- Vector4::new(
- m.submatrix(0, 0).determinant(),
- -m.submatrix(1, 0).determinant(),
- m.submatrix(2, 0).determinant(),
- -m.submatrix(3, 0).determinant(),
- ),
- Vector4::new(
- -m.submatrix(0, 1).determinant(),
- m.submatrix(1, 1).determinant(),
- -m.submatrix(2, 1).determinant(),
- m.submatrix(3, 1).determinant(),
- ),
- Vector4::new(
- m.submatrix(0, 2).determinant(),
- -m.submatrix(1, 2).determinant(),
- m.submatrix(2, 2).determinant(),
- -m.submatrix(3, 2).determinant(),
- ),
- Vector4::new(
- -m.submatrix(0, 3).determinant(),
- m.submatrix(1, 3).determinant(),
- -m.submatrix(2, 3).determinant(),
- m.submatrix(3, 3).determinant(),
- ),
- )
- }
-
- #[inline]
- pub fn invert(&self) -> Self {
- let d = self.determinant();
- let mut ret = self.adjoint();
-
- ret[0][0] = ret[0][0] / d;
- ret[0][1] = ret[0][1] / d;
- ret[0][2] = ret[0][2] / d;
- ret[0][3] = ret[0][3] / d;
-
- ret[1][0] = ret[1][0] / d;
- ret[1][1] = ret[1][1] / d;
- ret[1][2] = ret[1][2] / d;
- ret[1][3] = ret[1][3] / d;
-
- ret[2][0] = ret[2][0] / d;
- ret[2][1] = ret[2][1] / d;
- ret[2][2] = ret[2][2] / d;
- ret[2][3] = ret[2][3] / d;
-
- ret[3][0] = ret[3][0] / d;
- ret[3][1] = ret[3][1] / d;
- ret[3][2] = ret[3][2] / d;
- ret[3][3] = ret[3][3] / d;
-
- ret
- }
- }
-
- impl<T> Matrix4<T>
- where
- T: Float,
- {
- #[inline]
- pub fn ortho(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Self {
- let one = T::one();
- let two = one + one;
- let zero = T::zero();
-
- Matrix4::new(
- Vector4::new(two / (right - left), zero, zero, zero),
- Vector4::new(zero, two / (top - bottom), zero, zero),
- Vector4::new(zero, zero, -two / (far - near), zero),
- Vector4::new(
- -(right + left) / (right - left),
- -(top + bottom) / (top - bottom),
- -(far + near) / (far - near),
- one,
- ),
- )
- }
-
- #[inline]
- pub fn perspective(fov: Angle<T>, ratio: T, near: T, far: T) -> Self {
- let one = T::one();
- let two = one + one;
- let zero = T::zero();
-
- let top = near * fov.into_rad().into_inner().tan();
- let bottom = -top;
- let right = ratio * top;
- let left = -right;
-
- Matrix4::new(
- Vector4::new(two * near / (right - left), zero, zero, zero),
- Vector4::new(zero, two * near / (top - bottom), zero, zero),
- Vector4::new(
- (right + left) / (right - left),
- (top + bottom) / (top - bottom),
- -(far + near) / (far - near),
- -one,
- ),
- Vector4::new(zero, zero, -two * far * near / (far - near), zero),
- )
- }
- }
-
- impl<T, M> Mul<M> for Matrix4<T>
- where
- T: Float,
- M: Borrow<Matrix4<T>>,
- {
- type Output = Self;
-
- fn mul(self, rhs: M) -> Self::Output {
- self.multiply(rhs.borrow())
- }
- }
-
- #[cfg(test)]
- mod tests {
- use super::*;
-
- #[test]
- fn invert() {
- let m = Matrix4d::identity()
- * Matrix4::translate(Vector3::new(1.0, 2.0, 3.0))
- * Matrix4::scale(Vector3::new(30.0, 20.0, 10.0))
- * Matrix4::rotate(Vector3::new(1.0, 0.0, 0.0), Angle::Deg(45.0));
- let m = m.invert();
-
- let e = Matrix4d::new(
- Vector4::new(
- 0.019526214587563498,
- -0.000000000000000000,
- 0.000000000000000000,
- -0.000000000000000000,
- ),
- Vector4::new(
- -0.000000000000000000,
- 0.035355339059327376,
- -0.035355339059327376,
- 0.000000000000000000,
- ),
- Vector4::new(
- 0.00000000000000000,
- 0.07071067811865475,
- 0.07071067811865475,
- -0.00000000000000000,
- ),
- Vector4::new(
- -0.019526214587563498,
- -0.282842712474619000,
- -0.141421356237309560,
- 1.000000000000000000,
- ),
- );
-
- assert_eq!(e, m);
- }
- }
|