Skip to content

Commit

Permalink
Mesh can be scaled
Browse files Browse the repository at this point in the history
  • Loading branch information
ManevilleF committed Oct 25, 2023
1 parent 7679def commit 9f36228
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 20 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## [Unreleased]

* Added `PlaneMeshBuilder::with_scale` option to scale generated mesh (#121)
* Added `ColumnMeshBuilder::with_scale` option to scale generated mesh (#121)

## 0.11.0

* Reduced vertice and tri count of mesh generation (#119)
Expand Down
4 changes: 2 additions & 2 deletions examples/3d_columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ fn setup_grid(
let pos = layout.hex_to_world_pos(hex);
let id = commands
.spawn(PbrBundle {
transform: Transform::from_xyz(pos.x, hex.length() as f32 / 2.0, pos.y)
.with_scale(Vec3::splat(0.9)),
transform: Transform::from_xyz(pos.x, hex.length() as f32 / 2.0, pos.y),
mesh: mesh_handle.clone(),
material: default_material.clone(),
..default()
Expand Down Expand Up @@ -124,6 +123,7 @@ fn animate_rings(
fn hexagonal_column(hex_layout: &HexLayout) -> Mesh {
let mesh_info = ColumnMeshBuilder::new(hex_layout, COLUMN_HEIGHT)
.without_bottom_face()
.with_scale(Vec3::splat(0.9))
.build();
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, mesh_info.vertices);
Expand Down
7 changes: 5 additions & 2 deletions examples/a_star.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fn setup_grid(
.spawn(ColorMesh2dBundle {
mesh: mesh.clone().into(),
material,
transform: Transform::from_xyz(pos.x, pos.y, 0.0).with_scale(Vec3::splat(0.9)),
transform: Transform::from_xyz(pos.x, pos.y, 0.0),
..default()
})
.id();
Expand Down Expand Up @@ -151,7 +151,10 @@ fn handle_input(

/// Compute a bevy mesh from the layout
fn hexagonal_plane(hex_layout: &HexLayout) -> Mesh {
let mesh_info = PlaneMeshBuilder::new(hex_layout).facing(Vec3::Z).build();
let mesh_info = PlaneMeshBuilder::new(hex_layout)
.facing(Vec3::Z)
.with_scale(Vec3::splat(0.9))
.build();
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, mesh_info.vertices);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, mesh_info.normals);
Expand Down
7 changes: 5 additions & 2 deletions examples/chunks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn setup_grid(
let hex_mod = hex.to_lower_res(CHUNK_SIZE);
let color_index = (hex_mod.x - hex_mod.y).rem_euclid(3);
commands.spawn(ColorMesh2dBundle {
transform: Transform::from_xyz(pos.x, pos.y, 0.0).with_scale(Vec3::splat(0.9)),
transform: Transform::from_xyz(pos.x, pos.y, 0.0),
mesh: mesh_handle.clone().into(),
material: materials[color_index as usize].clone(),
..default()
Expand All @@ -58,7 +58,10 @@ fn setup_grid(

/// Compute a bevy mesh from the layout
fn hexagonal_plane(hex_layout: &HexLayout) -> Mesh {
let mesh_info = PlaneMeshBuilder::new(hex_layout).facing(Vec3::Z).build();
let mesh_info = PlaneMeshBuilder::new(hex_layout)
.with_scale(Vec3::splat(0.9))
.facing(Vec3::Z)
.build();
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, mesh_info.vertices);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, mesh_info.normals);
Expand Down
2 changes: 1 addition & 1 deletion examples/field_of_movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ fn setup_grid(
.spawn(ColorMesh2dBundle {
mesh: mesh.clone().into(),
material,
transform: Transform::from_xyz(pos.x, pos.y, 0.0).with_scale(Vec3::splat(1.)),
transform: Transform::from_xyz(pos.x, pos.y, 0.0),
..default()
})
.id();
Expand Down
7 changes: 5 additions & 2 deletions examples/field_of_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn setup_grid(
.spawn(ColorMesh2dBundle {
mesh: mesh.clone().into(),
material,
transform: Transform::from_xyz(pos.x, pos.y, 0.0).with_scale(Vec3::splat(0.9)),
transform: Transform::from_xyz(pos.x, pos.y, 0.0),
..default()
})
.id();
Expand Down Expand Up @@ -141,7 +141,10 @@ fn handle_input(

/// Compute a bevy mesh from the layout
fn hexagonal_plane(hex_layout: &HexLayout) -> Mesh {
let mesh_info = PlaneMeshBuilder::new(hex_layout).facing(Vec3::Z).build();
let mesh_info = PlaneMeshBuilder::new(hex_layout)
.facing(Vec3::Z)
.with_scale(Vec3::splat(0.9))
.build();
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, mesh_info.vertices);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, mesh_info.normals);
Expand Down
7 changes: 5 additions & 2 deletions examples/hex_grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ fn setup_grid(
let pos = layout.hex_to_world_pos(hex);
let id = commands
.spawn(ColorMesh2dBundle {
transform: Transform::from_xyz(pos.x, pos.y, 0.0).with_scale(Vec3::splat(0.95)),
transform: Transform::from_xyz(pos.x, pos.y, 0.0),
mesh: mesh_handle.clone().into(),
material: default_material.clone(),
..default()
Expand Down Expand Up @@ -199,7 +199,10 @@ fn handle_input(

/// Compute a bevy mesh from the layout
fn hexagonal_plane(hex_layout: &HexLayout) -> Mesh {
let mesh_info = PlaneMeshBuilder::new(hex_layout).facing(Vec3::Z).build();
let mesh_info = PlaneMeshBuilder::new(hex_layout)
.facing(Vec3::Z)
.with_scale(Vec3::splat(0.95))
.build();
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, mesh_info.vertices);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, mesh_info.normals);
Expand Down
3 changes: 3 additions & 0 deletions examples/mesh_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct BuilderParams {
pub bottom_face: bool,
pub sides_uvs: UVOptions,
pub caps_uvs: UVOptions,
pub scale: Vec3,
}

pub fn main() {
Expand Down Expand Up @@ -111,6 +112,7 @@ fn update_mesh(params: Res<BuilderParams>, info: Res<HexInfo>, mut meshes: ResMu
let mut new_mesh = ColumnMeshBuilder::new(&info.layout, params.height)
.with_subdivisions(params.subdivisions)
.with_offset(Vec3::NEG_Y * params.height / 2.0)
.with_scale(params.scale)
.with_caps_uv_options(params.caps_uvs.clone())
.with_sides_uv_options(params.sides_uvs.clone());
if !params.top_face {
Expand Down Expand Up @@ -144,6 +146,7 @@ impl Default for BuilderParams {
bottom_face: true,
sides_uvs: UVOptions::quad_default().with_scale_factor(vec2(1.0, 0.3)),
caps_uvs: UVOptions::cap_default().with_scale_factor(vec2(0.5, 0.5)),
scale: Vec3::ONE,
}
}
}
33 changes: 28 additions & 5 deletions src/mesh/column_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@ pub struct ColumnMeshBuilder<'l> {
pub pos: Hex,
/// Optional custom offset for the mesh vertex positions
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
///
/// By default the mesh is *facing* up (**Y** axis)
pub facing: Option<Vec3>,
/// Amount of quads to be generated on the sides of the column
Expand All @@ -64,6 +68,7 @@ impl<'l> ColumnMeshBuilder<'l> {
facing: None,
subdivisions: None,
offset: None,
scale: None,
top_face: true,
bottom_face: true,
sides_uv_options: UVOptions::quad_default(),
Expand All @@ -86,6 +91,8 @@ 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
#[must_use]
#[inline]
pub const fn facing(mut self, facing: Vec3) -> Self {
Expand Down Expand Up @@ -116,6 +123,13 @@ impl<'l> ColumnMeshBuilder<'l> {
self
}

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

/// Defines the column side quads amount
#[must_use]
#[inline]
Expand Down Expand Up @@ -164,19 +178,21 @@ impl<'l> ColumnMeshBuilder<'l> {
#[allow(clippy::many_single_char_names)]
/// Comsumes the builder to return the computed mesh data
pub fn build(self) -> MeshInfo {
// We compute the mesh at the origin to allow scaling
let cap_mesh = PlaneMeshBuilder::new(self.layout)
.at(self.pos)
.with_uv_options(self.caps_uv_options)
.build();
// We store the offset to match the `self.pos`
let mut offset = self.layout.hex_to_world_pos(self.pos).extend(0.0);
// We create the final mesh
let mut mesh = MeshInfo::default();
// Column sides
let subidivisions = self.subdivisions.unwrap_or(0).max(1);
let delta = self.height / subidivisions as f32;
let center = self.layout.hex_to_world_pos(self.pos);
let [a, b, c, d, e, f] = self.layout.hex_corners(self.pos);
let corners = [[a, b], [b, c], [c, d], [d, e], [e, f], [f, a]];
for [left, right] in corners {
let normal = (left - center + right - center).normalize();
let normal = (left + right).normalize();
for div in 0..subidivisions {
let height = delta * div as f32;
let left = Vec3::new(left.x, height, left.y);
Expand All @@ -194,14 +210,21 @@ impl<'l> ColumnMeshBuilder<'l> {
let bottom_face = cap_mesh.rotated(rotation);
mesh.merge_with(bottom_face);
}
if let Some(offset) = self.offset {
mesh = mesh.with_offset(offset);
// 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);
mesh = mesh.rotated(rotation);
}
// We offset the vertex positions after scaling and rotating
if let Some(custom_offset) = self.offset {
offset += custom_offset;
}
mesh = mesh.with_offset(offset);
mesh
}
}
31 changes: 27 additions & 4 deletions src/mesh/plane_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ pub struct PlaneMeshBuilder<'l> {
pub pos: Hex,
/// Optional custom offset for the mesh vertex positions
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
/// 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>,
Expand All @@ -33,6 +37,7 @@ impl<'l> PlaneMeshBuilder<'l> {
pos: Hex::ZERO,
facing: None,
offset: None,
scale: None,
uv_options: UVOptions::cap_default(),
}
}
Expand All @@ -51,6 +56,8 @@ 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
#[must_use]
pub const fn facing(mut self, facing: Vec3) -> Self {
self.facing = Some(facing);
Expand All @@ -64,6 +71,13 @@ impl<'l> PlaneMeshBuilder<'l> {
self
}

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

/// Specify custom UV mapping options
#[must_use]
pub const fn with_uv_options(mut self, uv_options: UVOptions) -> Self {
Expand All @@ -74,10 +88,19 @@ impl<'l> PlaneMeshBuilder<'l> {
/// Comsumes the builder to return the computed mesh data
#[must_use]
pub fn build(self) -> MeshInfo {
let mut mesh = MeshInfo::hexagonal_plane(self.layout, self.pos);
if let Some(offset) = self.offset {
mesh = mesh.with_offset(offset);
// We compute the mesh at the origin to allow scaling
let mut mesh = MeshInfo::hexagonal_plane(self.layout, Hex::ZERO);
// We store the offset to match the `self.pos`
let mut offset = self.layout.hex_to_world_pos(self.pos).extend(0.0);
// We apply optional scale
if let Some(scale) = self.scale {
mesh.vertices.iter_mut().for_each(|p| *p *= scale);
}
// We offset the vertex positions
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);
Expand Down

0 comments on commit 9f36228

Please sign in to comment.