#![allow(dead_code)]
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct MorphChannel {
name: String,
weight: f32,
active: bool,
}
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ChannelBlend {
Additive,
Override,
Multiply,
}
#[allow(dead_code)]
pub fn new_morph_channel(name: &str) -> MorphChannel {
MorphChannel {
name: name.to_string(),
weight: 0.0,
active: true,
}
}
#[allow(dead_code)]
pub fn channel_set_weight(ch: &mut MorphChannel, w: f32) {
ch.weight = w.clamp(0.0, 1.0);
}
#[allow(dead_code)]
pub fn channel_get_weight(ch: &MorphChannel) -> f32 {
ch.weight
}
#[allow(dead_code)]
pub fn channel_blend(a: f32, b: f32, mode: ChannelBlend) -> f32 {
match mode {
ChannelBlend::Additive => (a + b).clamp(0.0, 1.0),
ChannelBlend::Override => b,
ChannelBlend::Multiply => a * b,
}
}
#[allow(dead_code)]
pub fn channel_is_active(ch: &MorphChannel) -> bool {
ch.active
}
#[allow(dead_code)]
pub fn channel_name(ch: &MorphChannel) -> &str {
&ch.name
}
#[allow(dead_code)]
pub fn channel_reset(ch: &mut MorphChannel) {
ch.weight = 0.0;
}
#[allow(dead_code)]
pub fn channel_count(channels: &[MorphChannel]) -> usize {
channels.len()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_morph_channel() {
let ch = new_morph_channel("smile");
assert_eq!(channel_name(&ch), "smile");
assert_eq!(channel_get_weight(&ch), 0.0);
}
#[test]
fn test_channel_set_weight() {
let mut ch = new_morph_channel("a");
channel_set_weight(&mut ch, 0.5);
assert!((channel_get_weight(&ch) - 0.5).abs() < 1e-6);
}
#[test]
fn test_channel_set_weight_clamps() {
let mut ch = new_morph_channel("a");
channel_set_weight(&mut ch, 2.0);
assert!((channel_get_weight(&ch) - 1.0).abs() < 1e-6);
channel_set_weight(&mut ch, -1.0);
assert_eq!(channel_get_weight(&ch), 0.0);
}
#[test]
fn test_channel_blend_additive() {
let r = channel_blend(0.3, 0.5, ChannelBlend::Additive);
assert!((r - 0.8).abs() < 1e-6);
}
#[test]
fn test_channel_blend_override() {
let r = channel_blend(0.3, 0.7, ChannelBlend::Override);
assert!((r - 0.7).abs() < 1e-6);
}
#[test]
fn test_channel_blend_multiply() {
let r = channel_blend(0.5, 0.4, ChannelBlend::Multiply);
assert!((r - 0.2).abs() < 1e-6);
}
#[test]
fn test_channel_is_active() {
let ch = new_morph_channel("x");
assert!(channel_is_active(&ch));
}
#[test]
fn test_channel_reset() {
let mut ch = new_morph_channel("x");
channel_set_weight(&mut ch, 0.8);
channel_reset(&mut ch);
assert_eq!(channel_get_weight(&ch), 0.0);
}
#[test]
fn test_channel_count() {
let chs = vec![new_morph_channel("a"), new_morph_channel("b")];
assert_eq!(channel_count(&chs), 2);
}
#[test]
fn test_channel_blend_additive_clamps() {
let r = channel_blend(0.8, 0.5, ChannelBlend::Additive);
assert!((r - 1.0).abs() < 1e-6);
}
}