Skip to main content

oxihuman_morph/
chest_muscle_morph.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5pub struct ChestMuscleMorph {
6    pub pectoralis_major: f32,
7    pub separation: f32,
8    pub upper_chest: f32,
9}
10
11pub fn new_chest_muscle_morph() -> ChestMuscleMorph {
12    ChestMuscleMorph {
13        pectoralis_major: 0.0,
14        separation: 0.0,
15        upper_chest: 0.0,
16    }
17}
18
19pub fn chest_set_pec(m: &mut ChestMuscleMorph, v: f32) {
20    m.pectoralis_major = v.clamp(0.0, 1.0);
21}
22
23pub fn chest_is_muscular(m: &ChestMuscleMorph) -> bool {
24    m.pectoralis_major > 0.5
25}
26
27pub fn chest_overall_weight(m: &ChestMuscleMorph) -> f32 {
28    (m.pectoralis_major + m.separation + m.upper_chest) / 3.0
29}
30
31pub fn chest_blend(a: &ChestMuscleMorph, b: &ChestMuscleMorph, t: f32) -> ChestMuscleMorph {
32    let t = t.clamp(0.0, 1.0);
33    ChestMuscleMorph {
34        pectoralis_major: a.pectoralis_major + (b.pectoralis_major - a.pectoralis_major) * t,
35        separation: a.separation + (b.separation - a.separation) * t,
36        upper_chest: a.upper_chest + (b.upper_chest - a.upper_chest) * t,
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn test_new_zero() {
46        /* all zero */
47        let m = new_chest_muscle_morph();
48        assert!((m.pectoralis_major).abs() < 1e-5);
49    }
50
51    #[test]
52    fn test_set_pec_clamped() {
53        /* clamped */
54        let mut m = new_chest_muscle_morph();
55        chest_set_pec(&mut m, 1.5);
56        assert!((m.pectoralis_major - 1.0).abs() < 1e-5);
57    }
58
59    #[test]
60    fn test_not_muscular_by_default() {
61        /* not muscular */
62        let m = new_chest_muscle_morph();
63        assert!(!chest_is_muscular(&m));
64    }
65
66    #[test]
67    fn test_overall_weight_zero() {
68        /* zero weight */
69        let m = new_chest_muscle_morph();
70        assert!((chest_overall_weight(&m)).abs() < 1e-5);
71    }
72
73    #[test]
74    fn test_blend() {
75        /* midpoint */
76        let a = new_chest_muscle_morph();
77        let b = ChestMuscleMorph {
78            pectoralis_major: 1.0,
79            separation: 1.0,
80            upper_chest: 1.0,
81        };
82        let c = chest_blend(&a, &b, 0.5);
83        assert!((c.pectoralis_major - 0.5).abs() < 1e-5);
84    }
85}