mraphics_core/geometry/
geometry.rs1use crate::{GadgetData, GadgetIndex, InstanceUpdater, Interpolatable, constants};
2use nalgebra::Matrix4;
3use std::collections::HashMap;
4
5pub trait AllowedIndexFormat {}
6impl AllowedIndexFormat for u32 {}
7impl AllowedIndexFormat for u16 {}
8
9#[derive(Debug, Clone)]
10pub struct CustomIndices<T: AllowedIndexFormat> {
11 pub data: Vec<T>,
12 pub buffer: Option<wgpu::Buffer>,
13}
14
15impl<T: AllowedIndexFormat> CustomIndices<T> {
16 pub fn new(data: Vec<T>) -> Self {
17 Self { data, buffer: None }
18 }
19}
20
21#[derive(Debug, Clone)]
22pub enum GeometryIndices {
23 Sequential(u32),
24 CustomU16(CustomIndices<u16>),
25 CustomU32(CustomIndices<u32>),
26}
27
28#[derive(Debug)]
29pub enum GeometryViewError {
30 UnknownAttributeLabel,
31 UnknownUniformLabel,
32}
33
34#[derive(Debug)]
39pub struct GeometryView {
40 pub attributes: Vec<GadgetData>,
42
43 attribute_map: HashMap<String, usize>,
46
47 pub uniforms: Vec<GadgetData>,
49
50 uniform_map: HashMap<String, usize>,
53
54 pub indices: GeometryIndices,
56}
57
58impl GeometryView {
59 pub fn new() -> Self {
60 let mut out = Self {
61 indices: GeometryIndices::Sequential(0),
62
63 attributes: Vec::new(),
64 attribute_map: HashMap::new(),
65
66 uniforms: Vec::new(),
67 uniform_map: HashMap::new(),
68 };
69
70 out.add_uniform(
71 constants::MODEL_MAT_LABEL,
72 constants::MODEL_MAT_INDEX,
73 bytemuck::cast_slice(Matrix4::<f32>::identity().as_slice()).to_vec(),
74 );
75
76 out
77 }
78
79 pub fn with_indices(mut self, indices: GeometryIndices) -> Self {
80 self.indices = indices;
81 self
82 }
83
84 pub fn with_attributes(mut self, attributes: Vec<GadgetData>) -> Self {
85 self.attributes = attributes;
86 self
87 }
88
89 pub fn with_uniforms(mut self, uniforms: Vec<GadgetData>) -> Self {
90 self.uniforms = uniforms;
91 self
92 }
93
94 pub fn add_attribute(&mut self, label: &str, index: GadgetIndex, data: Vec<u8>) {
95 let attribute = GadgetData {
96 label: label.to_string(),
97 index,
98 data,
99 needs_update_value: true,
100 needs_update_buffer: true,
101 };
102
103 self.attribute_map
104 .insert(attribute.label.clone(), self.attributes.len());
105 self.attributes.push(attribute);
106 }
107
108 pub fn get_attribute(&self, label: &str) -> Result<&GadgetData, GeometryViewError> {
109 if let Some(index) = self.attribute_map.get(label) {
110 let attribute = &self.attributes[*index];
111 return Ok(attribute);
112 }
113
114 Err(GeometryViewError::UnknownAttributeLabel)
115 }
116
117 pub fn get_attribute_mut(&mut self, label: &str) -> Result<&mut GadgetData, GeometryViewError> {
118 if let Some(index) = self.attribute_map.get(label) {
119 let attribute = &mut self.attributes[*index];
120 return Ok(attribute);
121 }
122
123 Err(GeometryViewError::UnknownAttributeLabel)
124 }
125
126 pub fn set_attribute(&mut self, label: &str, data: Vec<u8>) -> Result<(), GeometryViewError> {
127 let attribute = self.get_attribute_mut(label)?;
128
129 if attribute.data.len() != data.len() {
130 attribute.needs_update_buffer = true;
131 }
132
133 attribute.data = data;
134 attribute.needs_update_value = true;
135
136 Ok(())
137 }
138
139 pub fn get_uniform(&self, label: &str) -> Result<&GadgetData, GeometryViewError> {
140 if let Some(index) = self.uniform_map.get(label) {
141 let uniform = &self.uniforms[*index];
142 return Ok(uniform);
143 }
144
145 Err(GeometryViewError::UnknownUniformLabel)
146 }
147
148 pub fn get_uniform_mut(&mut self, label: &str) -> Result<&mut GadgetData, GeometryViewError> {
149 if let Some(index) = self.uniform_map.get(label) {
150 let uniform = &mut self.uniforms[*index];
151 return Ok(uniform);
152 }
153
154 Err(GeometryViewError::UnknownUniformLabel)
155 }
156
157 pub fn add_uniform(&mut self, label: &str, index: GadgetIndex, data: Vec<u8>) {
158 let uniform = GadgetData {
159 label: label.to_string(),
160 index,
161 data,
162 needs_update_value: true,
163 needs_update_buffer: true,
164 };
165
166 self.uniform_map
167 .insert(uniform.label.clone(), self.uniforms.len());
168 self.uniforms.push(uniform);
169 }
170
171 pub fn set_uniform(&mut self, label: &str, data: Vec<u8>) -> Result<(), GeometryViewError> {
172 let uniform = self.get_uniform_mut(label)?;
173
174 if uniform.data.len() != data.len() {
175 uniform.needs_update_buffer = true;
176 }
177
178 uniform.data = data;
179 uniform.needs_update_value = true;
180
181 Ok(())
182 }
183
184 pub fn reset_vertices(&mut self) {
185 self.attributes = Vec::new();
186 self.attribute_map = HashMap::new();
187 self.indices = GeometryIndices::Sequential(0);
188 }
189
190 pub fn reset_uniforms(&mut self) {
191 self.uniforms = Vec::new();
192 self.uniform_map = HashMap::new();
193 }
194}
195
196pub trait Geometry: Clone {
206 fn init_view(&self, view: &mut GeometryView);
208
209 fn update_view(&self, view: &mut GeometryView);
211
212 fn update(&mut self) {}
214}
215
216#[derive(Clone)]
221pub struct Vertices {
222 pub data: Vec<[f32; 4]>,
223}
224
225impl Vertices {
226 pub fn new() -> Self {
228 Self { data: Vec::new() }
229 }
230
231 pub fn apply_transform<Trans: Fn(&[f32; 4]) -> [f32; 4]>(&self, transform: Trans) -> Self {
233 Self {
234 data: self.data.iter().map(transform).collect(),
235 }
236 }
237
238 pub fn update_geometry_view(&self, view: &mut GeometryView) {
243 let mut vertices = Vec::new();
244
245 for vertex in &self.data {
246 vertices.push(vertex[0]);
247 vertices.push(vertex[1]);
248 vertices.push(vertex[2]);
249 vertices.push(vertex[3]);
250 }
251
252 view.set_attribute(
253 crate::constants::POSITION_ATTR_LABEL,
254 Vec::from(bytemuck::cast_slice::<f32, u8>(&vertices)),
255 )
256 .unwrap();
257 }
258}
259
260impl Interpolatable for Vertices {
261 fn interpolate(&self, to: &Self, p: f32) -> Self {
262 Self {
263 data: self.data.interpolate(&to.data, p),
264 }
265 }
266}
267
268impl InstanceUpdater for Vertices {
273 fn update_instance(&self, instance: &mut super::RenderInstance) {
274 self.update_geometry_view(&mut instance.geometry);
275 }
276}
277
278impl Geometry for Vertices {
279 fn init_view(&self, view: &mut GeometryView) {
280 view.add_attribute(
281 crate::constants::POSITION_ATTR_LABEL,
282 crate::constants::POSITION_ATTR_INDEX,
283 bytemuck::cast_slice::<f32, u8>(&self.data.concat()).to_vec(),
284 );
285 }
286
287 fn update_view(&self, view: &mut GeometryView) {
288 self.update_geometry_view(view);
289 }
290}