Skip to main content

oxihuman_viewer/
material_instance_view.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5//! Material instance debug view — shows material instance hierarchy and parameter overrides.
6
7/// Material instance view configuration.
8#[derive(Debug, Clone)]
9pub struct MaterialInstanceView {
10    pub enabled: bool,
11    pub total_instances: u32,
12    pub unique_base_materials: u32,
13    pub show_overrides: bool,
14    pub highlight_overdraw_materials: bool,
15}
16
17impl MaterialInstanceView {
18    pub fn new() -> Self {
19        Self {
20            enabled: false,
21            total_instances: 0,
22            unique_base_materials: 0,
23            show_overrides: true,
24            highlight_overdraw_materials: false,
25        }
26    }
27}
28
29impl Default for MaterialInstanceView {
30    fn default() -> Self {
31        Self::new()
32    }
33}
34
35/// Create a new material instance view.
36pub fn new_material_instance_view() -> MaterialInstanceView {
37    MaterialInstanceView::new()
38}
39
40/// Enable or disable material instance debug overlay.
41pub fn miv_set_enabled(v: &mut MaterialInstanceView, enabled: bool) {
42    v.enabled = enabled;
43}
44
45/// Update instance and base material counts.
46pub fn miv_update_counts(v: &mut MaterialInstanceView, instances: u32, base_materials: u32) {
47    v.total_instances = instances;
48    v.unique_base_materials = base_materials.min(instances.max(1));
49}
50
51/// Toggle override parameter display.
52pub fn miv_set_show_overrides(v: &mut MaterialInstanceView, show: bool) {
53    v.show_overrides = show;
54}
55
56/// Toggle overdraw-heavy material highlighting.
57pub fn miv_set_highlight_overdraw(v: &mut MaterialInstanceView, highlight: bool) {
58    v.highlight_overdraw_materials = highlight;
59}
60
61/// Compute average instances per base material.
62pub fn miv_avg_instances_per_base(v: &MaterialInstanceView) -> f32 {
63    if v.unique_base_materials == 0 {
64        return 0.0;
65    }
66    v.total_instances as f32 / v.unique_base_materials as f32
67}
68
69/// Serialize to JSON-like string.
70pub fn material_instance_view_to_json(v: &MaterialInstanceView) -> String {
71    format!(
72        r#"{{"enabled":{},"total_instances":{},"unique_base_materials":{},"show_overrides":{},"highlight_overdraw_materials":{}}}"#,
73        v.enabled,
74        v.total_instances,
75        v.unique_base_materials,
76        v.show_overrides,
77        v.highlight_overdraw_materials
78    )
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[test]
86    fn test_defaults() {
87        let v = new_material_instance_view();
88        assert!(!v.enabled);
89        assert_eq!(v.total_instances, 0);
90    }
91
92    #[test]
93    fn test_enable() {
94        let mut v = new_material_instance_view();
95        miv_set_enabled(&mut v, true);
96        assert!(v.enabled);
97    }
98
99    #[test]
100    fn test_update_counts() {
101        let mut v = new_material_instance_view();
102        miv_update_counts(&mut v, 100, 10);
103        assert_eq!(v.total_instances, 100);
104        assert_eq!(v.unique_base_materials, 10);
105    }
106
107    #[test]
108    fn test_show_overrides_toggle() {
109        let mut v = new_material_instance_view();
110        miv_set_show_overrides(&mut v, false);
111        assert!(!v.show_overrides);
112    }
113
114    #[test]
115    fn test_highlight_toggle() {
116        let mut v = new_material_instance_view();
117        miv_set_highlight_overdraw(&mut v, true);
118        assert!(v.highlight_overdraw_materials);
119    }
120
121    #[test]
122    fn test_avg_instances_zero_base() {
123        let v = new_material_instance_view();
124        assert_eq!(miv_avg_instances_per_base(&v), 0.0);
125    }
126
127    #[test]
128    fn test_avg_instances_computed() {
129        let mut v = new_material_instance_view();
130        miv_update_counts(&mut v, 50, 5);
131        assert!((miv_avg_instances_per_base(&v) - 10.0).abs() < 1e-5);
132    }
133
134    #[test]
135    fn test_base_materials_capped() {
136        let mut v = new_material_instance_view();
137        miv_update_counts(&mut v, 5, 100);
138        assert!(v.unique_base_materials <= v.total_instances.max(1));
139    }
140
141    #[test]
142    fn test_json_keys() {
143        let v = new_material_instance_view();
144        let s = material_instance_view_to_json(&v);
145        assert!(s.contains("unique_base_materials"));
146    }
147
148    #[test]
149    fn test_clone() {
150        let v = new_material_instance_view();
151        let v2 = v.clone();
152        assert_eq!(v2.total_instances, v.total_instances);
153    }
154}