From e709e2dd3ff934c66108ab27925019fb592a5713 Mon Sep 17 00:00:00 2001 From: Verox001 Date: Sun, 4 May 2025 13:21:36 +0200 Subject: [PATCH] Added circles and geometries --- simulator/src/main.rs | 157 +++++++++++++++++++++++++++--------------- 1 file changed, 103 insertions(+), 54 deletions(-) diff --git a/simulator/src/main.rs b/simulator/src/main.rs index 882e4da..5032b39 100644 --- a/simulator/src/main.rs +++ b/simulator/src/main.rs @@ -1,4 +1,5 @@ use std::cmp::max; +use std::collections::HashMap; use std::sync::{Arc, RwLock}; use std::thread; use std::time::Duration; @@ -21,11 +22,24 @@ pub async fn run() { let _ = event_loop.run_app(&mut window_state); } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +enum Shape { + Polygon, + Circle, +} + +struct Geometry { + vertex_buffer: wgpu::Buffer, + index_buffer: wgpu::Buffer, + index_count: u32, +} + struct RenderInstance { position: cgmath::Vector3, rotation: cgmath::Quaternion, color: [f32; 3], - scale: f32 + scale: f32, + shape: Shape, } impl RenderInstance { @@ -83,20 +97,6 @@ impl Vertex { } } -const VERTICES: &[Vertex] = &[ - Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] }, - Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] }, - Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] }, - Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] }, - Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] }, -]; - -const INDICES: &[u16] = &[ - 0, 1, 4, - 1, 2, 4, - 2, 3, 4, -]; - struct StateApplication<'a> { state: Option>, } @@ -148,6 +148,26 @@ impl<'a> ApplicationHandler for StateApplication<'a>{ } } +fn create_circle_vertices(segment_count: usize, radius: f32, color: [f32; 3]) -> (Vec, Vec) { + let mut vertices = vec![Vertex { position: [0.0, 0.0, 0.0], color }]; + let mut indices = vec![]; + + for i in 0..=segment_count { + let theta = (i as f32) / (segment_count as f32) * std::f32::consts::TAU; + let x = radius * theta.cos(); + let y = radius * theta.sin(); + vertices.push(Vertex { position: [x, y, 0.0], color }); + } + + for i in 1..=segment_count { + indices.push(0); + indices.push(i as u16); + indices.push((i % segment_count + 1) as u16); + } + + (vertices, indices) +} + struct State<'a> { surface: Surface<'a>, device: Device, @@ -156,16 +176,13 @@ struct State<'a> { size: PhysicalSize, window: Arc, - + render_pipeline: wgpu::RenderPipeline, - vertex_buffer: wgpu::Buffer, - index_buffer: wgpu::Buffer, instances: Vec, instance_buffer: wgpu::Buffer, - num_vertices: u32, - num_indices: u32, + geometries: HashMap, simulator: Arc>, } @@ -183,11 +200,51 @@ impl<'a> State<'a> { surface.configure(&device, &config); let render_pipeline = Self::create_render_pipeline(&device, &config); - let vertex_buffer = Self::create_vertex_buffer(&device); - let index_buffer = Self::create_index_buffer(&device); - let num_vertices = VERTICES.len() as u32; - let num_indices = INDICES.len() as u32; + let mut geometries = HashMap::new(); + let polygon_vertices = vec![ + Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] }, + Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] }, + Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] }, + Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] }, + Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] }, + ]; + let polygon_indices = vec![0, 1, 4, 1, 2, 4, 2, 3, 4]; + + let polygon_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Polygon Vertex Buffer"), + contents: bytemuck::cast_slice(&polygon_vertices), + usage: wgpu::BufferUsages::VERTEX, + }); + + let polygon_index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Polygon Index Buffer"), + contents: bytemuck::cast_slice(&polygon_indices), + usage: wgpu::BufferUsages::INDEX, + }); + + geometries.insert(Shape::Polygon, Geometry { + vertex_buffer: polygon_vertex_buffer, + index_buffer: polygon_index_buffer, + index_count: polygon_indices.len() as u32, + }); + + let (circle_vertices, circle_indices) = create_circle_vertices(32, 0.5, [0.5, 0.5, 0.5]); + let circle_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Circle Vertex Buffer"), + contents: bytemuck::cast_slice(&circle_vertices), + usage: wgpu::BufferUsages::VERTEX, + }); + let circle_index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Circle Index Buffer"), + contents: bytemuck::cast_slice(&circle_indices), + usage: wgpu::BufferUsages::INDEX, + }); + geometries.insert(Shape::Circle, Geometry { + vertex_buffer: circle_vertex_buffer, + index_buffer: circle_index_buffer, + index_count: circle_indices.len() as u32, + }); let mut sim = Simulator::new(60.0 * 60.0 * 24.0); sim.add_body(Body { @@ -231,6 +288,7 @@ impl<'a> State<'a> { _ => [0.5, 0.5, 0.5], }, scale: 0.1, + shape: Shape::Circle }).collect::>() }; @@ -248,16 +306,12 @@ impl<'a> State<'a> { config, size, window: window_arc, - + render_pipeline, - vertex_buffer, - index_buffer, + geometries, instances, instance_buffer, - - num_vertices, - num_indices, simulator, } @@ -279,6 +333,7 @@ impl<'a> State<'a> { _ => [0.5, 0.5, 0.5], }, scale: 0.5, + shape: Shape::Circle }).collect() }; @@ -287,26 +342,6 @@ impl<'a> State<'a> { self.instances = updated_instances; } - fn create_index_buffer(device: &Device) -> wgpu::Buffer { - device.create_buffer_init( - &wgpu::util::BufferInitDescriptor { - label: Some("Index Buffer"), - contents: bytemuck::cast_slice(INDICES), - usage: wgpu::BufferUsages::INDEX, - } - ) - } - - fn create_vertex_buffer(device: &Device) -> wgpu::Buffer { - device.create_buffer_init( - &wgpu::util::BufferInitDescriptor { - label: Some("Vertex Buffer"), - contents: bytemuck::cast_slice(VERTICES), - usage: wgpu::BufferUsages::VERTEX, - } - ) - } - fn create_render_pipeline(device: &Device, config: &wgpu::SurfaceConfiguration) -> wgpu::RenderPipeline { let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("Shader"), @@ -449,11 +484,25 @@ impl<'a> State<'a> { }); render_pass.set_pipeline(&self.render_pipeline); - render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); - render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); - if !self.instances.is_empty() { + + for shape in [Shape::Polygon, Shape::Circle] { + let geometry = &self.geometries[&shape]; + + let relevant_instances: Vec<_> = self.instances + .iter() + .enumerate() + .filter(|(_, inst)| inst.shape == shape) + .map(|(i, _)| i as u32) + .collect(); + + if relevant_instances.is_empty() { + continue; + } + + render_pass.set_vertex_buffer(0, geometry.vertex_buffer.slice(..)); render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..)); - render_pass.draw_indexed(0..self.num_indices, 0, 0..self.instances.len() as u32); + render_pass.set_index_buffer(geometry.index_buffer.slice(..), wgpu::IndexFormat::Uint16); + render_pass.draw_indexed(0..geometry.index_count, 0, 0..relevant_instances.len() as u32); } }