Move Circle Gizmos to Their Own File (#10631)
## Objective - Give all the intuitive groups of gizmos their own file - don't be a breaking change - don't change Gizmos interface - eventually do arcs too - future types of gizmos should be in their own files - see also https://github.com/bevyengine/bevy/issues/9400 ## Solution - Moved `gizmos.circle`, `gizmos.2d_circle`, and assorted helpers into `circles.rs` - Can also do arcs in this MR if y'all want; just figured I should do one thing at a time. ## Changelog - Changed - `gizmos::CircleBuilder` moved to `gizmos::circles::Circle2dBuilder` - `gizmos::Circle2dBuilder` moved to `gizmos::circles::Circle2dBuilder` ## Migration Guide - change `gizmos::CircleBuilder` to `gizmos::circles::Circle2dBuilder` - change `gizmos::Circle2dBuilder` to `gizmos::circles::Circle2dBuilder` --------- Co-authored-by: François <mockersf@gmail.com>
This commit is contained in:
parent
e1c8d60f91
commit
04ab9a0531
@ -1,9 +1,13 @@
|
|||||||
//! Additional Gizmo Functions -- Arrows
|
//! Additional [`Gizmos`] Functions -- Arrows
|
||||||
|
//!
|
||||||
|
//! Includes the implementation of [`Gizmos::arrow`] and [`Gizmos::arrow_2d`],
|
||||||
|
//! and assorted support items.
|
||||||
|
|
||||||
use crate::prelude::Gizmos;
|
use crate::prelude::Gizmos;
|
||||||
use bevy_math::{Quat, Vec2, Vec3};
|
use bevy_math::{Quat, Vec2, Vec3};
|
||||||
use bevy_render::color::Color;
|
use bevy_render::color::Color;
|
||||||
|
|
||||||
|
/// A builder returned by [`Gizmos::arrow`] and [`Gizmos::arrow_2d`]
|
||||||
pub struct ArrowBuilder<'a, 's> {
|
pub struct ArrowBuilder<'a, 's> {
|
||||||
gizmos: &'a mut Gizmos<'s>,
|
gizmos: &'a mut Gizmos<'s>,
|
||||||
start: Vec3,
|
start: Vec3,
|
||||||
@ -12,7 +16,6 @@ pub struct ArrowBuilder<'a, 's> {
|
|||||||
tip_length: f32,
|
tip_length: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A builder returned by [`Gizmos::arrow`] and [`Gizmos::arrow_2d`]
|
|
||||||
impl ArrowBuilder<'_, '_> {
|
impl ArrowBuilder<'_, '_> {
|
||||||
/// Change the length of the tips to be `length`.
|
/// Change the length of the tips to be `length`.
|
||||||
/// The default tip length is [length of the arrow]/10.
|
/// The default tip length is [length of the arrow]/10.
|
||||||
|
145
crates/bevy_gizmos/src/circles.rs
Normal file
145
crates/bevy_gizmos/src/circles.rs
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
//! Additional [`Gizmos`] Functions -- Circles
|
||||||
|
//!
|
||||||
|
//! Includes the implementation of [`Gizmos::circle`] and [`Gizmos::circle_2d`],
|
||||||
|
//! and assorted support items.
|
||||||
|
|
||||||
|
use crate::prelude::Gizmos;
|
||||||
|
use bevy_math::{Quat, Vec2, Vec3};
|
||||||
|
use bevy_render::color::Color;
|
||||||
|
use std::f32::consts::TAU;
|
||||||
|
|
||||||
|
pub(crate) const DEFAULT_CIRCLE_SEGMENTS: usize = 32;
|
||||||
|
|
||||||
|
fn circle_inner(radius: f32, segments: usize) -> impl Iterator<Item = Vec2> {
|
||||||
|
(0..segments + 1).map(move |i| {
|
||||||
|
let angle = i as f32 * TAU / segments as f32;
|
||||||
|
Vec2::from(angle.sin_cos()) * radius
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s> Gizmos<'s> {
|
||||||
|
/// Draw a circle in 3D at `position` with the flat side facing `normal`.
|
||||||
|
///
|
||||||
|
/// This should be called for each frame the circle needs to be rendered.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// # use bevy_gizmos::prelude::*;
|
||||||
|
/// # use bevy_render::prelude::*;
|
||||||
|
/// # use bevy_math::prelude::*;
|
||||||
|
/// fn system(mut gizmos: Gizmos) {
|
||||||
|
/// gizmos.circle(Vec3::ZERO, Vec3::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)
|
||||||
|
/// .segments(64);
|
||||||
|
/// }
|
||||||
|
/// # bevy_ecs::system::assert_is_system(system);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn circle(
|
||||||
|
&mut self,
|
||||||
|
position: Vec3,
|
||||||
|
normal: Vec3,
|
||||||
|
radius: f32,
|
||||||
|
color: Color,
|
||||||
|
) -> CircleBuilder<'_, 's> {
|
||||||
|
CircleBuilder {
|
||||||
|
gizmos: self,
|
||||||
|
position,
|
||||||
|
normal,
|
||||||
|
radius,
|
||||||
|
color,
|
||||||
|
segments: DEFAULT_CIRCLE_SEGMENTS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Draw a circle in 2D.
|
||||||
|
///
|
||||||
|
/// This should be called for each frame the circle needs to be rendered.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// # use bevy_gizmos::prelude::*;
|
||||||
|
/// # use bevy_render::prelude::*;
|
||||||
|
/// # use bevy_math::prelude::*;
|
||||||
|
/// fn system(mut gizmos: Gizmos) {
|
||||||
|
/// gizmos.circle_2d(Vec2::ZERO, 1., Color::GREEN);
|
||||||
|
///
|
||||||
|
/// // Circles have 32 line-segments by default.
|
||||||
|
/// // You may want to increase this for larger circles.
|
||||||
|
/// gizmos
|
||||||
|
/// .circle_2d(Vec2::ZERO, 5., Color::RED)
|
||||||
|
/// .segments(64);
|
||||||
|
/// }
|
||||||
|
/// # bevy_ecs::system::assert_is_system(system);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn circle_2d(
|
||||||
|
&mut self,
|
||||||
|
position: Vec2,
|
||||||
|
radius: f32,
|
||||||
|
color: Color,
|
||||||
|
) -> Circle2dBuilder<'_, 's> {
|
||||||
|
Circle2dBuilder {
|
||||||
|
gizmos: self,
|
||||||
|
position,
|
||||||
|
radius,
|
||||||
|
color,
|
||||||
|
segments: DEFAULT_CIRCLE_SEGMENTS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A builder returned by [`Gizmos::circle`].
|
||||||
|
pub struct CircleBuilder<'a, 's> {
|
||||||
|
gizmos: &'a mut Gizmos<'s>,
|
||||||
|
position: Vec3,
|
||||||
|
normal: Vec3,
|
||||||
|
radius: f32,
|
||||||
|
color: Color,
|
||||||
|
segments: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CircleBuilder<'_, '_> {
|
||||||
|
/// Set the number of line-segments for this circle.
|
||||||
|
pub fn segments(mut self, segments: usize) -> Self {
|
||||||
|
self.segments = segments;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for CircleBuilder<'_, '_> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A builder returned by [`Gizmos::circle_2d`].
|
||||||
|
pub struct Circle2dBuilder<'a, 's> {
|
||||||
|
gizmos: &'a mut Gizmos<'s>,
|
||||||
|
position: Vec2,
|
||||||
|
radius: f32,
|
||||||
|
color: Color,
|
||||||
|
segments: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Circle2dBuilder<'_, '_> {
|
||||||
|
/// Set the number of line-segments for this circle.
|
||||||
|
pub fn segments(mut self, segments: usize) -> Self {
|
||||||
|
self.segments = segments;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Circle2dBuilder<'_, '_> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let positions = circle_inner(self.radius, self.segments).map(|vec2| (vec2 + self.position));
|
||||||
|
self.gizmos.linestrip_2d(positions, self.color);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use std::{f32::consts::TAU, iter};
|
use std::{f32::consts::TAU, iter};
|
||||||
|
|
||||||
|
use crate::circles::DEFAULT_CIRCLE_SEGMENTS;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
system::{Deferred, Resource, SystemBuffer, SystemMeta, SystemParam},
|
system::{Deferred, Resource, SystemBuffer, SystemMeta, SystemParam},
|
||||||
world::World,
|
world::World,
|
||||||
@ -13,8 +14,6 @@ use bevy_transform::TransformPoint;
|
|||||||
type PositionItem = [f32; 3];
|
type PositionItem = [f32; 3];
|
||||||
type ColorItem = [f32; 4];
|
type ColorItem = [f32; 4];
|
||||||
|
|
||||||
const DEFAULT_CIRCLE_SEGMENTS: usize = 32;
|
|
||||||
|
|
||||||
#[derive(Resource, Default)]
|
#[derive(Resource, Default)]
|
||||||
pub(crate) struct GizmoStorage {
|
pub(crate) struct GizmoStorage {
|
||||||
pub list_positions: Vec<PositionItem>,
|
pub list_positions: Vec<PositionItem>,
|
||||||
@ -201,44 +200,6 @@ impl<'s> Gizmos<'s> {
|
|||||||
strip_colors.push([f32::NAN; 4]);
|
strip_colors.push([f32::NAN; 4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a circle in 3D at `position` with the flat side facing `normal`.
|
|
||||||
///
|
|
||||||
/// This should be called for each frame the circle needs to be rendered.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
/// ```
|
|
||||||
/// # use bevy_gizmos::prelude::*;
|
|
||||||
/// # use bevy_render::prelude::*;
|
|
||||||
/// # use bevy_math::prelude::*;
|
|
||||||
/// fn system(mut gizmos: Gizmos) {
|
|
||||||
/// gizmos.circle(Vec3::ZERO, Vec3::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)
|
|
||||||
/// .segments(64);
|
|
||||||
/// }
|
|
||||||
/// # bevy_ecs::system::assert_is_system(system);
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn circle(
|
|
||||||
&mut self,
|
|
||||||
position: Vec3,
|
|
||||||
normal: Vec3,
|
|
||||||
radius: f32,
|
|
||||||
color: Color,
|
|
||||||
) -> CircleBuilder<'_, 's> {
|
|
||||||
CircleBuilder {
|
|
||||||
gizmos: self,
|
|
||||||
position,
|
|
||||||
normal,
|
|
||||||
radius,
|
|
||||||
color,
|
|
||||||
segments: DEFAULT_CIRCLE_SEGMENTS,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw a wireframe sphere in 3D made out of 3 circles around the axes.
|
/// Draw a wireframe sphere in 3D made out of 3 circles around the axes.
|
||||||
///
|
///
|
||||||
/// This should be called for each frame the sphere needs to be rendered.
|
/// This should be called for each frame the sphere needs to be rendered.
|
||||||
@ -466,42 +427,6 @@ impl<'s> Gizmos<'s> {
|
|||||||
self.line_gradient_2d(start, start + vector, start_color, end_color);
|
self.line_gradient_2d(start, start + vector, start_color, end_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a circle in 2D.
|
|
||||||
///
|
|
||||||
/// This should be called for each frame the circle needs to be rendered.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
/// ```
|
|
||||||
/// # use bevy_gizmos::prelude::*;
|
|
||||||
/// # use bevy_render::prelude::*;
|
|
||||||
/// # use bevy_math::prelude::*;
|
|
||||||
/// fn system(mut gizmos: Gizmos) {
|
|
||||||
/// gizmos.circle_2d(Vec2::ZERO, 1., Color::GREEN);
|
|
||||||
///
|
|
||||||
/// // Circles have 32 line-segments by default.
|
|
||||||
/// // You may want to increase this for larger circles.
|
|
||||||
/// gizmos
|
|
||||||
/// .circle_2d(Vec2::ZERO, 5., Color::RED)
|
|
||||||
/// .segments(64);
|
|
||||||
/// }
|
|
||||||
/// # bevy_ecs::system::assert_is_system(system);
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn circle_2d(
|
|
||||||
&mut self,
|
|
||||||
position: Vec2,
|
|
||||||
radius: f32,
|
|
||||||
color: Color,
|
|
||||||
) -> Circle2dBuilder<'_, 's> {
|
|
||||||
Circle2dBuilder {
|
|
||||||
gizmos: self,
|
|
||||||
position,
|
|
||||||
radius,
|
|
||||||
color,
|
|
||||||
segments: DEFAULT_CIRCLE_SEGMENTS,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw an arc, which is a part of the circumference of a circle, in 2D.
|
/// 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.
|
/// This should be called for each frame the arc needs to be rendered.
|
||||||
@ -603,33 +528,6 @@ impl<'s> Gizmos<'s> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A builder returned by [`Gizmos::circle`].
|
|
||||||
pub struct CircleBuilder<'a, 's> {
|
|
||||||
gizmos: &'a mut Gizmos<'s>,
|
|
||||||
position: Vec3,
|
|
||||||
normal: Vec3,
|
|
||||||
radius: f32,
|
|
||||||
color: Color,
|
|
||||||
segments: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CircleBuilder<'_, '_> {
|
|
||||||
/// Set the number of line-segments for this circle.
|
|
||||||
pub fn segments(mut self, segments: usize) -> Self {
|
|
||||||
self.segments = segments;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for CircleBuilder<'_, '_> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A builder returned by [`Gizmos::sphere`].
|
/// A builder returned by [`Gizmos::sphere`].
|
||||||
pub struct SphereBuilder<'a, 's> {
|
pub struct SphereBuilder<'a, 's> {
|
||||||
gizmos: &'a mut Gizmos<'s>,
|
gizmos: &'a mut Gizmos<'s>,
|
||||||
@ -658,30 +556,6 @@ impl Drop for SphereBuilder<'_, '_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A builder returned by [`Gizmos::circle_2d`].
|
|
||||||
pub struct Circle2dBuilder<'a, 's> {
|
|
||||||
gizmos: &'a mut Gizmos<'s>,
|
|
||||||
position: Vec2,
|
|
||||||
radius: f32,
|
|
||||||
color: Color,
|
|
||||||
segments: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Circle2dBuilder<'_, '_> {
|
|
||||||
/// Set the number of line-segments for this circle.
|
|
||||||
pub fn segments(mut self, segments: usize) -> Self {
|
|
||||||
self.segments = segments;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Circle2dBuilder<'_, '_> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
let positions = circle_inner(self.radius, self.segments).map(|vec2| (vec2 + self.position));
|
|
||||||
self.gizmos.linestrip_2d(positions, self.color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A builder returned by [`Gizmos::arc_2d`].
|
/// A builder returned by [`Gizmos::arc_2d`].
|
||||||
pub struct Arc2dBuilder<'a, 's> {
|
pub struct Arc2dBuilder<'a, 's> {
|
||||||
gizmos: &'a mut Gizmos<'s>,
|
gizmos: &'a mut Gizmos<'s>,
|
||||||
@ -730,13 +604,6 @@ fn arc_inner(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn circle_inner(radius: f32, segments: usize) -> impl Iterator<Item = Vec2> {
|
|
||||||
(0..segments + 1).map(move |i| {
|
|
||||||
let angle = i as f32 * TAU / segments as f32;
|
|
||||||
Vec2::from(angle.sin_cos()) * radius
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rect_inner(size: Vec2) -> [Vec2; 4] {
|
fn rect_inner(size: Vec2) -> [Vec2; 4] {
|
||||||
let half_size = size / 2.;
|
let half_size = size / 2.;
|
||||||
let tl = Vec2::new(-half_size.x, half_size.y);
|
let tl = Vec2::new(-half_size.x, half_size.y);
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
//!
|
//!
|
||||||
//! See the documentation on [`Gizmos`] for more examples.
|
//! See the documentation on [`Gizmos`] for more examples.
|
||||||
|
|
||||||
mod arrows;
|
pub mod arrows;
|
||||||
|
pub mod circles;
|
||||||
pub mod gizmos;
|
pub mod gizmos;
|
||||||
|
|
||||||
#[cfg(feature = "bevy_sprite")]
|
#[cfg(feature = "bevy_sprite")]
|
||||||
|
Loading…
Reference in New Issue
Block a user