oxihuman_export/
material.rs1#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
6pub struct PbrMaterial {
7 pub name: String,
8 pub base_color: [f32; 4],
10 pub metallic: f32,
12 pub roughness: f32,
14 pub emissive: [f32; 3],
16 pub double_sided: bool,
18 pub alpha_mode: String,
20}
21
22impl PbrMaterial {
23 #[allow(dead_code)]
25 pub fn skin() -> Self {
26 Self {
27 name: "skin".to_string(),
28 base_color: [0.94, 0.76, 0.69, 1.0],
29 metallic: 0.0,
30 roughness: 0.5,
31 emissive: [0.0, 0.0, 0.0],
32 double_sided: true,
33 alpha_mode: "OPAQUE".to_string(),
34 }
35 }
36
37 #[allow(dead_code)]
39 pub fn clothing() -> Self {
40 Self {
41 name: "clothing".to_string(),
42 base_color: [0.15, 0.15, 0.20, 1.0],
43 metallic: 0.0,
44 roughness: 0.85,
45 emissive: [0.0, 0.0, 0.0],
46 double_sided: false,
47 alpha_mode: "OPAQUE".to_string(),
48 }
49 }
50
51 #[allow(dead_code)]
53 pub fn default_material() -> Self {
54 Self {
55 name: "default".to_string(),
56 base_color: [0.8, 0.8, 0.8, 1.0],
57 metallic: 0.0,
58 roughness: 0.5,
59 emissive: [0.0, 0.0, 0.0],
60 double_sided: false,
61 alpha_mode: "OPAQUE".to_string(),
62 }
63 }
64
65 #[allow(dead_code)]
67 pub fn to_gltf_json(&self) -> serde_json::Value {
68 serde_json::json!({
69 "name": self.name,
70 "pbrMetallicRoughness": {
71 "baseColorFactor": [
72 self.base_color[0],
73 self.base_color[1],
74 self.base_color[2],
75 self.base_color[3]
76 ],
77 "metallicFactor": self.metallic,
78 "roughnessFactor": self.roughness
79 },
80 "emissiveFactor": [
81 self.emissive[0],
82 self.emissive[1],
83 self.emissive[2]
84 ],
85 "doubleSided": self.double_sided,
86 "alphaMode": self.alpha_mode
87 })
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn skin_material_has_correct_alpha() {
97 assert_eq!(PbrMaterial::skin().base_color[3], 1.0);
98 }
99
100 #[test]
101 fn to_gltf_json_has_pbr_key() {
102 let skin = PbrMaterial::skin();
103 let json = skin.to_gltf_json();
104 assert!(
105 json["pbrMetallicRoughness"].is_object(),
106 "pbrMetallicRoughness should be an object"
107 );
108 }
109
110 #[test]
111 fn clothing_is_opaque() {
112 assert_eq!(PbrMaterial::clothing().alpha_mode, "OPAQUE");
113 }
114
115 #[test]
116 fn gltf_json_metallic_is_float() {
117 let skin = PbrMaterial::skin();
118 let json = skin.to_gltf_json();
119 assert!(
120 json["pbrMetallicRoughness"]["metallicFactor"]
121 .as_f64()
122 .is_some(),
123 "metallicFactor should be a float"
124 );
125 }
126}