vox_geometry_rust/
surface_to_implicit2.rs

1/*
2 * // Copyright (c) 2021 Feng Yang
3 * //
4 * // I am making my contributions/submissions to this project solely in my
5 * // personal capacity and am not conveying any rights to any intellectual
6 * // property of any third parties.
7 */
8
9use crate::surface2::*;
10use crate::transform2::Transform2;
11use crate::implicit_surface2::ImplicitSurface2;
12use crate::vector2::Vector2D;
13use crate::bounding_box2::BoundingBox2D;
14use crate::ray2::Ray2D;
15use std::sync::{RwLock, Arc};
16
17///
18/// # 2-D implicit surface wrapper for generic Surface2 instance.
19///
20/// This class represents 2-D implicit surface that converts Surface2 instance
21/// to an ImplicitSurface2 object. The conversion is made by evaluating closest
22/// point and normal from a given point for the given (explicit) surface. Thus,
23/// this conversion won't work for every single surfaces. Use this class only
24/// for the basic primitives such as Sphere2 or Box2.
25///
26pub struct SurfaceToImplicit2 {
27    _surface: Surface2Ptr,
28
29    /// data from surface2
30    pub surface_data: Surface2Data,
31}
32
33impl SurfaceToImplicit2 {
34    /// Constructs an instance with generic Surface2 instance.
35    pub fn new(
36        surface: Surface2Ptr,
37        transform: Option<Transform2>,
38        is_normal_flipped: Option<bool>) -> SurfaceToImplicit2 {
39        return SurfaceToImplicit2 {
40            _surface: surface,
41            surface_data: Surface2Data::new(transform, is_normal_flipped),
42        };
43    }
44
45    /// Returns builder fox SurfaceToImplicit2.
46    pub fn builder() -> Builder {
47        return Builder::new();
48    }
49
50    /// Returns the raw surface instance.
51    pub fn surface(&self) -> Surface2Ptr {
52        return self._surface.clone();
53    }
54}
55
56impl Surface2 for SurfaceToImplicit2 {
57    fn closest_point_local(&self, other_point: &Vector2D) -> Vector2D {
58        return self._surface.read().unwrap().closest_point(other_point);
59    }
60
61    fn bounding_box_local(&self) -> BoundingBox2D {
62        return self._surface.read().unwrap().bounding_box();
63    }
64
65    fn closest_intersection_local(&self, ray: &Ray2D) -> SurfaceRayIntersection2 {
66        return self._surface.read().unwrap().closest_intersection(ray);
67    }
68
69    fn closest_normal_local(&self, other_point: &Vector2D) -> Vector2D {
70        return self._surface.read().unwrap().closest_normal(other_point);
71    }
72
73    fn intersects_local(&self, ray: &Ray2D) -> bool {
74        return self._surface.read().unwrap().intersects(ray);
75    }
76
77    fn closest_distance_local(&self, other_point: &Vector2D) -> f64 {
78        return self._surface.read().unwrap().closest_distance(other_point);
79    }
80
81    fn update_query_engine(&self) {
82        self._surface.read().unwrap().update_query_engine();
83    }
84
85    fn is_bounded(&self) -> bool {
86        return self._surface.read().unwrap().is_bounded();
87    }
88
89    fn is_valid_geometry(&self) -> bool {
90        return self._surface.read().unwrap().is_valid_geometry();
91    }
92
93    fn view(&self) -> &Surface2Data {
94        return &self.surface_data;
95    }
96}
97
98impl ImplicitSurface2 for SurfaceToImplicit2 {
99    fn signed_distance_local(&self, other_point: &Vector2D) -> f64 {
100        let x = self._surface.read().unwrap().closest_point(other_point);
101        let inside = self._surface.read().unwrap().is_inside(other_point);
102        return match inside {
103            true => -x.distance_to(*other_point),
104            false => x.distance_to(*other_point)
105        };
106    }
107
108    fn is_inside_local(&self, other_point: &Vector2D) -> bool {
109        return self._surface.read().unwrap().is_inside(other_point);
110    }
111}
112
113/// Shared pointer for the SurfaceToImplicit2 type.
114pub type SurfaceToImplicit2Ptr = Arc<RwLock<SurfaceToImplicit2>>;
115
116///
117/// # Front-end to create SurfaceToImplicit2 objects step by step.
118///
119pub struct Builder {
120    _surface: Option<Surface2Ptr>,
121
122    _surface_data: Surface2Data,
123}
124
125impl Builder {
126    /// Returns builder with surface.
127    pub fn with_surface(&mut self, surface: Surface2Ptr) -> &mut Self {
128        self._surface = Some(surface);
129        return self;
130    }
131
132    /// Builds SurfaceToImplicit2.
133    pub fn build(&mut self) -> SurfaceToImplicit2 {
134        return SurfaceToImplicit2::new(self._surface.as_ref().unwrap().clone(),
135                                       Some(self._surface_data.transform.clone()),
136                                       Some(self._surface_data.is_normal_flipped));
137    }
138
139    /// Builds shared pointer of SurfaceToImplicit2 instance.
140    pub fn make_shared(&mut self) -> SurfaceToImplicit2Ptr {
141        return SurfaceToImplicit2Ptr::new(RwLock::new(self.build()));
142    }
143
144    /// constructor
145    pub fn new() -> Builder {
146        return Builder {
147            _surface: None,
148            _surface_data: Surface2Data::new(None, None),
149        };
150    }
151}
152
153impl SurfaceBuilderBase2 for Builder {
154    fn view(&mut self) -> &mut Surface2Data {
155        return &mut self._surface_data;
156    }
157}