use super::functions::ImplicitSurface;
#[allow(unused_imports)]
use super::functions::*;
#[allow(unused_imports)]
use super::functions_2::*;
pub struct SdfPlane {
pub normal: [f64; 3],
pub d: f64,
}
impl SdfPlane {
pub fn new(normal: [f64; 3], d: f64) -> Self {
Self {
normal: normalize(normal),
d,
}
}
}
pub struct CsgSmoothDifference {
pub a: Box<dyn ImplicitSurface>,
pub b: Box<dyn ImplicitSurface>,
pub k: f64,
}
impl CsgSmoothDifference {
pub fn new(a: Box<dyn ImplicitSurface>, b: Box<dyn ImplicitSurface>, k: f64) -> Self {
Self { a, b, k }
}
}
pub struct SdfCone {
pub apex: [f64; 3],
pub half_angle: f64,
pub height: f64,
}
impl SdfCone {
pub fn new(apex: [f64; 3], half_angle: f64, height: f64) -> Self {
Self {
apex,
half_angle,
height,
}
}
}
pub struct SdfSphere {
pub center: [f64; 3],
pub radius: f64,
}
impl SdfSphere {
pub fn new(center: [f64; 3], radius: f64) -> Self {
Self { center, radius }
}
}
pub struct CsgIntersection {
pub a: Box<dyn ImplicitSurface>,
pub b: Box<dyn ImplicitSurface>,
}
impl CsgIntersection {
pub fn new(a: Box<dyn ImplicitSurface>, b: Box<dyn ImplicitSurface>) -> Self {
Self { a, b }
}
}
pub enum CsgTree {
Leaf(Box<dyn ImplicitSurface>),
Node {
op: CsgOp,
left: Box<CsgTree>,
right: Box<CsgTree>,
},
}
impl CsgTree {
pub fn leaf(s: impl ImplicitSurface + 'static) -> Self {
CsgTree::Leaf(Box::new(s))
}
pub fn union(left: CsgTree, right: CsgTree) -> Self {
CsgTree::Node {
op: CsgOp::Union,
left: Box::new(left),
right: Box::new(right),
}
}
pub fn intersection(left: CsgTree, right: CsgTree) -> Self {
CsgTree::Node {
op: CsgOp::Intersection,
left: Box::new(left),
right: Box::new(right),
}
}
pub fn difference(left: CsgTree, right: CsgTree) -> Self {
CsgTree::Node {
op: CsgOp::Difference,
left: Box::new(left),
right: Box::new(right),
}
}
}
pub struct CsgUnion {
pub a: Box<dyn ImplicitSurface>,
pub b: Box<dyn ImplicitSurface>,
}
impl CsgUnion {
pub fn new(a: Box<dyn ImplicitSurface>, b: Box<dyn ImplicitSurface>) -> Self {
Self { a, b }
}
}
pub struct SdfTorus {
pub major_radius: f64,
pub minor_radius: f64,
}
impl SdfTorus {
pub fn new(major_radius: f64, minor_radius: f64) -> Self {
Self {
major_radius,
minor_radius,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CsgOp {
Union,
Intersection,
Difference,
}
pub struct SdfCapsule {
pub center: [f64; 3],
pub radius: f64,
pub half_height: f64,
}
impl SdfCapsule {
pub fn new(center: [f64; 3], radius: f64, half_height: f64) -> Self {
Self {
center,
radius,
half_height,
}
}
}
pub struct CsgOffsetSurface {
pub(super) inner_sdf: f64,
pub offset: f64,
pub bbox_min: [f64; 3],
pub bbox_max: [f64; 3],
}
impl CsgOffsetSurface {
pub fn new(offset: f64, bbox_min: [f64; 3], bbox_max: [f64; 3]) -> Self {
Self {
inner_sdf: 0.0,
offset,
bbox_min,
bbox_max,
}
}
}
#[derive(Debug, Clone)]
pub struct MarchingCell {
pub min: [f64; 3],
pub step: f64,
pub corner_values: [f64; 8],
}
impl MarchingCell {
pub fn has_surface(&self) -> bool {
let has_inside = self.corner_values.iter().any(|&v| v < 0.0);
let has_outside = self.corner_values.iter().any(|&v| v >= 0.0);
has_inside && has_outside
}
fn edge_vertex(&self, i0: usize, i1: usize) -> [f64; 3] {
let offsets: [[f64; 3]; 8] = [
[0.0, 0.0, 0.0],
[self.step, 0.0, 0.0],
[self.step, self.step, 0.0],
[0.0, self.step, 0.0],
[0.0, 0.0, self.step],
[self.step, 0.0, self.step],
[self.step, self.step, self.step],
[0.0, self.step, self.step],
];
let v0 = self.corner_values[i0];
let v1 = self.corner_values[i1];
let t = if (v1 - v0).abs() > 1e-14 {
v0 / (v0 - v1)
} else {
0.5
};
let p0 = add(self.min, offsets[i0]);
let p1 = add(self.min, offsets[i1]);
lerp3(p0, p1, t)
}
pub fn extract_vertices(&self) -> Vec<[f64; 3]> {
if !self.has_surface() {
return vec![];
}
let edges: [(usize, usize); 12] = [
(0, 1),
(1, 2),
(2, 3),
(3, 0),
(4, 5),
(5, 6),
(6, 7),
(7, 4),
(0, 4),
(1, 5),
(2, 6),
(3, 7),
];
edges
.iter()
.filter_map(|&(i0, i1)| {
let v0 = self.corner_values[i0];
let v1 = self.corner_values[i1];
if v0.signum() != v1.signum() {
Some(self.edge_vertex(i0, i1))
} else {
None
}
})
.collect()
}
}
pub struct SdfBox {
pub center: [f64; 3],
pub half_extents: [f64; 3],
}
impl SdfBox {
pub fn new(center: [f64; 3], half_extents: [f64; 3]) -> Self {
Self {
center,
half_extents,
}
}
}
pub struct SdfCylinder {
pub center: [f64; 3],
pub radius: f64,
}
impl SdfCylinder {
pub fn new(center: [f64; 3], radius: f64) -> Self {
Self { center, radius }
}
}
pub struct CsgDifference {
pub a: Box<dyn ImplicitSurface>,
pub b: Box<dyn ImplicitSurface>,
}
impl CsgDifference {
pub fn new(a: Box<dyn ImplicitSurface>, b: Box<dyn ImplicitSurface>) -> Self {
Self { a, b }
}
}
pub struct CsgSmoothUnion {
pub a: Box<dyn ImplicitSurface>,
pub b: Box<dyn ImplicitSurface>,
pub k: f64,
}
impl CsgSmoothUnion {
pub fn new(a: Box<dyn ImplicitSurface>, b: Box<dyn ImplicitSurface>, k: f64) -> Self {
Self { a, b, k }
}
}
pub struct CsgSmoothIntersection {
pub a: Box<dyn ImplicitSurface>,
pub b: Box<dyn ImplicitSurface>,
pub k: f64,
}
impl CsgSmoothIntersection {
pub fn new(a: Box<dyn ImplicitSurface>, b: Box<dyn ImplicitSurface>, k: f64) -> Self {
Self { a, b, k }
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PlaneSide {
Front,
Back,
OnPlane,
}
pub struct SdfCappedCylinder {
pub center: [f64; 3],
pub radius: f64,
pub half_height: f64,
}
impl SdfCappedCylinder {
pub fn new(center: [f64; 3], radius: f64, half_height: f64) -> Self {
Self {
center,
radius,
half_height,
}
}
}
pub struct SdfRoundedBox {
pub center: [f64; 3],
pub half_extents: [f64; 3],
pub radius: f64,
}
impl SdfRoundedBox {
pub fn new(center: [f64; 3], half_extents: [f64; 3], radius: f64) -> Self {
Self {
center,
half_extents,
radius,
}
}
}