Skip to content
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

Contextually clearing gizmos #10973

Merged
merged 13 commits into from
Apr 23, 2024
1 change: 1 addition & 0 deletions crates/bevy_gizmos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.14.0-dev" }
bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.14.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.14.0-dev" }
bevy_gizmos_macros = { path = "macros", version = "0.14.0-dev" }
bevy_time = { path = "../bevy_time", version = "0.14.0-dev" }

bytemuck = "1.0"

Expand Down
62 changes: 47 additions & 15 deletions crates/bevy_gizmos/src/arcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ use std::f32::consts::TAU;

// === 2D ===

impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Draw an arc, which is a part of the circumference of a circle, in 2D.
///
/// This should be called for each frame the arc needs to be rendered.
Expand Down Expand Up @@ -50,7 +54,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
arc_angle: f32,
radius: f32,
color: impl Into<Color>,
) -> Arc2dBuilder<'_, 'w, 's, T> {
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
Arc2dBuilder {
gizmos: self,
position,
Expand All @@ -64,8 +68,12 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
}

/// A builder returned by [`Gizmos::arc_2d`].
pub struct Arc2dBuilder<'a, 'w, 's, T: GizmoConfigGroup> {
gizmos: &'a mut Gizmos<'w, 's, T>,
pub struct Arc2dBuilder<'a, 'w, 's, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
position: Vec2,
direction_angle: f32,
arc_angle: f32,
Expand All @@ -74,15 +82,23 @@ pub struct Arc2dBuilder<'a, 'w, 's, T: GizmoConfigGroup> {
segments: Option<usize>,
}

impl<T: GizmoConfigGroup> Arc2dBuilder<'_, '_, '_, T> {
impl<Config, Clear> Arc2dBuilder<'_, '_, '_, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Set the number of line-segments for this arc.
pub fn segments(mut self, segments: usize) -> Self {
self.segments.replace(segments);
self
}
}

impl<T: GizmoConfigGroup> Drop for Arc2dBuilder<'_, '_, '_, T> {
impl<Config, Clear> Drop for Arc2dBuilder<'_, '_, '_, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
fn drop(&mut self) {
if !self.gizmos.enabled {
return;
Expand Down Expand Up @@ -114,7 +130,11 @@ fn arc_2d_inner(

// === 3D ===

impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Draw an arc, which is a part of the circumference of a circle, in 3D. For default values
/// this is drawing a standard arc. A standard arc is defined as
///
Expand Down Expand Up @@ -169,7 +189,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
position: Vec3,
rotation: Quat,
color: impl Into<Color>,
) -> Arc3dBuilder<'_, 'w, 's, T> {
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
Arc3dBuilder {
gizmos: self,
start_vertex: Vec3::X,
Expand Down Expand Up @@ -226,7 +246,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
from: Vec3,
to: Vec3,
color: impl Into<Color>,
) -> Arc3dBuilder<'_, 'w, 's, T> {
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
self.arc_from_to(center, from, to, color, |x| x)
}

Expand Down Expand Up @@ -273,7 +293,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
from: Vec3,
to: Vec3,
color: impl Into<Color>,
) -> Arc3dBuilder<'_, 'w, 's, T> {
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
self.arc_from_to(center, from, to, color, |angle| {
if angle > 0.0 {
TAU - angle
Expand All @@ -293,7 +313,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
to: Vec3,
color: impl Into<Color>,
angle_fn: impl Fn(f32) -> f32,
) -> Arc3dBuilder<'_, 'w, 's, T> {
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
// `from` and `to` can be the same here since in either case nothing gets rendered and the
// orientation ambiguity of `up` doesn't matter
let from_axis = (from - center).normalize_or_zero();
Expand All @@ -320,8 +340,12 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
}

/// A builder returned by [`Gizmos::arc_2d`].
pub struct Arc3dBuilder<'a, 'w, 's, T: GizmoConfigGroup> {
gizmos: &'a mut Gizmos<'w, 's, T>,
pub struct Arc3dBuilder<'a, 'w, 's, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
// this is the vertex the arc starts on in the XZ plane. For the normal arc_3d method this is
// always starting at Vec3::X. For the short/long arc methods we actually need a way to start
// at the from position and this is where this internal field comes into play. Some implicit
Expand All @@ -340,15 +364,23 @@ pub struct Arc3dBuilder<'a, 'w, 's, T: GizmoConfigGroup> {
segments: Option<usize>,
}

impl<T: GizmoConfigGroup> Arc3dBuilder<'_, '_, '_, T> {
impl<Config, Clear> Arc3dBuilder<'_, '_, '_, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Set the number of line-segments for this arc.
pub fn segments(mut self, segments: usize) -> Self {
self.segments.replace(segments);
self
}
}

impl<T: GizmoConfigGroup> Drop for Arc3dBuilder<'_, '_, '_, T> {
impl<Config, Clear> Drop for Arc3dBuilder<'_, '_, '_, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
fn drop(&mut self) {
if !self.gizmos.enabled {
return;
Expand Down
36 changes: 28 additions & 8 deletions crates/bevy_gizmos/src/arrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,24 @@ use bevy_math::{Quat, Vec2, Vec3};
use bevy_transform::TransformPoint;

/// A builder returned by [`Gizmos::arrow`] and [`Gizmos::arrow_2d`]
pub struct ArrowBuilder<'a, 'w, 's, T: GizmoConfigGroup> {
gizmos: &'a mut Gizmos<'w, 's, T>,
pub struct ArrowBuilder<'a, 'w, 's, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
start: Vec3,
end: Vec3,
color: Color,
double_ended: bool,
tip_length: f32,
}

impl<T: GizmoConfigGroup> ArrowBuilder<'_, '_, '_, T> {
impl<Config, Clear> ArrowBuilder<'_, '_, '_, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Change the length of the tips to be `length`.
/// The default tip length is [length of the arrow]/10.
///
Expand Down Expand Up @@ -51,7 +59,11 @@ impl<T: GizmoConfigGroup> ArrowBuilder<'_, '_, '_, T> {
}
}

impl<T: GizmoConfigGroup> Drop for ArrowBuilder<'_, '_, '_, T> {
impl<Config, Clear> Drop for ArrowBuilder<'_, '_, '_, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Draws the arrow, by drawing lines with the stored [`Gizmos`]
fn drop(&mut self) {
if !self.gizmos.enabled {
Expand Down Expand Up @@ -90,7 +102,11 @@ impl<T: GizmoConfigGroup> Drop for ArrowBuilder<'_, '_, '_, T> {
}
}

impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Draw an arrow in 3D, from `start` to `end`. Has four tips for convenient viewing from any direction.
///
/// This should be called for each frame the arrow needs to be rendered.
Expand All @@ -111,7 +127,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
start: Vec3,
end: Vec3,
color: impl Into<Color>,
) -> ArrowBuilder<'_, 'w, 's, T> {
) -> ArrowBuilder<'_, 'w, 's, Config, Clear> {
let length = (end - start).length();
ArrowBuilder {
gizmos: self,
Expand Down Expand Up @@ -143,12 +159,16 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
start: Vec2,
end: Vec2,
color: impl Into<Color>,
) -> ArrowBuilder<'_, 'w, 's, T> {
) -> ArrowBuilder<'_, 'w, 's, Config, Clear> {
self.arrow(start.extend(0.), end.extend(0.), color)
}
}

impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Draw a set of axes local to the given transform (`transform`), with length scaled by a factor
/// of `base_length`.
///
Expand Down
55 changes: 42 additions & 13 deletions crates/bevy_gizmos/src/circles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ fn ellipse_inner(half_size: Vec2, segments: usize) -> impl Iterator<Item = Vec2>
})
}

impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Draw an ellipse in 3D at `position` with the flat side facing `normal`.
///
/// This should be called for each frame the ellipse needs to be rendered.
Expand Down Expand Up @@ -48,7 +52,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
rotation: Quat,
half_size: Vec2,
color: impl Into<Color>,
) -> EllipseBuilder<'_, 'w, 's, T> {
) -> EllipseBuilder<'_, 'w, 's, Config, Clear> {
EllipseBuilder {
gizmos: self,
position,
Expand Down Expand Up @@ -87,7 +91,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
angle: f32,
half_size: Vec2,
color: impl Into<Color>,
) -> Ellipse2dBuilder<'_, 'w, 's, T> {
) -> Ellipse2dBuilder<'_, 'w, 's, Config, Clear> {
Ellipse2dBuilder {
gizmos: self,
position,
Expand Down Expand Up @@ -126,7 +130,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
normal: Dir3,
radius: f32,
color: impl Into<Color>,
) -> EllipseBuilder<'_, 'w, 's, T> {
) -> EllipseBuilder<'_, 'w, 's, Config, Clear> {
EllipseBuilder {
gizmos: self,
position,
Expand Down Expand Up @@ -164,7 +168,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
position: Vec2,
radius: f32,
color: impl Into<Color>,
) -> Ellipse2dBuilder<'_, 'w, 's, T> {
) -> Ellipse2dBuilder<'_, 'w, 's, Config, Clear> {
Ellipse2dBuilder {
gizmos: self,
position,
Expand All @@ -177,24 +181,36 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
}

/// A builder returned by [`Gizmos::ellipse`].
pub struct EllipseBuilder<'a, 'w, 's, T: GizmoConfigGroup> {
gizmos: &'a mut Gizmos<'w, 's, T>,
pub struct EllipseBuilder<'a, 'w, 's, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
position: Vec3,
rotation: Quat,
half_size: Vec2,
color: Color,
segments: usize,
}

impl<T: GizmoConfigGroup> EllipseBuilder<'_, '_, '_, T> {
impl<Config, Clear> EllipseBuilder<'_, '_, '_, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Set the number of line-segments for this ellipse.
pub fn segments(mut self, segments: usize) -> Self {
self.segments = segments;
self
}
}

impl<T: GizmoConfigGroup> Drop for EllipseBuilder<'_, '_, '_, T> {
impl<Config, Clear> Drop for EllipseBuilder<'_, '_, '_, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
fn drop(&mut self) {
if !self.gizmos.enabled {
return;
Expand All @@ -208,24 +224,37 @@ impl<T: GizmoConfigGroup> Drop for EllipseBuilder<'_, '_, '_, T> {
}

/// A builder returned by [`Gizmos::ellipse_2d`].
pub struct Ellipse2dBuilder<'a, 'w, 's, T: GizmoConfigGroup> {
gizmos: &'a mut Gizmos<'w, 's, T>,
pub struct Ellipse2dBuilder<'a, 'w, 's, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
position: Vec2,
rotation: Mat2,
half_size: Vec2,
color: Color,
segments: usize,
}

impl<T: GizmoConfigGroup> Ellipse2dBuilder<'_, '_, '_, T> {
impl<Config, Clear> Ellipse2dBuilder<'_, '_, '_, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Set the number of line-segments for this ellipse.
pub fn segments(mut self, segments: usize) -> Self {
self.segments = segments;
self
}
}

impl<T: GizmoConfigGroup> Drop for Ellipse2dBuilder<'_, '_, '_, T> {
impl<Config, Clear> Drop for Ellipse2dBuilder<'_, '_, '_, Config, Clear>
where
Config: GizmoConfigGroup,
Clear: 'static + Send + Sync,
{
/// Set the number of line-segments for this ellipse.
fn drop(&mut self) {
if !self.gizmos.enabled {
return;
Expand Down
Loading