nova_math/vector/
std140.rs

1/*
2 *
3 * This file is a part of NovaEngine
4 * https://gitlab.com/MindSpunk/NovaEngine
5 *
6 *
7 * MIT License
8 *
9 * Copyright (c) 2018 Nathan Voglsam
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in all
19 * copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
30use crate::traits::{IntoSTD140, Pack, Real};
31use crate::vector::{TVec2, TVec3, TVec4};
32
33///
34/// A wrapper struct that is used to implement std140 packing for the underlying vector
35///
36#[repr(transparent)]
37#[derive(Copy, Clone, Debug)]
38pub struct TVec2P<T: Real>([T; 2]);
39
40///
41/// Const fn for constructing a TVec2 in a const context
42///
43pub const fn vector_2_packed_f32(x: f32, y: f32) -> TVec2P<f32> {
44    TVec2P::<f32> { 0: [x, y] }
45}
46
47///
48/// Const fn for constructing a TVec2 in a const context
49///
50pub const fn vector_2_packed_f64(x: f64, y: f64) -> TVec2P<f64> {
51    TVec2P::<f64> { 0: [x, y] }
52}
53
54impl<T: Real> TVec2P<T> {
55    pub fn new(x: T, y: T) -> Self {
56        Self([x, y])
57    }
58}
59
60impl<T: Real> From<TVec2<T>> for TVec2P<T> {
61    fn from(other: TVec2<T>) -> Self {
62        Self([other[0], other[1]])
63    }
64}
65
66impl<T: Real> From<[T; 2]> for TVec2P<T> {
67    fn from(other: [T; 2]) -> Self {
68        Self(other)
69    }
70}
71
72impl<T: Real> From<(T, T)> for TVec2P<T> {
73    fn from(other: (T, T)) -> Self {
74        Self([other.0, other.1])
75    }
76}
77
78impl<T: Real> Pack for TVec2P<T> {
79    type GLSLOutput = [T; 2];
80    type HLSLOutput = [T; 2];
81    type GLSLOutputArray = Self::GLSLOutput;
82    type HLSLOutputArray = Self::HLSLOutput;
83    type CPUOutput = [T; 2];
84
85    #[inline]
86    fn into_packed_glsl(self) -> Self::GLSLOutput {
87        self.0
88    }
89
90    #[inline]
91    fn into_packed_hlsl(self) -> Self::HLSLOutput {
92        self.0
93    }
94
95    #[inline]
96    fn into_packed_glsl_array(self) -> Self::GLSLOutputArray {
97        self.0
98    }
99
100    #[inline]
101    fn into_packed_hlsl_array(self) -> Self::HLSLOutputArray {
102        self.0
103    }
104
105    #[inline]
106    fn into_packed_cpu(self) -> Self::CPUOutput {
107        self.0
108    }
109}
110
111///
112/// A wrapper struct that is used to implement std140 packing for the underlying vector
113///
114#[repr(transparent)]
115#[derive(Copy, Clone, Debug)]
116pub struct TVec3P<T: Real>([T; 3]);
117
118///
119/// Const fn for constructing a TVec3P in a const context
120///
121pub const fn vector_3_packed_f32(x: f32, y: f32, z: f32) -> TVec3P<f32> {
122    TVec3P::<f32> { 0: [x, y, z] }
123}
124
125///
126/// Const fn for constructing a TVec3P in a const context
127///
128pub const fn vector_3_packed_f64(x: f64, y: f64, z: f64) -> TVec3P<f64> {
129    TVec3P::<f64> { 0: [x, y, z] }
130}
131
132impl<T: Real> TVec3P<T> {
133    pub fn new(x: T, y: T, z: T) -> Self {
134        Self([x, y, z])
135    }
136}
137
138impl<T: Real> From<TVec3<T>> for TVec3P<T> {
139    fn from(other: TVec3<T>) -> Self {
140        Self([other[0], other[1], other[2]])
141    }
142}
143
144impl<T: Real> From<[T; 3]> for TVec3P<T> {
145    fn from(other: [T; 3]) -> Self {
146        Self(other)
147    }
148}
149
150impl<T: Real> From<(T, T, T)> for TVec3P<T> {
151    fn from(other: (T, T, T)) -> Self {
152        Self([other.0, other.1, other.2])
153    }
154}
155
156impl<T: Real> Pack for TVec3P<T> {
157    type GLSLOutput = [T; 4];
158    type HLSLOutput = [T; 4];
159    type GLSLOutputArray = Self::GLSLOutput;
160    type HLSLOutputArray = Self::HLSLOutput;
161    type CPUOutput = [T; 3];
162
163    #[inline]
164    fn into_packed_glsl(self) -> Self::GLSLOutput {
165        [self.0[0], self.0[1], self.0[2], T::zero()]
166    }
167
168    #[inline]
169    fn into_packed_hlsl(self) -> Self::HLSLOutput {
170        [self.0[0], self.0[1], self.0[2], T::zero()]
171    }
172
173    #[inline]
174    fn into_packed_glsl_array(self) -> Self::GLSLOutputArray {
175        self.into_packed_glsl()
176    }
177
178    #[inline]
179    fn into_packed_hlsl_array(self) -> Self::HLSLOutputArray {
180        self.into_packed_hlsl()
181    }
182
183    #[inline]
184    fn into_packed_cpu(self) -> Self::CPUOutput {
185        [self.0[0], self.0[1], self.0[2]]
186    }
187}
188
189///
190/// A wrapper struct that is used to implement std140 packing for the underlying vector
191///
192#[repr(transparent)]
193#[derive(Copy, Clone, Debug)]
194pub struct TVec4P<T: Real>([T; 4]);
195
196///
197/// Const fn for constructing a TVec4P in a const context
198///
199pub const fn vector_4_packed_f32(x: f32, y: f32, z: f32, w: f32) -> TVec4P<f32> {
200    TVec4P::<f32> { 0: [x, y, z, w] }
201}
202
203///
204/// Const fn for constructing a TVec4P in a const context
205///
206pub const fn vector_4_packed_f64(x: f64, y: f64, z: f64, w: f64) -> TVec4P<f64> {
207    TVec4P::<f64> { 0: [x, y, z, w] }
208}
209
210impl<T: Real> TVec4P<T> {
211    pub fn new(x: T, y: T, z: T, w: T) -> Self {
212        Self([x, y, z, w])
213    }
214}
215
216impl<T: Real> From<TVec4<T>> for TVec4P<T> {
217    fn from(other: TVec4<T>) -> Self {
218        Self([other[0], other[1], other[2], other[3]])
219    }
220}
221
222impl<T: Real> From<[T; 4]> for TVec4P<T> {
223    fn from(other: [T; 4]) -> Self {
224        Self(other)
225    }
226}
227
228impl<T: Real> From<(T, T, T, T)> for TVec4P<T> {
229    fn from(other: (T, T, T, T)) -> Self {
230        Self([other.0, other.1, other.2, other.3])
231    }
232}
233
234impl<T: Real> Pack for TVec4P<T> {
235    type GLSLOutput = [T; 4];
236    type HLSLOutput = [T; 4];
237    type GLSLOutputArray = Self::GLSLOutput;
238    type HLSLOutputArray = Self::HLSLOutput;
239    type CPUOutput = [T; 4];
240
241    #[inline]
242    fn into_packed_glsl(self) -> Self::GLSLOutput {
243        self.0
244    }
245
246    #[inline]
247    fn into_packed_hlsl(self) -> Self::HLSLOutput {
248        self.0
249    }
250
251    #[inline]
252    fn into_packed_glsl_array(self) -> Self::GLSLOutputArray {
253        self.into_packed_glsl()
254    }
255
256    #[inline]
257    fn into_packed_hlsl_array(self) -> Self::HLSLOutputArray {
258        self.into_packed_hlsl()
259    }
260
261    #[inline]
262    fn into_packed_cpu(self) -> Self::CPUOutput {
263        self.0
264    }
265}
266
267impl<T: Real> IntoSTD140 for TVec2<T> {
268    type Output = TVec2P<T>;
269
270    fn into_std140(self) -> Self::Output {
271        TVec2P::from(self)
272    }
273}
274
275impl<T: Real> IntoSTD140 for TVec3<T> {
276    type Output = TVec3P<T>;
277
278    fn into_std140(self) -> Self::Output {
279        TVec3P::from(self)
280    }
281}
282
283impl<T: Real> IntoSTD140 for TVec4<T> {
284    type Output = TVec4P<T>;
285
286    fn into_std140(self) -> Self::Output {
287        TVec4P::from(self)
288    }
289}