1#[cfg(feature = "utils")]
2
3use std::mem;
4use std::sync::atomic::AtomicUsize;
5use std::sync::atomic::Ordering::SeqCst;
6use time;
7
8static DEVICE_ID_COUNTER: AtomicUsize = AtomicUsize::new(0);
9
10#[allow(dead_code)]
12pub fn new_id() -> u32 {
13 DEVICE_ID_COUNTER.fetch_add(1, SeqCst) as u32
14}
15
16#[allow(dead_code)]
18pub fn timestamp() -> f64 {
19 let timespec = time::get_time();
20 timespec.sec as f64 * 1000.0 + (timespec.nsec as f64 * 1e-6)
21}
22
23#[allow(dead_code)]
25pub fn multiply_matrix(a: &[f32; 16], b: &[f32; 16], out: &mut [f32; 16]) {
26 let mut tmp: [f32; 16] = [0.; 16];
27
28 tmp[0] = b[0] * a[0] + b[1] * a[4] + b[2] * a[8] + b[3] * a[12];
29 tmp[1] = b[0] * a[1] + b[1] * a[5] + b[2] * a[9] + b[3] * a[13];
30 tmp[2] = b[0] * a[2] + b[1] * a[6] + b[2] * a[10] + b[3] * a[14];
31 tmp[3] = b[0] * a[3] + b[1] * a[7] + b[2] * a[11] + b[3] * a[15];
32
33 tmp[4] = b[4] * a[0] + b[5] * a[4] + b[6] * a[8] + b[7] * a[12];
34 tmp[5] = b[4] * a[1] + b[5] * a[5] + b[6] * a[9] + b[7] * a[13];
35 tmp[6] = b[4] * a[2] + b[5] * a[6] + b[6] * a[10] + b[7] * a[14];
36 tmp[7] = b[4] * a[3] + b[5] * a[7] + b[6] * a[11] + b[7] * a[15];
37
38 tmp[8] = b[8] * a[0] + b[9] * a[4] + b[10] * a[8] + b[11] * a[12];
39 tmp[9] = b[8] * a[1] + b[9] * a[5] + b[10] * a[9] + b[11] * a[13];
40 tmp[10] = b[8] * a[2] + b[9] * a[6] + b[10] * a[10] + b[11] * a[14];
41 tmp[11] = b[8] * a[3] + b[9] * a[7] + b[10] * a[11] + b[11] * a[15];
42
43 tmp[12] = b[12] * a[0] + b[13] * a[4] + b[14] * a[8] + b[15] * a[12];
44 tmp[13] = b[12] * a[1] + b[13] * a[5] + b[14] * a[9] + b[15] * a[13];
45 tmp[14] = b[12] * a[2] + b[13] * a[6] + b[14] * a[10] + b[15] * a[14];
46 tmp[15] = b[12] * a[3] + b[13] * a[7] + b[14] * a[11] + b[15] * a[15];
47
48 *out = tmp;
49}
50
51#[allow(dead_code)]
52pub fn inverse_matrix(m: &[f32; 16], out: &mut [f32; 16]) -> bool {
53 adjoint_matrix(&m, out);
54
55 let det = determinant4x4(m);
56 if det == 0f32 {
57 return false;
58 }
59
60 for i in 0..16 {
61 out[i] = out[i] / det;
62 }
63 true
64}
65
66#[allow(dead_code)]
67pub fn adjoint_matrix(m: &[f32; 16], out: &mut [f32; 16]) {
68 let mut tmp: [f32; 16] = [0.; 16];
69
70 tmp[0] = determinant3x3(m[5], m[9], m[13], m[6], m[10], m[14], m[7], m[11], m[15]);
71 tmp[4] = - determinant3x3(m[4], m[8], m[12], m[6], m[10], m[14], m[7], m[11], m[15]);
72 tmp[8] = determinant3x3(m[4], m[8], m[12], m[5], m[9], m[13], m[7], m[11], m[15]);
73 tmp[12] = - determinant3x3(m[4], m[8], m[12], m[5], m[9], m[13], m[6], m[10], m[14]);
74
75 tmp[1] = - determinant3x3(m[1], m[9], m[13], m[2], m[10], m[14], m[3], m[11], m[15]);
76 tmp[5] = determinant3x3(m[0], m[8], m[12], m[2], m[10], m[14], m[3], m[11], m[15]);
77 tmp[9] = - determinant3x3(m[0], m[8], m[12], m[1], m[9], m[13], m[3], m[11], m[15]);
78 tmp[13] = determinant3x3(m[0], m[8], m[12], m[1], m[9], m[13], m[2], m[10], m[14]);
79
80 tmp[2] = determinant3x3(m[1], m[5], m[13], m[2], m[6], m[14], m[3], m[7], m[15]);
81 tmp[6] = - determinant3x3(m[0], m[4], m[12], m[2], m[6], m[14], m[3], m[7], m[15]);
82 tmp[10] = determinant3x3(m[0], m[4], m[12], m[1], m[5], m[13], m[3], m[7], m[15]);
83 tmp[14] = - determinant3x3(m[0], m[4], m[12], m[1], m[5], m[13], m[2], m[6], m[14]);
84
85 tmp[3] = - determinant3x3(m[1], m[5], m[9], m[2], m[6], m[10], m[3], m[7], m[11]);
86 tmp[7] = determinant3x3(m[0], m[4], m[8], m[2], m[6], m[10], m[3], m[7], m[11]);
87 tmp[11] = - determinant3x3(m[0], m[4], m[8], m[1], m[5], m[9], m[3], m[7], m[11]);
88 tmp[15] = determinant3x3(m[0], m[4], m[8], m[1], m[5], m[9], m[2], m[6], m[10]);
89
90 *out = tmp;
91}
92
93#[allow(dead_code)]
94pub fn determinant4x4(m: &[f32; 16]) -> f32 {
95 m[0] * determinant3x3(m[5], m[9], m[13], m[6], m[10], m[14], m[7], m[11], m[15])
96 - m[1] * determinant3x3(m[4], m[8], m[12], m[6], m[10], m[14], m[7], m[11], m[15])
97 + m[2] * determinant3x3(m[4], m[8], m[12], m[5], m[9], m[13], m[7], m[11], m[15])
98 - m[3] * determinant3x3(m[4], m[8], m[12], m[5], m[9], m[13], m[6], m[10], m[14])
99}
100
101#[allow(dead_code)]
102fn determinant3x3(a1: f32, a2: f32, a3: f32, b1: f32, b2: f32, b3: f32, c1: f32, c2: f32, c3: f32) -> f32 {
103 a1 * determinant2x2(b2, b3, c2, c3)
104 - b1 * determinant2x2(a2, a3, c2, c3)
105 + c1 * determinant2x2(a2, a3, b2, b3)
106}
107
108#[allow(dead_code)]
109#[inline]
110fn determinant2x2(a: f32, b: f32, c: f32, d: f32) -> f32 {
111 a * d - b * c
112}
113
114#[allow(dead_code)]
116#[inline]
117pub fn matrix_to_quat(matrix: &[f32; 16]) -> [f32; 4] {
118 let m: &[[f32; 4]; 4] = unsafe { mem::transmute(matrix) };
119 let w = f32::max(0.0, 1.0 + m[0][0] + m[1][1] + m[2][2]).sqrt() * 0.5;
120 let mut x = f32::max(0.0, 1.0 + m[0][0] - m[1][1] - m[2][2]).sqrt() * 0.5;
121 let mut y = f32::max(0.0, 1.0 - m[0][0] + m[1][1] - m[2][2]).sqrt() * 0.5;
122 let mut z = f32::max(0.0, 1.0 - m[0][0] - m[1][1] + m[2][2]).sqrt() * 0.5;
123
124 x = copysign(x, m[2][1] - m[1][2]);
125 y = copysign(y, m[0][2] - m[2][0]);
126 z = copysign(z, m[1][0] - m[0][1]);
127
128 [x, y, z, w]
129}
130
131#[allow(dead_code)]
132#[inline]
133pub fn copysign(a: f32, b: f32) -> f32 {
134 if b == 0.0 {
135 0.0
136 } else {
137 a.abs() * b.signum()
138 }
139}