Skip to content

Commit 1bd3908

Browse files
committed
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.
1 parent 51201ae commit 1bd3908

23 files changed

+88
-40
lines changed

crates/bevy_render/src/mesh/shape/mod.rs

+58-15
Original file line numberDiff line numberDiff line change
@@ -187,33 +187,76 @@ impl From<Quad> for Mesh {
187187
pub struct Plane {
188188
/// The total side length of the square.
189189
pub size: f32,
190+
/// The number of subdivisions in the mesh.
191+
///
192+
/// 0 - is the original plane geometry, the 4 points in the XZ plane.
193+
///
194+
/// 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.
195+
///
196+
/// 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.
197+
///
198+
/// and so on...
199+
pub subdivisions: u32,
190200
}
191201

192202
impl Default for Plane {
193203
fn default() -> Self {
194-
Plane { size: 1.0 }
204+
Plane {
205+
size: 1.0,
206+
subdivisions: 0,
207+
}
208+
}
209+
}
210+
211+
impl Plane {
212+
/// Creates a new plane centered at the origin with the supplied side length and zero subdivisions.
213+
pub fn from_size(size: f32) -> Self {
214+
Self {
215+
size,
216+
subdivisions: 0,
217+
}
195218
}
196219
}
197220

198221
impl From<Plane> for Mesh {
199222
fn from(plane: Plane) -> Self {
200-
let extent = plane.size / 2.0;
201-
202-
let vertices = [
203-
([extent, 0.0, -extent], [0.0, 1.0, 0.0], [1.0, 1.0]),
204-
([extent, 0.0, extent], [0.0, 1.0, 0.0], [1.0, 0.0]),
205-
([-extent, 0.0, extent], [0.0, 1.0, 0.0], [0.0, 0.0]),
206-
([-extent, 0.0, -extent], [0.0, 1.0, 0.0], [0.0, 1.0]),
207-
];
208-
209-
let indices = Indices::U32(vec![0, 2, 1, 0, 3, 2]);
223+
// here this is split in the z and x directions if one ever needs asymetrical subdivision
224+
// two Plane struct fields would need to be added instead of the single subdivisions field
225+
let z_vertex_count = plane.subdivisions + 2;
226+
let x_vertex_count = plane.subdivisions + 2;
227+
let num_vertices = (z_vertex_count * x_vertex_count) as usize;
228+
let num_indices = ((z_vertex_count - 1) * (x_vertex_count - 1) * 6) as usize;
229+
let up = Vec3::Y.to_array();
230+
231+
let mut positions: Vec<[f32; 3]> = Vec::with_capacity(num_vertices);
232+
let mut normals: Vec<[f32; 3]> = Vec::with_capacity(num_vertices);
233+
let mut uvs: Vec<[f32; 2]> = Vec::with_capacity(num_vertices);
234+
let mut indices: Vec<u32> = Vec::with_capacity(num_indices);
235+
236+
for y in 0..z_vertex_count {
237+
for x in 0..x_vertex_count {
238+
let tx = x as f32 / (x_vertex_count - 1) as f32;
239+
let ty = y as f32 / (z_vertex_count - 1) as f32;
240+
positions.push([(-0.5 + tx) * plane.size, 0.0, (-0.5 + ty) * plane.size]);
241+
normals.push(up);
242+
uvs.push([tx, 1.0 - ty]);
243+
}
244+
}
210245

211-
let positions: Vec<_> = vertices.iter().map(|(p, _, _)| *p).collect();
212-
let normals: Vec<_> = vertices.iter().map(|(_, n, _)| *n).collect();
213-
let uvs: Vec<_> = vertices.iter().map(|(_, _, uv)| *uv).collect();
246+
for y in 0..z_vertex_count - 1 {
247+
for x in 0..x_vertex_count - 1 {
248+
let quad = y * x_vertex_count + x;
249+
indices.push(quad + x_vertex_count + 1);
250+
indices.push(quad + 1);
251+
indices.push(quad + x_vertex_count);
252+
indices.push(quad);
253+
indices.push(quad + x_vertex_count);
254+
indices.push(quad + 1);
255+
}
256+
}
214257

215258
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
216-
mesh.set_indices(Some(indices));
259+
mesh.set_indices(Some(Indices::U32(indices)));
217260
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);
218261
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals);
219262
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);

examples/3d/3d_scene.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn setup(
1717
) {
1818
// plane
1919
commands.spawn(PbrBundle {
20-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
20+
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
2121
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
2222
..default()
2323
});

examples/3d/3d_shapes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ fn setup(
7575

7676
// ground plane
7777
commands.spawn(PbrBundle {
78-
mesh: meshes.add(shape::Plane { size: 50. }.into()),
78+
mesh: meshes.add(shape::Plane::from_size(50.0).into()),
7979
material: materials.add(Color::SILVER.into()),
8080
..default()
8181
});

examples/3d/blend_modes.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ fn setup(
148148
// Chessboard Plane
149149
let black_material = materials.add(Color::BLACK.into());
150150
let white_material = materials.add(Color::WHITE.into());
151-
let plane_mesh = meshes.add(shape::Plane { size: 2.0 }.into());
151+
152+
let plane_mesh = meshes.add(shape::Plane::from_size(2.0).into());
152153

153154
for x in -3..4 {
154155
for z in -3..4 {

examples/3d/fxaa.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ fn setup(
4444

4545
// plane
4646
commands.spawn(PbrBundle {
47-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
47+
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
4848
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
4949
..default()
5050
});

examples/3d/lighting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ fn setup(
2525
) {
2626
// ground plane
2727
commands.spawn(PbrBundle {
28-
mesh: meshes.add(Mesh::from(shape::Plane { size: 10.0 })),
28+
mesh: meshes.add(shape::Plane::from_size(10.0).into()),
2929
material: materials.add(StandardMaterial {
3030
base_color: Color::WHITE,
3131
perceptual_roughness: 1.0,

examples/3d/orthographic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fn setup(
2929

3030
// plane
3131
commands.spawn(PbrBundle {
32-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
32+
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
3333
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
3434
..default()
3535
});

examples/3d/shadow_biases.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,7 @@ fn setup(
104104

105105
// ground plane
106106
commands.spawn(PbrBundle {
107-
mesh: meshes.add(Mesh::from(shape::Plane {
108-
size: 2.0 * spawn_plane_depth,
109-
})),
107+
mesh: meshes.add(shape::Plane::from_size(2.0 * spawn_plane_depth).into()),
110108
material: white_handle,
111109
..default()
112110
});

examples/3d/shadow_caster_receiver.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn setup(
6767
// floating plane - initially not a shadow receiver and not a caster
6868
commands.spawn((
6969
PbrBundle {
70-
mesh: meshes.add(Mesh::from(shape::Plane { size: 20.0 })),
70+
mesh: meshes.add(shape::Plane::from_size(20.0).into()),
7171
material: materials.add(Color::GREEN.into()),
7272
transform: Transform::from_xyz(0.0, 1.0, -10.0),
7373
..default()
@@ -78,7 +78,7 @@ fn setup(
7878

7979
// lower ground plane - initially a shadow receiver
8080
commands.spawn(PbrBundle {
81-
mesh: meshes.add(Mesh::from(shape::Plane { size: 20.0 })),
81+
mesh: meshes.add(shape::Plane::from_size(20.0).into()),
8282
material: white_handle,
8383
..default()
8484
});

examples/3d/spherical_area_lights.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn setup(
2323

2424
// plane
2525
commands.spawn(PbrBundle {
26-
mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })),
26+
mesh: meshes.add(shape::Plane::from_size(100.0).into()),
2727
material: materials.add(StandardMaterial {
2828
base_color: Color::rgb(0.2, 0.2, 0.2),
2929
perceptual_roughness: 0.08,

examples/3d/split_screen.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn setup(
2424
) {
2525
// plane
2626
commands.spawn(PbrBundle {
27-
mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })),
27+
mesh: meshes.add(shape::Plane::from_size(100.0).into()),
2828
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
2929
..default()
3030
});

examples/3d/spotlight.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fn setup(
2929
) {
3030
// ground plane
3131
commands.spawn(PbrBundle {
32-
mesh: meshes.add(Mesh::from(shape::Plane { size: 100.0 })),
32+
mesh: meshes.add(shape::Plane::from_size(100.0).into()),
3333
material: materials.add(StandardMaterial {
3434
base_color: Color::GREEN,
3535
perceptual_roughness: 1.0,

examples/3d/transparency_3d.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn setup(
2020
) {
2121
// opaque plane, uses `alpha_mode: Opaque` by default
2222
commands.spawn(PbrBundle {
23-
mesh: meshes.add(Mesh::from(shape::Plane { size: 6.0 })),
23+
mesh: meshes.add(shape::Plane::from_size(6.0).into()),
2424
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
2525
..default()
2626
});

examples/3d/two_passes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn setup(
1717
) {
1818
// plane
1919
commands.spawn(PbrBundle {
20-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
20+
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
2121
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
2222
..default()
2323
});

examples/3d/vertex_colors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn setup(
1717
) {
1818
// plane
1919
commands.spawn(PbrBundle {
20-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
20+
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
2121
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
2222
..default()
2323
});

examples/3d/wireframe.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fn setup(
3030
wireframe_config.global = false;
3131
// plane
3232
commands.spawn(PbrBundle {
33-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
33+
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
3434
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
3535
..default()
3636
});

examples/animation/animated_fox.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ fn setup(
4444

4545
// Plane
4646
commands.spawn(PbrBundle {
47-
mesh: meshes.add(Mesh::from(shape::Plane { size: 500000.0 })),
47+
mesh: meshes.add(shape::Plane::from_size(500000.0).into()),
4848
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
4949
..default()
5050
});

examples/mobile/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ fn setup_scene(
5555
) {
5656
// plane
5757
commands.spawn(PbrBundle {
58-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
58+
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
5959
material: materials.add(Color::rgb(0.1, 0.2, 0.1).into()),
6060
..default()
6161
});

examples/shader/shader_material_screenspace_texture.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn setup(
2626
mut standard_materials: ResMut<Assets<StandardMaterial>>,
2727
) {
2828
commands.spawn(PbrBundle {
29-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
29+
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
3030
material: standard_materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
3131
..default()
3232
});

examples/shader/shader_prepass.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn setup(
5858

5959
// plane
6060
commands.spawn(PbrBundle {
61-
mesh: meshes.add(shape::Plane { size: 5.0 }.into()),
61+
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
6262
material: std_materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
6363
..default()
6464
});

examples/stress_tests/many_foxes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ fn setup(
161161

162162
// Plane
163163
commands.spawn(PbrBundle {
164-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5000.0 })),
164+
mesh: meshes.add(shape::Plane::from_size(5000.0).into()),
165165
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
166166
..default()
167167
});

tests/window/minimising.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ fn setup_3d(
3636
) {
3737
// plane
3838
commands.spawn(PbrBundle {
39-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
39+
mesh: meshes.add(Mesh::from(shape::Plane {
40+
size: 5.0,
41+
subdivisions: 0,
42+
})),
4043
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
4144
..default()
4245
});

tests/window/resizing.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,10 @@ fn setup_3d(
114114
) {
115115
// plane
116116
commands.spawn(PbrBundle {
117-
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
117+
mesh: meshes.add(Mesh::from(shape::Plane {
118+
size: 5.0,
119+
subdivisions: 0,
120+
})),
118121
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
119122
..default()
120123
});

0 commit comments

Comments
 (0)