Moved closest_line_seg_line_seg to common/systems/src/phys.rs and renamed to closest_points_ls3

This commit is contained in:
Woeful_Wolf 2024-02-01 22:34:42 +02:00
parent b9239cf603
commit c86f000881
2 changed files with 39 additions and 51 deletions

View File

@ -2200,6 +2200,43 @@ fn closest_points(n: LineSegment2<f32>, m: LineSegment2<f32>) -> (Vec2<f32>, Vec
}
}
// Get closest point between 2 3D line segments https://math.stackexchange.com/a/4289668
pub fn closest_points_ls3(n: LineSegment3<f32>, m: LineSegment3<f32>) -> (Vec3<f32>, Vec3<f32>) {
let p1 = n.start;
let p2 = n.end;
let p3 = m.start;
let p4 = m.end;
let d1 = p2 - p1;
let d2 = p4 - p3;
let d21 = p3 - p1;
let v22 = d2.dot(d2);
let v11 = d1.dot(d1);
let v21 = d2.dot(d1);
let v21_1 = d21.dot(d1);
let v21_2 = d21.dot(d2);
let denom = v21 * v21 - v22 * v11;
let (s, t) = if denom == 0.0 {
let s = 0.0;
let t = (v11 * s - v21_1) / v21;
(s, t)
} else {
let s = (v21_2 * v21 - v22 * v21_1) / denom;
let t = (-v21_1 * v21 + v11 * v21_2) / denom;
(s, t)
};
let (s, t) = (s.clamp(0.0, 1.0), t.clamp(0.0, 1.0));
let p_a = p1 + s * d1;
let p_b = p3 + t * d2;
(p_a, p_b)
}
/// Find pushback vector and collision_distance we assume between this
/// colliders assuming that only one of them is capsule prism.
fn capsule2cylinder(c0: ColliderContext, c1: ColliderContext) -> (Vec2<f32>, f32) {

View File

@ -13,6 +13,7 @@ use common::{
vol::ReadVol,
};
use common_base::span;
use common_systems::phys::closest_points_ls3;
#[derive(Clone, Copy, Debug)]
pub struct Target<T> {
@ -305,12 +306,7 @@ pub(super) fn ray_entities(
start: world_p0,
end: world_p1,
};
closest_line_seg_line_seg(
seg_ray.start,
seg_ray.end,
seg_capsule.start,
seg_capsule.end,
)
closest_points_ls3(seg_ray, seg_capsule)
} else {
let nearest = seg_ray.projected_point(world_p0);
(nearest, world_p0)
@ -338,48 +334,3 @@ pub(super) fn ray_entities(
entity
}
// Get closest point between 2 line segments https://math.stackexchange.com/a/4289668
fn closest_line_seg_line_seg(
p1: Vec3<f32>,
p2: Vec3<f32>,
p3: Vec3<f32>,
p4: Vec3<f32>,
) -> (Vec3<f32>, Vec3<f32>) {
let p1 = Vec3::new(p1.x as f64, p1.y as f64, p1.z as f64);
let p2 = Vec3::new(p2.x as f64, p2.y as f64, p2.z as f64);
let p3 = Vec3::new(p3.x as f64, p3.y as f64, p3.z as f64);
let p4 = Vec3::new(p4.x as f64, p4.y as f64, p4.z as f64);
let d1 = p2 - p1;
let d2 = p4 - p3;
let d21 = p3 - p1;
let v22 = d2.dot(d2);
let v11 = d1.dot(d1);
let v21 = d2.dot(d1);
let v21_1 = d21.dot(d1);
let v21_2 = d21.dot(d2);
let denom = v21 * v21 - v22 * v11;
let (s, t) = if denom == 0.0 {
let s = 0.0;
let t = (v11 * s - v21_1) / v21;
(s, t)
} else {
let s = (v21_2 * v21 - v22 * v21_1) / denom;
let t = (-v21_1 * v21 + v11 * v21_2) / denom;
(s, t)
};
let (s, t) = (s.clamp(0.0, 1.0), t.clamp(0.0, 1.0));
let p_a = p1 + s * d1;
let p_b = p3 + t * d2;
(
Vec3::new(p_a.x as f32, p_a.y as f32, p_a.z as f32),
Vec3::new(p_b.x as f32, p_b.y as f32, p_b.z as f32),
)
}