From 5fa358a465d32d1420a8cdfd23dd1a88ca4ae797 Mon Sep 17 00:00:00 2001 From: HampusM Date: Tue, 14 Jan 2025 13:32:02 +0100 Subject: feat(engine): add simple collision --- engine/src/mesh.rs | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) (limited to 'engine/src/mesh.rs') diff --git a/engine/src/mesh.rs b/engine/src/mesh.rs index de0af70..a9914e7 100644 --- a/engine/src/mesh.rs +++ b/engine/src/mesh.rs @@ -1,5 +1,6 @@ use ecs::Component; +use crate::vector::Vec3; use crate::vertex::Vertex; pub mod cube; @@ -30,4 +31,103 @@ impl Mesh { self.indices.as_deref() } + + /// 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() + } +} + +#[derive(Debug, Clone)] +pub struct DirectionPositions<'mesh> +{ + pub up: &'mesh Vec3, + pub down: &'mesh Vec3, + pub left: &'mesh Vec3, + pub right: &'mesh Vec3, + pub back: &'mesh Vec3, + pub front: &'mesh Vec3, +} + +impl<'mesh> From> 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, + dot_prod: f32, + direction: &'mesh Vec3, +} + +impl<'mesh> FurthestPos<'mesh> +{ + fn new(pos: &'mesh Vec3, direction: &'mesh Vec3) -> Self + { + Self { + pos, + dot_prod: direction.dot(&pos), + direction, + } + } + + fn update_if_further(&mut self, point: &'mesh Vec3) + { + let point_dot_prod = self.direction.dot(point); + + if point_dot_prod > self.dot_prod { + self.pos = point; + self.dot_prod = point_dot_prod; + } + } } -- cgit v1.2.3-18-g5258