feat: connected surfaces

This commit is contained in:
2024-03-11 22:46:23 +01:00
parent 9c9e473490
commit ac39a15b4f
2 changed files with 49 additions and 38 deletions

View File

@@ -7,42 +7,50 @@ pub fn split_surface(mut triangles: Vec<Triangle<f64>>) -> Vec<Mesh<f64>> {
while let Some(triangle) = triangles.pop() { while let Some(triangle) = triangles.pop() {
let mut surface = vec![triangle]; let mut surface = vec![triangle];
let mut bvh = Bvh::build(&mut surface); let mut bvh = Bvh::build(&mut surface);
let mut aabb = surface[0].aabb; let mut aabb = surface[0].aabb.clone();
triangles.retain_mut(|triangle| {
let mut stack = Vec::<usize>::new(); loop {
stack.push(0); let mut mutated = false;
while let Some(i) = stack.pop() { triangles.retain_mut(|triangle| {
match bvh.nodes[i] { let mut stack = Vec::<usize>::new();
BvhNode::Node { stack.push(0);
parent_index: _, while let Some(i) = stack.pop() {
child_l_index, match bvh.nodes[i] {
child_l_aabb, BvhNode::Node {
child_r_index, parent_index: _,
child_r_aabb, child_l_index,
} => { child_l_aabb,
if triangle.has_point_in_aabb(&child_l_aabb) { child_r_index,
stack.push(child_l_index); child_r_aabb,
} => {
if triangle.has_point_in_aabb(&child_l_aabb) {
stack.push(child_l_index);
}
if triangle.has_point_in_aabb(&child_r_aabb) {
stack.push(child_r_index);
}
} }
if triangle.has_point_in_aabb(&child_r_aabb) { BvhNode::Leaf {
stack.push(child_r_index); parent_index: _,
} shape_index,
} } => {
BvhNode::Leaf { if triangle.connected_with_triangle(surface[shape_index]) {
parent_index: _, mutated = true;
shape_index, surface.push(*triangle);
} => { let index = surface.len() - 1;
if triangle.connected_with_triangle(surface[shape_index]) { bvh.add_shape(&mut surface, index);
surface.push(*triangle); aabb.join_mut(&triangle.aabb);
let index = surface.len() - 1; return false;
bvh.add_shape(&mut surface, index); }
aabb.join_mut(&triangle.aabb);
return false;
} }
} }
} }
true
});
if !mutated {
break;
} }
true }
});
surfaces.push(Mesh { surfaces.push(Mesh {
triangles: surface, triangles: surface,

View File

@@ -18,16 +18,19 @@ pub struct Triangle<T: SimdPartialOrd + Scalar + Copy> {
pub aabb: Aabb<T, 3>, pub aabb: Aabb<T, 3>,
} }
fn vec_inside_aabb<T: SimdPartialOrd + Scalar + Copy + Float>( #[inline(always)]
fn vec_inside_aabb<T: SimdPartialOrd + Scalar + Copy + Float + RelativeEq + approx::AbsDiffEq>(
vec: &Vector3<T>, vec: &Vector3<T>,
aabb: &Aabb<T, 3>, aabb: &Aabb<T, 3>,
) -> bool { ) -> bool {
vec.x >= aabb.min.x macro_rules! within {
&& vec.y >= aabb.min.y ($axis:ident) => {
&& vec.z >= aabb.min.z ((vec.$axis >= aabb.min.$axis && vec.$axis <= aabb.max.$axis)
&& vec.x <= aabb.max.x || relative_eq!(vec.$axis, aabb.min.$axis)
&& vec.y <= aabb.max.y || relative_eq!(vec.$axis, aabb.max.$axis))
&& vec.z <= aabb.max.z };
}
within!(x) && within!(y) && within!(z)
} }
impl<T> Triangle<T> impl<T> Triangle<T>