#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct MrLevel {
pub positions: Vec<[f32; 3]>,
pub indices: Vec<u32>,
pub displacements: Vec<[f32; 3]>,
}
#[derive(Debug, Clone)]
pub struct MultiresolutionMesh {
pub levels: Vec<MrLevel>,
pub base_level: usize,
}
impl MultiresolutionMesh {
pub fn new(positions: Vec<[f32; 3]>, indices: Vec<u32>) -> Self {
let displacements = vec![[0.0_f32; 3]; positions.len()];
let level0 = MrLevel {
positions,
indices,
displacements,
};
Self {
levels: vec![level0],
base_level: 0,
}
}
pub fn level_count(&self) -> usize {
self.levels.len()
}
}
pub fn push_level(mr: &mut MultiresolutionMesh) {
let (new_positions, new_indices) = match mr.levels.last() {
Some(top) => (top.positions.clone(), top.indices.clone()),
None => return,
};
let displacements = vec![[0.0_f32; 3]; new_positions.len()];
mr.levels.push(MrLevel {
positions: new_positions,
indices: new_indices,
displacements,
});
}
pub fn pop_level(mr: &mut MultiresolutionMesh) -> bool {
if mr.levels.len() > 1 {
mr.levels.pop();
true
} else {
false
}
}
pub fn apply_displacement(
mr: &mut MultiresolutionMesh,
level: usize,
vertex: usize,
delta: [f32; 3],
) {
if let Some(lvl) = mr.levels.get_mut(level) {
if let Some(d) = lvl.displacements.get_mut(vertex) {
d[0] += delta[0];
d[1] += delta[1];
d[2] += delta[2];
}
}
}
pub fn total_displacement_magnitude(mr: &MultiresolutionMesh, level: usize) -> f32 {
if let Some(lvl) = mr.levels.get(level) {
lvl.displacements
.iter()
.map(|d| (d[0] * d[0] + d[1] * d[1] + d[2] * d[2]).sqrt())
.sum()
} else {
0.0
}
}
pub fn reset_displacements(mr: &mut MultiresolutionMesh, level: usize) {
if let Some(lvl) = mr.levels.get_mut(level) {
for d in &mut lvl.displacements {
*d = [0.0, 0.0, 0.0];
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn sample_mr() -> MultiresolutionMesh {
let pos = vec![[0.0_f32, 0.0, 0.0], [1.0, 0.0, 0.0], [0.5, 1.0, 0.0]];
let idx = vec![0u32, 1, 2];
MultiresolutionMesh::new(pos, idx)
}
#[test]
fn test_new_has_one_level() {
let mr = sample_mr();
assert_eq!(mr.level_count(), 1);
}
#[test]
fn test_push_level_increments_count() {
let mut mr = sample_mr();
push_level(&mut mr);
assert_eq!(mr.level_count(), 2);
}
#[test]
fn test_pop_level_decrements_count() {
let mut mr = sample_mr();
push_level(&mut mr);
assert!(pop_level(&mut mr));
assert_eq!(mr.level_count(), 1);
}
#[test]
fn test_pop_level_base_returns_false() {
let mut mr = sample_mr();
assert!(!pop_level(&mut mr));
assert_eq!(mr.level_count(), 1);
}
#[test]
fn test_apply_displacement_accumulates() {
let mut mr = sample_mr();
apply_displacement(&mut mr, 0, 0, [1.0, 0.0, 0.0]);
apply_displacement(&mut mr, 0, 0, [0.0, 2.0, 0.0]);
let d = mr.levels[0].displacements[0];
assert!((d[0] - 1.0).abs() < 1e-6);
assert!((d[1] - 2.0).abs() < 1e-6);
}
#[test]
fn test_total_displacement_magnitude_zero_initially() {
let mr = sample_mr();
assert!((total_displacement_magnitude(&mr, 0) - 0.0).abs() < 1e-6);
}
#[test]
fn test_total_displacement_magnitude_nonzero_after_apply() {
let mut mr = sample_mr();
apply_displacement(&mut mr, 0, 0, [3.0, 4.0, 0.0]);
let mag = total_displacement_magnitude(&mr, 0);
assert!(mag > 4.9);
}
#[test]
fn test_reset_displacements() {
let mut mr = sample_mr();
apply_displacement(&mut mr, 0, 0, [1.0, 1.0, 1.0]);
reset_displacements(&mut mr, 0);
assert!((total_displacement_magnitude(&mr, 0) - 0.0).abs() < 1e-6);
}
#[test]
fn test_invalid_level_ignored() {
let mut mr = sample_mr();
apply_displacement(&mut mr, 99, 0, [1.0, 0.0, 0.0]);
reset_displacements(&mut mr, 99);
assert_eq!(total_displacement_magnitude(&mr, 99), 0.0);
}
}