Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

558 rader
14 KiB

  1. #![allow(dead_code)]
  2. use std::borrow::Borrow;
  3. use std::convert::{AsMut, AsRef};
  4. use std::fmt::{Debug, Formatter, Result as FmtResult};
  5. use std::ops::{Deref, DerefMut, Mul};
  6. use super::vector::{Element, Vector2, Vector3, Vector4};
  7. macro_rules! first_ptr {
  8. ($this:ident, $first:ident $(,$other:ident)*) => {
  9. unsafe { $this.$first.as_ptr() }
  10. };
  11. }
  12. macro_rules! define_mat {
  13. ($Name:ident, $Vector:ident, $size:tt, $($T:ident => $i:tt => $f:ident),*) => {
  14. #[repr(C, packed)]
  15. pub struct $Name<T> {
  16. $(pub $f: $Vector<T>,)+
  17. }
  18. impl<T> $Name<T> {
  19. #[inline]
  20. pub fn new($($f: $Vector<T>,)+) -> Self {
  21. Self { $($f,)+ }
  22. }
  23. pub fn as_ptr(&self) -> * const T {
  24. first_ptr!(self $(,$f)+)
  25. }
  26. }
  27. impl<T> Default for $Name<T>
  28. where
  29. T: Element
  30. {
  31. #[inline]
  32. fn default() -> Self {
  33. Self::identity()
  34. }
  35. }
  36. impl<T> Debug for $Name<T>
  37. where
  38. T: Debug
  39. {
  40. fn fmt(&self, fmt: &mut Formatter<'_>) -> FmtResult {
  41. fmt.debug_list().entries(self.as_ref().iter()).finish()
  42. }
  43. }
  44. impl<T, S> PartialEq<$Name<S>> for $Name<T>
  45. where
  46. $Vector<S>: PartialEq<$Vector<T>>,
  47. {
  48. fn eq(&self, other: &$Name<S>) -> bool {
  49. unsafe { true $(&& other.$f.eq(&self.$f))+ }
  50. }
  51. }
  52. impl<T> Eq for $Name<T>
  53. where
  54. T: Eq
  55. { }
  56. impl<T> Deref for $Name<T> {
  57. type Target = [$Vector<T>; $size];
  58. #[inline]
  59. fn deref(&self) -> &Self::Target {
  60. self.as_ref()
  61. }
  62. }
  63. impl<T> DerefMut for $Name<T> {
  64. #[inline]
  65. fn deref_mut(&mut self) -> &mut Self::Target {
  66. self.as_mut()
  67. }
  68. }
  69. impl<T> AsRef<[$Vector<T>; $size]> for $Name<T> {
  70. #[inline]
  71. fn as_ref(&self) -> &[$Vector<T>; $size] {
  72. unsafe {
  73. let raw: * const _ = self;
  74. let raw = raw as * const [$Vector<T>; $size];
  75. &*raw
  76. }
  77. }
  78. }
  79. impl<T> AsMut<[$Vector<T>; $size]> for $Name<T> {
  80. #[inline]
  81. fn as_mut(&mut self) -> &mut [$Vector<T>; $size] {
  82. unsafe {
  83. let raw: * mut _ = self;
  84. let raw = raw as * mut [$Vector<T>; $size];
  85. &mut *raw
  86. }
  87. }
  88. }
  89. impl<T> Clone for $Name<T>
  90. where
  91. T: Clone
  92. {
  93. #[inline]
  94. fn clone(&self) -> Self {
  95. unsafe {
  96. Self {
  97. $($f: self.$f.clone(),)+
  98. }
  99. }
  100. }
  101. }
  102. impl<T> Copy for $Name<T>
  103. where
  104. T: Copy
  105. { }
  106. impl<T> From<[$Vector<T>; $size]> for $Name<T>
  107. where
  108. T: Copy,
  109. {
  110. #[inline]
  111. fn from(arr: [$Vector<T>; $size]) -> Self {
  112. Self {
  113. $($f: arr[$i],)+
  114. }
  115. }
  116. }
  117. impl<T> From<($($Vector<$T>,)+)> for $Name<T> {
  118. #[inline]
  119. fn from(($($f,)+): ($($Vector<$T>,)+)) -> Self {
  120. Self {
  121. $($f,)+
  122. }
  123. }
  124. }
  125. };
  126. }
  127. define_mat!(Matrix2, Vector2, 2, T => 0 => axis_x, T => 1 => axis_y);
  128. define_mat!(Matrix3, Vector3, 3, T => 0 => axis_x, T => 1 => axis_y, T => 2 => axis_z);
  129. define_mat!(Matrix4, Vector4, 4, T => 0 => axis_x, T => 1 => axis_y, T => 2 => axis_z, T => 3 => position);
  130. pub type Matrix2f = Matrix2<gl::GLfloat>;
  131. pub type Matrix3f = Matrix3<gl::GLfloat>;
  132. pub type Matrix4f = Matrix4<gl::GLfloat>;
  133. pub type Matrix2d = Matrix2<gl::GLdouble>;
  134. pub type Matrix3d = Matrix3<gl::GLdouble>;
  135. pub type Matrix4d = Matrix4<gl::GLdouble>;
  136. pub type Matrix2i = Matrix2<gl::GLint>;
  137. pub type Matrix3i = Matrix3<gl::GLint>;
  138. pub type Matrix4i = Matrix4<gl::GLint>;
  139. /* Matrix2 */
  140. impl<T> Matrix2<T>
  141. where
  142. T: Element,
  143. {
  144. #[inline]
  145. pub fn identity() -> Self {
  146. let one = T::one();
  147. let zero = T::zero();
  148. Self::new(Vector2::new(one, zero), Vector2::new(zero, one))
  149. }
  150. }
  151. /* Matrix3 */
  152. impl<T> Matrix3<T>
  153. where
  154. T: Element,
  155. {
  156. #[inline]
  157. pub fn identity() -> Self {
  158. let one = T::one();
  159. let zero = T::zero();
  160. Self::new(
  161. Vector3::new(one, zero, zero),
  162. Vector3::new(zero, one, zero),
  163. Vector3::new(zero, zero, one),
  164. )
  165. }
  166. #[inline]
  167. pub fn determinant(&self) -> T {
  168. let m = self;
  169. 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]
  170. - m[2][0] * m[1][1] * m[0][2]
  171. - m[1][0] * m[0][1] * m[2][2]
  172. - m[0][0] * m[2][1] * m[1][2]
  173. }
  174. }
  175. /* Matrix4 */
  176. impl<T> Matrix4<T>
  177. where
  178. T: Element,
  179. {
  180. #[inline]
  181. pub fn identity() -> Self {
  182. let one = T::one();
  183. let zero = T::zero();
  184. Self::new(
  185. Vector4::new(one, zero, zero, zero),
  186. Vector4::new(zero, one, zero, zero),
  187. Vector4::new(zero, zero, one, zero),
  188. Vector4::new(zero, zero, zero, one),
  189. )
  190. }
  191. #[inline]
  192. pub fn translate(v: Vector3<T>) -> Self {
  193. let one = T::one();
  194. let zero = T::zero();
  195. Self::new(
  196. Vector4::new(one, zero, zero, zero),
  197. Vector4::new(zero, one, zero, zero),
  198. Vector4::new(zero, zero, one, zero),
  199. Vector4::new(v.x, v.y, v.z, one),
  200. )
  201. }
  202. #[inline]
  203. pub fn scale(v: Vector3<T>) -> Self {
  204. let one = T::one();
  205. let zero = T::zero();
  206. Self::new(
  207. Vector4::new(v.x, zero, zero, zero),
  208. Vector4::new(zero, v.y, zero, zero),
  209. Vector4::new(zero, zero, v.z, zero),
  210. Vector4::new(zero, zero, zero, one),
  211. )
  212. }
  213. #[inline]
  214. #[allow(clippy::many_single_char_names)]
  215. pub fn rotate(axis: Vector3<T>, angle: Angle<T>) -> Self {
  216. let axis = axis.normalize();
  217. let x = axis.x;
  218. let y = axis.y;
  219. let z = axis.z;
  220. let angle = angle.into_rad().into_inner();
  221. let s = T::sin(angle);
  222. let c = T::cos(angle);
  223. let one = T::one();
  224. let zero = T::zero();
  225. Self::new(
  226. Vector4::new(
  227. x * x + (one - y * y) * c,
  228. x * y * (one - c) + z * s,
  229. x * z * (one - c) - y * s,
  230. zero,
  231. ),
  232. Vector4::new(
  233. x * y * (one - c) - z * s,
  234. y * y + (one - y * y) * c,
  235. y * z * (one - c) + x * s,
  236. zero,
  237. ),
  238. Vector4::new(
  239. x * z * (one - c) + y * s,
  240. y * z * (one - c) - x * s,
  241. z * z + (one - z * z) * c,
  242. zero,
  243. ),
  244. Vector4::new(zero, zero, zero, one),
  245. )
  246. }
  247. #[inline]
  248. pub fn multiply(&self, other: &Self) -> Self {
  249. let m1 = self;
  250. let m2 = other;
  251. macro_rules! mul {
  252. ($x:tt, $y:tt) => {
  253. m1[0][$y] * m2[$x][0]
  254. + m1[1][$y] * m2[$x][1]
  255. + m1[2][$y] * m2[$x][2]
  256. + m1[3][$y] * m2[$x][3]
  257. };
  258. }
  259. Self::new(
  260. Vector4::new(mul!(0, 0), mul!(0, 1), mul!(0, 2), mul!(0, 3)),
  261. Vector4::new(mul!(1, 0), mul!(1, 1), mul!(1, 2), mul!(1, 3)),
  262. Vector4::new(mul!(2, 0), mul!(2, 1), mul!(2, 2), mul!(2, 3)),
  263. Vector4::new(mul!(3, 0), mul!(3, 1), mul!(3, 2), mul!(3, 3)),
  264. )
  265. }
  266. #[inline]
  267. pub fn transform(&self, v: &Vector4<T>) -> Vector4<T> {
  268. let m = self;
  269. macro_rules! mul {
  270. ($i:tt) => {
  271. m[0][$i] * v[0] + m[1][$i] * v[1] + m[2][$i] * v[2] + m[3][$i] * v[3]
  272. };
  273. }
  274. Vector4::new(mul!(0), mul!(1), mul!(2), mul!(3))
  275. }
  276. #[inline]
  277. pub fn transpose(&self) -> Self {
  278. let m = self;
  279. Self::new(
  280. Vector4::new(m[0][0], m[1][0], m[2][0], m[3][0]),
  281. Vector4::new(m[0][1], m[1][1], m[2][1], m[3][1]),
  282. Vector4::new(m[0][2], m[1][2], m[2][2], m[3][2]),
  283. Vector4::new(m[0][3], m[1][3], m[2][3], m[3][3]),
  284. )
  285. }
  286. #[inline]
  287. pub fn submatrix(&self, s: usize, z: usize) -> Matrix3<T> {
  288. let mut ret = Matrix3::identity();
  289. for i in 0..=2 {
  290. for j in 0..=2 {
  291. let x = if i >= s { i + 1 } else { i };
  292. let y = if j >= z { j + 1 } else { j };
  293. ret[i][j] = self[x][y];
  294. }
  295. }
  296. ret
  297. }
  298. #[inline]
  299. pub fn determinant(&self) -> T {
  300. let m = self;
  301. m[0][0] * m.submatrix(0, 0).determinant() - m[1][0] * m.submatrix(1, 0).determinant()
  302. + m[2][0] * m.submatrix(2, 0).determinant()
  303. + m[3][0] * m.submatrix(3, 0).determinant()
  304. }
  305. #[inline]
  306. pub fn adjoint(&self) -> Self {
  307. let m = self;
  308. Self::new(
  309. Vector4::new(
  310. m.submatrix(0, 0).determinant(),
  311. -m.submatrix(1, 0).determinant(),
  312. m.submatrix(2, 0).determinant(),
  313. -m.submatrix(3, 0).determinant(),
  314. ),
  315. Vector4::new(
  316. -m.submatrix(0, 1).determinant(),
  317. m.submatrix(1, 1).determinant(),
  318. -m.submatrix(2, 1).determinant(),
  319. m.submatrix(3, 1).determinant(),
  320. ),
  321. Vector4::new(
  322. m.submatrix(0, 2).determinant(),
  323. -m.submatrix(1, 2).determinant(),
  324. m.submatrix(2, 2).determinant(),
  325. -m.submatrix(3, 2).determinant(),
  326. ),
  327. Vector4::new(
  328. -m.submatrix(0, 3).determinant(),
  329. m.submatrix(1, 3).determinant(),
  330. -m.submatrix(2, 3).determinant(),
  331. m.submatrix(3, 3).determinant(),
  332. ),
  333. )
  334. }
  335. #[inline]
  336. pub fn invert(&self) -> Self {
  337. let d = self.determinant();
  338. let mut ret = self.adjoint();
  339. ret[0][0] = ret[0][0] / d;
  340. ret[0][1] = ret[0][1] / d;
  341. ret[0][2] = ret[0][2] / d;
  342. ret[0][3] = ret[0][3] / d;
  343. ret[1][0] = ret[1][0] / d;
  344. ret[1][1] = ret[1][1] / d;
  345. ret[1][2] = ret[1][2] / d;
  346. ret[1][3] = ret[1][3] / d;
  347. ret[2][0] = ret[2][0] / d;
  348. ret[2][1] = ret[2][1] / d;
  349. ret[2][2] = ret[2][2] / d;
  350. ret[2][3] = ret[2][3] / d;
  351. ret[3][0] = ret[3][0] / d;
  352. ret[3][1] = ret[3][1] / d;
  353. ret[3][2] = ret[3][2] / d;
  354. ret[3][3] = ret[3][3] / d;
  355. ret
  356. }
  357. }
  358. impl<T> Matrix4<T>
  359. where
  360. T: Element<AsFloat = T>,
  361. {
  362. #[inline]
  363. pub fn ortho(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Self {
  364. let one = T::one();
  365. let two = one + one;
  366. let zero = T::zero();
  367. Matrix4::new(
  368. Vector4::new(two / (right - left), zero, zero, zero),
  369. Vector4::new(zero, two / (top - bottom), zero, zero),
  370. Vector4::new(zero, zero, -two / (far - near), zero),
  371. Vector4::new(
  372. -(right + left) / (right - left),
  373. -(top + bottom) / (top - bottom),
  374. -(far + near) / (far - near),
  375. one,
  376. ),
  377. )
  378. }
  379. #[inline]
  380. pub fn perspective(fov: Angle<T>, ratio: T, near: T, far: T) -> Self {
  381. let one = T::one();
  382. let two = one + one;
  383. let zero = T::zero();
  384. let top = near * fov.into_rad().into_inner().tan();
  385. let bottom = -top;
  386. let right = ratio * top;
  387. let left = -right;
  388. Matrix4::new(
  389. Vector4::new(two * near / (right - left), zero, zero, zero),
  390. Vector4::new(zero, two * near / (top - bottom), zero, zero),
  391. Vector4::new(
  392. (right + left) / (right - left),
  393. (top + bottom) / (top - bottom),
  394. -(far + near) / (far - near),
  395. -one,
  396. ),
  397. Vector4::new(zero, zero, -two * far * near / (far - near), zero),
  398. )
  399. }
  400. }
  401. impl<T, M> Mul<M> for Matrix4<T>
  402. where
  403. T: Element,
  404. M: Borrow<Matrix4<T>>,
  405. {
  406. type Output = Self;
  407. fn mul(self, rhs: M) -> Self::Output {
  408. self.multiply(rhs.borrow())
  409. }
  410. }
  411. /* Angle */
  412. pub enum Angle<T> {
  413. Deg(T),
  414. Rad(T),
  415. }
  416. impl<T> Angle<T>
  417. where
  418. T: Element,
  419. {
  420. pub fn into_inner(self) -> T {
  421. match self {
  422. Self::Deg(v) => v,
  423. Self::Rad(v) => v,
  424. }
  425. }
  426. pub fn into_deg(self) -> Self {
  427. match self {
  428. Self::Deg(v) => Self::Deg(v),
  429. Self::Rad(v) => Self::Rad(T::to_degrees(v)),
  430. }
  431. }
  432. pub fn into_rad(self) -> Self {
  433. match self {
  434. Self::Deg(v) => Self::Deg(T::to_radians(v)),
  435. Self::Rad(v) => Self::Rad(v),
  436. }
  437. }
  438. }
  439. #[cfg(test)]
  440. mod tests {
  441. use super::*;
  442. #[test]
  443. fn invert() {
  444. let m = Matrix4d::identity()
  445. * Matrix4::translate(Vector3::new(1.0, 2.0, 3.0))
  446. * Matrix4::scale(Vector3::new(30.0, 20.0, 10.0))
  447. * Matrix4::rotate(Vector3::new(1.0, 0.0, 0.0), Angle::Deg(45.0));
  448. let m = m.invert();
  449. let e = Matrix4d::new(
  450. Vector4::new(
  451. 0.019526214587563498,
  452. -0.000000000000000000,
  453. 0.000000000000000000,
  454. -0.000000000000000000,
  455. ),
  456. Vector4::new(
  457. -0.000000000000000000,
  458. 0.035355339059327376,
  459. -0.035355339059327376,
  460. 0.000000000000000000,
  461. ),
  462. Vector4::new(
  463. 0.00000000000000000,
  464. 0.07071067811865475,
  465. 0.07071067811865475,
  466. -0.00000000000000000,
  467. ),
  468. Vector4::new(
  469. -0.019526214587563498,
  470. -0.282842712474619000,
  471. -0.141421356237309560,
  472. 1.000000000000000000,
  473. ),
  474. );
  475. assert_eq!(e, m);
  476. }
  477. }