vec3/
transform.rs

1use core::ops::{Add, Div, Mul, Neg, Sub};
2
3use num_traits::{One, Zero};
4
5/// # Example
6/// ```
7/// let mut v = vec3::new_zero();
8/// vec3::transform_mat2(&mut v, &vec3::new_one(), &[1_f32, 0_f32, 0_f32, 1_f32]);
9/// assert_eq!(v, vec3::new_one());
10/// ```
11#[inline]
12pub fn transform_mat2<'out, T>(out: &'out mut [T; 3], v: &[T; 3], m: &[T; 4]) -> &'out mut [T; 3]
13where
14    T: Clone + Add<T, Output = T>,
15    for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
16{
17    out[0] = &v[0] * &m[0] + &v[1] * &m[2];
18    out[1] = &v[0] * &m[1] + &v[1] * &m[3];
19    out[2] = v[2].clone();
20    out
21}
22/// # Example
23/// ```
24/// let mut v = vec3::new_one();
25/// vec3::transform_mat2_mut(&mut v, &[1_f32, 0_f32, 0_f32, 1_f32]);
26/// assert_eq!(v, vec3::new_one());
27/// ```
28#[inline]
29pub fn transform_mat2_mut<'out, T>(out: &'out mut [T; 3], m: &[T; 4]) -> &'out mut [T; 3]
30where
31    T: Clone + Add<T, Output = T>,
32    for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
33{
34    let tmp = out.clone();
35    transform_mat2(out, &tmp, m)
36}
37/// # Example
38/// ```
39/// let mut v = vec3::new_zero();
40/// vec3::transform_mat3(&mut v, &vec3::new_one(),
41///     &[1_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 1_f32],
42/// );
43/// assert_eq!(v, vec3::new_one());
44/// ```
45#[inline]
46pub fn transform_mat3<'out, T>(out: &'out mut [T; 3], v: &[T; 3], m: &[T; 9]) -> &'out mut [T; 3]
47where
48    T: Add<T, Output = T>,
49    for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
50{
51    out[0] = &v[0] * &m[0] + &v[1] * &m[3] + &v[2] * &m[6];
52    out[1] = &v[0] * &m[1] + &v[1] * &m[4] + &v[2] * &m[7];
53    out[2] = &v[0] * &m[2] + &v[1] * &m[5] + &v[2] * &m[8];
54    out
55}
56/// # Example
57/// ```
58/// let mut v = vec3::new_one();
59/// vec3::transform_mat3_mut(&mut v,
60///     &[1_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 1_f32],
61/// );
62/// assert_eq!(v, vec3::new_one());
63/// ```
64#[inline]
65pub fn transform_mat3_mut<'out, T>(out: &'out mut [T; 3], m: &[T; 9]) -> &'out mut [T; 3]
66where
67    T: Clone + Add<T, Output = T>,
68    for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
69{
70    let tmp = out.clone();
71    transform_mat3(out, &tmp, m)
72}
73/// # Example
74/// ```
75/// let mut v = vec3::new_zero();
76/// vec3::transform_mat4(&mut v, &vec3::new_one(),
77///     &[1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32]
78/// );
79/// assert_eq!(v, vec3::new_one());
80/// ```
81#[inline]
82pub fn transform_mat4<'out, T>(out: &'out mut [T; 3], v: &[T; 3], m: &[T; 16]) -> &'out mut [T; 3]
83where
84    T: Clone + Add<T, Output = T>,
85    for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
86{
87    out[0] = &v[0] * &m[0] + &v[1] * &m[4] + &v[2] * &m[8] + m[12].clone();
88    out[1] = &v[0] * &m[1] + &v[1] * &m[5] + &v[2] * &m[9] + m[13].clone();
89    out[2] = &v[0] * &m[2] + &v[1] * &m[6] + &v[2] * &m[10] + m[14].clone();
90    out
91}
92/// # Example
93/// ```
94/// let mut v = vec3::new_one();
95/// vec3::transform_mat4_mut(&mut v,
96///     &[1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32]
97/// );
98/// assert_eq!(v, vec3::new_one());
99/// ```
100#[inline]
101pub fn transform_mat4_mut<'out, T>(out: &'out mut [T; 3], m: &[T; 16]) -> &'out mut [T; 3]
102where
103    T: Clone + Add<T, Output = T>,
104    for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
105{
106    let tmp = out.clone();
107    transform_mat4(out, &tmp, m)
108}
109/// # Example
110/// ```
111/// let mut v = vec3::new_zero();
112/// vec3::transform_mat4_rotation(&mut v, &vec3::new_one(),
113///     &[1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32]
114/// );
115/// assert_eq!(v, vec3::new_one());
116/// ```
117#[inline]
118pub fn transform_mat4_rotation<'out, T>(
119    out: &'out mut [T; 3],
120    v: &[T; 3],
121    m: &[T; 16],
122) -> &'out mut [T; 3]
123where
124    T: Clone + Add<T, Output = T>,
125    for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
126{
127    out[0] = &v[0] * &m[0] + &v[1] * &m[4] + &v[2] * &m[8];
128    out[1] = &v[0] * &m[1] + &v[1] * &m[5] + &v[2] * &m[9];
129    out[2] = &v[0] * &m[2] + &v[1] * &m[6] + &v[2] * &m[10];
130    out
131}
132/// # Example
133/// ```
134/// let mut v = vec3::new_one();
135/// vec3::transform_mat4_rotation_mut(&mut v,
136///     &[1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32]
137/// );
138/// assert_eq!(v, vec3::new_one());
139/// ```
140#[inline]
141pub fn transform_mat4_rotation_mut<'out, T>(out: &'out mut [T; 3], m: &[T; 16]) -> &'out mut [T; 3]
142where
143    T: Clone + Add<T, Output = T>,
144    for<'a, 'b> &'a T: Mul<&'b T, Output = T>,
145{
146    let tmp = out.clone();
147    transform_mat4(out, &tmp, m)
148}
149/// # Example
150/// ```
151/// let mut v = vec3::new_zero();
152/// vec3::transform_mat4_projection(&mut v, &vec3::new_one(),
153///     &[1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32]
154/// );
155/// assert_eq!(v, vec3::new_one());
156/// ```
157#[inline]
158pub fn transform_mat4_projection<'out, T>(
159    out: &'out mut [T; 3],
160    v: &[T; 3],
161    m: &[T; 16],
162) -> &'out mut [T; 3]
163where
164    T: Clone + One + Zero + Add<T, Output = T>,
165    for<'a, 'b> &'a T: Div<&'b T, Output = T> + Mul<&'b T, Output = T>,
166{
167    let d = &v[0] * &m[3] + &v[1] * &m[7] + &v[2] * &m[11] + m[15].clone();
168    let inv_d = if d.is_zero() { d } else { &T::one() / &d };
169
170    out[0] = &(&v[0] * &m[0] + &v[1] * &m[4] + &v[2] * &m[8] + m[12].clone()) * &inv_d;
171    out[1] = &(&v[0] * &m[1] + &v[1] * &m[5] + &v[2] * &m[9] + m[13].clone()) * &inv_d;
172    out[2] = &(&v[0] * &m[2] + &v[1] * &m[6] + &v[2] * &m[10] + m[14].clone()) * &inv_d;
173    out
174}
175/// # Example
176/// ```
177/// let mut v = vec3::new_one();
178/// vec3::transform_mat4_projection_mut(&mut v,
179///     &[1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32, 0_f32, 0_f32, 0_f32, 0_f32, 1_f32]
180/// );
181/// assert_eq!(v, vec3::new_one());
182/// ```
183#[inline]
184pub fn transform_mat4_projection_mut<'out, T>(
185    out: &'out mut [T; 3],
186    m: &[T; 16],
187) -> &'out mut [T; 3]
188where
189    T: Clone + One + Zero + Add<T, Output = T>,
190    for<'a, 'b> &'a T: Div<&'b T, Output = T> + Mul<&'b T, Output = T>,
191{
192    let tmp = out.clone();
193    transform_mat4_projection(out, &tmp, m)
194}
195/// # Example
196/// ```
197/// let mut v = vec3::new_zero();
198/// vec3::transform_quat(&mut v, &vec3::new_one(), &[0_f32, 0_f32, 0_f32, 1_f32]);
199/// assert_eq!(v, vec3::new_one());
200/// ```
201#[inline]
202pub fn transform_quat<'out, T>(out: &'out mut [T; 3], v: &[T; 3], q: &[T; 4]) -> &'out mut [T; 3]
203where
204    T: Add<T, Output = T> + Sub<T, Output = T>,
205    for<'a, 'b> &'a T: Neg<Output = T> + Mul<&'b T, Output = T>,
206{
207    let ix = &q[3] * &v[0] + &q[1] * &v[2] - &q[2] * &v[1];
208    let iy = &q[3] * &v[1] + &q[2] * &v[0] - &q[0] * &v[2];
209    let iz = &q[3] * &v[2] + &q[0] * &v[1] - &q[1] * &v[0];
210    let iw = &-&q[0] * &v[0] - &q[1] * &v[1] - &q[2] * &v[2];
211
212    out[0] = &ix * &q[3] + &iw * &-&q[0] + &iy * &-&q[2] - &iz * &-&q[1];
213    out[1] = &iy * &q[3] + &iw * &-&q[1] + &iz * &-&q[0] - &ix * &-&q[2];
214    out[2] = &iz * &q[3] + &iw * &-&q[2] + &ix * &-&q[1] - &iy * &-&q[0];
215    out
216}
217/// # Example
218/// ```
219/// let mut v = vec3::new_one();
220/// vec3::transform_quat_mut(&mut v, &[0_f32, 0_f32, 0_f32, 1_f32]);
221/// assert_eq!(v, vec3::new_one());
222/// ```
223#[inline]
224pub fn transform_quat_mut<'out, T>(out: &'out mut [T; 3], q: &[T; 4]) -> &'out mut [T; 3]
225where
226    T: Clone + Add<T, Output = T> + Sub<T, Output = T>,
227    for<'a, 'b> &'a T: Neg<Output = T> + Mul<&'b T, Output = T>,
228{
229    let tmp = out.clone();
230    transform_quat(out, &tmp, q)
231}