From 901fb79ae6a34f223453fa2e088da1a39a4f6e42 Mon Sep 17 00:00:00 2001 From: Jarrod Doyle Date: Fri, 22 Sep 2023 10:17:49 +0100 Subject: [PATCH] Add vertex merging --- csg/src/brush.rs | 55 ++++++++++++++++++++++++++++++++++++---------- editor/src/main.rs | 19 ++++++---------- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/csg/src/brush.rs b/csg/src/brush.rs index 8b10781..ee96325 100644 --- a/csg/src/brush.rs +++ b/csg/src/brush.rs @@ -1,10 +1,14 @@ use glam::Vec3; -use crate::plane::{Plane, PlaneIntersection}; +use crate::{ + math, + plane::{Plane, PlaneIntersection}, +}; -#[derive(Default)] +#[derive(Default, Debug, Clone)] pub struct MaterialId(pub String); +#[derive(Debug, Clone, Copy)] pub struct TextureProjection { pub u: Plane, pub v: Plane, @@ -25,7 +29,7 @@ impl Default for TextureProjection { } } -#[derive(Default)] +#[derive(Default, Debug, Clone)] pub struct BrushPlane { pub plane: Plane, pub material: MaterialId, @@ -34,18 +38,27 @@ pub struct BrushPlane { pub struct Brush { pub planes: Vec, + raw_vertices: Vec, + vertices: Vec, } impl Brush { - pub fn get_vertices(&self) -> Vec { - if self.planes.len() < 3 { - println!("fug"); - return vec![]; + pub fn new(planes: &[BrushPlane]) -> Self { + Self { + planes: planes.to_vec(), + raw_vertices: vec![], + vertices: vec![], + } + } + + pub fn rebuild(&mut self) { + if self.planes.len() < 4 { + panic!("Invalid number of planes. Minimum 4 planes required."); } // Test all permutations of brush planes for intersections let mut intersections = vec![]; - let mut vs = vec![]; + let mut vs: Vec = vec![]; let len = self.planes.len(); for i in 0..(len - 2) { for j in (i + 1)..(len - 1) { @@ -63,7 +76,7 @@ impl Brush { // Validate intersections against other brush planes // TODO: No need to check against planes that are part of the intersection - for intersection in intersections { + for intersection in &intersections { let mut valid = true; for bplane in &self.planes { if !intersection.in_halfspace_mat(&bplane.plane) { @@ -72,11 +85,31 @@ impl Brush { } } + // Merge vertices if valid { - vs.push(intersection.get_intersection_point()); + let point = intersection.get_intersection_point(); + let mut duplicate = false; + for v in &vs { + if v.abs_diff_eq(point, math::EPSILON) { + duplicate = true; + break; + } + } + if !duplicate { + vs.push(point); + } } } - vs + self.vertices = vs; + self.raw_vertices = intersections; + } + + pub fn get_vertices(&self) -> Vec { + self.vertices.clone() + } + + pub fn get_intersections(&self) -> Vec { + self.raw_vertices.clone() } } diff --git a/editor/src/main.rs b/editor/src/main.rs index 3f83e63..6363b1a 100644 --- a/editor/src/main.rs +++ b/editor/src/main.rs @@ -22,13 +22,9 @@ fn generate_box_brush(position: Vec3, extent: Vec3) -> Brush { plane: Plane::from_point_normal(point, *normal), ..Default::default() }); - - println!("Plane: {:?}", brush_planes.last().unwrap().plane); } - Brush { - planes: brush_planes, - } + Brush::new(&brush_planes) } /// Position is center of base plane @@ -43,14 +39,12 @@ fn generate_pyramid_brush(position: Vec3, height: f32, side_count: u32) -> Brush for i in 0..side_count { let angle = (i as f32 / side_count as f32) * 360.0_f32.to_radians(); - dbg!(angle); let rot_mat = Mat3::from_cols( Vec3::new(angle.cos(), 0.0, -angle.sin()), Vec3::Y, Vec3::new(angle.sin(), 0.0, angle.cos()), ); let normal = rot_mat * Vec3::new(1.0, 1.0, 0.0); - dbg!(normal); brush_planes.push(BrushPlane { plane: Plane::from_point_normal(tip, normal), @@ -58,18 +52,19 @@ fn generate_pyramid_brush(position: Vec3, height: f32, side_count: u32) -> Brush }); } - Brush { - planes: brush_planes, - } + Brush::new(&brush_planes) } fn main() { - let brush = generate_box_brush(Vec3::new(1.0, 0.0, 0.0), Vec3::new(1.0, 2.0, 1.0)); + let mut brush = generate_box_brush(Vec3::new(1.0, 0.0, 0.0), Vec3::new(1.0, 2.0, 1.0)); + brush.rebuild(); let vs = brush.get_vertices(); println!("Vertices: {vs:?}"); - let vs = generate_pyramid_brush(Vec3::ZERO, 1.0, 4).get_vertices(); + let mut brush = generate_pyramid_brush(Vec3::ZERO, 1.0, 4); + brush.rebuild(); + let vs = brush.get_vertices(); println!("Vertices: {vs:?}"); }