use crate::compiled::real::{Real, Vec3R};
use glam::Vec3;
#[inline(always)]
pub fn sdf_plane_r<R: Real>(p: Vec3R<R>, normal: Vec3, distance: f32) -> R {
p.dot(Vec3R::splat(normal)) - R::splat(distance)
}
#[inline(always)]
pub fn sdf_plane(point: Vec3, normal: Vec3, distance: f32) -> f32 {
sdf_plane_r::<f32>(point.into(), normal, distance)
}
#[inline(always)]
pub const fn sdf_plane_xy(point: Vec3) -> f32 {
point.z
}
#[inline(always)]
pub const fn sdf_plane_xz(point: Vec3) -> f32 {
point.y
}
#[inline(always)]
pub const fn sdf_plane_yz(point: Vec3) -> f32 {
point.x
}
#[inline(always)]
pub fn sdf_plane_from_points(point: Vec3, a: Vec3, b: Vec3, c: Vec3) -> f32 {
let ab = b - a;
let ac = c - a;
let normal = ab.cross(ac).normalize();
let distance = normal.dot(a);
sdf_plane(point, normal, distance)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_plane_horizontal() {
let normal = Vec3::new(0.0, 1.0, 0.0);
let d = sdf_plane(Vec3::new(0.0, 1.0, 0.0), normal, 0.0);
assert!((d - 1.0).abs() < 0.0001);
let d = sdf_plane(Vec3::new(5.0, 0.0, -3.0), normal, 0.0);
assert!(d.abs() < 0.0001);
let d = sdf_plane(Vec3::new(0.0, -2.0, 0.0), normal, 0.0);
assert!((d + 2.0).abs() < 0.0001);
}
#[test]
fn test_plane_offset() {
let normal = Vec3::new(0.0, 1.0, 0.0);
let d = sdf_plane(Vec3::new(0.0, 1.0, 0.0), normal, 1.0);
assert!(d.abs() < 0.0001);
let d = sdf_plane(Vec3::new(0.0, 2.0, 0.0), normal, 1.0);
assert!((d - 1.0).abs() < 0.0001);
}
#[test]
fn test_plane_diagonal() {
let normal = Vec3::new(1.0, 1.0, 0.0).normalize();
let d = sdf_plane(Vec3::ZERO, normal, 0.0);
assert!(d.abs() < 0.0001);
let d = sdf_plane(Vec3::new(1.0, 1.0, 0.0), normal, 0.0);
let expected = 2.0_f32.sqrt();
assert!((d - expected).abs() < 0.0001);
}
#[test]
fn test_axis_planes() {
assert!((sdf_plane_xy(Vec3::new(0.0, 0.0, 1.0)) - 1.0).abs() < 0.0001);
assert!((sdf_plane_xz(Vec3::new(0.0, 1.0, 0.0)) - 1.0).abs() < 0.0001);
assert!((sdf_plane_yz(Vec3::new(1.0, 0.0, 0.0)) - 1.0).abs() < 0.0001);
}
#[test]
fn test_plane_from_points() {
let a = Vec3::new(0.0, 0.0, 0.0);
let b = Vec3::new(1.0, 0.0, 0.0);
let c = Vec3::new(0.0, 0.0, 1.0);
let d = sdf_plane_from_points(Vec3::new(0.0, 1.0, 0.0), a, b, c);
assert!((d.abs() - 1.0).abs() < 0.0001);
}
}