1use crate::{Material, MaterialAspect, ShortIndex};
11
12#[derive(Debug, Clone)]
25pub struct BaseData {
26 pub rgba: u32,
30 pub metallic_roughness: u32,
36 pub emissive_rgb: u32,
40 pub alpha_etc: u32,
44}
45
46impl Default for BaseData {
48 fn default() -> Self {
49 0xffffffff_u32.into()
50 }
51}
52
53impl BaseData {
55 pub fn of_rgba((r, g, b, a): (u8, u8, u8, u8)) -> Self {
58 let rgba: u32 = (r as u32) | ((g as u32) << 8) | ((b as u32) << 16) | ((a as u32) << 24);
59 rgba.into()
60 }
61
62 pub fn set_rgba(&mut self, (r, g, b, a): (u8, u8, u8, u8)) {
65 let rgba: u32 = (r as u32) | ((g as u32) << 8) | ((b as u32) << 16) | ((a as u32) << 24);
66 self.rgba = rgba;
67 }
68
69 pub fn set_emissive_rgb(&mut self, (r, g, b): (u8, u8, u8)) {
72 let rgb: u32 = (r as u32) | ((g as u32) << 8) | ((b as u32) << 16);
73 self.emissive_rgb = rgb
74 }
75
76 pub fn set_mr(&mut self, metallic: f32, roughness: f32) {
79 let metallic = (metallic * 65535.0) as u32;
80 let roughness = (roughness * 65535.0) as u32;
81 self.metallic_roughness = (roughness << 16) | metallic;
82 }
83
84 pub fn metallic_roughness(&self) -> (f32, f32) {
87 let metallic = self.metallic_roughness & 65535;
88 let roughness = (self.metallic_roughness >> 16) & 65535;
89 let metallic = (metallic as f32) / 65535.0;
90 let roughness = (roughness as f32) / 65535.0;
91 (metallic, roughness)
92 }
93
94 pub fn rgba_tuple(&self) -> (u8, u8, u8, u8) {
97 let r = self.rgba & 0xff;
98 let g = (self.rgba >> 8) & 0xff;
99 let b = (self.rgba >> 16) & 0xff;
100 let a = (self.rgba >> 24) & 0xff;
101 (r as u8, g as u8, b as u8, a as u8)
102 }
103
104 }
106
107impl From<u32> for BaseData {
108 fn from(rgba: u32) -> Self {
109 Self {
110 rgba,
111 metallic_roughness: 0,
112 emissive_rgb: 0,
113 alpha_etc: 0,
114 }
115 }
116}
117
118#[derive(Debug)]
122pub struct BaseMaterial {
123 base_data: BaseData,
125}
126
127impl BaseMaterial {
129 pub fn of_rgba(rgba: u32) -> Self {
132 let base_data: BaseData = rgba.into();
133 Self { base_data }
134 }
135
136 pub fn set_mr(&mut self, metallic: f32, roughness: f32) {
139 self.base_data.set_mr(metallic, roughness);
140 }
141}
142
143impl Material for BaseMaterial {
145 fn base_data(&self) -> &BaseData {
146 &self.base_data
147 }
148}
149
150#[derive(Debug, Default)]
154pub struct PbrMaterial {
155 base_data: BaseData,
156 base_texture: ShortIndex,
157 normal_texture: ShortIndex,
158 mr_texture: ShortIndex,
159 occlusion_texture: ShortIndex,
160 emission_texture: ShortIndex,
161}
162
163impl PbrMaterial {
165 pub fn of_rgba(rgba: u32) -> Self {
168 let base_data: BaseData = rgba.into();
169 Self {
170 base_data,
171 ..Default::default()
172 }
173 }
174
175 pub fn set_rgba(&mut self, (r, g, b, a): (u8, u8, u8, u8)) {
180 self.base_data.set_rgba((r, g, b, a));
181 }
182
183 pub fn set_emissive_rgb(&mut self, (r, g, b): (u8, u8, u8)) {
186 self.base_data.set_emissive_rgb((r, g, b));
187 }
188
189 pub fn set_mr(&mut self, metallic: f32, roughness: f32) {
192 self.base_data.set_mr(metallic, roughness);
193 }
194
195 pub fn set_base_data(&mut self, base_data: &BaseData) {
198 self.base_data = base_data.clone();
199 }
200
201 pub fn set_texture(&mut self, aspect: MaterialAspect, index: ShortIndex) {
204 use MaterialAspect::*;
205 #[allow(unreachable_patterns)]
206 match aspect {
207 Color => {
208 self.base_texture = index;
209 }
210 Normal => {
211 self.normal_texture = index;
212 }
213 MetallicRoughness => {
214 self.mr_texture = index;
215 }
216 Occlusion => {
217 self.occlusion_texture = index;
218 }
219 Emission => {
220 self.emission_texture = index;
221 }
222 _ => (),
223 }
224 }
225}
226
227impl Material for PbrMaterial {
229 fn base_data(&self) -> &BaseData {
230 &self.base_data
231 }
232
233 fn texture(&self, aspect: MaterialAspect) -> ShortIndex {
234 use MaterialAspect::*;
235 #[allow(unreachable_patterns)]
236 match aspect {
237 Color => self.base_texture,
238 Normal => self.normal_texture,
239 MetallicRoughness => self.mr_texture,
240 Occlusion => self.occlusion_texture,
241 Emission => self.emission_texture,
242 _ => ShortIndex::none(),
243 }
244 }
245}