use glam::{Vec2, Vec3};
#[inline(always)]
pub fn sdf_infinite_cone(p: Vec3, angle: f32) -> f32 {
let c = Vec2::new(angle.sin(), angle.cos());
let q = Vec2::new(p.x.hypot(p.z), -p.y);
let d = (q - c * q.dot(c).max(0.0)).length();
d * if q.x.mul_add(c.y, -(q.y * c.x)) < 0.0 {
-1.0
} else {
1.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_infinite_cone_origin() {
let d = sdf_infinite_cone(Vec3::ZERO, 0.5);
assert!(d.abs() < 0.001, "Origin is on the tip, got {}", d);
}
#[test]
fn test_infinite_cone_inside() {
let d = sdf_infinite_cone(Vec3::new(0.0, -1.0, 0.0), 0.5);
assert!(d < 0.0, "On-axis below should be inside, got {}", d);
}
#[test]
fn test_infinite_cone_outside() {
let d = sdf_infinite_cone(Vec3::new(5.0, 0.0, 0.0), 0.3);
assert!(d > 0.0, "Far side should be outside, got {}", d);
}
}