mirror of
https://github.com/bevyengine/bevy
synced 2024-11-29 08:00:20 +00:00
added subdivisions to shape::Plane (#7546)
# Objective There was issue #191 requesting subdivisions on the shape::Plane. I also could have used this recently. I then write the solution. Fixes #191 ## Solution I changed the shape::Plane to include subdivisions field and the code to create the subdivisions. I don't know how people are counting subdivisions so as I put in the doc comments 0 subdivisions results in the original geometry of the Plane. Greater then 0 results in the number of lines dividing the plane. I didn't know if it would be better to create a new struct that implemented this feature, say SubdivisionPlane or change Plane. I decided on changing Plane as that was what the original issue was. It would be trivial to alter this to use another struct instead of altering Plane. The issues of migration, although small, would be eliminated if a new struct was implemented. ## Changelog ### Added Added subdivisions field to shape::Plane ## Migration Guide All the examples needed to be updated to initalize the subdivisions field. Also there were two tests in tests/window that need to be updated. A user would have to update all their uses of shape::Plane to initalize the subdivisions field.
This commit is contained in:
parent
51201ae54c
commit
1bd390806f
23 changed files with 86 additions and 38 deletions
|
@ -187,33 +187,76 @@ impl From<Quad> for Mesh {
|
||||||
pub struct Plane {
|
pub struct Plane {
|
||||||
/// The total side length of the square.
|
/// The total side length of the square.
|
||||||
pub size: f32,
|
pub size: f32,
|
||||||
|
/// 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 Default for Plane {
|
impl Default for Plane {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Plane { size: 1.0 }
|
Plane {
|
||||||
|
size: 1.0,
|
||||||
|
subdivisions: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Plane {
|
||||||
|
/// Creates a new plane centered at the origin with the supplied side length and zero subdivisions.
|
||||||
|
pub fn from_size(size: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
size,
|
||||||
|
subdivisions: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Plane> for Mesh {
|
impl From<Plane> for Mesh {
|
||||||
fn from(plane: Plane) -> Self {
|
fn from(plane: Plane) -> Self {
|
||||||
let extent = plane.size / 2.0;
|
// here this is split in the z and x directions if one ever needs asymetrical subdivision
|
||||||
|
// two Plane struct fields would need to be added instead of the single subdivisions field
|
||||||
|
let z_vertex_count = plane.subdivisions + 2;
|
||||||
|
let x_vertex_count = plane.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 up = Vec3::Y.to_array();
|
||||||
|
|
||||||
let vertices = [
|
let mut positions: Vec<[f32; 3]> = Vec::with_capacity(num_vertices);
|
||||||
([extent, 0.0, -extent], [0.0, 1.0, 0.0], [1.0, 1.0]),
|
let mut normals: Vec<[f32; 3]> = Vec::with_capacity(num_vertices);
|
||||||
([extent, 0.0, extent], [0.0, 1.0, 0.0], [1.0, 0.0]),
|
let mut uvs: Vec<[f32; 2]> = Vec::with_capacity(num_vertices);
|
||||||
([-extent, 0.0, extent], [0.0, 1.0, 0.0], [0.0, 0.0]),
|
let mut indices: Vec<u32> = Vec::with_capacity(num_indices);
|
||||||
([-extent, 0.0, -extent], [0.0, 1.0, 0.0], [0.0, 1.0]),
|
|
||||||
];
|
|
||||||
|
|
||||||
let indices = Indices::U32(vec![0, 2, 1, 0, 3, 2]);
|
for y in 0..z_vertex_count {
|
||||||
|
for x in 0..x_vertex_count {
|
||||||
|
let tx = x as f32 / (x_vertex_count - 1) as f32;
|
||||||
|
let ty = y as f32 / (z_vertex_count - 1) as f32;
|
||||||
|
positions.push([(-0.5 + tx) * plane.size, 0.0, (-0.5 + ty) * plane.size]);
|
||||||
|
normals.push(up);
|
||||||
|
uvs.push([tx, 1.0 - ty]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let positions: Vec<_> = vertices.iter().map(|(p, _, _)| *p).collect();
|
for y in 0..z_vertex_count - 1 {
|
||||||
let normals: Vec<_> = vertices.iter().map(|(_, n, _)| *n).collect();
|
for x in 0..x_vertex_count - 1 {
|
||||||
let uvs: Vec<_> = vertices.iter().map(|(_, _, uv)| *uv).collect();
|
let quad = y * 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
|
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
|
||||||
mesh.set_indices(Some(indices));
|
mesh.set_indices(Some(Indices::U32(indices)));
|
||||||
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);
|
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);
|
||||||
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals);
|
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals);
|
||||||
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
|
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
|
||||||
|
|
|
@ -17,7 +17,7 @@ fn setup(
|
||||||
) {
|
) {
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
|
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -75,7 +75,7 @@ fn setup(
|
||||||
|
|
||||||
// ground plane
|
// ground plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(shape::Plane { size: 50. }.into()),
|
mesh: meshes.add(shape::Plane::from_size(50.0).into()),
|
||||||
material: materials.add(Color::SILVER.into()),
|
material: materials.add(Color::SILVER.into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -148,7 +148,8 @@ fn setup(
|
||||||
// Chessboard Plane
|
// Chessboard Plane
|
||||||
let black_material = materials.add(Color::BLACK.into());
|
let black_material = materials.add(Color::BLACK.into());
|
||||||
let white_material = materials.add(Color::WHITE.into());
|
let white_material = materials.add(Color::WHITE.into());
|
||||||
let plane_mesh = meshes.add(shape::Plane { size: 2.0 }.into());
|
|
||||||
|
let plane_mesh = meshes.add(shape::Plane::from_size(2.0).into());
|
||||||
|
|
||||||
for x in -3..4 {
|
for x in -3..4 {
|
||||||
for z in -3..4 {
|
for z in -3..4 {
|
||||||
|
|
|
@ -44,7 +44,7 @@ fn setup(
|
||||||
|
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
|
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,7 +25,7 @@ fn setup(
|
||||||
) {
|
) {
|
||||||
// ground plane
|
// ground plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 10.0 })),
|
mesh: meshes.add(shape::Plane::from_size(10.0).into()),
|
||||||
material: materials.add(StandardMaterial {
|
material: materials.add(StandardMaterial {
|
||||||
base_color: Color::WHITE,
|
base_color: Color::WHITE,
|
||||||
perceptual_roughness: 1.0,
|
perceptual_roughness: 1.0,
|
||||||
|
|
|
@ -29,7 +29,7 @@ fn setup(
|
||||||
|
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
|
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -104,9 +104,7 @@ fn setup(
|
||||||
|
|
||||||
// ground plane
|
// ground plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane {
|
mesh: meshes.add(shape::Plane::from_size(2.0 * spawn_plane_depth).into()),
|
||||||
size: 2.0 * spawn_plane_depth,
|
|
||||||
})),
|
|
||||||
material: white_handle,
|
material: white_handle,
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn setup(
|
||||||
// floating plane - initially not a shadow receiver and not a caster
|
// floating plane - initially not a shadow receiver and not a caster
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
PbrBundle {
|
PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 20.0 })),
|
mesh: meshes.add(shape::Plane::from_size(20.0).into()),
|
||||||
material: materials.add(Color::GREEN.into()),
|
material: materials.add(Color::GREEN.into()),
|
||||||
transform: Transform::from_xyz(0.0, 1.0, -10.0),
|
transform: Transform::from_xyz(0.0, 1.0, -10.0),
|
||||||
..default()
|
..default()
|
||||||
|
@ -78,7 +78,7 @@ fn setup(
|
||||||
|
|
||||||
// lower ground plane - initially a shadow receiver
|
// lower ground plane - initially a shadow receiver
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 20.0 })),
|
mesh: meshes.add(shape::Plane::from_size(20.0).into()),
|
||||||
material: white_handle,
|
material: white_handle,
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,7 +23,7 @@ fn setup(
|
||||||
|
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })),
|
mesh: meshes.add(shape::Plane::from_size(100.0).into()),
|
||||||
material: materials.add(StandardMaterial {
|
material: materials.add(StandardMaterial {
|
||||||
base_color: Color::rgb(0.2, 0.2, 0.2),
|
base_color: Color::rgb(0.2, 0.2, 0.2),
|
||||||
perceptual_roughness: 0.08,
|
perceptual_roughness: 0.08,
|
||||||
|
|
|
@ -24,7 +24,7 @@ fn setup(
|
||||||
) {
|
) {
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })),
|
mesh: meshes.add(shape::Plane::from_size(100.0).into()),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,7 +29,7 @@ fn setup(
|
||||||
) {
|
) {
|
||||||
// ground plane
|
// ground plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })),
|
mesh: meshes.add(shape::Plane::from_size(100.0).into()),
|
||||||
material: materials.add(StandardMaterial {
|
material: materials.add(StandardMaterial {
|
||||||
base_color: Color::GREEN,
|
base_color: Color::GREEN,
|
||||||
perceptual_roughness: 1.0,
|
perceptual_roughness: 1.0,
|
||||||
|
|
|
@ -20,7 +20,7 @@ fn setup(
|
||||||
) {
|
) {
|
||||||
// opaque plane, uses `alpha_mode: Opaque` by default
|
// opaque plane, uses `alpha_mode: Opaque` by default
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 6.0 })),
|
mesh: meshes.add(shape::Plane::from_size(6.0).into()),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,7 +17,7 @@ fn setup(
|
||||||
) {
|
) {
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
|
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,7 +17,7 @@ fn setup(
|
||||||
) {
|
) {
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
|
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -30,7 +30,7 @@ fn setup(
|
||||||
wireframe_config.global = false;
|
wireframe_config.global = false;
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
|
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -44,7 +44,7 @@ fn setup(
|
||||||
|
|
||||||
// Plane
|
// Plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 500000.0 })),
|
mesh: meshes.add(shape::Plane::from_size(500000.0).into()),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -55,7 +55,7 @@ fn setup_scene(
|
||||||
) {
|
) {
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
|
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
|
||||||
material: materials.add(Color::rgb(0.1, 0.2, 0.1).into()),
|
material: materials.add(Color::rgb(0.1, 0.2, 0.1).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@ fn setup(
|
||||||
mut standard_materials: ResMut<Assets<StandardMaterial>>,
|
mut standard_materials: ResMut<Assets<StandardMaterial>>,
|
||||||
) {
|
) {
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
|
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
|
||||||
material: standard_materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: standard_materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,7 +58,7 @@ fn setup(
|
||||||
|
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(shape::Plane { size: 5.0 }.into()),
|
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
|
||||||
material: std_materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: std_materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -161,7 +161,7 @@ fn setup(
|
||||||
|
|
||||||
// Plane
|
// Plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5000.0 })),
|
mesh: meshes.add(shape::Plane::from_size(5000.0).into()),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,7 +36,10 @@ fn setup_3d(
|
||||||
) {
|
) {
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
|
mesh: meshes.add(Mesh::from(shape::Plane {
|
||||||
|
size: 5.0,
|
||||||
|
subdivisions: 0,
|
||||||
|
})),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
|
@ -114,7 +114,10 @@ fn setup_3d(
|
||||||
) {
|
) {
|
||||||
// plane
|
// plane
|
||||||
commands.spawn(PbrBundle {
|
commands.spawn(PbrBundle {
|
||||||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
|
mesh: meshes.add(Mesh::from(shape::Plane {
|
||||||
|
size: 5.0,
|
||||||
|
subdivisions: 0,
|
||||||
|
})),
|
||||||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue