mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
Switch rotation & translation in grid gizmos (#14656)
# Objective - Fixes #14655 ## Solution Rotation should happen first as this is more easier to conceptualize in the mind: We rotate around the coordinate origin `Vec3::ZERO` and then we just shift the geometry so that its center is exactly on the specified position ## Testing && Showcase Code: ```rust gizmos.grid( Vec3::ONE * 10.0, Quat::from_rotation_x(PI / 3. * 2.), UVec2::splat(20), Vec2::new(2., 2.), PURPLE, ); gizmos.sphere(Vec3::ONE * 10.0, Quat::default(), 1.0, PURPLE); ``` Before picture: ![image](https://github.com/user-attachments/assets/7fea2e71-e62b-4763-9f9f-7a1ecd630ada) After picture: ![image](https://github.com/user-attachments/assets/899dad64-010a-4e4b-86ae-53b85fef0bbc) ## Migration Guide - Users might have to double check their already existing calls to all the `grid` methods. It should be more intuitive now though.
This commit is contained in:
parent
313db39912
commit
d7cb781977
2 changed files with 68 additions and 67 deletions
|
@ -5,7 +5,7 @@
|
|||
|
||||
use crate::prelude::{GizmoConfigGroup, Gizmos};
|
||||
use bevy_color::LinearRgba;
|
||||
use bevy_math::{Quat, UVec2, UVec3, Vec2, Vec3};
|
||||
use bevy_math::{Quat, UVec2, UVec3, Vec2, Vec3, Vec3Swizzles};
|
||||
|
||||
/// A builder returned by [`Gizmos::grid_3d`]
|
||||
pub struct GridBuilder3d<'a, 'w, 's, Config, Clear>
|
||||
|
@ -368,78 +368,71 @@ fn draw_grid<Config, Clear>(
|
|||
return;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn or_zero(cond: bool, val: Vec3) -> Vec3 {
|
||||
if cond {
|
||||
val
|
||||
} else {
|
||||
Vec3::ZERO
|
||||
}
|
||||
}
|
||||
|
||||
// Offset between two adjacent grid cells along the x/y-axis and accounting for skew.
|
||||
let dx = spacing.x
|
||||
* Vec3::new(1., skew.y.tan(), skew.z.tan())
|
||||
* if cell_count.x != 0 { 1. } else { 0. };
|
||||
let dy = spacing.y
|
||||
* Vec3::new(skew.x.tan(), 1., skew.z.tan())
|
||||
* if cell_count.y != 0 { 1. } else { 0. };
|
||||
let dz = spacing.z
|
||||
* Vec3::new(skew.x.tan(), skew.y.tan(), 1.)
|
||||
* if cell_count.z != 0 { 1. } else { 0. };
|
||||
let skew_tan = Vec3::from(skew.to_array().map(f32::tan));
|
||||
let dx = or_zero(
|
||||
cell_count.x != 0,
|
||||
spacing.x * Vec3::new(1., skew_tan.y, skew_tan.z),
|
||||
);
|
||||
let dy = or_zero(
|
||||
cell_count.y != 0,
|
||||
spacing.y * Vec3::new(skew_tan.x, 1., skew_tan.z),
|
||||
);
|
||||
let dz = or_zero(
|
||||
cell_count.z != 0,
|
||||
spacing.z * Vec3::new(skew_tan.x, skew_tan.y, 1.),
|
||||
);
|
||||
|
||||
// Bottom-left-front corner of the grid
|
||||
let grid_start = position
|
||||
- cell_count.x as f32 / 2.0 * dx
|
||||
- cell_count.y as f32 / 2.0 * dy
|
||||
- cell_count.z as f32 / 2.0 * dz;
|
||||
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 line_count = UVec3::new(
|
||||
if outer_edges[0] {
|
||||
cell_count.x + 1
|
||||
} else {
|
||||
cell_count.x.saturating_sub(1)
|
||||
},
|
||||
if outer_edges[1] {
|
||||
cell_count.y + 1
|
||||
} else {
|
||||
cell_count.y.saturating_sub(1)
|
||||
},
|
||||
if outer_edges[2] {
|
||||
cell_count.z + 1
|
||||
} else {
|
||||
cell_count.z.saturating_sub(1)
|
||||
},
|
||||
);
|
||||
let x_start = grid_start + if outer_edges[0] { Vec3::ZERO } else { dy + dz };
|
||||
let y_start = grid_start + if outer_edges[1] { Vec3::ZERO } else { dx + dz };
|
||||
let z_start = grid_start + if outer_edges[2] { Vec3::ZERO } else { dx + dy };
|
||||
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);
|
||||
|
||||
let x_start = grid_start + or_zero(!outer_edges[0], dy + dz);
|
||||
let y_start = grid_start + or_zero(!outer_edges[1], dx + dz);
|
||||
let z_start = grid_start + or_zero(!outer_edges[2], dx + dy);
|
||||
|
||||
fn iter_lines(
|
||||
delta_a: Vec3,
|
||||
delta_b: Vec3,
|
||||
delta_c: Vec3,
|
||||
line_count: UVec2,
|
||||
cell_count: u32,
|
||||
start: Vec3,
|
||||
) -> impl Iterator<Item = [Vec3; 2]> {
|
||||
let dline = delta_a * cell_count as f32;
|
||||
(0..line_count.x).map(|v| v as f32).flat_map(move |b| {
|
||||
(0..line_count.y).map(|v| v as f32).map(move |c| {
|
||||
let line_start = start + b * delta_b + c * delta_c;
|
||||
let line_end = line_start + dline;
|
||||
[line_start, line_end]
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Lines along the x direction
|
||||
let dline = dx * cell_count.x as f32;
|
||||
for iy in 0..line_count.y {
|
||||
let iy = iy as f32;
|
||||
for iz in 0..line_count.z {
|
||||
let iz = iz as f32;
|
||||
let line_start = x_start + iy * dy + iz * dz;
|
||||
let line_end = line_start + dline;
|
||||
|
||||
gizmos.line(rotation * line_start, rotation * line_end, color);
|
||||
}
|
||||
}
|
||||
let x_lines = iter_lines(dx, dy, dz, line_count.yz(), cell_count.x, x_start);
|
||||
// Lines along the y direction
|
||||
let dline = dy * cell_count.y as f32;
|
||||
for ix in 0..line_count.x {
|
||||
let ix = ix as f32;
|
||||
for iz in 0..line_count.z {
|
||||
let iz = iz as f32;
|
||||
let line_start = y_start + ix * dx + iz * dz;
|
||||
let line_end = line_start + dline;
|
||||
|
||||
gizmos.line(rotation * line_start, rotation * line_end, color);
|
||||
}
|
||||
}
|
||||
let y_lines = iter_lines(dy, dz, dx, line_count.zx(), cell_count.y, y_start);
|
||||
// Lines along the z direction
|
||||
let dline = dz * cell_count.z as f32;
|
||||
for ix in 0..line_count.x {
|
||||
let ix = ix as f32;
|
||||
for iy in 0..line_count.y {
|
||||
let iy = iy as f32;
|
||||
let line_start = z_start + ix * dx + iy * dy;
|
||||
let line_end = line_start + dline;
|
||||
|
||||
gizmos.line(rotation * line_start, rotation * line_end, color);
|
||||
}
|
||||
}
|
||||
let z_lines = iter_lines(dz, dx, dy, line_count.xy(), cell_count.z, z_start);
|
||||
x_lines
|
||||
.chain(y_lines)
|
||||
.chain(z_lines)
|
||||
.map(|ps| ps.map(|p| position + rotation * p))
|
||||
.for_each(|[start, end]| {
|
||||
gizmos.line(start, end, color);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -90,6 +90,14 @@ fn draw_example_collection(
|
|||
// Light gray
|
||||
LinearRgba::gray(0.65),
|
||||
);
|
||||
gizmos.grid(
|
||||
Vec3::ONE * 10.0,
|
||||
Quat::from_rotation_x(PI / 3. * 2.),
|
||||
UVec2::splat(20),
|
||||
Vec2::new(2., 2.),
|
||||
PURPLE,
|
||||
);
|
||||
gizmos.sphere(Vec3::ONE * 10.0, Quat::default(), 1.0, PURPLE);
|
||||
|
||||
gizmos.cuboid(
|
||||
Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
|
||||
|
|
Loading…
Reference in a new issue