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    #[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// ------------- FVec4
111
112#[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}