glium_types/vectors/
vec4.rs

1use derive_cmp_ops::CmpOps;
2use glium::uniforms::AsUniformValue;
3use crate::prelude::Mat4;
4use super::{vec3::{vec3, Vec3}, bvec4::*};
5#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, CmpOps)]
6///a vector made from a x, y, z and w coordinate.
7pub struct Vec4{
8    pub x: f32,
9    pub y: f32,
10    pub z: f32,
11    pub w: f32
12}
13impl Vec4{
14    ///a zero vector
15    pub const ZERO: Self = vec4(0.0, 0.0, 0.0, 0.0);
16    ///a vector full of ones
17    pub const ONE: Self = vec4(1.0, 1.0, 1.0, 1.0);
18    ///the x axis
19    pub const X: Self = vec4(1.0, 0.0, 0.0, 0.0);
20    ///the y axis
21    pub const Y: Self = vec4(0.0, 1.0, 0.0, 0.0);
22    ///the z axis
23    pub const Z: Self = vec4(0.0, 0.0, 1.0, 0.0);
24    ///the w axis
25    pub const W: Self = vec4(0.0, 0.0, 0.0, 1.0);
26
27    pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self { Self { x, y, z, w } }
28    pub const fn truncate(self) -> Vec3 { vec3(self.x, self.y, self.z) }
29    ///create a vector where x, y and z equals `value`.
30    pub const fn splat(value: f32) -> Self{ Self::new(value, value, value, value) }
31
32    ///the length of the vector before being square rooted.
33    pub fn length_squared(self) -> f32{
34        self.x*self.x + self.y*self.y + self.z*self.z + self.w*self.w
35    }
36    ///length of the vector.
37    pub fn length(self) -> f32{
38        self.length_squared().sqrt()
39    }
40    ///distance between two vectors before being square rooted.
41    pub fn distance_squared(self, other: Vec4) -> f32{
42        (self - other).length_squared()
43    }
44    ///distance between two vectors.
45    pub fn distance(self, other: Vec4) -> f32{
46        (self - other).length()
47    }
48    ///get the dot product of 2 vectors. equal to the cosign of the angle between vectors.
49    pub fn dot(self, other: Vec4) -> f32{
50        self.x * other.x + self.y * other.y + self.z * other.z + self.w * other.w
51    }
52    ///multiplies each value by the scalar.
53    pub fn scale(self, scalar: f32) -> Vec4{
54        Self::new(self.x * scalar, self.y * scalar, self.z * scalar, self.w * scalar)
55    }
56    ///makes the length of the vector equal to 1. on fail returns vec4 of zeros
57    pub fn normalise(self) -> Self{
58        let length = self.length();
59        if length == 0.0 { return vec4(0.0, 0.0, 0.0, 0.0); }
60        self.scale(1.0 / length)
61    }
62    ///transforms vector by the matrix
63    pub fn transform(self, matrix: Mat4) -> Vec4{
64        let a: Vec4 = matrix.row(0).into();
65        let b: Vec4 = matrix.row(1).into();
66        let c: Vec4 = matrix.row(2).into();
67        let d: Vec4 = matrix.row(3).into();
68        vec4(a.dot(self), b.dot(self), c.dot(self), d.dot(self))
69    }
70
71    /// returns whether the 2 components are equal
72    pub fn eq(self, rhs: Self) -> BVec4 { bvec4(self.x == rhs.x, self.y == rhs.y, self.z == rhs.z, self.w == rhs.w) }
73    /// returns whether the 1st components are less than the 2nd
74    pub fn less(self, rhs: Self) -> BVec4 { bvec4(self.x < rhs.x, self.y < rhs.y, self.z < rhs.z, self.w < rhs.w) }
75    /// returns whether the 1st components are more than the 2nd
76    pub fn more(self, rhs: Self) -> BVec4 { bvec4(self.x > rhs.x, self.y > rhs.y, self.z > rhs.z, self.w > rhs.w) }
77    /// returns whether the 1st components are less than or equal to the 2nd
78    pub fn less_or_eq(self, rhs: Self) -> BVec4 {
79        bvec4(self.x <= rhs.x, self.y <= rhs.y, self.z <= rhs.z, self.w <= rhs.w)
80    }
81    /// returns whether the 1st components are more than or equal to the 2nd
82    pub fn more_or_eq(self, rhs: Self) -> BVec4 {
83        bvec4(self.x >= rhs.x, self.y >= rhs.y, self.z >= rhs.z, self.w >= rhs.w)
84    }
85}
86impl std::ops::Mul<Vec4> for f32 {
87    fn mul(self, rhs: Vec4) -> Self::Output { rhs * self }
88    type Output = Vec4;
89}
90impl std::ops::Mul<f32> for Vec4 {
91    fn mul(self, rhs: f32) -> Self::Output { self.scale(rhs) }
92    type Output = Self;
93}
94impl std::ops::MulAssign<f32> for Vec4 { fn mul_assign(&mut self, rhs: f32) { *self = *self * rhs } }
95impl std::ops::Div<Vec4> for f32 {
96    fn div(self, rhs: Vec4) -> Self::Output { Vec4::splat(self) / rhs }
97    type Output = Vec4;
98}
99impl std::ops::Div<f32> for Vec4 {
100    fn div(self, rhs: f32) -> Self::Output { self.scale(1.0/rhs) }
101    type Output = Self;
102}
103impl std::ops::DivAssign<f32> for Vec4 { fn div_assign(&mut self, rhs: f32) { *self = *self / rhs } }
104impl std::ops::Rem<Vec4> for f32 {
105    fn rem(self, rhs: Vec4) -> Self::Output { Vec4::splat(self) % rhs }
106    type Output = Vec4;
107}
108impl std::ops::Rem<f32> for Vec4 {
109    fn rem(self, rhs: f32) -> Self::Output { self % Vec4::splat(rhs) }
110    type Output = Self;
111}
112impl std::ops::RemAssign<f32> for Vec4 { fn rem_assign(&mut self, rhs: f32) { *self = *self % rhs } }
113impl AsUniformValue for Vec4{
114    fn as_uniform_value(&self) -> glium::uniforms::UniformValue<'_> {
115        glium::uniforms::UniformValue::Vec4([self.x, self.y, self.z, self.w])
116    }
117}
118impl From<[f32; 4]> for Vec4 {
119    fn from(value: [f32; 4]) -> Self {
120        Self { x: value[0], y: value[1], z: value[2], w: value[3] }
121    }
122}
123impl From<(f32, f32, f32, f32)> for Vec4 {
124    fn from(value: (f32, f32, f32, f32)) -> Self {
125        Self { x: value.0, y: value.1, z: value.2, w: value.3 }
126    }
127}
128impl From<Vec4> for [f32; 4] {
129    fn from(value: Vec4) -> Self {
130        [value.x, value.y, value.z, value.w]
131    }
132}
133impl From<Vec4> for (f32, f32, f32, f32) {
134    fn from(value: Vec4) -> Self {
135        (value.x, value.y, value.z, value.w)
136    }
137}
138///create a vector with an x, y, z and w coordinate.
139pub const fn vec4(x: f32, y: f32, z: f32, w: f32) -> Vec4{
140    Vec4 { x, y, z, w }
141}