#![allow(dead_code)]
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MeshHash {
pub hash_value: u64,
}
fn hash_f32_slice(data: &[[f32; 3]]) -> u64 {
let mut hasher = DefaultHasher::new();
for v in data {
for &f in v {
f.to_bits().hash(&mut hasher);
}
}
hasher.finish()
}
#[allow(dead_code)]
pub fn hash_positions(positions: &[[f32; 3]]) -> u64 {
hash_f32_slice(positions)
}
#[allow(dead_code)]
pub fn hash_normals(normals: &[[f32; 3]]) -> u64 {
hash_f32_slice(normals)
}
#[allow(dead_code)]
pub fn hash_uvs(uvs: &[[f32; 2]]) -> u64 {
let mut hasher = DefaultHasher::new();
for uv in uvs {
for &f in uv {
f.to_bits().hash(&mut hasher);
}
}
hasher.finish()
}
#[allow(dead_code)]
pub fn hash_indices(indices: &[[u32; 3]]) -> u64 {
let mut hasher = DefaultHasher::new();
for tri in indices {
for &i in tri {
i.hash(&mut hasher);
}
}
hasher.finish()
}
#[allow(dead_code)]
pub fn hash_mesh_full(
positions: &[[f32; 3]],
normals: &[[f32; 3]],
uvs: &[[f32; 2]],
indices: &[[u32; 3]],
) -> u64 {
let mut hasher = DefaultHasher::new();
hash_positions(positions).hash(&mut hasher);
hash_normals(normals).hash(&mut hasher);
hash_uvs(uvs).hash(&mut hasher);
hash_indices(indices).hash(&mut hasher);
hasher.finish()
}
#[allow(dead_code)]
pub fn mesh_hash_to_hex(hash: u64) -> String {
format!("{:016x}", hash)
}
#[allow(dead_code)]
pub fn mesh_hashes_equal(a: u64, b: u64) -> bool {
a == b
}
#[allow(dead_code)]
pub fn hash_vertex_count(count: usize) -> u64 {
let mut hasher = DefaultHasher::new();
count.hash(&mut hasher);
hasher.finish()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hash_positions() {
let p = vec![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
let h = hash_positions(&p);
assert_ne!(h, 0);
}
#[test]
fn test_hash_positions_deterministic() {
let p = vec![[1.0, 2.0, 3.0]];
assert_eq!(hash_positions(&p), hash_positions(&p));
}
#[test]
fn test_hash_normals() {
let n = vec![[0.0, 0.0, 1.0]];
let h = hash_normals(&n);
assert_ne!(h, 0);
}
#[test]
fn test_hash_uvs() {
let uvs = vec![[0.0, 1.0], [0.5, 0.5]];
let h = hash_uvs(&uvs);
assert_ne!(h, 0);
}
#[test]
fn test_hash_indices() {
let i = vec![[0u32, 1, 2]];
let h = hash_indices(&i);
assert_ne!(h, 0);
}
#[test]
fn test_hash_mesh_full() {
let p = vec![[0.0, 0.0, 0.0]];
let n = vec![[0.0, 0.0, 1.0]];
let uv = vec![[0.0, 0.0]];
let i = vec![[0u32, 0, 0]];
let h = hash_mesh_full(&p, &n, &uv, &i);
assert_ne!(h, 0);
}
#[test]
fn test_mesh_hash_to_hex() {
let hex = mesh_hash_to_hex(255);
assert_eq!(hex, "00000000000000ff");
}
#[test]
fn test_mesh_hashes_equal() {
assert!(mesh_hashes_equal(42, 42));
assert!(!mesh_hashes_equal(42, 43));
}
#[test]
fn test_hash_vertex_count() {
let h1 = hash_vertex_count(100);
let h2 = hash_vertex_count(200);
assert_ne!(h1, h2);
}
#[test]
fn test_different_positions_different_hash() {
let p1 = vec![[1.0, 0.0, 0.0]];
let p2 = vec![[0.0, 1.0, 0.0]];
assert_ne!(hash_positions(&p1), hash_positions(&p2));
}
}