three_d/renderer/geometry/
mesh.rs1use crate::core::*;
2use crate::renderer::*;
3
4use super::BaseMesh;
5
6pub struct Mesh {
10 base_mesh: BaseMesh,
11 context: Context,
12 aabb: AxisAlignedBoundingBox,
13 transformation: Mat4,
14 animation_transformation: Mat4,
15 animation: Option<Box<dyn Fn(f32) -> Mat4 + Send + Sync>>,
16}
17
18impl Mesh {
19 pub fn new(context: &Context, cpu_mesh: &CpuMesh) -> Self {
24 let aabb = cpu_mesh.compute_aabb();
25 Self {
26 context: context.clone(),
27 base_mesh: BaseMesh::new(context, cpu_mesh),
28 aabb,
29 transformation: Mat4::identity(),
30 animation_transformation: Mat4::identity(),
31 animation: None,
32 }
33 }
34
35 pub(in crate::renderer) fn set_transformation_2d(&mut self, transformation: Mat3) {
36 self.set_transformation(Mat4::new(
37 transformation.x.x,
38 transformation.x.y,
39 0.0,
40 transformation.x.z,
41 transformation.y.x,
42 transformation.y.y,
43 0.0,
44 transformation.y.z,
45 0.0,
46 0.0,
47 1.0,
48 0.0,
49 transformation.z.x,
50 transformation.z.y,
51 0.0,
52 transformation.z.z,
53 ));
54 }
55
56 pub fn transformation(&self) -> Mat4 {
60 self.transformation
61 }
62
63 pub fn set_transformation(&mut self, transformation: Mat4) {
68 self.transformation = transformation;
69 }
70
71 pub fn set_animation(&mut self, animation: impl Fn(f32) -> Mat4 + Send + Sync + 'static) {
77 self.animation = Some(Box::new(animation));
78 self.animate(0.0);
79 }
80
81 pub fn vertex_count(&self) -> u32 {
85 self.base_mesh.indices.vertex_count()
86 }
87
88 pub fn indices_mut(&mut self) -> &mut TriangleBuffer {
93 &mut self.base_mesh.indices
94 }
95
96 pub fn set_positions(&mut self, positions: &[Vec3]) -> Result<(), RendererError> {
101 if positions.len() as u32 != self.vertex_count() {
102 Err(RendererError::InvalidBufferLength(
103 "Position".to_string(),
104 self.vertex_count() as usize,
105 positions.len(),
106 ))?;
107 }
108 self.base_mesh.positions.fill(positions);
109 self.aabb = AxisAlignedBoundingBox::new_with_positions(positions);
110 Ok(())
111 }
112
113 pub fn set_positions_partially(
118 &mut self,
119 offset: u32,
120 positions: &[Vec3],
121 ) -> Result<(), RendererError> {
122 if offset + positions.len() as u32 > self.vertex_count() {
123 Err(RendererError::InvalidBufferLength(
124 "Position".to_string(),
125 self.vertex_count() as usize,
126 offset as usize + positions.len(),
127 ))?;
128 }
129 self.base_mesh.positions.fill_subset(offset, positions);
130 self.aabb.expand(positions);
131 Ok(())
132 }
133
134 #[deprecated = "use set_positions and set_positions_partially instead"]
139 pub fn positions_mut(&mut self) -> &mut VertexBuffer<Vec3> {
140 &mut self.base_mesh.positions
141 }
142
143 pub fn set_normals(&mut self, normals: &[Vec3]) -> Result<(), RendererError> {
148 if normals.len() as u32 != self.vertex_count() {
149 Err(RendererError::InvalidBufferLength(
150 "Normal".to_string(),
151 self.vertex_count() as usize,
152 normals.len(),
153 ))?;
154 }
155 if let Some(buffer) = self.base_mesh.normals.as_mut() {
156 buffer.fill(normals);
157 } else {
158 self.base_mesh.normals = Some(VertexBuffer::new_with_data(&self.context, normals));
159 }
160 Ok(())
161 }
162
163 pub fn set_normals_partially(
169 &mut self,
170 offset: u32,
171 normals: &[Vec3],
172 ) -> Result<(), RendererError> {
173 if offset + normals.len() as u32 > self.vertex_count() {
174 Err(RendererError::InvalidBufferLength(
175 "Normal".to_string(),
176 self.vertex_count() as usize,
177 offset as usize + normals.len(),
178 ))?;
179 }
180 if let Some(buffer) = self.base_mesh.normals.as_mut() {
181 buffer.fill_subset(offset, normals);
182 } else {
183 Err(RendererError::PartialUpdateFailedMissingBuffer(
184 "Normal".to_string(),
185 ))?;
186 }
187 Ok(())
188 }
189
190 #[deprecated = "use set_normals and set_normals_partially instead"]
195 pub fn normals_mut(&mut self) -> &mut Option<VertexBuffer<Vec3>> {
196 &mut self.base_mesh.normals
197 }
198
199 pub fn set_uvs(&mut self, uvs: &[Vec2]) -> Result<(), RendererError> {
204 if uvs.len() as u32 != self.vertex_count() {
205 Err(RendererError::InvalidBufferLength(
206 "UV".to_string(),
207 self.vertex_count() as usize,
208 uvs.len(),
209 ))?;
210 }
211 if let Some(buffer) = self.base_mesh.uvs.as_mut() {
212 buffer.fill(uvs);
213 } else {
214 self.base_mesh.uvs = Some(VertexBuffer::new_with_data(&self.context, uvs));
215 }
216 Ok(())
217 }
218
219 pub fn set_uvs_partially(&mut self, offset: u32, uvs: &[Vec2]) -> Result<(), RendererError> {
225 if offset + uvs.len() as u32 > self.vertex_count() {
226 Err(RendererError::InvalidBufferLength(
227 "UV".to_string(),
228 self.vertex_count() as usize,
229 offset as usize + uvs.len(),
230 ))?;
231 }
232 if let Some(buffer) = self.base_mesh.uvs.as_mut() {
233 buffer.fill_subset(offset, uvs);
234 } else {
235 Err(RendererError::PartialUpdateFailedMissingBuffer(
236 "UV".to_string(),
237 ))?;
238 }
239 Ok(())
240 }
241
242 #[deprecated = "use set_uvs and set_uvs_partially instead"]
247 pub fn uvs_mut(&mut self) -> &mut Option<VertexBuffer<Vec2>> {
248 &mut self.base_mesh.uvs
249 }
250
251 pub fn set_tangents(&mut self, tangents: &[Vec4]) -> Result<(), RendererError> {
256 if tangents.len() as u32 != self.vertex_count() {
257 Err(RendererError::InvalidBufferLength(
258 "Tangents".to_string(),
259 self.vertex_count() as usize,
260 tangents.len(),
261 ))?;
262 }
263 if let Some(buffer) = self.base_mesh.tangents.as_mut() {
264 buffer.fill(tangents);
265 } else {
266 self.base_mesh.tangents = Some(VertexBuffer::new_with_data(&self.context, tangents));
267 }
268 Ok(())
269 }
270
271 pub fn set_tangents_partially(
277 &mut self,
278 offset: u32,
279 tangents: &[Vec4],
280 ) -> Result<(), RendererError> {
281 if offset + tangents.len() as u32 > self.vertex_count() {
282 Err(RendererError::InvalidBufferLength(
283 "Tangent".to_string(),
284 self.vertex_count() as usize,
285 offset as usize + tangents.len(),
286 ))?;
287 }
288 if let Some(buffer) = self.base_mesh.tangents.as_mut() {
289 buffer.fill_subset(offset, tangents);
290 } else {
291 Err(RendererError::PartialUpdateFailedMissingBuffer(
292 "Tangent".to_string(),
293 ))?;
294 }
295 Ok(())
296 }
297
298 #[deprecated = "use set_tangents and set_tangents_partially instead"]
303 pub fn tangents_mut(&mut self) -> &mut Option<VertexBuffer<Vec4>> {
304 &mut self.base_mesh.tangents
305 }
306
307 pub fn set_colors(&mut self, colors: &[Vec4]) -> Result<(), RendererError> {
312 if colors.len() as u32 != self.vertex_count() {
313 Err(RendererError::InvalidBufferLength(
314 "Color".to_string(),
315 self.vertex_count() as usize,
316 colors.len(),
317 ))?;
318 }
319 if let Some(buffer) = self.base_mesh.colors.as_mut() {
320 buffer.fill(colors);
321 } else {
322 self.base_mesh.colors = Some(VertexBuffer::new_with_data(&self.context, colors));
323 }
324 Ok(())
325 }
326
327 pub fn set_colors_partially(
333 &mut self,
334 offset: u32,
335 colors: &[Vec4],
336 ) -> Result<(), RendererError> {
337 if offset + colors.len() as u32 > self.vertex_count() {
338 Err(RendererError::InvalidBufferLength(
339 "Color".to_string(),
340 self.vertex_count() as usize,
341 offset as usize + colors.len(),
342 ))?;
343 }
344 if let Some(buffer) = self.base_mesh.colors.as_mut() {
345 buffer.fill_subset(offset, colors);
346 } else {
347 Err(RendererError::PartialUpdateFailedMissingBuffer(
348 "Color".to_string(),
349 ))?;
350 }
351 Ok(())
352 }
353
354 #[deprecated = "use set_colors and set_colors_partially instead"]
359 pub fn colors_mut(&mut self) -> &mut Option<VertexBuffer<Vec4>> {
360 &mut self.base_mesh.colors
361 }
362}
363
364impl<'a> IntoIterator for &'a Mesh {
365 type Item = &'a dyn Geometry;
366 type IntoIter = std::iter::Once<&'a dyn Geometry>;
367
368 fn into_iter(self) -> Self::IntoIter {
369 std::iter::once(self)
370 }
371}
372
373impl Geometry for Mesh {
374 fn aabb(&self) -> AxisAlignedBoundingBox {
375 self.aabb
376 .transformed(self.transformation * self.animation_transformation)
377 }
378
379 fn animate(&mut self, time: f32) {
380 if let Some(animation) = &self.animation {
381 self.animation_transformation = animation(time);
382 }
383 }
384
385 fn draw(&self, viewer: &dyn Viewer, program: &Program, render_states: RenderStates) {
386 let local2world = self.transformation * self.animation_transformation;
387 if let Some(inverse) = local2world.invert() {
388 program.use_uniform_if_required("normalMatrix", inverse.transpose());
389 } else {
390 return;
392 }
393
394 program.use_uniform("viewProjection", viewer.projection() * viewer.view());
395 program.use_uniform("modelMatrix", local2world);
396
397 self.base_mesh.draw(program, render_states, viewer);
398 }
399
400 fn vertex_shader_source(&self) -> String {
401 self.base_mesh.vertex_shader_source()
402 }
403
404 fn id(&self) -> GeometryId {
405 GeometryId::Mesh(
406 self.base_mesh.normals.is_some(),
407 self.base_mesh.tangents.is_some(),
408 self.base_mesh.uvs.is_some(),
409 self.base_mesh.colors.is_some(),
410 )
411 }
412
413 fn render_with_material(
414 &self,
415 material: &dyn Material,
416 viewer: &dyn Viewer,
417 lights: &[&dyn Light],
418 ) {
419 if let Err(e) = render_with_material(&self.context, viewer, &self, material, lights) {
420 panic!("{}", e.to_string());
421 }
422 }
423
424 fn render_with_effect(
425 &self,
426 material: &dyn Effect,
427 viewer: &dyn Viewer,
428 lights: &[&dyn Light],
429 color_texture: Option<ColorTexture>,
430 depth_texture: Option<DepthTexture>,
431 ) {
432 if let Err(e) = render_with_effect(
433 &self.context,
434 viewer,
435 self,
436 material,
437 lights,
438 color_texture,
439 depth_texture,
440 ) {
441 panic!("{}", e.to_string());
442 }
443 }
444}