#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct MeshDeformBinding {
pub cage_vertex_indices: [usize; 4],
pub weights: [f32; 4],
}
impl Default for MeshDeformBinding {
fn default() -> Self {
MeshDeformBinding {
cage_vertex_indices: [0, 1, 2, 3],
weights: [0.25; 4],
}
}
}
#[derive(Debug, Clone)]
pub struct MeshDeformMorph {
pub bindings: Vec<MeshDeformBinding>,
pub blend_weight: f32,
pub bound: bool,
}
impl MeshDeformMorph {
pub fn new(vertex_count: usize) -> Self {
MeshDeformMorph {
bindings: (0..vertex_count)
.map(|_| MeshDeformBinding::default())
.collect(),
blend_weight: 0.0,
bound: false,
}
}
}
pub fn new_mesh_deform_morph(vertex_count: usize) -> MeshDeformMorph {
MeshDeformMorph::new(vertex_count)
}
pub fn mdm_set_weight(mdm: &mut MeshDeformMorph, weight: f32) {
mdm.blend_weight = weight.clamp(0.0, 1.0);
}
pub fn mdm_bind(mdm: &mut MeshDeformMorph) {
mdm.bound = true;
}
pub fn mdm_unbind(mdm: &mut MeshDeformMorph) {
mdm.bound = false;
}
pub fn mdm_vertex_count(mdm: &MeshDeformMorph) -> usize {
mdm.bindings.len()
}
pub fn mdm_to_json(mdm: &MeshDeformMorph) -> String {
format!(
r#"{{"vertices":{},"weight":{:.4},"bound":{}}}"#,
mdm.bindings.len(),
mdm.blend_weight,
mdm.bound
)
}
pub fn mdm_validate_weights(mdm: &MeshDeformMorph) -> bool {
mdm.bindings
.iter()
.all(|b| (b.weights.iter().sum::<f32>() - 1.0).abs() < 1e-4)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_mdm_vertex_count() {
let m = new_mesh_deform_morph(8);
assert_eq!(mdm_vertex_count(&m), 8 ,);
}
#[test]
fn test_initial_weight_zero() {
let m = new_mesh_deform_morph(3);
assert!((m.blend_weight).abs() < 1e-6, );
}
#[test]
fn test_set_weight_clamps() {
let mut m = new_mesh_deform_morph(2);
mdm_set_weight(&mut m, 5.0);
assert!((m.blend_weight - 1.0).abs() < 1e-5, );
}
#[test]
fn test_bind_sets_bound() {
let mut m = new_mesh_deform_morph(2);
mdm_bind(&mut m);
assert!(m.bound ,);
}
#[test]
fn test_unbind_clears_bound() {
let mut m = new_mesh_deform_morph(2);
mdm_bind(&mut m);
mdm_unbind(&mut m);
assert!(!m.bound ,);
}
#[test]
fn test_initial_weights_valid() {
let m = new_mesh_deform_morph(4);
assert!(mdm_validate_weights(&m), );
}
#[test]
fn test_to_json_contains_weight() {
let m = new_mesh_deform_morph(3);
let j = mdm_to_json(&m);
assert!(j.contains("weight") ,);
}
#[test]
fn test_to_json_contains_bound() {
let m = new_mesh_deform_morph(3);
let j = mdm_to_json(&m);
assert!(j.contains("bound") ,);
}
#[test]
fn test_set_weight_negative_clamps() {
let mut m = new_mesh_deform_morph(2);
mdm_set_weight(&mut m, -1.0);
assert!((m.blend_weight).abs() < 1e-6, );
}
#[test]
fn test_initial_not_bound() {
let m = new_mesh_deform_morph(5);
assert!(!m.bound ,);
}
}