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 current_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 current_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 self.current_transformation = transformation;
70 }
71
72 pub fn set_animation(&mut self, animation: impl Fn(f32) -> Mat4 + Send + Sync + 'static) {
78 self.animation = Some(Box::new(animation));
79 }
80
81 pub fn vertex_count(&self) -> u32 {
85 self.base_mesh.positions.vertex_count()
86 }
87
88 pub fn indices_mut(&mut self) -> &mut IndexBuffer {
93 &mut self.base_mesh.indices
94 }
95
96 pub fn positions_mut(&mut self) -> &mut VertexBuffer<Vec3> {
101 &mut self.base_mesh.positions
102 }
103
104 pub fn normals_mut(&mut self) -> &mut Option<VertexBuffer<Vec3>> {
109 &mut self.base_mesh.normals
110 }
111
112 pub fn uvs_mut(&mut self) -> &mut Option<VertexBuffer<Vec2>> {
117 &mut self.base_mesh.uvs
118 }
119
120 pub fn tangents_mut(&mut self) -> &mut Option<VertexBuffer<Vec4>> {
125 &mut self.base_mesh.tangents
126 }
127
128 pub fn colors_mut(&mut self) -> &mut Option<VertexBuffer<Vec4>> {
133 &mut self.base_mesh.colors
134 }
135
136 #[deprecated = "use positions_mut instead"]
142 pub fn update_positions(&mut self, positions: &[Vector3<f32>]) {
143 if positions.len() as u32 != self.vertex_count() {
144 panic!("Failed updating positions: The number of positions {} does not match the number of vertices {} in the mesh.", positions.len(), self.vertex_count())
145 }
146 self.positions_mut().fill(positions);
147 }
148
149 #[deprecated = "use normals_mut instead"]
156 pub fn update_normals(&mut self, normals: &[Vector3<f32>]) {
157 if normals.len() as u32 != self.vertex_count() {
158 panic!("Failed updating normals: The number of normals {} does not match the number of vertices {} in the mesh.", normals.len(), self.vertex_count())
159 }
160
161 if let Some(normal_buffer) = self.normals_mut() {
162 normal_buffer.fill(normals);
163 } else {
164 *self.normals_mut() = Some(VertexBuffer::new_with_data(&self.context, normals));
165 }
166 }
167}
168
169impl<'a> IntoIterator for &'a Mesh {
170 type Item = &'a dyn Geometry;
171 type IntoIter = std::iter::Once<&'a dyn Geometry>;
172
173 fn into_iter(self) -> Self::IntoIter {
174 std::iter::once(self)
175 }
176}
177
178impl Geometry for Mesh {
179 fn aabb(&self) -> AxisAlignedBoundingBox {
180 self.aabb.transformed(self.current_transformation)
181 }
182
183 fn animate(&mut self, time: f32) {
184 if let Some(animation) = &self.animation {
185 self.current_transformation = self.transformation * animation(time);
186 }
187 }
188
189 fn draw(&self, viewer: &dyn Viewer, program: &Program, render_states: RenderStates) {
190 if let Some(inverse) = self.current_transformation.invert() {
191 program.use_uniform_if_required("normalMatrix", inverse.transpose());
192 } else {
193 return;
195 }
196
197 program.use_uniform("viewProjection", viewer.projection() * viewer.view());
198 program.use_uniform("modelMatrix", self.current_transformation);
199
200 self.base_mesh.draw(program, render_states, viewer);
201 }
202
203 fn vertex_shader_source(&self) -> String {
204 self.base_mesh.vertex_shader_source()
205 }
206
207 fn id(&self) -> GeometryId {
208 GeometryId::Mesh(
209 self.base_mesh.normals.is_some(),
210 self.base_mesh.tangents.is_some(),
211 self.base_mesh.uvs.is_some(),
212 self.base_mesh.colors.is_some(),
213 )
214 }
215
216 fn render_with_material(
217 &self,
218 material: &dyn Material,
219 viewer: &dyn Viewer,
220 lights: &[&dyn Light],
221 ) {
222 render_with_material(&self.context, viewer, &self, material, lights);
223 }
224
225 fn render_with_effect(
226 &self,
227 material: &dyn Effect,
228 viewer: &dyn Viewer,
229 lights: &[&dyn Light],
230 color_texture: Option<ColorTexture>,
231 depth_texture: Option<DepthTexture>,
232 ) {
233 render_with_effect(
234 &self.context,
235 viewer,
236 self,
237 material,
238 lights,
239 color_texture,
240 depth_texture,
241 )
242 }
243}