diff --git a/Cargo.toml b/Cargo.toml index 6bac351..3fbcc5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,8 @@ thiserror = "1.0.63" # Adapter dependencies bevy = { version = "0.14", default-features = false, features = [ "bevy_pbr", + "bevy_ui", + "bevy_gizmos", ], optional = true } [dev-dependencies] diff --git a/src/smesh/transform.rs b/src/smesh/transform.rs index ae028be..c996553 100644 --- a/src/smesh/transform.rs +++ b/src/smesh/transform.rs @@ -3,25 +3,39 @@ use glam::{Quat, Vec3}; use itertools::Itertools; use selection::MeshSelection; +/// Pivot point to use for transformations pub enum Pivot { - Zero, + /// Use the origin (0,0,0) as the pivot point + Origin, + /// Use the center of gravity of the entire mesh as the pivot point MeshCog, + /// Use the center of gravity of the selection as the pivot point SelectionCog, - Local(Vec3), + /// Use a specific point as the pivot point + Point(Vec3), } impl Pivot { + /// Calculate the concrete pivot point based on the pivot type fn calculate>(&self, mesh: &SMesh, selection: S) -> SMeshResult { Ok(match self { - Pivot::Zero => Vec3::ZERO, + Pivot::Origin => Vec3::ZERO, Pivot::MeshCog => mesh.center_of_gravity(mesh.vertices().collect_vec())?, Pivot::SelectionCog => mesh.center_of_gravity(selection)?, - Pivot::Local(pos) => *pos, + Pivot::Point(pos) => *pos, }) } } +/// Methods for transforming mesh elements impl SMesh { + /// Translates the selected vertices by a given vector. + /// + /// # Parameters + /// + /// - `selection`: The selection of vertices, edges, or faces to translate. + /// It can be any type that implements `Into`. + /// - `translation`: The vector by which to translate the selected vertices. pub fn translate>( &mut self, selection: S, @@ -36,6 +50,14 @@ impl SMesh { Ok(self) } + /// Scales the selected vertices by a given factor around a pivot point. + /// + /// # Parameters + /// + /// - `selection`: The selection of vertices, edges, or faces to scale. + /// It can be any type that implements `Into`. + /// - `scale`: The scale factors along the X, Y, and Z axes. + /// - `pivot`: The pivot point around which the scaling is performed. pub fn scale>( &mut self, selection: S, @@ -48,7 +70,55 @@ impl SMesh { Ok(self) } - pub fn scale_around>( + /// Rotates the selected vertices around a pivot point using a quaternion. + /// + /// This function calculates the pivot point based on the provided `Pivot` enum + /// and then rotates the selected vertices accordingly. + /// + /// # Parameters + /// + /// - `selection`: The selection of vertices, edges, or faces to rotate. + /// It can be any type that implements `Into`. + /// - `quaternion`: The rotation represented as a quaternion. + /// - `pivot`: The pivot point around which the rotation is performed. + pub fn rotate>( + &mut self, + selection: S, + quaternion: Quat, + pivot: Pivot, + ) -> SMeshResult<&mut SMesh> { + let s: MeshSelection = selection.into(); + let p = pivot.calculate(self, s.clone())?; + self.rotate_around(s, quaternion, p)?; + Ok(self) + } + + /// Calculates the center of gravity (centroid) of the selected vertices. + /// + /// This function computes the average position of all selected vertices. + /// + /// # Parameters + /// + /// - `selection`: The selection of vertices, edges, or faces for which to calculate the center of gravity. + /// It can be any type that implements `Into`. + pub fn center_of_gravity>(&self, selection: S) -> SMeshResult { + let vertices = selection.into().resolve_to_vertices(self)?; + + if vertices.is_empty() { + bail!("No vertices in selection"); + } + + let mut sum = Vec3::ZERO; + for v_id in &vertices { + let pos = v_id.position(self)?; + sum += pos; + } + + let center = sum / vertices.len() as f32; + Ok(center) + } + + fn scale_around>( &mut self, selection: S, scale: Vec3, @@ -68,19 +138,7 @@ impl SMesh { Ok(self) } - pub fn rotate>( - &mut self, - selection: S, - quaternion: Quat, - pivot: Pivot, - ) -> SMeshResult<&mut SMesh> { - let s: MeshSelection = selection.into(); - let p = pivot.calculate(self, s.clone())?; - self.rotate_around(s, quaternion, p)?; - Ok(self) - } - - pub fn rotate_around>( + fn rotate_around>( &mut self, selection: S, quaternion: Quat, @@ -100,21 +158,4 @@ impl SMesh { } Ok(self) } - - pub fn center_of_gravity>(&self, selection: S) -> SMeshResult { - let vertices = selection.into().resolve_to_vertices(self)?; - - if vertices.is_empty() { - bail!("No vertices in selection"); - } - - let mut sum = Vec3::ZERO; - for v_id in &vertices { - let pos = v_id.position(self)?; - sum += pos; - } - - let center = sum / vertices.len() as f32; - Ok(center) - } }