1use cgmath::{Matrix3, Matrix4, One, Quaternion, Vector3, Zero};
2
3use crate::renderer;
4
5pub trait Vertex {
6 fn desc() -> wgpu::VertexBufferLayout<'static>;
7}
8
9#[repr(C)]
10#[derive(Debug, Clone, Copy, bytemuck::Zeroable, bytemuck::Pod)]
11pub struct ModelVertex {
12 pub position: [f32; 3],
13 pub text_cords: [f32; 2],
14 pub normal: [f32; 3],
15 pub color: [f32; 3],
16 pub tangent: [f32; 3],
17 pub bitangent: [f32; 3],
18}
19
20impl Vertex for ModelVertex {
21 fn desc() -> wgpu::VertexBufferLayout<'static> {
22 use std::mem;
23 wgpu::VertexBufferLayout {
24 array_stride: mem::size_of::<ModelVertex>() as wgpu::BufferAddress,
25 step_mode: wgpu::VertexStepMode::Vertex,
26 attributes: &[
27 wgpu::VertexAttribute {
28 offset: 0,
29 shader_location: 0,
30 format: wgpu::VertexFormat::Float32x3,
31 },
32 wgpu::VertexAttribute {
33 offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
34 shader_location: 1,
35 format: wgpu::VertexFormat::Float32x2,
36 },
37 wgpu::VertexAttribute {
38 offset: mem::size_of::<[f32; 5]>() as wgpu::BufferAddress,
39 shader_location: 2,
40 format: wgpu::VertexFormat::Float32x3,
41 },
42 wgpu::VertexAttribute {
43 offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
44 shader_location: 3,
45 format: wgpu::VertexFormat::Float32x3,
46 },
47 wgpu::VertexAttribute {
48 offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
49 shader_location: 4,
50 format: wgpu::VertexFormat::Float32x3,
51 },
52 wgpu::VertexAttribute {
53 offset: mem::size_of::<[f32; 11]>() as wgpu::BufferAddress,
54 shader_location: 5,
55 format: wgpu::VertexFormat::Float32x3,
56 },
57 ],
58 }
59 }
60}
61
62pub trait DrawModel<'a> {
63 fn draw_mesh(
64 &mut self,
65 mesh: &'a renderer::Mesh,
66 material: &'a renderer::Material,
67 instances: std::ops::Range<u32>,
68 instance_buffer: &'a wgpu::Buffer,
69 camera_bind_group: &'a wgpu::BindGroup,
70 light_bind_group: &'a wgpu::BindGroup,
71 shadow_bind_group: &'a wgpu::BindGroup,
72 wind_bind_group: &'a wgpu::BindGroup,
73 );
74
75 fn draw_model(
76 &mut self,
77 model: &'a Model,
78 camera_bind_group: &'a wgpu::BindGroup,
79 light_bind_group: &'a wgpu::BindGroup,
80 shadow_bind_group: &'a wgpu::BindGroup,
81 wind_bind_group: &'a wgpu::BindGroup,
82 );
83}
84
85impl<'a, 'b> DrawModel<'b> for wgpu::RenderPass<'a>
86where
87 'b: 'a,
88{
89 fn draw_mesh(
90 &mut self,
91 mesh: &'b renderer::Mesh,
92 material: &'b renderer::Material,
93 instances: std::ops::Range<u32>,
94 instance_buffer: &'a wgpu::Buffer,
95 camera_bind_group: &'b wgpu::BindGroup,
96 light_bind_group: &'a wgpu::BindGroup,
97 shadow_bind_group: &'a wgpu::BindGroup,
98 wind_bind_group: &'a wgpu::BindGroup,
99 ) {
100 self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
101 self.set_vertex_buffer(1, instance_buffer.slice(..));
102 self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
103 self.set_bind_group(0, &material.bind_group, &[]);
104 self.set_bind_group(1, camera_bind_group, &[]);
105 self.set_bind_group(2, light_bind_group, &[]);
106 self.set_bind_group(3, shadow_bind_group, &[]);
107 self.set_bind_group(4, wind_bind_group, &[]);
108 self.draw_indexed(0..mesh.indices, 0, instances);
109 }
110
111 fn draw_model(
112 &mut self,
113 model: &'b Model,
114 camera_bind_group: &'b wgpu::BindGroup,
115 light_bind_group: &'a wgpu::BindGroup,
116 shadow_bind_group: &'a wgpu::BindGroup,
117 wind_bind_group: &'a wgpu::BindGroup,
118 ) {
119 for mesh in &model.meshes {
120 let material: &renderer::Material = &model.materials[mesh.material];
121 self.draw_mesh(
122 mesh,
123 material,
124 0..model.instances.len() as u32,
125 &model.instance_buffer,
126 camera_bind_group,
127 light_bind_group,
128 shadow_bind_group,
129 wind_bind_group,
130 );
131 }
132 }
133}
134
135#[repr(C)]
136#[derive(Clone, Copy, Debug, bytemuck::Pod, bytemuck::Zeroable)]
137#[allow(dead_code)]
138pub struct InstanceRaw {
139 pub model: [[f32; 4]; 4],
140 pub normals: [[f32; 3]; 3],
141 pub wind_weight: f32,
142}
143
144impl InstanceRaw {
145 pub fn desc() -> wgpu::VertexBufferLayout<'static> {
146 use std::mem;
147
148 wgpu::VertexBufferLayout {
149 array_stride: mem::size_of::<InstanceRaw>() as wgpu::BufferAddress,
150 step_mode: wgpu::VertexStepMode::Instance,
151 attributes: &[
152 wgpu::VertexAttribute {
153 format: wgpu::VertexFormat::Float32x4,
154 offset: 0,
155 shader_location: 6,
156 },
157 wgpu::VertexAttribute {
158 format: wgpu::VertexFormat::Float32x4,
159 offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress,
160 shader_location: 7,
161 },
162 wgpu::VertexAttribute {
163 format: wgpu::VertexFormat::Float32x4,
164 offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
165 shader_location: 8,
166 },
167 wgpu::VertexAttribute {
168 format: wgpu::VertexFormat::Float32x4,
169 offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress,
170 shader_location: 9,
171 },
172 wgpu::VertexAttribute {
173 format: wgpu::VertexFormat::Float32x3,
174 offset: mem::size_of::<[f32; 16]>() as wgpu::BufferAddress,
175 shader_location: 10,
176 },
177 wgpu::VertexAttribute {
178 format: wgpu::VertexFormat::Float32x3,
179 offset: mem::size_of::<[f32; 19]>() as wgpu::BufferAddress,
180 shader_location: 11,
181 },
182 wgpu::VertexAttribute {
183 format: wgpu::VertexFormat::Float32x3,
184 offset: mem::size_of::<[f32; 22]>() as wgpu::BufferAddress,
185 shader_location: 12,
186 },
187 wgpu::VertexAttribute {
188 format: wgpu::VertexFormat::Float32,
189 offset: mem::size_of::<[f32; 25]>() as wgpu::BufferAddress,
190 shader_location: 13,
191 },
192 ],
193 }
194 }
195}
196
197pub struct Instance {
198 pub position: cgmath::Vector3<f32>,
199 pub rotation: cgmath::Quaternion<f32>,
200 pub scale: cgmath::Vector3<f32>,
201 pub wind_weight: f32,
202}
203
204impl Instance {
205 pub fn new(
206 position: cgmath::Vector3<f32>,
207 rotation: cgmath::Quaternion<f32>,
208 scale: cgmath::Vector3<f32>,
209 ) -> Self {
210 Self {
211 position,
212 rotation,
213 scale,
214 wind_weight: 0.0,
215 }
216 }
217
218 pub fn with_wind(mut self, weight: f32) -> Self {
219 self.wind_weight = weight;
220 self
221 }
222
223 pub fn to_raw(&self) -> InstanceRaw {
224 let translation: Matrix4<f32> = cgmath::Matrix4::from_translation(self.position);
225 let rotation: Matrix4<f32> = cgmath::Matrix4::from(self.rotation);
226 let scale: Matrix4<f32> =
227 cgmath::Matrix4::from_nonuniform_scale(self.scale.x, self.scale.y, self.scale.z);
228
229 let normals: Matrix3<f32> = cgmath::Matrix3::from(self.rotation);
230
231 InstanceRaw {
232 model: (translation * rotation * scale).into(),
233 normals: normals.into(),
234 wind_weight: self.wind_weight,
235 }
236 }
237}
238
239impl Default for Instance {
240 fn default() -> Self {
241 Self {
242 position: Vector3::zero(),
243 rotation: Quaternion::one(),
244 scale: Vector3::new(1.0, 1.0, 1.0),
245 wind_weight: 0.0,
246 }
247 }
248}
249
250pub trait DrawLight<'a> {
251 fn draw_light_model(
252 &mut self,
253 model: &'a Model,
254 camera_bind_group: &'a wgpu::BindGroup,
255 light_bind_group: &'a wgpu::BindGroup,
256 );
257}
258
259impl<'a, 'b> DrawLight<'b> for wgpu::RenderPass<'a>
260where
261 'b: 'a,
262{
263 fn draw_light_model(
264 &mut self,
265 model: &'a Model,
266 camera_bind_group: &'b wgpu::BindGroup,
267 light_bind_group: &'b wgpu::BindGroup,
268 ) {
269 for mesh in &model.meshes {
270 let material: &renderer::Material = &model.materials[mesh.material];
271 self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
272 self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
273 self.set_bind_group(0, camera_bind_group, &[]);
274 self.set_bind_group(1, light_bind_group, &[]);
275 self.set_bind_group(2, &material.bind_group, &[]);
276 self.draw_indexed(0..mesh.indices, 0, 0..1);
277 }
278 }
279}
280
281pub trait DrawShadow<'a> {
282 fn draw_shadow_model(&mut self, model: &'a Model, light_bind_group: &'a wgpu::BindGroup);
283}
284
285impl<'a, 'b> DrawShadow<'b> for wgpu::RenderPass<'a>
286where
287 'b: 'a,
288{
289 fn draw_shadow_model(&mut self, model: &'a Model, light_bind_group: &'b wgpu::BindGroup) {
290 for mesh in &model.meshes {
291 self.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
292 self.set_vertex_buffer(1, model.instance_buffer.slice(..));
293 self.set_index_buffer(mesh.index_buffer.slice(..), wgpu::IndexFormat::Uint32);
294 self.set_bind_group(0, light_bind_group, &[]);
295 self.draw_indexed(0..mesh.indices, 0, 0..model.instances.len() as u32);
296 }
297 }
298}
299
300pub struct Model {
301 pub meshes: Vec<renderer::Mesh>,
302 pub materials: Vec<renderer::Material>,
303 pub instances: Vec<Instance>,
304 pub instance_buffer: wgpu::Buffer,
305 pub type_model: TypeModel,
306}
307
308pub struct ModelDesc<'a> {
309 pub path: &'a str,
310 pub instances: Vec<Instance>,
311 pub kind: TypeModel,
312}
313
314impl<'a> ModelDesc<'a> {
315 pub fn new(path: &'a str, instances: Vec<Instance>, kind: TypeModel) -> Self {
316 Self {
317 path,
318 instances,
319 kind,
320 }
321 }
322}
323
324#[derive(Clone)]
325pub enum TypeModel {
326 StaticObj,
327 PointOfLight,
328}