Basic brush plane intersection calculation

This commit is contained in:
Jarrod Doyle 2023-09-18 11:23:49 +01:00
parent cdf3ed0444
commit 9dbcb2b811
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
8 changed files with 183 additions and 2 deletions

12
Cargo.lock generated
View File

@ -5,7 +5,19 @@ version = 3
[[package]]
name = "csg"
version = "0.1.0"
dependencies = [
"glam",
]
[[package]]
name = "editor"
version = "0.1.0"
dependencies = [
"csg",
]
[[package]]
name = "glam"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42218cb640844e3872cc3c153dc975229e080a6c4733b34709ef445610550226"

View File

@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
glam = "0.24.1"

63
csg/src/brush.rs Normal file
View File

@ -0,0 +1,63 @@
use glam::Vec3;
use crate::plane::{Plane, PlaneIntersection};
pub struct MaterialId(pub String);
pub struct TextureProjection {
pub u: Plane,
pub v: Plane,
}
impl Default for TextureProjection {
fn default() -> Self {
Self {
u: Plane {
normal: glam::vec3(1.0, 0.0, 0.0),
offset: 0.0,
},
v: Plane {
normal: glam::vec3(0.0, 1.0, 0.0),
offset: 0.0,
},
}
}
}
pub struct BrushPlane {
pub plane: Plane,
pub material: MaterialId,
pub tex_projection: TextureProjection,
}
pub struct Brush {
pub planes: Vec<BrushPlane>,
}
impl Brush {
pub fn get_vertices(&self) -> Vec<Vec3> {
if self.planes.len() < 3 {
println!("fug");
return vec![];
}
let mut vs = vec![];
let len = self.planes.len();
for i in 0..(len - 2) {
for j in (i + 1)..(len - 1) {
for k in (j + 1)..len {
if let Some(intersection) = PlaneIntersection::from_planes(
self.planes[i].plane,
self.planes[j].plane,
self.planes[k].plane,
) {
// TODO: Validate that the found intersection is within all brush planes
vs.push(intersection.get_intersection_point())
}
}
}
}
vs
}
}

View File

@ -1,3 +1,9 @@
pub mod brush;
pub mod math;
pub mod plane;
pub use glam;
pub fn add(left: usize, right: usize) -> usize {
left + right
}

1
csg/src/math.rs Normal file
View File

@ -0,0 +1 @@
pub const EPSILON: f32 = 0.0001;

66
csg/src/plane.rs Normal file
View File

@ -0,0 +1,66 @@
use glam::{Mat3, Vec3};
use crate::math;
#[derive(Clone, Copy, Debug)]
pub struct Plane {
pub normal: Vec3,
pub offset: f32,
}
impl Plane {
pub fn from_point_normal(point: Vec3, normal: Vec3) -> Self {
Self {
normal,
offset: -point.dot(normal),
}
}
}
pub struct PlaneIntersection {
pub planes: [Plane; 3],
}
impl PlaneIntersection {
pub fn from_planes(p1: Plane, p2: Plane, p3: Plane) -> Option<Self> {
let plane = Self {
planes: [p1, p2, p3],
};
let determinant = plane.get_matrix().determinant();
// println!("Determinant: {determinant}");
if determinant.abs() > math::EPSILON {
Some(plane)
} else {
None
}
}
pub fn get_intersection_point(&self) -> Vec3 {
let base_matrix = self.get_matrix();
let base_det = base_matrix.determinant();
let offsets = glam::vec3(
self.planes[0].offset,
self.planes[1].offset,
self.planes[2].offset,
);
let mut vs = vec![];
for idx in 0..3 {
let mut matrix = base_matrix;
*(matrix.col_mut(idx)) = -offsets;
vs.push(matrix.determinant() / base_det);
}
Vec3::from_slice(&vs)
}
fn get_matrix(&self) -> Mat3 {
glam::mat3(
self.planes[0].normal,
self.planes[1].normal,
self.planes[2].normal,
)
.transpose()
}
}

View File

@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
csg = { path = "../csg" }

View File

@ -1,3 +1,34 @@
use csg::{
brush::{self, Brush, BrushPlane, MaterialId, TextureProjection},
glam::{self},
plane::Plane,
};
fn main() {
println!("Hello, world!");
let points = vec![
glam::vec3(1.0, 0.0, 0.0),
glam::vec3(-1.0, 0.0, 0.0),
glam::vec3(0.0, 1.0, 0.0),
glam::vec3(0.0, -1.0, 0.0),
glam::vec3(0.0, 0.0, 1.0),
glam::vec3(0.0, 0.0, -1.0),
];
let mut brush_planes = vec![];
for point in &points {
brush_planes.push(BrushPlane {
plane: Plane::from_point_normal(*point, *point),
material: MaterialId("Epic".to_string()),
tex_projection: TextureProjection::default(),
});
println!("Plane: {:?}", brush_planes.last().unwrap().plane);
}
let brush = Brush {
planes: brush_planes,
};
let vs = brush.get_vertices();
println!("Vertices: {vs:?}");
}