1use crate::{Num, Vec2, Vec3, impl_vec, vec2, vec3};
2use std::fmt::{Display, Formatter};
3
4pub type Vec4F = Vec4<f32>;
5pub type Vec4I = Vec4<i32>;
6pub type Vec4U = Vec4<u32>;
7
8#[repr(C)]
10#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
11pub struct Vec4<T> {
12 pub x: T,
13 pub y: T,
14 pub z: T,
15 pub w: T,
16}
17
18#[inline]
20pub const fn vec4<T>(x: T, y: T, z: T, w: T) -> Vec4<T> {
21 Vec4 { x, y, z, w }
22}
23
24impl_vec!(
25 NAME = Vec4
26 SHORT = vec4
27 LEN = 4
28 FIELDS = (x, y, z, w)
29 TUPLE = (T, T, T, T)
30);
31
32impl<T> Vec4<T> {
33 #[inline]
35 pub fn with_x(self, x: T) -> Self {
36 Self { x, ..self }
37 }
38
39 #[inline]
41 pub fn with_y(self, y: T) -> Self {
42 Self { y, ..self }
43 }
44
45 #[inline]
47 pub fn with_z(self, z: T) -> Self {
48 Self { z, ..self }
49 }
50
51 #[inline]
53 pub fn with_w(self, w: T) -> Self {
54 Self { w, ..self }
55 }
56}
57
58impl<T: Copy> Vec4<T> {
59 #[inline]
61 pub const fn xy(self) -> Vec2<T> {
62 vec2(self.x, self.y)
63 }
64
65 #[inline]
67 pub const fn xyz(self) -> Vec3<T> {
68 vec3(self.x, self.y, self.z)
69 }
70
71 #[inline]
73 pub fn yxzw(self) -> Self {
74 vec4(self.y, self.x, self.z, self.w)
75 }
76
77 #[inline]
79 pub fn zxyw(self) -> Self {
80 vec4(self.z, self.x, self.y, self.w)
81 }
82
83 #[inline]
85 pub fn wxzy(self) -> Self {
86 vec4(self.w, self.x, self.z, self.y)
87 }
88
89 #[inline]
91 pub fn yxwz(self) -> Self {
92 vec4(self.y, self.x, self.w, self.z)
93 }
94
95 #[inline]
97 pub fn yzxw(self) -> Self {
98 vec4(self.y, self.z, self.x, self.w)
99 }
100
101 #[inline]
103 pub fn zyxw(self) -> Self {
104 vec4(self.z, self.y, self.x, self.w)
105 }
106
107 #[inline]
109 pub fn wzxy(self) -> Self {
110 vec4(self.w, self.z, self.x, self.y)
111 }
112
113 #[inline]
115 pub fn yzwx(self) -> Self {
116 vec4(self.y, self.z, self.w, self.x)
117 }
118
119 #[inline]
121 pub fn zywx(self) -> Self {
122 vec4(self.z, self.y, self.w, self.x)
123 }
124
125 #[inline]
127 pub fn wzyx(self) -> Self {
128 vec4(self.w, self.z, self.y, self.x)
129 }
130
131 #[inline]
133 pub fn ywzx(self) -> Self {
134 vec4(self.y, self.w, self.z, self.x)
135 }
136}
137
138impl<T: Num> Vec4<T> {
139 pub const X_AXIS: Self = vec4(T::ONE, T::ZERO, T::ZERO, T::ZERO);
141
142 pub const Y_AXIS: Self = vec4(T::ZERO, T::ONE, T::ZERO, T::ZERO);
144
145 pub const Z_AXIS: Self = vec4(T::ZERO, T::ZERO, T::ONE, T::ZERO);
147
148 pub const W_AXIS: Self = vec4(T::ZERO, T::ZERO, T::ZERO, T::ONE);
150}
151
152impl<T: Display> Display for Vec4<T> {
153 #[inline]
154 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
155 self.x.fmt(f)?;
156 f.write_str(", ")?;
157 self.y.fmt(f)?;
158 f.write_str(", ")?;
159 self.z.fmt(f)?;
160 f.write_str(", ")?;
161 self.w.fmt(f)
162 }
163}
164
165impl<T: Num> From<Vec2<T>> for Vec4<T> {
166 #[inline]
167 fn from(Vec2 { x, y }: Vec2<T>) -> Self {
168 vec4(x, y, T::ZERO, T::ZERO)
169 }
170}
171
172impl<T: Num> From<Vec3<T>> for Vec4<T> {
173 #[inline]
174 fn from(Vec3 { x, y, z }: Vec3<T>) -> Self {
175 vec4(x, y, z, T::ZERO)
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use super::*;
182
183 #[test]
184 fn vec4_math() {
185 assert_eq!(
186 vec4(1.0, 2.0, 3.0, 4.0) + vec4(2.0, 3.0, 4.0, 5.0),
187 vec4(3.0, 5.0, 7.0, 9.0)
188 );
189 assert_eq!(vec4(1.0, 2.0, 2.0, 4.0).len(), 5.0); assert_eq!(vec4(1.0, 2.0, 3.0, 4.0) * 2.0, vec4(2.0, 4.0, 6.0, 8.0));
191 assert_eq!(
192 vec4(1.0, 2.0, 3.0, 4.0).min(vec4(4.0, 3.0, 2.0, 1.0)),
193 vec4(1.0, 2.0, 2.0, 1.0)
194 );
195 assert_eq!(
196 vec4(1.0, 2.0, 3.0, 4.0).max(vec4(4.0, 3.0, 2.0, 1.0)),
197 vec4(4.0, 3.0, 3.0, 4.0)
198 );
199 assert_eq!(
200 vec4(1.0, 2.0, 3.0, 4.0).clamp(vec4(2.0, 2.0, 2.0, 2.0), vec4(3.0, 3.0, 3.0, 3.0)),
201 vec4(2.0, 2.0, 3.0, 3.0)
202 );
203 }
204}