From d5f5949107e98cf7e6abb720445b78e1bb010649 Mon Sep 17 00:00:00 2001 From: Verox001 Date: Mon, 5 May 2025 21:52:42 +0200 Subject: [PATCH] Added Spheres and improved geometry creation --- simulator/src/main.rs | 2 +- solar_engine/src/render.rs | 40 +++++++++++++++++++++++++ solar_engine/src/state.rs | 61 ++++++++++++++++++-------------------- 3 files changed, 70 insertions(+), 33 deletions(-) diff --git a/simulator/src/main.rs b/simulator/src/main.rs index 7f51b0c..e64d243 100644 --- a/simulator/src/main.rs +++ b/simulator/src/main.rs @@ -64,7 +64,7 @@ pub async fn run() { _ => [0.5, 0.5, 0.5], }, scale: 0.05, - shape: solar_engine::Shape::Circle, + shape: solar_engine::Shape::Sphere, } }) .collect(); diff --git a/solar_engine/src/render.rs b/solar_engine/src/render.rs index 13c5024..f812328 100644 --- a/solar_engine/src/render.rs +++ b/solar_engine/src/render.rs @@ -8,6 +8,7 @@ pub struct Globals { pub enum Shape { Polygon, Circle, + Sphere, } pub struct Geometry { @@ -105,5 +106,44 @@ pub fn create_circle_vertices(segment_count: usize, radius: f32, color: [f32; 3] indices.push((i % segment_count + 1) as u16); } + (vertices, indices) +} + +pub fn create_sphere_vertices(stacks: usize, slices: usize, radius: f32, color: [f32; 3]) -> (Vec, Vec) { + let mut vertices = Vec::new(); + let mut indices = Vec::new(); + + for i in 0..=stacks { + let phi = std::f32::consts::PI * (i as f32) / (stacks as f32); + let y = phi.cos(); + let r = phi.sin(); + + for j in 0..=slices { + let theta = 2.0 * std::f32::consts::PI * (j as f32) / (slices as f32); + let x = r * theta.cos(); + let z = r * theta.sin(); + + vertices.push(Vertex { + position: [x * radius, y * radius, z * radius], + color, + }); + } + } + + for i in 0..stacks { + for j in 0..slices { + let first = i * (slices + 1) + j; + let second = first + slices + 1; + + indices.push(first as u16); + indices.push(second as u16); + indices.push((first + 1) as u16); + + indices.push(second as u16); + indices.push((second + 1) as u16); + indices.push((first + 1) as u16); + } + } + (vertices, indices) } \ No newline at end of file diff --git a/solar_engine/src/state.rs b/solar_engine/src/state.rs index f2b8b36..d88b702 100644 --- a/solar_engine/src/state.rs +++ b/solar_engine/src/state.rs @@ -9,7 +9,7 @@ use wgpu::{Adapter, Device, Instance, PresentMode, Queue, Surface, SurfaceCapabi use winit::dpi::PhysicalSize; use winit::window::{Window}; use crate::camera::Camera; -use crate::render::{create_circle_vertices, Geometry, Globals, InstanceRaw, RenderInstance, SampleCount, Shape, Vertex}; +use crate::render::{create_circle_vertices, create_sphere_vertices, Geometry, Globals, InstanceRaw, RenderInstance, SampleCount, Shape, Vertex}; pub struct State<'a> { surface: Surface<'a>, @@ -123,41 +123,38 @@ impl<'a> State<'a> { ]; 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 polygon_geometry = Self::create_geometry(device, &polygon_vertices, &polygon_indices); + geometries.insert(Shape::Polygon, polygon_geometry); let (circle_vertices, circle_indices) = create_circle_vertices(512, 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 circle_geometry = Self::create_geometry(device, &circle_vertices, &circle_indices); + geometries.insert(Shape::Circle, circle_geometry); + + let (sphere_vertices, sphere_indices) = create_sphere_vertices(32, 32, 0.5, [0.5, 0.5, 0.5]); + let sphere_geometry = Self::create_geometry(device, &sphere_vertices, &sphere_indices); + geometries.insert(Shape::Sphere, sphere_geometry); geometries } + + fn create_geometry(device: &Device, vertices: &[Vertex], indices: &[u16]) -> Geometry { + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(vertices), + usage: wgpu::BufferUsages::VERTEX, + }); + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(indices), + usage: wgpu::BufferUsages::INDEX, + }); + + Geometry { + vertex_buffer, + index_buffer, + index_count: indices.len() as u32, + } + } fn probe_msaa_support(device: &Device, config: &SurfaceConfiguration) -> u32 { pollster::block_on(async { @@ -361,7 +358,7 @@ impl<'a> State<'a> { render_pass.set_pipeline(&self.render_pipeline); render_pass.set_bind_group(0, &self.global_bind_group, &[]); - for shape in [Shape::Polygon, Shape::Circle] { + for shape in self.geometries.keys().copied() { let geometry = &self.geometries[&shape]; let relevant_instances: Vec<_> = self.instances