use crate::surface2::*;
use crate::transform2::Transform2;
use crate::implicit_surface2::ImplicitSurface2;
use crate::vector2::Vector2D;
use crate::bounding_box2::BoundingBox2D;
use crate::ray2::Ray2D;
use std::sync::{RwLock, Arc};
pub struct SurfaceToImplicit2 {
_surface: Surface2Ptr,
pub surface_data: Surface2Data,
}
impl SurfaceToImplicit2 {
pub fn new(
surface: Surface2Ptr,
transform: Option<Transform2>,
is_normal_flipped: Option<bool>) -> SurfaceToImplicit2 {
return SurfaceToImplicit2 {
_surface: surface,
surface_data: Surface2Data::new(transform, is_normal_flipped),
};
}
pub fn builder() -> Builder {
return Builder::new();
}
pub fn surface(&self) -> Surface2Ptr {
return self._surface.clone();
}
}
impl Surface2 for SurfaceToImplicit2 {
fn closest_point_local(&self, other_point: &Vector2D) -> Vector2D {
return self._surface.read().unwrap().closest_point(other_point);
}
fn bounding_box_local(&self) -> BoundingBox2D {
return self._surface.read().unwrap().bounding_box();
}
fn closest_intersection_local(&self, ray: &Ray2D) -> SurfaceRayIntersection2 {
return self._surface.read().unwrap().closest_intersection(ray);
}
fn closest_normal_local(&self, other_point: &Vector2D) -> Vector2D {
return self._surface.read().unwrap().closest_normal(other_point);
}
fn intersects_local(&self, ray: &Ray2D) -> bool {
return self._surface.read().unwrap().intersects(ray);
}
fn closest_distance_local(&self, other_point: &Vector2D) -> 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) -> &Surface2Data {
return &self.surface_data;
}
}
impl ImplicitSurface2 for SurfaceToImplicit2 {
fn signed_distance_local(&self, other_point: &Vector2D) -> 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: &Vector2D) -> bool {
return self._surface.read().unwrap().is_inside(other_point);
}
}
pub type SurfaceToImplicit2Ptr = Arc<RwLock<SurfaceToImplicit2>>;
pub struct Builder {
_surface: Option<Surface2Ptr>,
_surface_data: Surface2Data,
}
impl Builder {
pub fn with_surface(&mut self, surface: Surface2Ptr) -> &mut Self {
self._surface = Some(surface);
return self;
}
pub fn build(&mut self) -> SurfaceToImplicit2 {
return SurfaceToImplicit2::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) -> SurfaceToImplicit2Ptr {
return SurfaceToImplicit2Ptr::new(RwLock::new(self.build()));
}
pub fn new() -> Builder {
return Builder {
_surface: None,
_surface_data: Surface2Data::new(None, None),
};
}
}
impl SurfaceBuilderBase2 for Builder {
fn view(&mut self) -> &mut Surface2Data {
return &mut self._surface_data;
}
}