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 #[must_use]
50 pub fn from_scale(x: f32, y: f32, z: f32) -> Self {
51 Self::from([
52 [x, 0.0, 0.0, 0.0],
53 [0.0, y, 0.0, 0.0],
54 [0.0, 0.0, z, 0.0],
55 [0.0, 0.0, 0.0, 1.0],
56 ])
57 }
58
59 #[inline]
60 #[must_use]
61 pub fn from_translation(x: f32, y: f32, z: f32) -> Self {
62 Self::from([
63 [1.0, 0.0, 0.0, 0.0],
64 [0.0, 1.0, 0.0, 0.0],
65 [0.0, 0.0, 1.0, 0.0],
66 [x, y, z, 1.0],
67 ])
68 }
69
70 #[inline]
71 #[must_use]
72 pub fn identity() -> Self {
73 Self::from_scale(1.0, 1.0, 1.0)
74 }
75}
76
77impl From<[[f32; 4]; 4]> for Matrix4 {
78 fn from(v: [[f32; 4]; 4]) -> Self {
79 Self([v[0].into(), v[1].into(), v[2].into(), v[3].into()])
80 }
81}
82
83impl Index<usize> for Matrix4 {
84 type Output = Vec4;
85
86 #[inline]
87 fn index(&self, index: usize) -> &Self::Output {
88 &self.0[index]
89 }
90}
91
92impl Mul<Self> for Matrix4 {
93 type Output = Self;
94
95 fn mul(self, rhs: Self) -> Self::Output {
96 let a = self[0];
97 let b = self[1];
98 let c = self[2];
99 let d = self[3];
100
101 Self([
102 a * rhs[0][0] + b * rhs[0][1] + c * rhs[0][2] + d * rhs[0][3],
103 a * rhs[1][0] + b * rhs[1][1] + c * rhs[1][2] + d * rhs[1][3],
104 a * rhs[2][0] + b * rhs[2][1] + c * rhs[2][2] + d * rhs[2][3],
105 a * rhs[3][0] + b * rhs[3][1] + c * rhs[3][2] + d * rhs[3][3],
106 ])
107 }
108}
109
110#[derive(Copy, Clone)]
113#[repr(transparent)]
114pub struct Vec4(pub [f32; 4]);
115
116impl From<[f32; 4]> for Vec4 {
117 fn from(v: [f32; 4]) -> Self {
118 Self(v)
119 }
120}
121
122impl Mul<f32> for Vec4 {
123 type Output = Self;
124
125 fn mul(self, rhs: f32) -> Self::Output {
126 Self([self[0] * rhs, self[1] * rhs, self[2] * rhs, self[3] * rhs])
127 }
128}
129
130impl Add<Self> for Vec4 {
131 type Output = Self;
132
133 fn add(self, rhs: Self) -> Self::Output {
134 Self([
135 self.0[0] + rhs.0[0],
136 self.0[1] + rhs.0[1],
137 self.0[2] + rhs.0[2],
138 self.0[3] + rhs.0[3],
139 ])
140 }
141}
142
143impl Index<usize> for Vec4 {
144 type Output = f32;
145
146 #[inline]
147 fn index(&self, index: usize) -> &Self::Output {
148 &self.0[index]
149 }
150}