Skip to content

Commit

Permalink
add some docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Bendzae committed Oct 8, 2024
1 parent 8cfb0cc commit f85ee3e
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 35 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
111 changes: 76 additions & 35 deletions src/smesh/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<S: Into<MeshSelection>>(&self, mesh: &SMesh, selection: S) -> SMeshResult<Vec3> {
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<MeshSelection>`.
/// - `translation`: The vector by which to translate the selected vertices.
pub fn translate<S: Into<MeshSelection>>(
&mut self,
selection: S,
Expand All @@ -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<MeshSelection>`.
/// - `scale`: The scale factors along the X, Y, and Z axes.
/// - `pivot`: The pivot point around which the scaling is performed.
pub fn scale<S: Into<MeshSelection>>(
&mut self,
selection: S,
Expand All @@ -48,7 +70,55 @@ impl SMesh {
Ok(self)
}

pub fn scale_around<S: Into<MeshSelection>>(
/// 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<MeshSelection>`.
/// - `quaternion`: The rotation represented as a quaternion.
/// - `pivot`: The pivot point around which the rotation is performed.
pub fn rotate<S: Into<MeshSelection>>(
&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<MeshSelection>`.
pub fn center_of_gravity<S: Into<MeshSelection>>(&self, selection: S) -> SMeshResult<Vec3> {
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<S: Into<MeshSelection>>(
&mut self,
selection: S,
scale: Vec3,
Expand All @@ -68,19 +138,7 @@ impl SMesh {
Ok(self)
}

pub fn rotate<S: Into<MeshSelection>>(
&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<S: Into<MeshSelection>>(
fn rotate_around<S: Into<MeshSelection>>(
&mut self,
selection: S,
quaternion: Quat,
Expand All @@ -100,21 +158,4 @@ impl SMesh {
}
Ok(self)
}

pub fn center_of_gravity<S: Into<MeshSelection>>(&self, selection: S) -> SMeshResult<Vec3> {
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)
}
}

0 comments on commit f85ee3e

Please sign in to comment.