1
2use crate::prelude::*;
3use std::{
4 collections::{HashMap, BTreeSet},
5 fmt::Debug,
6 rc::Rc,
7};
8
9#[derive(Debug, Clone)]
11pub enum MaterialComponent {
12 Texture(Rc<dyn GenericTexture>),
13 Color(Vec4),
14 Luminance(f32),
15}
16
17#[derive(Default, Debug, Clone)]
19pub struct MaterialLegacy {
20 pub ambient: MaterialComponent,
22
23 pub diffuse: MaterialComponent,
25
26 pub specular: MaterialComponent,
28
29 pub specular_power: MaterialComponent,
31
32 pub normal: MaterialComponent,
34
35 pub emissive: MaterialComponent,
37
38 pub others: HashMap<String, MaterialComponent>,
40}
41
42#[derive(Default, Debug, Clone)]
44pub struct MaterialPbr {
45 pub albedo: MaterialComponent,
47
48 pub normal: MaterialComponent,
50
51 pub ao: MaterialComponent,
53
54 pub displacement: MaterialComponent,
56
57 pub roughness: MaterialComponent,
59
60 pub metalness: MaterialComponent,
62
63 pub emissive: MaterialComponent,
65
66 pub others: HashMap<String, MaterialComponent>,
68}
69
70impl Default for MaterialComponent {
71 fn default() -> Self {
72 Self::Color(Vec4::new(0.5, 0.5, 0.5, 1.0))
73 }
74}
75
76pub trait Material: Debug {
78 fn get_ambient(&self) -> Option<&MaterialComponent>;
80
81 fn get_diffuse(&self) -> Option<&MaterialComponent>;
83
84 fn get_specular(&self) -> Option<&MaterialComponent>;
86
87 fn get_specular_power(&self) -> Option<&MaterialComponent>;
89
90 fn get_albedo(&self) -> Option<&MaterialComponent>;
92
93 fn get_ao(&self) -> Option<&MaterialComponent>;
95
96 fn get_displacement(&self) -> Option<&MaterialComponent>;
98
99 fn get_roughness(&self) -> Option<&MaterialComponent>;
101
102 fn get_metalness(&self) -> Option<&MaterialComponent>;
104
105 fn get_normal(&self) -> Option<&MaterialComponent>;
107
108 fn get_emissive(&self) -> Option<&MaterialComponent>;
110
111 fn get_names(&self) -> BTreeSet<String>;
113
114 fn get_by_name(&self, name: &str) -> Option<&MaterialComponent>;
116
117 fn set_by_name(&mut self, name: &str, texture: MaterialComponent);
119}
120
121impl Material for MaterialLegacy {
122 fn get_ambient(&self) -> Option<&MaterialComponent> {Some(&self.ambient)}
123 fn get_diffuse(&self) -> Option<&MaterialComponent> {Some(&self.diffuse)}
124 fn get_specular(&self) -> Option<&MaterialComponent> {Some(&self.specular)}
125 fn get_specular_power(&self) -> Option<&MaterialComponent> {Some(&self.specular_power)}
126 fn get_normal(&self) -> Option<&MaterialComponent> {Some(&self.normal)}
127 fn get_emissive(&self) -> Option<&MaterialComponent> {Some(&self.emissive)}
128
129 fn get_albedo(&self) -> Option<&MaterialComponent> {None}
130 fn get_ao(&self) -> Option<&MaterialComponent> {None}
131 fn get_displacement(&self) -> Option<&MaterialComponent> {None}
132 fn get_roughness(&self) -> Option<&MaterialComponent> {None}
133 fn get_metalness(&self) -> Option<&MaterialComponent> {None}
134
135 fn get_names(&self) -> BTreeSet<String> {
136 let mut ret = BTreeSet::new();
137 ret.insert("ambient".to_owned());
138 ret.insert("diffuse".to_owned());
139 ret.insert("specular".to_owned());
140 ret.insert("specular_power".to_owned());
141 ret.insert("normal".to_owned());
142 ret.insert("emissive".to_owned());
143 for (name, _) in self.others.iter() {
144 ret.insert(name.clone());
145 }
146 ret
147 }
148
149 fn get_by_name(&self, name: &str) -> Option<&MaterialComponent> {
150 match self.others.get(name) {
151 Some(data) => Some(data),
152 None => {
153 match name {
154 "ambient" => self.get_ambient(),
155 "diffuse" => self.get_diffuse(),
156 "specular" => self.get_specular(),
157 "specular_power" => self.get_specular_power(),
158 "normal" => self.get_normal(),
159 "emissive" => self.get_emissive(),
160 _ => None,
161 }
162 }
163 }
164 }
165
166 fn set_by_name(&mut self, name: &str, texture: MaterialComponent) {
167 match name {
168 "ambient" => self.ambient = texture,
169 "diffuse" => self.diffuse = texture,
170 "specular" => self.specular = texture,
171 "specular_power" => self.specular_power = texture,
172 "normal" => self.normal = texture,
173 "emissive" => self.emissive = texture,
174 others =>{
175 self.others.insert(others.to_owned(), texture);
176 }
177 }
178 }
179}
180
181impl Material for MaterialPbr {
182 fn get_albedo(&self) -> Option<&MaterialComponent> {Some(&self.albedo)}
183 fn get_ao(&self) -> Option<&MaterialComponent> {Some(&self.ao)}
184 fn get_displacement(&self) -> Option<&MaterialComponent> {Some(&self.displacement)}
185 fn get_roughness(&self) -> Option<&MaterialComponent> {Some(&self.roughness)}
186 fn get_metalness(&self) -> Option<&MaterialComponent> {Some(&self.metalness)}
187 fn get_normal(&self) -> Option<&MaterialComponent> {Some(&self.normal)}
188 fn get_emissive(&self) -> Option<&MaterialComponent> {Some(&self.emissive)}
189
190 fn get_ambient(&self) -> Option<&MaterialComponent> {None}
191 fn get_diffuse(&self) -> Option<&MaterialComponent> {None}
192 fn get_specular(&self) -> Option<&MaterialComponent> {None}
193 fn get_specular_power(&self) -> Option<&MaterialComponent> {None}
194
195 fn get_names(&self) -> BTreeSet<String> {
196 let mut ret = BTreeSet::new();
197 ret.insert("albedo".to_owned());
198 ret.insert("ao".to_owned());
199 ret.insert("displacement".to_owned());
200 ret.insert("roughness".to_owned());
201 ret.insert("metalness".to_owned());
202 ret.insert("normal".to_owned());
203 ret.insert("emissive".to_owned());
204 for (name, _) in self.others.iter() {
205 ret.insert(name.clone());
206 }
207 ret
208 }
209
210 fn get_by_name(&self, name: &str) -> Option<&MaterialComponent> {
211 match self.others.get(name) {
212 Some(data) => Some(data),
213 None => {
214 match name {
215 "albedo" => self.get_albedo(),
216 "ao" => self.get_ao(),
217 "displacement" => self.get_displacement(),
218 "roughness" => self.get_roughness(),
219 "metalness" => self.get_metalness(),
220 "normal" => self.get_normal(),
221 "emissive" => self.get_emissive(),
222 _ => None,
223 }
224 }
225 }
226 }
227
228 fn set_by_name(&mut self, name: &str, texture: MaterialComponent) {
229 match name {
230 "albedo" => self.albedo = texture,
231 "ao" => self.ao = texture,
232 "displacement" => self.displacement = texture,
233 "roughness" => self.roughness = texture,
234 "metalness" => self.metalness = texture,
235 "normal" => self.normal = texture,
236 "emissive" => self.emissive = texture,
237 others =>{
238 self.others.insert(others.to_owned(), texture);
239 }
240 }
241 }
242}