Skip to main content

mraphics_mobject/three_d/
point_3d.rs

1use mraphics_core::{
2    BasicMaterial, Geometry, InstanceUpdater, Interpolatable, Material, MeshLike, MraphicsID,
3    RenderInstance, Representable, Sphere, Transformable,
4};
5use nalgebra::Vector3;
6#[cfg(feature = "wasm")]
7use wasm_bindgen::prelude::wasm_bindgen;
8
9#[derive(Clone)]
10pub struct Point3DCenter {
11    pub position: [f32; 3],
12}
13
14#[cfg_attr(feature = "wasm", wasm_bindgen)]
15pub struct Point3D {
16    pub radius: f32,
17
18    #[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
19    pub center: Point3DCenter,
20
21    #[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
22    pub identifier: MraphicsID,
23
24    #[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
25    pub geometry: Sphere,
26
27    #[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
28    pub material: BasicMaterial,
29}
30
31#[cfg_attr(feature = "wasm", wasm_bindgen)]
32impl Point3D {
33    #[cfg_attr(feature = "wasm", wasm_bindgen(constructor))]
34    pub fn new() -> Self {
35        Self::default()
36    }
37
38    #[cfg_attr(feature = "wasm", wasm_bindgen(js_name = "withRadius"))]
39    pub fn with_radius(mut self, radius: f32) -> Self {
40        self.radius = radius;
41        self.geometry.radius = radius;
42        self
43    }
44}
45
46impl Point3D {
47    pub fn with_center(mut self, center: [f32; 3]) -> Self {
48        self.center = Point3DCenter { position: center };
49        self
50    }
51}
52
53impl Default for Point3D {
54    fn default() -> Self {
55        Self {
56            radius: 0.06,
57            center: Point3DCenter {
58                position: [0.0, 0.0, 0.0],
59            },
60            identifier: MraphicsID::acquire(),
61            geometry: Sphere {
62                radius: 0.06,
63                theta_segments: 8,
64                phi_segments: 16,
65                ..Default::default()
66            },
67            material: BasicMaterial::new(),
68        }
69    }
70}
71
72impl InstanceUpdater for Point3D {
73    fn update_instance(&self, instance: &mut RenderInstance) {
74        self.center.update_instance(instance);
75
76        self.geometry.update_view(&mut instance.geometry);
77        self.material.update_view(&mut instance.material);
78    }
79}
80
81impl MeshLike for Point3D {
82    fn build_instance(&self) -> RenderInstance {
83        let mut instance = RenderInstance::new(self.identifier, &self.material);
84
85        self.geometry.init_view(&mut instance.geometry);
86
87        instance
88    }
89
90    fn identifier(&self) -> MraphicsID {
91        self.identifier
92    }
93
94    fn update(&mut self) {
95        self.geometry.update();
96    }
97}
98
99impl Interpolatable for Point3DCenter {
100    fn interpolate(&self, to: &Self, p: f32) -> Self {
101        Self {
102            position: self.position.interpolate(&to.position, p),
103        }
104    }
105}
106
107impl InstanceUpdater for Point3DCenter {
108    fn update_instance(&self, instance: &mut RenderInstance) {
109        instance.move_to(&Vector3::from_column_slice(&self.position));
110    }
111}
112
113impl Representable for Point3D {
114    type Intermediate = Point3DCenter;
115
116    fn as_intermediate(&self) -> Self::Intermediate {
117        self.center.clone()
118    }
119
120    fn update_from_intermediate(&mut self, repr: &Self::Intermediate) {
121        self.center = repr.clone();
122    }
123}
124
125impl Transformable for Point3D {
126    fn apply_transform<Trans: Fn(&[f32; 3]) -> [f32; 3]>(
127        &self,
128        transform: Trans,
129    ) -> Self::Intermediate {
130        Point3DCenter {
131            position: transform(&self.center.position),
132        }
133    }
134}