mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Add subdivisions to PlaneMeshBuilder (#13580)
# Objective - Plane subdivision was removed without providing an alternative ## Solution - Add subdivision to the PlaneMeshBuilder --- ## Migration Guide If you were using `Plane` `subdivisions`, you now need to use `Plane3d::default().mesh().subdivisions(10)` fixes https://github.com/bevyengine/bevy/issues/13258
This commit is contained in:
parent
52ace67f0e
commit
bb51635481
2 changed files with 68 additions and 13 deletions
|
@ -11,6 +11,16 @@ use crate::{
|
|||
pub struct PlaneMeshBuilder {
|
||||
/// The [`Plane3d`] shape.
|
||||
pub plane: Plane3d,
|
||||
/// The number of subdivisions in the mesh.
|
||||
///
|
||||
/// 0 - is the original plane geometry, the 4 points in the XZ plane.
|
||||
///
|
||||
/// 1 - is split by 1 line in the middle of the plane on both the X axis and the Z axis, resulting in a plane with 4 quads / 8 triangles.
|
||||
///
|
||||
/// 2 - is a plane split by 2 lines on both the X and Z axes, subdividing the plane into 3 equal sections along each axis, resulting in a plane with 9 quads / 18 triangles.
|
||||
///
|
||||
/// and so on...
|
||||
pub subdivisions: u32,
|
||||
}
|
||||
|
||||
impl PlaneMeshBuilder {
|
||||
|
@ -22,6 +32,7 @@ impl PlaneMeshBuilder {
|
|||
normal,
|
||||
half_size: size / 2.0,
|
||||
},
|
||||
subdivisions: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +44,7 @@ impl PlaneMeshBuilder {
|
|||
half_size: size / 2.0,
|
||||
..Default::default()
|
||||
},
|
||||
subdivisions: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,6 +57,7 @@ impl PlaneMeshBuilder {
|
|||
half_size: Vec2::splat(length) / 2.0,
|
||||
..Default::default()
|
||||
},
|
||||
subdivisions: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,27 +78,66 @@ impl PlaneMeshBuilder {
|
|||
self.plane.half_size = Vec2::new(width, height) / 2.0;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the subdivisions of the plane mesh.
|
||||
///
|
||||
/// 0 - is the original plane geometry, the 4 points in the XZ plane.
|
||||
///
|
||||
/// 1 - is split by 1 line in the middle of the plane on both the X axis and the Z axis,
|
||||
/// resulting in a plane with 4 quads / 8 triangles.
|
||||
///
|
||||
/// 2 - is a plane split by 2 lines on both the X and Z axes, subdividing the plane into 3
|
||||
/// equal sections along each axis, resulting in a plane with 9 quads / 18 triangles.
|
||||
#[inline]
|
||||
pub fn subdivisions(mut self, subdivisions: u32) -> Self {
|
||||
self.subdivisions = subdivisions;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl MeshBuilder for PlaneMeshBuilder {
|
||||
fn build(&self) -> Mesh {
|
||||
let rotation = Quat::from_rotation_arc(Vec3::Y, *self.plane.normal);
|
||||
let positions = vec![
|
||||
rotation * Vec3::new(self.plane.half_size.x, 0.0, -self.plane.half_size.y),
|
||||
rotation * Vec3::new(-self.plane.half_size.x, 0.0, -self.plane.half_size.y),
|
||||
rotation * Vec3::new(-self.plane.half_size.x, 0.0, self.plane.half_size.y),
|
||||
rotation * Vec3::new(self.plane.half_size.x, 0.0, self.plane.half_size.y),
|
||||
];
|
||||
let z_vertex_count = self.subdivisions + 2;
|
||||
let x_vertex_count = self.subdivisions + 2;
|
||||
let num_vertices = (z_vertex_count * x_vertex_count) as usize;
|
||||
let num_indices = ((z_vertex_count - 1) * (x_vertex_count - 1) * 6) as usize;
|
||||
|
||||
let normals = vec![self.plane.normal.to_array(); 4];
|
||||
let uvs = vec![[1.0, 0.0], [0.0, 0.0], [0.0, 1.0], [1.0, 1.0]];
|
||||
let indices = Indices::U32(vec![0, 1, 2, 0, 2, 3]);
|
||||
let mut positions: Vec<Vec3> = Vec::with_capacity(num_vertices);
|
||||
let mut normals: Vec<[f32; 3]> = Vec::with_capacity(num_vertices);
|
||||
let mut uvs: Vec<[f32; 2]> = Vec::with_capacity(num_vertices);
|
||||
let mut indices: Vec<u32> = Vec::with_capacity(num_indices);
|
||||
|
||||
let rotation = Quat::from_rotation_arc(Vec3::Y, *self.plane.normal);
|
||||
let size = self.plane.half_size * 2.0;
|
||||
|
||||
for z in 0..z_vertex_count {
|
||||
for x in 0..x_vertex_count {
|
||||
let tx = x as f32 / (x_vertex_count - 1) as f32;
|
||||
let tz = z as f32 / (z_vertex_count - 1) as f32;
|
||||
let pos = rotation * Vec3::new((-0.5 + tx) * size.x, 0.0, (-0.5 + tz) * size.y);
|
||||
positions.push(pos);
|
||||
normals.push(self.plane.normal.to_array());
|
||||
uvs.push([tx, tz]);
|
||||
}
|
||||
}
|
||||
|
||||
for z in 0..z_vertex_count - 1 {
|
||||
for x in 0..x_vertex_count - 1 {
|
||||
let quad = z * x_vertex_count + x;
|
||||
indices.push(quad + x_vertex_count + 1);
|
||||
indices.push(quad + 1);
|
||||
indices.push(quad + x_vertex_count);
|
||||
indices.push(quad);
|
||||
indices.push(quad + x_vertex_count);
|
||||
indices.push(quad + 1);
|
||||
}
|
||||
}
|
||||
|
||||
Mesh::new(
|
||||
PrimitiveTopology::TriangleList,
|
||||
RenderAssetUsages::default(),
|
||||
)
|
||||
.with_inserted_indices(indices)
|
||||
.with_inserted_indices(Indices::U32(indices))
|
||||
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions)
|
||||
.with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
|
||||
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
|
||||
|
@ -96,7 +148,10 @@ impl Meshable for Plane3d {
|
|||
type Output = PlaneMeshBuilder;
|
||||
|
||||
fn mesh(&self) -> Self::Output {
|
||||
PlaneMeshBuilder { plane: *self }
|
||||
PlaneMeshBuilder {
|
||||
plane: *self,
|
||||
subdivisions: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ fn setup(
|
|||
|
||||
// ground plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)),
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0).subdivisions(10)),
|
||||
material: materials.add(Color::from(SILVER)),
|
||||
..default()
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue