honeycomb_core/geometry/dim3/
vertex.rs1use crate::attributes::{AttrSparseVec, AttributeBind, AttributeError, AttributeUpdate};
6use crate::cmap::{OrbitPolicy, VertexIdType};
7use crate::geometry::{CoordsFloat, Vector3, Vertex2};
8
9#[derive(Debug, Clone, Copy, Default, PartialEq)]
55pub struct Vertex3<T: CoordsFloat>(pub T, pub T, pub T);
56
57unsafe impl<T: CoordsFloat> Send for Vertex3<T> {}
58unsafe impl<T: CoordsFloat> Sync for Vertex3<T> {}
59
60impl<T: CoordsFloat> Vertex3<T> {
61 pub fn into_inner(self) -> (T, T, T) {
63 (self.0, self.1, self.2)
64 }
65
66 pub fn x(&self) -> T {
68 self.0
69 }
70
71 pub fn y(&self) -> T {
73 self.1
74 }
75
76 pub fn z(&self) -> T {
78 self.2
79 }
80
81 pub fn average(lhs: &Vertex3<T>, rhs: &Vertex3<T>) -> Vertex3<T> {
99 let two = T::from(2.0).unwrap();
100 Vertex3(
101 (lhs.0 + rhs.0) / two,
102 (lhs.1 + rhs.1) / two,
103 (lhs.2 + rhs.2) / two,
104 )
105 }
106}
107
108impl<T: CoordsFloat> From<(T, T, T)> for Vertex3<T> {
111 fn from((x, y, z): (T, T, T)) -> Self {
112 Self(x, y, z)
113 }
114}
115
116impl<T: CoordsFloat> From<Vertex2<T>> for Vertex3<T> {
117 fn from(v: Vertex2<T>) -> Self {
118 Self(v.0, v.1, T::zero())
119 }
120}
121
122impl<T: CoordsFloat> std::ops::Add<Vector3<T>> for Vertex3<T> {
127 type Output = Self;
129 fn add(self, rhs: Vector3<T>) -> Self::Output {
130 Self(self.0 + rhs.0, self.1 + rhs.1, self.2 + rhs.2)
131 }
132}
133
134impl<T: CoordsFloat> std::ops::AddAssign<Vector3<T>> for Vertex3<T> {
135 fn add_assign(&mut self, rhs: Vector3<T>) {
136 self.0 += rhs.0;
137 self.1 += rhs.1;
138 self.2 += rhs.2;
139 }
140}
141
142impl<T: CoordsFloat> std::ops::Add<&Vector3<T>> for Vertex3<T> {
143 type Output = Self;
145 fn add(self, rhs: &Vector3<T>) -> Self::Output {
146 Self(self.0 + rhs.0, self.1 + rhs.1, self.2 + rhs.2)
147 }
148}
149
150impl<T: CoordsFloat> std::ops::AddAssign<&Vector3<T>> for Vertex3<T> {
151 fn add_assign(&mut self, rhs: &Vector3<T>) {
152 self.0 += rhs.0;
153 self.1 += rhs.1;
154 self.2 += rhs.2;
155 }
156}
157
158impl<T: CoordsFloat> std::ops::Sub<Vector3<T>> for Vertex3<T> {
160 type Output = Self;
162 fn sub(self, rhs: Vector3<T>) -> Self::Output {
163 Self(self.0 - rhs.0, self.1 - rhs.1, self.2 - rhs.2)
164 }
165}
166
167impl<T: CoordsFloat> std::ops::SubAssign<Vector3<T>> for Vertex3<T> {
168 fn sub_assign(&mut self, rhs: Vector3<T>) {
169 self.0 -= rhs.0;
170 self.1 -= rhs.1;
171 self.2 -= rhs.2;
172 }
173}
174
175impl<T: CoordsFloat> std::ops::Sub<&Vector3<T>> for Vertex3<T> {
176 type Output = Self;
178 fn sub(self, rhs: &Vector3<T>) -> Self::Output {
179 Self(self.0 - rhs.0, self.1 - rhs.1, self.2 - rhs.2)
180 }
181}
182
183impl<T: CoordsFloat> std::ops::SubAssign<&Vector3<T>> for Vertex3<T> {
184 fn sub_assign(&mut self, rhs: &Vector3<T>) {
185 self.0 -= rhs.0;
186 self.1 -= rhs.1;
187 self.2 -= rhs.2;
188 }
189}
190
191impl<T: CoordsFloat> std::ops::Sub<Vertex3<T>> for Vertex3<T> {
192 type Output = Vector3<T>;
193 fn sub(self, rhs: Vertex3<T>) -> Self::Output {
194 Vector3(self.0 - rhs.0, self.1 - rhs.1, self.2 - rhs.2)
195 }
196}
197
198impl<T: CoordsFloat> AttributeUpdate for Vertex3<T> {
199 fn merge(attr1: Self, attr2: Self) -> Result<Self, AttributeError> {
200 Ok(Self::average(&attr1, &attr2))
201 }
202
203 fn split(attr: Self) -> Result<(Self, Self), AttributeError> {
204 Ok((attr, attr))
205 }
206
207 fn merge_incomplete(attr: Self) -> Result<Self, AttributeError> {
208 Ok(attr)
209 }
210}
211
212impl<T: CoordsFloat> AttributeBind for Vertex3<T> {
213 type StorageType = AttrSparseVec<Self>;
214 type IdentifierType = VertexIdType;
215 const BIND_POLICY: OrbitPolicy = OrbitPolicy::Vertex;
216}