1#[cfg(feature = "Matrix3")]
2use crate::mat3::Mat3;
3#[cfg(feature = "Matrix4")]
4use crate::mat4::Mat4;
5use crate::slice_ops::*;
6#[cfg(feature = "Matrix4")]
7use crate::vec4::Vec4;
8#[cfg(any(feature = "Matrix3", feature = "Matrix4"))]
9use crate::vector::MulVectorMatrix;
10use crate::vector::Vector;
11use std::f32;
12
13pub type Vec3 = [f32; 3];
14
15impl_vector!(Vec3, 3);
16
17#[cfg(feature = "Matrix3")]
18impl MulVectorMatrix<Mat3> for Vec3 {
19 type VectorType = Vec3;
20
21 fn mul_matrix_left(&self, lhs: &Mat3) -> Self::VectorType {
22 let x = self[0];
23 let y = self[1];
24 let z = self[2];
25
26 [
27 lhs[0] * x + lhs[1] * y + lhs[2] * z,
28 lhs[3] * x + lhs[4] * y + lhs[5] * z,
29 lhs[6] * x + lhs[7] * y + lhs[8] * z,
30 ]
31 }
32
33 fn mul_matrix(&self, rhs: &Mat3) -> Self::VectorType {
34 let x = self[0];
35 let y = self[1];
36 let z = self[2];
37
38 [
39 rhs[0] * x + rhs[3] * y + rhs[6] * z,
40 rhs[1] * x + rhs[4] * y + rhs[7] * z,
41 rhs[2] * x + rhs[5] * y + rhs[8] * z,
42 ]
43 }
44}
45
46#[cfg(feature = "Matrix4")]
47impl MulVectorMatrix<Mat4> for Vec3 {
48 type VectorType = Vec4;
49
50 fn mul_matrix_left(&self, lhs: &Mat4) -> Self::VectorType {
53 let x = self[0];
54 let y = self[1];
55 let z = self[2];
56 [
59 lhs[0] * x + lhs[1] * y + lhs[2] * z + lhs[3],
60 lhs[4] * x + lhs[5] * y + lhs[6] * z + lhs[7],
61 lhs[8] * x + lhs[9] * y + lhs[10] * z + lhs[11],
62 lhs[12] * x + lhs[13] * y + lhs[14] * z + lhs[15],
63 ]
64 }
65
66 fn mul_matrix(&self, rhs: &Mat4) -> Self::VectorType {
69 let x = self[0];
70 let y = self[1];
71 let z = self[2];
72 [
75 rhs[0] * x + rhs[4] * y + rhs[8] * z + rhs[12],
76 rhs[1] * x + rhs[5] * y + rhs[9] * z + rhs[13],
77 rhs[2] * x + rhs[6] * y + rhs[10] * z + rhs[14],
78 rhs[3] * x + rhs[7] * y + rhs[11] * z + rhs[15],
79 ]
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use crate::utils::almost_eq;
87
88 #[test]
89 #[cfg(feature = "Matrix3")]
90 fn vec3_mul_matrix_left() {
91 let a = [1., 2., 3., 4., 5., 6., 7., 8., 9.];
92 let b = [11., 12., 13.];
93
94 let c = b.mul_matrix_left(&a);
95 assert_eq!(c, [74., 182., 290.]);
96 }
97
98 #[test]
99 #[cfg(feature = "Matrix3")]
100 fn vec3_mul_matrix() {
101 let a = [1., 2., 3., 4., 5., 6., 7., 8., 9.];
102 let b = [11., 12., 13.];
103
104 let c = b.mul_matrix(&a);
105 assert_eq!(c, [150., 186., 222.]);
106 }
107 #[test]
108 #[cfg(feature = "Matrix4")]
109 fn vec3_mul_matrix4() {
110 let a = [
111 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
112 ];
113 let b = [17., 18., 19.];
114
115 let c = b.mul_matrix(&a);
116 assert_eq!(c, [291., 346., 401., 456.]);
117 }
118
119 #[test]
120 #[cfg(feature = "Matrix4")]
121 fn vec3_mul_matrix4_left() {
122 let a = [
123 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
124 ];
125 let b = [17., 18., 19.];
126
127 let c = b.mul_matrix_left(&a);
128 assert_eq!(c, [114., 334., 554., 774.]);
129 }
130
131 #[test]
132 fn vec3_is_immutable() {
133 let b = [2., 3., 4.];
134 let c = [3., 2., 3.];
135
136 let _d = b.add(&c);
137 assert_eq!(b, [2., 3., 4.]);
138 }
139
140 #[test]
141 fn vec3_add() {
142 let a = [1., 2., 3.];
143 let b = [-1., -2., -3.];
144
145 assert_eq!(a.add(&b), [0., 0., 0.]);
146 }
147
148 #[test]
149 fn vec3_sub() {
150 let a = [1., 2., 3.];
151 let b = [1., 2., 3.];
152
153 assert_eq!(a.sub(&b), [0., 0., 0.]);
154 }
155
156 #[test]
157 fn vec3_mul() {
158 let a = [1., 2., 3.];
159 let b = [2., 3., 4.];
160
161 assert_eq!(a.mul(&b), [2., 6., 12.]);
162 }
163
164 #[test]
165 fn vec3_scale() {
166 let a = [1., 2., 3.];
167
168 assert_eq!(a.scale(3.), [3., 6., 9.]);
169 }
170
171 #[test]
172 fn vec3_dot() {
173 let a = [1., 2., 3.];
174 let b = [2., 3., 4.];
175
176 assert_eq!(a.dot(&b), 2. + 6. + 12.);
177 }
178 #[test]
179 fn vec3_mag() {
180 let b = [2., 3., 4.];
181 assert!(almost_eq(&[b.mag()], &[5.385164807]));
182 }
183 #[test]
184 fn vec3_mag2() {
185 let b = [2., 3., 4.];
186 assert!(almost_eq(&[b.mag2()], &[29.]));
187 }
188}