use std::collections::HashMap; use wgpu::{Device, Buffer}; use wgpu::util::DeviceExt; use crate::renderer::Vertex; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum Shape { Circle, Sphere, } pub struct Geometry { pub(crate) vertex_buffer: Buffer, pub(crate) index_buffer: Buffer, pub(crate) index_count: u32, } pub struct GeometryManager { pub geometries: HashMap, } impl GeometryManager { pub fn new(device: &Device) -> Self { let mut geometries = HashMap::new(); // Circle let (circle_vertices, circle_indices) = create_circle_vertices(512, 0.5, [0.5, 0.5, 0.5]); geometries.insert( Shape::Circle, Self::create_geometry(device, &circle_vertices, &circle_indices), ); // Sphere let (sphere_vertices, sphere_indices) = create_sphere_vertices(32, 32, 0.5, [0.5, 0.5, 0.5]); geometries.insert( Shape::Sphere, Self::create_geometry(device, &sphere_vertices, &sphere_indices), ); // Füge hier beliebige weitere Shapes hinzu Self { geometries } } pub fn get(&self, shape: &Shape) -> Option<&Geometry> { self.geometries.get(shape) } pub fn shapes(&self) -> impl Iterator + '_ { self.geometries.keys().copied() } 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, } } } pub 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, normal: [0.0, 0.0, 1.0], }]; 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, normal: [0.0, 0.0, 1.0], }); } for i in 1..=segment_count { indices.push(0); indices.push(i as u16); 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(); let normal = [x, y, z]; vertices.push(Vertex { position: [x * radius, y * radius, z * radius], color, normal, }); } } 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) }