limnus_wgpu_math/
lib.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/limnus
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use bytemuck::{Pod, Zeroable};
6use std::ops::{Add, Index, Mul};
7
8// ------------ Ortho -------------
9pub 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        //    #[rustfmt::skip]
30        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// ----------------- FMatrix4 ----------------
40#[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// ------------- FVec4
108
109#[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}