use std::{
collections::HashMap,
io::Read,
str,
};
use byteorder::{ByteOrder, LittleEndian};
pub fn get_box_size(matrix: &[[f32; 4]; 4]) -> (usize, usize, usize) {
let mut result = [0.0; 3];
let mut values = [
[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
];
for (i, value) in values.iter_mut().enumerate() {
let vector = mat4_mul_vec4(&matrix, value);
result[i] = vec3_norm(&vector);
}
((result[0] * 2.0) as usize, (result[1] * 2.0) as usize, (result[2] * 2.0) as usize)
}
pub fn get_value(dict: &HashMap<String, Vec<u8>>, key: &str) -> Vec<u8> {
if let Some(value) = dict.get(key) {
value.to_vec()
} else {
Default::default()
}
}
pub fn get_value_string(dict: &HashMap<String, Vec<u8>>, key: &str) -> String {
let value = get_value(dict, &key);
if value.len() > 0 {
str::from_utf8(&value).unwrap().to_string()
} else {
"".to_string()
}
}
pub fn get_value_int(dict: &HashMap<String, Vec<u8>>, key: &str) -> i32 {
let value = get_value(dict, &key);
if value.len() > 0 {
((value[0] as i32) << 0) +
((value[1] as i32) << 8) +
((value[2] as i32) << 16) +
((value[3] as i32) << 24)
} else {
0
}
}
fn mat4_mul_vec4(matrix: &[[f32; 4]; 4], vector: &[f32; 4]) -> [f32; 4] {
let mut result = [0.0; 4];
for i in 0..4 {
for j in 0..4 {
result[i] += matrix[i][j] * vector[j];
}
}
result
}
pub fn parse_float(byte_array: &[u8; 4]) -> f32 {
LittleEndian::read_f32(byte_array)
}
pub fn read(stream: &mut dyn Read, bytes: i32) -> Vec<u8> {
let mut result = vec![];
for _ in 0..bytes {
result.push(read_u8(stream));
}
result
}
pub fn read_dict(stream: &mut dyn Read, max_bytes: i32) -> HashMap<String, Vec<u8>> {
let mut result = HashMap::new();
let mut bytes_read = 0;
if max_bytes == 0 {
return result;
}
while let Some((key, value, key_value_length)) = read_dict_key_value(stream) {
result.insert(key, value);
bytes_read += key_value_length;
if bytes_read >= max_bytes {
break;
}
}
result
}
pub fn read_dict_key_value(stream: &mut dyn Read) -> Option<(String, Vec<u8>, i32)> {
let key_size = read_int(stream);
if key_size > 0 {
let key = read_str(stream, key_size);
let value_size = read_int(stream);
let value = read(stream, value_size);
Some((key.to_string(), value, key_size + value_size + 8))
} else {
None
}
}
pub fn read_int(stream: &mut dyn Read) -> i32 {
let mut buffer = [0; 4];
let _result = stream.read(&mut buffer);
((buffer[0] as i32) << 0) +
((buffer[1] as i32) << 8) +
((buffer[2] as i32) << 16) +
((buffer[3] as i32) << 24)
}
pub fn read_str(stream: &mut dyn Read, bytes: i32) -> String {
let result = read(stream, bytes);
match str::from_utf8(&result) {
Ok(string) => string.to_string(),
_ => "".to_string()
}
}
pub fn read_u8(stream: &mut dyn Read) -> u8 {
let mut buffer = [0; 1];
let _result = stream.read(&mut buffer);
(buffer[0] << 0)
}
fn vec3_dot(lhs: &[f32; 4], rhs: &[f32; 4]) -> f32 {
lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2]
}
fn vec3_norm(vector: &[f32; 4]) -> f32 {
let dot = vec3_dot(vector, vector);
dot.sqrt()
}