use crate::surface3::*;
use crate::transform3::Transform3;
use crate::implicit_surface3::ImplicitSurface3;
use crate::vector3::Vector3D;
use crate::bounding_box3::BoundingBox3D;
use crate::ray3::Ray3D;
use std::sync::{RwLock, Arc};
pub struct SurfaceToImplicit3 {
_surface: Surface3Ptr,
pub surface_data: Surface3Data,
}
impl SurfaceToImplicit3 {
pub fn new(
surface: Surface3Ptr,
transform: Option<Transform3>,
is_normal_flipped: Option<bool>) -> SurfaceToImplicit3 {
return SurfaceToImplicit3 {
_surface: surface,
surface_data: Surface3Data::new(transform, is_normal_flipped),
};
}
pub fn builder() -> Builder {
return Builder::new();
}
pub fn surface(&self) -> Surface3Ptr {
return self._surface.clone();
}
}
impl Surface3 for SurfaceToImplicit3 {
fn closest_point_local(&self, other_point: &Vector3D) -> Vector3D {
return self._surface.read().unwrap().closest_point(other_point);
}
fn bounding_box_local(&self) -> BoundingBox3D {
return self._surface.read().unwrap().bounding_box();
}
fn closest_intersection_local(&self, ray: &Ray3D) -> SurfaceRayIntersection3 {
return self._surface.read().unwrap().closest_intersection(ray);
}
fn closest_normal_local(&self, other_point: &Vector3D) -> Vector3D {
return self._surface.read().unwrap().closest_normal(other_point);
}
fn intersects_local(&self, ray: &Ray3D) -> bool {
return self._surface.read().unwrap().intersects(ray);
}
fn closest_distance_local(&self, other_point: &Vector3D) -> f64 {
return self._surface.read().unwrap().closest_distance(other_point);
}
fn update_query_engine(&self) {
self._surface.read().unwrap().update_query_engine();
}
fn is_bounded(&self) -> bool {
return self._surface.read().unwrap().is_bounded();
}
fn is_valid_geometry(&self) -> bool {
return self._surface.read().unwrap().is_valid_geometry();
}
fn view(&self) -> &Surface3Data {
return &self.surface_data;
}
}
impl ImplicitSurface3 for SurfaceToImplicit3 {
fn signed_distance_local(&self, other_point: &Vector3D) -> f64 {
let x = self._surface.read().unwrap().closest_point(other_point);
let inside = self._surface.read().unwrap().is_inside(other_point);
return match inside {
true => -x.distance_to(*other_point),
false => x.distance_to(*other_point)
};
}
fn is_inside_local(&self, other_point: &Vector3D) -> bool {
return self._surface.read().unwrap().is_inside(other_point);
}
}
pub type SurfaceToImplicit3Ptr = Arc<RwLock<SurfaceToImplicit3>>;
pub struct Builder {
_surface: Option<Surface3Ptr>,
_surface_data: Surface3Data,
}
impl Builder {
pub fn with_surface(&mut self, surface: Surface3Ptr) -> &mut Self {
self._surface = Some(surface);
return self;
}
pub fn build(&mut self) -> SurfaceToImplicit3 {
return SurfaceToImplicit3::new(self._surface.as_ref().unwrap().clone(),
Some(self._surface_data.transform.clone()),
Some(self._surface_data.is_normal_flipped));
}
pub fn make_shared(&mut self) -> SurfaceToImplicit3Ptr {
return SurfaceToImplicit3Ptr::new(RwLock::new(self.build()));
}
pub fn new() -> Builder {
return Builder {
_surface: None,
_surface_data: Surface3Data::new(None, None),
};
}
}
impl SurfaceBuilderBase3 for Builder {
fn view(&mut self) -> &mut Surface3Data {
return &mut self._surface_data;
}
}