1use bytemuck::{Pod, Zeroable};
6use std::ops::{Add, Index, Mul};
7
8pub struct OrthoInfo {
10 pub left: f32,
11 pub right: f32,
12 pub bottom: f32,
13 pub top: f32,
14 pub near: f32,
15 pub far: f32,
16}
17
18impl From<OrthoInfo> for Matrix4 {
19 fn from(ortho: OrthoInfo) -> Self {
20 let c0r0 = 2.0 / (ortho.right - ortho.left);
21 let c1r1 = 2.0 / (ortho.top - ortho.bottom);
22
23 let c2r2 = -2.0 / (ortho.far - ortho.near);
24
25 let c3r0 = -(ortho.right + ortho.left) / (ortho.right - ortho.left);
26 let c3r1 = -(ortho.top + ortho.bottom) / (ortho.top - ortho.bottom);
27 let c3r2 = -(ortho.far + ortho.near) / (ortho.far - ortho.near);
28
29 Self([
31 [c0r0, 0.0, 0.0, 0.0].into(),
32 [0.0, c1r1, 0.0, 0.0].into(),
33 [0.0, 0.0, c2r2, 0.0].into(),
34 [c3r0, c3r1, c3r2, 1.0].into(),
35 ])
36 }
37}
38
39#[derive(Copy, Clone)]
41#[repr(transparent)]
42pub struct Matrix4([Vec4; 4]);
43
44unsafe impl Pod for Matrix4 {}
45unsafe impl Zeroable for Matrix4 {}
46
47impl Matrix4 {
48 #[inline]
49 pub fn from_scale(x: f32, y: f32, z: f32) -> Self {
50 Self::from([
51 [x, 0.0, 0.0, 0.0],
52 [0.0, y, 0.0, 0.0],
53 [0.0, 0.0, z, 0.0],
54 [0.0, 0.0, 0.0, 1.0],
55 ])
56 }
57
58 #[inline]
59 pub fn from_translation(x: f32, y: f32, z: f32) -> Self {
60 Self::from([
61 [1.0, 0.0, 0.0, 0.0],
62 [0.0, 1.0, 0.0, 0.0],
63 [0.0, 0.0, 1.0, 0.0],
64 [x, y, z, 1.0],
65 ])
66 }
67
68 #[inline]
69 pub fn identity() -> Self {
70 Self::from_scale(1.0, 1.0, 1.0)
71 }
72}
73
74impl From<[[f32; 4]; 4]> for Matrix4 {
75 fn from(v: [[f32; 4]; 4]) -> Self {
76 Self([v[0].into(), v[1].into(), v[2].into(), v[3].into()])
77 }
78}
79
80impl Index<usize> for Matrix4 {
81 type Output = Vec4;
82
83 #[inline]
84 fn index(&self, index: usize) -> &Self::Output {
85 &self.0[index]
86 }
87}
88
89impl Mul<Self> for Matrix4 {
90 type Output = Self;
91
92 fn mul(self, rhs: Self) -> Self::Output {
93 let a = self[0];
94 let b = self[1];
95 let c = self[2];
96 let d = self[3];
97
98 Self([
99 a * rhs[0][0] + b * rhs[0][1] + c * rhs[0][2] + d * rhs[0][3],
100 a * rhs[1][0] + b * rhs[1][1] + c * rhs[1][2] + d * rhs[1][3],
101 a * rhs[2][0] + b * rhs[2][1] + c * rhs[2][2] + d * rhs[2][3],
102 a * rhs[3][0] + b * rhs[3][1] + c * rhs[3][2] + d * rhs[3][3],
103 ])
104 }
105}
106
107#[derive(Copy, Clone)]
110#[repr(transparent)]
111pub struct Vec4(pub [f32; 4]);
112
113impl From<[f32; 4]> for Vec4 {
114 fn from(v: [f32; 4]) -> Self {
115 Self(v)
116 }
117}
118
119impl Mul<f32> for Vec4 {
120 type Output = Self;
121
122 fn mul(self, rhs: f32) -> Self::Output {
123 Self([self[0] * rhs, self[1] * rhs, self[2] * rhs, self[3] * rhs])
124 }
125}
126
127impl Add<Self> for Vec4 {
128 type Output = Self;
129
130 fn add(self, rhs: Self) -> Self::Output {
131 Self([
132 self.0[0] + rhs.0[0],
133 self.0[1] + rhs.0[1],
134 self.0[2] + rhs.0[2],
135 self.0[3] + rhs.0[3],
136 ])
137 }
138}
139
140impl Index<usize> for Vec4 {
141 type Output = f32;
142
143 #[inline]
144 fn index(&self, index: usize) -> &Self::Output {
145 &self.0[index]
146 }
147}