Skip to content

Commit

Permalink
Use Direction3d for gizmos.circle normal (#11422)
Browse files Browse the repository at this point in the history
# Objective

Fix weird visuals when drawing a gizmo with a non-normed normal.

Fixes #11401

## Solution
Just normalize right before we draw. Could do it when constructing the
builder but that seems less consistent.

## Changelog
- gizmos.circle normal is now a Direction3d instead of a Vec3.

## Migration Guide
- Pass a Direction3d for gizmos.circle normal, eg.
`Direction3d::new(vec).unwrap_or(default)` or potentially
`Direction3d::new_unchecked(vec)` if you know your vec is definitely
normalized.
  • Loading branch information
ArthurBrussee committed Jan 21, 2024
1 parent 259fb68 commit ffb6faa
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 11 deletions.
12 changes: 6 additions & 6 deletions crates/bevy_gizmos/src/circles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! and assorted support items.

use crate::prelude::{GizmoConfigGroup, Gizmos};
use bevy_math::{Quat, Vec2, Vec3};
use bevy_math::{primitives::Direction3d, Quat, Vec2, Vec3};
use bevy_render::color::Color;
use std::f32::consts::TAU;

Expand All @@ -28,12 +28,12 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
/// # use bevy_render::prelude::*;
/// # use bevy_math::prelude::*;
/// fn system(mut gizmos: Gizmos) {
/// gizmos.circle(Vec3::ZERO, Vec3::Z, 1., Color::GREEN);
/// gizmos.circle(Vec3::ZERO, Direction3d::Z, 1., Color::GREEN);
///
/// // Circles have 32 line-segments by default.
/// // You may want to increase this for larger circles.
/// gizmos
/// .circle(Vec3::ZERO, Vec3::Z, 5., Color::RED)
/// .circle(Vec3::ZERO, Direction3d::Z, 5., Color::RED)
/// .segments(64);
/// }
/// # bevy_ecs::system::assert_is_system(system);
Expand All @@ -42,7 +42,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
pub fn circle(
&mut self,
position: Vec3,
normal: Vec3,
normal: Direction3d,
radius: f32,
color: Color,
) -> CircleBuilder<'_, 'w, 's, T> {
Expand Down Expand Up @@ -97,7 +97,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
pub struct CircleBuilder<'a, 'w, 's, T: GizmoConfigGroup> {
gizmos: &'a mut Gizmos<'w, 's, T>,
position: Vec3,
normal: Vec3,
normal: Direction3d,
radius: f32,
color: Color,
segments: usize,
Expand All @@ -116,7 +116,7 @@ impl<T: GizmoConfigGroup> Drop for CircleBuilder<'_, '_, '_, T> {
if !self.gizmos.enabled {
return;
}
let rotation = Quat::from_rotation_arc(Vec3::Z, self.normal);
let rotation = Quat::from_rotation_arc(Vec3::Z, *self.normal);
let positions = circle_inner(self.radius, self.segments)
.map(|vec2| self.position + rotation * vec2.extend(0.));
self.gizmos.linestrip(positions, self.color);
Expand Down
9 changes: 7 additions & 2 deletions crates/bevy_gizmos/src/gizmos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use bevy_ecs::{
system::{Deferred, ReadOnlySystemParam, Res, Resource, SystemBuffer, SystemMeta, SystemParam},
world::{unsafe_world_cell::UnsafeWorldCell, World},
};
use bevy_math::{Mat2, Quat, Vec2, Vec3};
use bevy_math::{primitives::Direction3d, Mat2, Quat, Vec2, Vec3};
use bevy_render::color::Color;
use bevy_transform::TransformPoint;

Expand Down Expand Up @@ -618,7 +618,12 @@ impl<T: GizmoConfigGroup> Drop for SphereBuilder<'_, '_, '_, T> {
}
for axis in Vec3::AXES {
self.gizmos
.circle(self.position, self.rotation * axis, self.radius, self.color)
.circle(
self.position,
Direction3d::new_unchecked(self.rotation * axis),
self.radius,
self.color,
)
.segments(self.circle_segments);
}
}
Expand Down
5 changes: 3 additions & 2 deletions examples/3d/3d_gizmos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::f32::consts::PI;

use bevy::math::primitives::Direction3d;
use bevy::prelude::*;

fn main() {
Expand Down Expand Up @@ -96,10 +97,10 @@ fn system(mut gizmos: Gizmos, mut my_gizmos: Gizmos<MyRoundGizmos>, time: Res<Ti
}

// Circles have 32 line-segments by default.
my_gizmos.circle(Vec3::ZERO, Vec3::Y, 3., Color::BLACK);
my_gizmos.circle(Vec3::ZERO, Direction3d::Y, 3., Color::BLACK);
// You may want to increase this for larger circles or spheres.
my_gizmos
.circle(Vec3::ZERO, Vec3::Y, 3.1, Color::NAVY)
.circle(Vec3::ZERO, Direction3d::Y, 3.1, Color::NAVY)
.segments(64);
my_gizmos
.sphere(Vec3::ZERO, Quat::IDENTITY, 3.2, Color::BLACK)
Expand Down
8 changes: 7 additions & 1 deletion examples/3d/3d_viewport_to_world.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! This example demonstrates how to use the `Camera::viewport_to_world` method.

use bevy::math::primitives::Direction3d;
use bevy::prelude::*;

fn main() {
Expand Down Expand Up @@ -36,7 +37,12 @@ fn draw_cursor(
let point = ray.get_point(distance);

// Draw a circle just above the ground plane at that position.
gizmos.circle(point + ground.up() * 0.01, ground.up(), 0.2, Color::WHITE);
gizmos.circle(
point + ground.up() * 0.01,
Direction3d::new_unchecked(ground.up()), // Up vector is already normalized.
0.2,
Color::WHITE,
);
}

#[derive(Component)]
Expand Down

0 comments on commit ffb6faa

Please sign in to comment.