Skip to content

Bug fix in Gizmo grid #19697

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
43 changes: 31 additions & 12 deletions crates/bevy_gizmos/src/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use crate::{gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
use bevy_color::Color;
use bevy_math::{ops, Isometry2d, Isometry3d, Quat, UVec2, UVec3, Vec2, Vec3, Vec3Swizzles};
use bevy_math::{ops, Isometry2d, Isometry3d, Quat, UVec2, UVec3, Vec2, Vec3};

/// A builder returned by [`GizmoBuffer::grid_3d`]
pub struct GridBuilder3d<'a, Config, Clear>
Expand Down Expand Up @@ -66,19 +66,19 @@ where
self
}

/// Declare that the outer edges of the grid along the x axis should be drawn.
/// Declare that the outer edges of the grid parallel to the x axis should be drawn.
/// By default, the outer edges will not be drawn.
pub fn outer_edges_x(mut self) -> Self {
self.outer_edges[0] = true;
self
}
/// Declare that the outer edges of the grid along the y axis should be drawn.
/// Declare that the outer edges of the grid parallel to the y axis should be drawn.
/// By default, the outer edges will not be drawn.
pub fn outer_edges_y(mut self) -> Self {
self.outer_edges[1] = true;
self
}
/// Declare that the outer edges of the grid along the z axis should be drawn.
/// Declare that the outer edges of the grid parallel to the z axis should be drawn.
/// By default, the outer edges will not be drawn.
pub fn outer_edges_z(mut self) -> Self {
self.outer_edges[2] = true;
Expand Down Expand Up @@ -116,13 +116,13 @@ where
self
}

/// Declare that the outer edges of the grid along the x axis should be drawn.
/// Declare that the outer edges of the grid parallel to the x axis should be drawn.
/// By default, the outer edges will not be drawn.
pub fn outer_edges_x(mut self) -> Self {
self.outer_edges[0] = true;
self
}
/// Declare that the outer edges of the grid along the y axis should be drawn.
/// Declare that the outer edges of the grid parallel to the y axis should be drawn.
/// By default, the outer edges will not be drawn.
pub fn outer_edges_y(mut self) -> Self {
self.outer_edges[1] = true;
Expand Down Expand Up @@ -389,9 +389,27 @@ fn draw_grid<Config, Clear>(
let cell_count_half = cell_count.as_vec3() * 0.5;
let grid_start = -cell_count_half.x * dx - cell_count_half.y * dy - cell_count_half.z * dz;

let outer_edges_u32 = UVec3::from(outer_edges.map(|v| v as u32));
let line_count = outer_edges_u32 * cell_count.saturating_add(UVec3::ONE)
+ (UVec3::ONE - outer_edges_u32) * cell_count.saturating_sub(UVec3::ONE);
#[inline]
fn cell_count_to_line_count(include_outer: bool, cell_count: u32) -> u32 {
if include_outer {
cell_count.saturating_add(1)
} else {
cell_count.saturating_sub(1).max(1)
}
}

let x_line_count = UVec2::new(
cell_count_to_line_count(outer_edges[0], cell_count.y),
cell_count_to_line_count(outer_edges[0], cell_count.z),
);
let y_line_count = UVec2::new(
cell_count_to_line_count(outer_edges[1], cell_count.z),
cell_count_to_line_count(outer_edges[1], cell_count.x),
);
let z_line_count = UVec2::new(
cell_count_to_line_count(outer_edges[2], cell_count.x),
cell_count_to_line_count(outer_edges[2], cell_count.y),
);

let x_start = grid_start + or_zero(!outer_edges[0], dy + dz);
let y_start = grid_start + or_zero(!outer_edges[1], dx + dz);
Expand All @@ -416,11 +434,12 @@ fn draw_grid<Config, Clear>(
}

// Lines along the x direction
let x_lines = iter_lines(dx, dy, dz, line_count.yz(), cell_count.x, x_start);
let x_lines = iter_lines(dx, dy, dz, x_line_count, cell_count.x, x_start);
// Lines along the y direction
let y_lines = iter_lines(dy, dz, dx, line_count.zx(), cell_count.y, y_start);
let y_lines = iter_lines(dy, dz, dx, y_line_count, cell_count.y, y_start);
// Lines along the z direction
let z_lines = iter_lines(dz, dx, dy, line_count.xy(), cell_count.z, z_start);
let z_lines = iter_lines(dz, dx, dy, z_line_count, cell_count.z, z_start);

x_lines
.chain(y_lines)
.chain(z_lines)
Expand Down
44 changes: 41 additions & 3 deletions examples/testbed/3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,18 +304,56 @@ mod gizmos {
pub fn setup(mut commands: Commands) {
commands.spawn((
Camera3d::default(),
Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
Transform::from_xyz(-1.0, 2.5, 6.5).looking_at(Vec3::ZERO, Vec3::Y),
DespawnOnExitState(super::Scene::Gizmos),
));
}

pub fn draw_gizmos(mut gizmos: Gizmos) {
gizmos.cuboid(
Transform::from_translation(Vec3::X * 2.0).with_scale(Vec3::splat(2.0)),
Transform::from_translation(Vec3::X * -1.75).with_scale(Vec3::splat(1.25)),
RED,
);
gizmos
.sphere(Isometry3d::from_translation(Vec3::X * -2.0), 1.0, GREEN)
.sphere(Isometry3d::from_translation(Vec3::X * -3.5), 0.75, GREEN)
.resolution(30_000 / 3);

fn grid_position(row: usize, col: usize) -> Vec3 {
Vec3::new(1.5 * col as f32, (1.0 - row as f32) * 1.25, 0.)
}

// Display 2d and 3d grids with all variations of outer edges on or off
for i in 0..4 {
let mut grid = gizmos.grid(
grid_position(0, i),
UVec2::new(5, 4),
Vec2::splat(0.175),
Color::WHITE,
);
if i & 1 > 0 {
grid = grid.outer_edges_x();
}
if i & 2 > 0 {
grid.outer_edges_y();
}
}

for i in 0..8 {
let mut grid = gizmos.grid_3d(
Isometry3d::new(grid_position(1 + i / 4, i % 4), Quat::IDENTITY),
UVec3::new(5, 4, 3),
Vec3::splat(0.175),
Color::WHITE,
);
if i & 1 > 0 {
grid = grid.outer_edges_x();
}
if i & 2 > 0 {
grid = grid.outer_edges_y();
}
if i & 4 > 0 {
grid.outer_edges_z();
}
}
}
}