1use std::fmt;
4use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
5
6use super::single::{self, InvariantF32};
7use super::{Matrix4x4, Vector2, Vector3};
8
9#[derive(Clone, Copy, Debug, PartialEq, Default)]
11pub struct Vector4 {
12 pub x: f32,
14 pub y: f32,
16 pub z: f32,
18 pub w: f32,
20}
21
22impl Vector4 {
23 pub const ZERO: Vector4 = Vector4::new(0.0, 0.0, 0.0, 0.0);
25 pub const ONE: Vector4 = Vector4::new(1.0, 1.0, 1.0, 1.0);
27 pub const UNIT_X: Vector4 = Vector4::new(1.0, 0.0, 0.0, 0.0);
29 pub const UNIT_Y: Vector4 = Vector4::new(0.0, 1.0, 0.0, 0.0);
31 pub const UNIT_Z: Vector4 = Vector4::new(0.0, 0.0, 1.0, 0.0);
33 pub const UNIT_W: Vector4 = Vector4::new(0.0, 0.0, 0.0, 1.0);
35
36 #[inline]
38 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
39 Self { x, y, z, w }
40 }
41
42 #[inline]
44 pub const fn from_value(value: f32) -> Self {
45 Self::new(value, value, value, value)
46 }
47
48 #[inline]
50 pub const fn from_vector2(value: Vector2, z: f32, w: f32) -> Self {
51 Self::new(value.x, value.y, z, w)
52 }
53
54 #[inline]
56 pub const fn from_vector3(value: Vector3, w: f32) -> Self {
57 Self::new(value.x, value.y, value.z, w)
58 }
59
60 #[inline]
63 pub fn abs(value: Vector4) -> Vector4 {
64 Vector4::new(value.x.abs(), value.y.abs(), value.z.abs(), value.w.abs())
65 }
66
67 #[inline]
70 pub fn clamp(value1: Vector4, min: Vector4, max: Vector4) -> Vector4 {
71 Vector4::min(Vector4::max(value1, min), max)
72 }
73
74 #[inline]
76 pub fn distance(value1: Vector4, value2: Vector4) -> f32 {
77 Vector4::distance_squared(value1, value2).sqrt()
78 }
79
80 #[inline]
82 pub fn distance_squared(value1: Vector4, value2: Vector4) -> f32 {
83 (value1 - value2).length_squared()
84 }
85
86 #[inline]
88 pub fn dot(vector1: Vector4, vector2: Vector4) -> f32 {
89 (vector1.x * vector2.x) + (vector1.y * vector2.y) + (vector1.z * vector2.z) + (vector1.w * vector2.w)
90 }
91
92 #[inline]
94 pub fn length(&self) -> f32 {
95 self.length_squared().sqrt()
96 }
97
98 #[inline]
100 pub fn length_squared(&self) -> f32 {
101 Vector4::dot(*self, *self)
102 }
103
104 #[inline]
106 pub fn lerp(value1: Vector4, value2: Vector4, amount: f32) -> Vector4 {
107 (value1 * (1.0 - amount)) + (value2 * amount)
108 }
109
110 #[inline]
113 pub fn max(value1: Vector4, value2: Vector4) -> Vector4 {
114 Vector4::new(
115 single::max(value1.x, value2.x),
116 single::max(value1.y, value2.y),
117 single::max(value1.z, value2.z),
118 single::max(value1.w, value2.w),
119 )
120 }
121
122 #[inline]
125 pub fn min(value1: Vector4, value2: Vector4) -> Vector4 {
126 Vector4::new(
127 single::min(value1.x, value2.x),
128 single::min(value1.y, value2.y),
129 single::min(value1.z, value2.z),
130 single::min(value1.w, value2.w),
131 )
132 }
133
134 #[inline]
137 pub fn normalize(vector: Vector4) -> Vector4 {
138 vector / vector.length()
139 }
140
141 #[inline]
144 pub fn square_root(value: Vector4) -> Vector4 {
145 Vector4::new(value.x.sqrt(), value.y.sqrt(), value.z.sqrt(), value.w.sqrt())
146 }
147
148 #[inline]
150 pub fn transform(vector: Vector4, matrix: Matrix4x4) -> Vector4 {
151 Vector4::new(
152 (vector.x * matrix.m11) + (vector.y * matrix.m21) + (vector.z * matrix.m31) + (vector.w * matrix.m41),
153 (vector.x * matrix.m12) + (vector.y * matrix.m22) + (vector.z * matrix.m32) + (vector.w * matrix.m42),
154 (vector.x * matrix.m13) + (vector.y * matrix.m23) + (vector.z * matrix.m33) + (vector.w * matrix.m43),
155 (vector.x * matrix.m14) + (vector.y * matrix.m24) + (vector.z * matrix.m34) + (vector.w * matrix.m44),
156 )
157 }
158
159 #[inline]
162 pub fn transform_vector3(position: Vector3, matrix: Matrix4x4) -> Vector4 {
163 Vector4::transform(Vector4::from_vector3(position, 1.0), matrix)
164 }
165
166 #[inline]
169 pub fn transform_vector2(position: Vector2, matrix: Matrix4x4) -> Vector4 {
170 Vector4::transform(Vector4::from_vector2(position, 0.0, 1.0), matrix)
171 }
172}
173
174impl Add for Vector4 {
175 type Output = Vector4;
176 #[inline]
177 fn add(self, right: Vector4) -> Vector4 {
178 Vector4::new(self.x + right.x, self.y + right.y, self.z + right.z, self.w + right.w)
179 }
180}
181
182impl Sub for Vector4 {
183 type Output = Vector4;
184 #[inline]
185 fn sub(self, right: Vector4) -> Vector4 {
186 Vector4::new(self.x - right.x, self.y - right.y, self.z - right.z, self.w - right.w)
187 }
188}
189
190impl Mul for Vector4 {
191 type Output = Vector4;
192 #[inline]
193 fn mul(self, right: Vector4) -> Vector4 {
194 Vector4::new(self.x * right.x, self.y * right.y, self.z * right.z, self.w * right.w)
195 }
196}
197
198impl Mul<f32> for Vector4 {
199 type Output = Vector4;
200 #[inline]
201 fn mul(self, right: f32) -> Vector4 {
202 Vector4::new(self.x * right, self.y * right, self.z * right, self.w * right)
203 }
204}
205
206impl Mul<Vector4> for f32 {
207 type Output = Vector4;
208 #[inline]
209 fn mul(self, right: Vector4) -> Vector4 {
210 right * self
211 }
212}
213
214impl Div for Vector4 {
215 type Output = Vector4;
216 #[inline]
217 fn div(self, right: Vector4) -> Vector4 {
218 Vector4::new(self.x / right.x, self.y / right.y, self.z / right.z, self.w / right.w)
219 }
220}
221
222impl Div<f32> for Vector4 {
223 type Output = Vector4;
224 #[inline]
225 fn div(self, right: f32) -> Vector4 {
226 Vector4::new(self.x / right, self.y / right, self.z / right, self.w / right)
227 }
228}
229
230impl Neg for Vector4 {
231 type Output = Vector4;
232 #[inline]
233 fn neg(self) -> Vector4 {
234 Vector4::new(-self.x, -self.y, -self.z, -self.w)
235 }
236}
237
238impl AddAssign for Vector4 {
239 #[inline]
240 fn add_assign(&mut self, right: Vector4) {
241 *self = *self + right;
242 }
243}
244
245impl SubAssign for Vector4 {
246 #[inline]
247 fn sub_assign(&mut self, right: Vector4) {
248 *self = *self - right;
249 }
250}
251
252impl MulAssign for Vector4 {
253 #[inline]
254 fn mul_assign(&mut self, right: Vector4) {
255 *self = *self * right;
256 }
257}
258
259impl MulAssign<f32> for Vector4 {
260 #[inline]
261 fn mul_assign(&mut self, right: f32) {
262 *self = *self * right;
263 }
264}
265
266impl DivAssign for Vector4 {
267 #[inline]
268 fn div_assign(&mut self, right: Vector4) {
269 *self = *self / right;
270 }
271}
272
273impl DivAssign<f32> for Vector4 {
274 #[inline]
275 fn div_assign(&mut self, right: f32) {
276 *self = *self / right;
277 }
278}
279
280impl fmt::Display for Vector4 {
281 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282 write!(
283 f,
284 "<{}, {}, {}, {}>",
285 InvariantF32(self.x),
286 InvariantF32(self.y),
287 InvariantF32(self.z),
288 InvariantF32(self.w)
289 )
290 }
291}