Skip to content

Commit

Permalink
Custm rotation, SRT order of transformation
Browse files Browse the repository at this point in the history
  • Loading branch information
ManevilleF committed Oct 25, 2023
1 parent e31beb9 commit 2a32b43
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 29 deletions.
41 changes: 29 additions & 12 deletions src/mesh/column_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ use crate::{Hex, HexLayout, PlaneMeshBuilder, UVOptions};
/// .without_top_face()
/// .build();
/// ```
///
/// # Note
///
/// Transform operations (Scale, Rotate, Translate) through the methods
///
/// - Scale: [`Self::with_scale`]
/// - Rotate": [`Self::with_rotation`], [`Self::facing`]
/// - Translate: [`Self::with_offset`], [`Self::at`]
///
/// Are executed in that order, or **SRT**
#[derive(Debug, Clone)]
#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
pub struct ColumnMeshBuilder<'l> {
Expand All @@ -38,13 +48,13 @@ pub struct ColumnMeshBuilder<'l> {
pub offset: Option<Vec3>,
/// Optional custom scale factor for the mesh vertex positions
pub scale: Option<Vec3>,
/// Optional custom facing direction, useful to have the mesh already
/// Optional rotation quaternion, useful to have the mesh already
/// rotated
///
/// Note that the `scale` factor will be applied before the rotation
///
/// By default the mesh is *facing* up (**Y** axis)
pub facing: Option<Vec3>,
pub rotation: Option<Quat>,
/// Amount of quads to be generated on the sides of the column
pub subdivisions: Option<usize>,
/// Should the top hexagonal face be present
Expand All @@ -65,7 +75,7 @@ impl<'l> ColumnMeshBuilder<'l> {
layout,
height,
pos: Hex::ZERO,
facing: None,
rotation: None,
subdivisions: None,
offset: None,
scale: None,
Expand All @@ -92,11 +102,20 @@ impl<'l> ColumnMeshBuilder<'l> {
/// Specify a custom *facing* direction for the mesh, by default the column
/// is vertical (facing up)
///
/// Note that the `scale` factor will be applied before the rotation
/// # Panics
///
/// Will panic if `facing` is zero length
#[must_use]
#[inline]
pub const fn facing(mut self, facing: Vec3) -> Self {
self.facing = Some(facing);
pub fn facing(mut self, facing: Vec3) -> Self {
self.rotation = Some(Quat::from_rotation_arc(BASE_FACING, facing));
self
}

/// Specify a custom rotation for the whole mesh
#[must_use]
pub const fn with_rotation(mut self, rotation: Quat) -> Self {
self.rotation = Some(rotation);
self
}

Expand Down Expand Up @@ -211,17 +230,15 @@ impl<'l> ColumnMeshBuilder<'l> {
let bottom_face = cap_mesh.rotated(rotation);
mesh.merge_with(bottom_face);
}
// We apply optional scale
// **S** - We apply optional scale
if let Some(scale) = self.scale {
mesh.vertices.iter_mut().for_each(|p| *p *= scale);
}
// We rotate the mesh to face the given direction
if let Some(facing) = self.facing {
let facing = facing.normalize();
let rotation = Quat::from_rotation_arc(BASE_FACING, facing);
// **R** - We rotate the mesh to face the given direction
if let Some(rotation) = self.rotation {
mesh = mesh.rotated(rotation);
}
// We offset the vertex positions after scaling and rotating
// **T** - We offset the vertex positions after scaling and rotating
if let Some(custom_offset) = self.offset {
offset += custom_offset;
}
Expand Down
49 changes: 32 additions & 17 deletions src/mesh/plane_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ use glam::{Quat, Vec3};
///
/// The mesh will be anchored at the center of the hexagon, use offsets to
/// cutomize anchor/pivot position.
///
/// # Note
///
/// Transform operations (Scale, Rotate, Translate) through the methods
///
/// - Scale: [`Self::with_scale`]
/// - Rotate": [`Self::with_rotation`], [`Self::facing`]
/// - Translate: [`Self::with_offset`], [`Self::at`]
///
/// Are executed in that order, or **SRT**
#[derive(Debug, Clone)]
#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
pub struct PlaneMeshBuilder<'l> {
Expand All @@ -17,13 +27,11 @@ pub struct PlaneMeshBuilder<'l> {
pub offset: Option<Vec3>,
/// Optional custom scale factor for the mesh vertex positions
pub scale: Option<Vec3>,
/// Optional custom facing direction, useful to have the mesh already
/// rotated.
///
/// Note that the `scale` factor will be applied before the rotation
/// Optional custom rotation, useful to have the mesh already
/// rotated
///
/// By default the mesh is *facing* up (**Y** axis)
pub facing: Option<Vec3>,
pub rotation: Option<Quat>,
/// UV mapping options
pub uv_options: UVOptions,
}
Expand All @@ -35,7 +43,7 @@ impl<'l> PlaneMeshBuilder<'l> {
Self {
layout,
pos: Hex::ZERO,
facing: None,
rotation: None,
offset: None,
scale: None,
uv_options: UVOptions::cap_default(),
Expand All @@ -57,10 +65,19 @@ impl<'l> PlaneMeshBuilder<'l> {
/// Specify a custom *facing* direction for the mesh, by default the column
/// is vertical (facing up)
///
/// Note that the `scale` factor will be applied before the rotation
/// # Panics
///
/// Will panic if `facing` is zero length
#[must_use]
pub fn facing(mut self, facing: Vec3) -> Self {
self.rotation = Some(Quat::from_rotation_arc(BASE_FACING, facing.normalize()));
self
}

/// Specify a custom rotation for the whole mesh
#[must_use]
pub const fn facing(mut self, facing: Vec3) -> Self {
self.facing = Some(facing);
pub const fn with_rotation(mut self, rotation: Quat) -> Self {
self.rotation = Some(rotation);
self
}

Expand Down Expand Up @@ -93,20 +110,18 @@ impl<'l> PlaneMeshBuilder<'l> {
// We store the offset to match the `self.pos`
let pos = self.layout.hex_to_world_pos(self.pos);
let mut offset = Vec3::new(pos.x, 0.0, pos.y);
// We apply optional scale
// **S** - We apply optional scale
if let Some(scale) = self.scale {
mesh.vertices.iter_mut().for_each(|p| *p *= scale);
}
// We offset the vertex positions
// **R** - We rotate the mesh to face the given direction
if let Some(rotation) = self.rotation {
mesh = mesh.rotated(rotation);
}
// **T** - We offset the vertex positions after scaling and rotating
if let Some(custom_offset) = self.offset {
offset += custom_offset;
}
mesh = mesh.with_offset(offset);
if let Some(facing) = self.facing {
let facing = facing.normalize();
let rotation = Quat::from_rotation_arc(BASE_FACING, facing);
mesh = mesh.rotated(rotation);
}
self.uv_options.alter_uvs(&mut mesh.uvs);
mesh
}
Expand Down

0 comments on commit 2a32b43

Please sign in to comment.