#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct InvertedTriangleConfig {
pub shoulder_broadness: f32,
pub chest_width: f32,
pub hip_narrowness: f32,
}
impl Default for InvertedTriangleConfig {
fn default() -> Self {
InvertedTriangleConfig {
shoulder_broadness: 0.85,
chest_width: 0.7,
hip_narrowness: 0.6,
}
}
}
#[derive(Debug, Clone)]
pub struct InvertedTriangleMorph {
pub intensity: f32,
pub config: InvertedTriangleConfig,
pub enabled: bool,
}
pub fn new_inverted_triangle_morph() -> InvertedTriangleMorph {
InvertedTriangleMorph {
intensity: 0.0,
config: InvertedTriangleConfig::default(),
enabled: true,
}
}
pub fn inv_set_intensity(m: &mut InvertedTriangleMorph, v: f32) {
m.intensity = v.clamp(0.0, 1.0);
}
pub fn inv_shoulder_broad(m: &InvertedTriangleMorph) -> f32 {
m.intensity * m.config.shoulder_broadness
}
pub fn inv_chest_width(m: &InvertedTriangleMorph) -> f32 {
m.intensity * m.config.chest_width
}
pub fn inv_hip_narrow(m: &InvertedTriangleMorph) -> f32 {
m.intensity * m.config.hip_narrowness
}
pub fn inv_shoulder_hip_ratio(m: &InvertedTriangleMorph) -> f32 {
1.0 + 0.4 * m.intensity
}
pub fn inv_to_json(m: &InvertedTriangleMorph) -> String {
format!(
r#"{{"intensity":{:.3},"shoulder_broad":{:.3},"enabled":{}}}"#,
m.intensity,
inv_shoulder_broad(m),
m.enabled
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_zero() {
let m = new_inverted_triangle_morph();
assert!((m.intensity - 0.0).abs() < 1e-6 );
}
#[test]
fn clamp() {
let mut m = new_inverted_triangle_morph();
inv_set_intensity(&mut m, 5.0);
assert!((m.intensity - 1.0).abs() < 1e-6 );
}
#[test]
fn shoulder_broad_at_full() {
let mut m = new_inverted_triangle_morph();
inv_set_intensity(&mut m, 1.0);
assert!((inv_shoulder_broad(&m) - m.config.shoulder_broadness).abs() < 1e-6 );
}
#[test]
fn hip_narrow_zero_at_zero() {
let m = new_inverted_triangle_morph();
assert!((inv_hip_narrow(&m) - 0.0).abs() < 1e-6 );
}
#[test]
fn shoulder_hip_ratio_increases() {
let mut m = new_inverted_triangle_morph();
inv_set_intensity(&mut m, 0.0);
let r0 = inv_shoulder_hip_ratio(&m);
inv_set_intensity(&mut m, 1.0);
let r1 = inv_shoulder_hip_ratio(&m);
assert!(r1 > r0 );
}
#[test]
fn json_has_shoulder() {
let m = new_inverted_triangle_morph();
assert!(inv_to_json(&m).contains("shoulder") );
}
#[test]
fn enabled_default() {
let m = new_inverted_triangle_morph();
assert!(m.enabled );
}
#[test]
fn config_positive() {
let m = new_inverted_triangle_morph();
assert!(m.config.chest_width > 0.0 );
}
}