Basic brush plane intersection calculation
This commit is contained in:
parent
cdf3ed0444
commit
9dbcb2b811
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
pub const EPSILON: f32 = 0.0001;
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
[package]
|
||||
name = "editor"
|
||||
name = "editor"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
csg = { path = "../csg" }
|
||||
|
|
|
@ -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:?}");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue