summaryrefslogtreecommitdiff
path: root/engine/src/mesh.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/mesh.rs')
-rw-r--r--engine/src/mesh.rs139
1 files changed, 135 insertions, 4 deletions
diff --git a/engine/src/mesh.rs b/engine/src/mesh.rs
index de0af70..fb977af 100644
--- a/engine/src/mesh.rs
+++ b/engine/src/mesh.rs
@@ -1,10 +1,9 @@
-use ecs::Component;
-
-use crate::vertex::Vertex;
+use crate::builder;
+use crate::vector::{Vec2, Vec3};
pub mod cube;
-#[derive(Debug, Clone, Component)]
+#[derive(Debug, Clone, Default)]
pub struct Mesh
{
vertices: Vec<Vertex>,
@@ -26,8 +25,140 @@ impl Mesh
}
#[must_use]
+ pub fn vertices_mut(&mut self) -> &mut [Vertex]
+ {
+ &mut self.vertices
+ }
+
+ #[must_use]
pub fn indices(&self) -> Option<&[u32]>
{
self.indices.as_deref()
}
+
+ #[must_use]
+ pub fn indices_mut(&mut self) -> Option<&mut [u32]>
+ {
+ self.indices.as_deref_mut()
+ }
+
+ /// Finds the vertex positions that are furthest in every 3D direction. Keep in mind
+ /// that this can be quite time-expensive if the mesh has many vertices.
+ pub fn find_furthest_vertex_positions(&self) -> DirectionPositions<'_>
+ {
+ let mut point_iter = self.vertices().iter().map(|vertex| &vertex.pos).into_iter();
+
+ let first_point = point_iter.next().unwrap();
+
+ point_iter
+ .fold(
+ FurthestPosAcc {
+ up: FurthestPos::new(&first_point, &Vec3::UP),
+ down: FurthestPos::new(&first_point, &Vec3::DOWN),
+ left: FurthestPos::new(&first_point, &Vec3::LEFT),
+ right: FurthestPos::new(&first_point, &Vec3::RIGHT),
+ back: FurthestPos::new(&first_point, &Vec3::BACK),
+ front: FurthestPos::new(&first_point, &Vec3::FRONT),
+ },
+ |mut furthest_pos_acc, pos| {
+ furthest_pos_acc.up.update_if_further(pos);
+ furthest_pos_acc.down.update_if_further(pos);
+ furthest_pos_acc.left.update_if_further(pos);
+ furthest_pos_acc.right.update_if_further(pos);
+ furthest_pos_acc.back.update_if_further(pos);
+ furthest_pos_acc.front.update_if_further(pos);
+
+ furthest_pos_acc
+ },
+ )
+ .into()
+ }
+}
+
+builder! {
+#[builder(name = VertexBuilder, derives = (Debug, Default, Clone))]
+#[derive(Debug, Clone, Default, PartialEq)]
+#[non_exhaustive]
+pub struct Vertex
+{
+ pub pos: Vec3<f32>,
+ pub texture_coords: Vec2<f32>,
+ pub normal: Vec3<f32>,
+}
+}
+
+impl Vertex
+{
+ #[must_use]
+ pub fn builder() -> VertexBuilder
+ {
+ VertexBuilder::default()
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct DirectionPositions<'mesh>
+{
+ pub up: &'mesh Vec3<f32>,
+ pub down: &'mesh Vec3<f32>,
+ pub left: &'mesh Vec3<f32>,
+ pub right: &'mesh Vec3<f32>,
+ pub back: &'mesh Vec3<f32>,
+ pub front: &'mesh Vec3<f32>,
+}
+
+impl<'mesh> From<FurthestPosAcc<'mesh>> for DirectionPositions<'mesh>
+{
+ fn from(acc: FurthestPosAcc<'mesh>) -> Self
+ {
+ Self {
+ up: acc.up.pos,
+ down: acc.down.pos,
+ left: acc.left.pos,
+ right: acc.right.pos,
+ back: acc.back.pos,
+ front: acc.front.pos,
+ }
+ }
+}
+
+#[derive(Debug)]
+struct FurthestPosAcc<'mesh>
+{
+ up: FurthestPos<'mesh>,
+ down: FurthestPos<'mesh>,
+ left: FurthestPos<'mesh>,
+ right: FurthestPos<'mesh>,
+ back: FurthestPos<'mesh>,
+ front: FurthestPos<'mesh>,
+}
+
+#[derive(Debug)]
+struct FurthestPos<'mesh>
+{
+ pos: &'mesh Vec3<f32>,
+ dot_prod: f32,
+ direction: &'mesh Vec3<f32>,
+}
+
+impl<'mesh> FurthestPos<'mesh>
+{
+ fn new(pos: &'mesh Vec3<f32>, direction: &'mesh Vec3<f32>) -> Self
+ {
+ Self {
+ pos,
+ dot_prod: direction.dot(&pos),
+ direction,
+ }
+ }
+
+ fn update_if_further(&mut self, point: &'mesh Vec3<f32>)
+ {
+ let point_dot_prod = self.direction.dot(point);
+
+ if point_dot_prod > self.dot_prod {
+ self.pos = point;
+ self.dot_prod = point_dot_prod;
+ }
+ }
}