Struct Gizmos

Source
pub struct Gizmos<'w, 's, Config = DefaultGizmoConfigGroup, Clear = ()>
where Config: GizmoConfigGroup, Clear: 'static + Send + Sync,
{ pub config: &'w GizmoConfig, pub config_ext: &'w Config, /* private fields */ }
Expand description

A SystemParam for drawing gizmos.

They are drawn in immediate mode, which means they will be rendered only for the frames, or ticks when in FixedMain, in which they are spawned.

A system in Main will be cleared each rendering frame, while a system in FixedMain will be cleared each time the RunFixedMainLoop schedule is run.

Gizmos should be spawned before the Last schedule to ensure they are drawn.

To set up your own clearing context (useful for custom scheduling similar to FixedMain):

use bevy_gizmos::{prelude::*, *, gizmos::GizmoStorage};
struct ClearContextSetup;
impl Plugin for ClearContextSetup {
    fn build(&self, app: &mut App) {
        app.init_resource::<GizmoStorage<DefaultGizmoConfigGroup, MyContext>>()
           // Make sure this context starts/ends cleanly if inside another context. E.g. it
           // should start after the parent context starts and end after the parent context ends.
           .add_systems(StartOfMyContext, start_gizmo_context::<DefaultGizmoConfigGroup, MyContext>)
           // If not running multiple times, put this with [`start_gizmo_context`].
           .add_systems(StartOfRun, clear_gizmo_context::<DefaultGizmoConfigGroup, MyContext>)
           // If not running multiple times, put this with [`end_gizmo_context`].
           .add_systems(EndOfRun, collect_requested_gizmos::<DefaultGizmoConfigGroup, MyContext>)
           .add_systems(EndOfMyContext, end_gizmo_context::<DefaultGizmoConfigGroup, MyContext>)
           .add_systems(
               Last,
               propagate_gizmos::<DefaultGizmoConfigGroup, MyContext>.before(UpdateGizmoMeshes),
           );
    }
}

Fields§

§config: &'w GizmoConfig

The currently used GizmoConfig

§config_ext: &'w Config

The currently used GizmoConfigGroup

Methods from Deref<Target = GizmoBuffer<Config, Clear>>§

Source

pub fn arc_2d( &mut self, isometry: impl Into<Isometry2d>, arc_angle: f32, radius: f32, color: impl Into<Color>, ) -> Arc2dBuilder<'_, Config, Clear>

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.

§Arguments
  • isometry defines the translation and rotation of the arc.
    • the translation specifies the center of the arc
    • the rotation is counter-clockwise starting from Vec2::Y
  • arc_angle sets the length of this arc, in radians.
  • radius controls the distance from position to this arc, and thus its curvature.
  • color sets the color to draw the arc.
§Example
fn system(mut gizmos: Gizmos) {
    gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_4, 1., GREEN);

    // Arcs have 32 line-segments by default.
    // You may want to increase this for larger arcs.
    gizmos
        .arc_2d(Isometry2d::IDENTITY, FRAC_PI_4, 5., RED)
        .resolution(64);
}
Examples found in repository?
examples/gizmos/2d_gizmos.rs (lines 98-103)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn arc_3d( &mut self, angle: f32, radius: f32, isometry: impl Into<Isometry3d>, color: impl Into<Color>, ) -> Arc3dBuilder<'_, Config, Clear>

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

  • an arc with a center at Vec3::ZERO
  • starting at Vec3::X
  • embedded in the XZ plane
  • rotates counterclockwise

This should be called for each frame the arc needs to be rendered.

§Arguments
  • angle: sets how much of a circle circumference is passed, e.g. PI is half a circle. This value should be in the range (-2 * PI..=2 * PI)
  • radius: distance between the arc and its center point
  • isometry defines the translation and rotation of the arc.
    • the translation specifies the center of the arc
    • the rotation is counter-clockwise starting from Vec3::Y
  • color: color of the arc
§Builder methods

The resolution of the arc (i.e. the level of detail) can be adjusted with the .resolution(...) method.

§Example
fn system(mut gizmos: Gizmos) {
    // rotation rotates normal to point in the direction of `Vec3::NEG_ONE`
    let rotation = Quat::from_rotation_arc(Vec3::Y, Vec3::NEG_ONE.normalize());

    gizmos
       .arc_3d(
         270.0_f32.to_radians(),
         0.25,
         Isometry3d::new(Vec3::ONE, rotation),
         ORANGE
         )
         .resolution(100);
}
Examples found in repository?
examples/gizmos/3d_gizmos.rs (lines 175-183)
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}
Source

pub fn short_arc_3d_between( &mut self, center: Vec3, from: Vec3, to: Vec3, color: impl Into<Color>, ) -> Arc3dBuilder<'_, Config, Clear>

Draws the shortest arc between two points (from and to) relative to a specified center point.

§Arguments
  • center: The center point around which the arc is drawn.
  • from: The starting point of the arc.
  • to: The ending point of the arc.
  • color: color of the arc
§Builder methods

The resolution of the arc (i.e. the level of detail) can be adjusted with the .resolution(...) method.

§Examples
fn system(mut gizmos: Gizmos) {
    gizmos.short_arc_3d_between(
       Vec3::ONE,
       Vec3::ONE + Vec3::NEG_ONE,
       Vec3::ZERO,
       ORANGE
       )
       .resolution(100);
}
§Notes
  • This method assumes that the points from and to are distinct from center. If one of the points is coincident with center, nothing is rendered.
  • The arc is drawn as a portion of a circle with a radius equal to the distance from the center to from. If the distance from center to to is not equal to the radius, then the results will behave as if this were the case
Source

pub fn long_arc_3d_between( &mut self, center: Vec3, from: Vec3, to: Vec3, color: impl Into<Color>, ) -> Arc3dBuilder<'_, Config, Clear>

Draws the longest arc between two points (from and to) relative to a specified center point.

§Arguments
  • center: The center point around which the arc is drawn.
  • from: The starting point of the arc.
  • to: The ending point of the arc.
  • color: color of the arc
§Builder methods

The resolution of the arc (i.e. the level of detail) can be adjusted with the .resolution(...) method.

§Examples
fn system(mut gizmos: Gizmos) {
    gizmos.long_arc_3d_between(
       Vec3::ONE,
       Vec3::ONE + Vec3::NEG_ONE,
       Vec3::ZERO,
       ORANGE
       )
       .resolution(100);
}
§Notes
  • This method assumes that the points from and to are distinct from center. If one of the points is coincident with center, nothing is rendered.
  • The arc is drawn as a portion of a circle with a radius equal to the distance from the center to from. If the distance from center to to is not equal to the radius, then the results will behave as if this were the case.
Source

pub fn short_arc_2d_between( &mut self, center: Vec2, from: Vec2, to: Vec2, color: impl Into<Color>, ) -> Arc2dBuilder<'_, Config, Clear>

Draws the shortest arc between two points (from and to) relative to a specified center point.

§Arguments
  • center: The center point around which the arc is drawn.
  • from: The starting point of the arc.
  • to: The ending point of the arc.
  • color: color of the arc
§Builder methods

The resolution of the arc (i.e. the level of detail) can be adjusted with the .resolution(...) method.

§Examples
fn system(mut gizmos: Gizmos) {
    gizmos.short_arc_2d_between(
       Vec2::ZERO,
       Vec2::X,
       Vec2::Y,
       ORANGE
       )
       .resolution(100);
}
§Notes
  • This method assumes that the points from and to are distinct from center. If one of the points is coincident with center, nothing is rendered.
  • The arc is drawn as a portion of a circle with a radius equal to the distance from the center to from. If the distance from center to to is not equal to the radius, then the results will behave as if this were the case
Examples found in repository?
examples/gizmos/2d_gizmos.rs (line 106)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn long_arc_2d_between( &mut self, center: Vec2, from: Vec2, to: Vec2, color: impl Into<Color>, ) -> Arc2dBuilder<'_, Config, Clear>

Draws the longest arc between two points (from and to) relative to a specified center point.

§Arguments
  • center: The center point around which the arc is drawn.
  • from: The starting point of the arc.
  • to: The ending point of the arc.
  • color: color of the arc
§Builder methods

The resolution of the arc (i.e. the level of detail) can be adjusted with the .resolution(...) method.

§Examples
fn system(mut gizmos: Gizmos) {
    gizmos.long_arc_2d_between(
       Vec2::ZERO,
       Vec2::X,
       Vec2::Y,
       ORANGE
       )
       .resolution(100);
}
§Notes
  • This method assumes that the points from and to are distinct from center. If one of the points is coincident with center, nothing is rendered.
  • The arc is drawn as a portion of a circle with a radius equal to the distance from the center to from. If the distance from center to to is not equal to the radius, then the results will behave as if this were the case.
Examples found in repository?
examples/gizmos/2d_gizmos.rs (line 105)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn arrow( &mut self, start: Vec3, end: Vec3, color: impl Into<Color>, ) -> ArrowBuilder<'_, Config, Clear>

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.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.arrow(Vec3::ZERO, Vec3::ONE, GREEN);
}
Examples found in repository?
examples/transforms/align.rs (line 125)
122fn draw_ship_axes(mut gizmos: Gizmos, ship_transform: Single<&Transform, With<Ship>>) {
123    // Local Z-axis arrow, negative direction
124    let z_ends = arrow_ends(*ship_transform, Vec3::NEG_Z, 1.5);
125    gizmos.arrow(z_ends.0, z_ends.1, RED);
126
127    // local X-axis arrow
128    let x_ends = arrow_ends(*ship_transform, Vec3::X, 1.5);
129    gizmos.arrow(x_ends.0, x_ends.1, Color::srgb(0.65, 0., 0.));
130}
131
132// Draw the randomly generated axes
133fn draw_random_axes(mut gizmos: Gizmos, random_axes: Single<&RandomAxes>) {
134    let RandomAxes(v1, v2) = *random_axes;
135    gizmos.arrow(Vec3::ZERO, 1.5 * *v1, WHITE);
136    gizmos.arrow(Vec3::ZERO, 1.5 * *v2, GRAY);
137}
More examples
Hide additional examples
examples/picking/mesh_picking.rs (line 181)
174fn draw_mesh_intersections(pointers: Query<&PointerInteraction>, mut gizmos: Gizmos) {
175    for (point, normal) in pointers
176        .iter()
177        .filter_map(|interaction| interaction.get_nearest_hit())
178        .filter_map(|(_entity, hit)| hit.position.zip(hit.normal))
179    {
180        gizmos.sphere(point, 0.05, RED_500);
181        gizmos.arrow(point, point + normal.normalize() * 0.5, PINK_100);
182    }
183}
examples/gizmos/3d_gizmos.rs (line 197)
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}
Source

pub fn arrow_2d( &mut self, start: Vec2, end: Vec2, color: impl Into<Color>, ) -> ArrowBuilder<'_, Config, Clear>

Draw an arrow in 2D (on the xy plane), from start to end.

This should be called for each frame the arrow needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.arrow_2d(Vec2::ZERO, Vec2::X, GREEN);
}
Examples found in repository?
examples/math/cubic_splines.rs (line 194)
185fn draw_control_points(
186    control_points: Res<ControlPoints>,
187    spline_mode: Res<SplineMode>,
188    mut gizmos: Gizmos,
189) {
190    for &(point, tangent) in &control_points.points_and_tangents {
191        gizmos.circle_2d(point, 10.0, Color::srgb(0.0, 1.0, 0.0));
192
193        if matches!(*spline_mode, SplineMode::Hermite) {
194            gizmos.arrow_2d(point, point + tangent, Color::srgb(1.0, 0.0, 0.0));
195        }
196    }
197}
198
199/// Helper function for generating a [`Curve`] from [control points] and selected modes.
200///
201/// [control points]: ControlPoints
202fn form_curve(
203    control_points: &ControlPoints,
204    spline_mode: SplineMode,
205    cycling_mode: CyclingMode,
206) -> Curve {
207    let (points, tangents): (Vec<_>, Vec<_>) =
208        control_points.points_and_tangents.iter().copied().unzip();
209
210    match spline_mode {
211        SplineMode::Hermite => {
212            let spline = CubicHermite::new(points, tangents);
213            Curve(match cycling_mode {
214                CyclingMode::NotCyclic => spline.to_curve().ok(),
215                CyclingMode::Cyclic => spline.to_curve_cyclic().ok(),
216            })
217        }
218        SplineMode::Cardinal => {
219            let spline = CubicCardinalSpline::new_catmull_rom(points);
220            Curve(match cycling_mode {
221                CyclingMode::NotCyclic => spline.to_curve().ok(),
222                CyclingMode::Cyclic => spline.to_curve_cyclic().ok(),
223            })
224        }
225        SplineMode::B => {
226            let spline = CubicBSpline::new(points);
227            Curve(match cycling_mode {
228                CyclingMode::NotCyclic => spline.to_curve().ok(),
229                CyclingMode::Cyclic => spline.to_curve_cyclic().ok(),
230            })
231        }
232    }
233}
234
235// --------------------
236// Text-related Components and Systems
237// --------------------
238
239/// Marker component for the text node that displays the current [`SplineMode`].
240#[derive(Component)]
241struct SplineModeText;
242
243/// Marker component for the text node that displays the current [`CyclingMode`].
244#[derive(Component)]
245struct CyclingModeText;
246
247fn update_spline_mode_text(
248    spline_mode: Res<SplineMode>,
249    mut spline_mode_text: Query<&mut Text, With<SplineModeText>>,
250) {
251    if !spline_mode.is_changed() {
252        return;
253    }
254
255    let new_text = format!("Spline: {}", *spline_mode);
256
257    for mut spline_mode_text in spline_mode_text.iter_mut() {
258        (**spline_mode_text).clone_from(&new_text);
259    }
260}
261
262fn update_cycling_mode_text(
263    cycling_mode: Res<CyclingMode>,
264    mut cycling_mode_text: Query<&mut Text, With<CyclingModeText>>,
265) {
266    if !cycling_mode.is_changed() {
267        return;
268    }
269
270    let new_text = format!("{}", *cycling_mode);
271
272    for mut cycling_mode_text in cycling_mode_text.iter_mut() {
273        (**cycling_mode_text).clone_from(&new_text);
274    }
275}
276
277// -----------------------------------
278// Input-related Resources and Systems
279// -----------------------------------
280
281/// A small state machine which tracks a click-and-drag motion used to create new control points.
282///
283/// When the user is not doing a click-and-drag motion, the `start` field is `None`. When the user
284/// presses the left mouse button, the location of that press is temporarily stored in the field.
285#[derive(Clone, Default, Resource)]
286struct MouseEditMove {
287    start: Option<Vec2>,
288}
289
290/// The current mouse position, if known.
291#[derive(Clone, Default, Resource)]
292struct MousePosition(Option<Vec2>);
293
294/// Update the current cursor position and track it in the [`MousePosition`] resource.
295fn handle_mouse_move(
296    mut cursor_events: EventReader<CursorMoved>,
297    mut mouse_position: ResMut<MousePosition>,
298) {
299    if let Some(cursor_event) = cursor_events.read().last() {
300        mouse_position.0 = Some(cursor_event.position);
301    }
302}
303
304/// This system handles updating the [`MouseEditMove`] resource, orchestrating the logical part
305/// of the click-and-drag motion which actually creates new control points.
306fn handle_mouse_press(
307    mut button_events: EventReader<MouseButtonInput>,
308    mouse_position: Res<MousePosition>,
309    mut edit_move: ResMut<MouseEditMove>,
310    mut control_points: ResMut<ControlPoints>,
311    camera: Single<(&Camera, &GlobalTransform)>,
312) {
313    let Some(mouse_pos) = mouse_position.0 else {
314        return;
315    };
316
317    // Handle click and drag behavior
318    for button_event in button_events.read() {
319        if button_event.button != MouseButton::Left {
320            continue;
321        }
322
323        match button_event.state {
324            ButtonState::Pressed => {
325                if edit_move.start.is_some() {
326                    // If the edit move already has a start, press event should do nothing.
327                    continue;
328                }
329                // This press represents the start of the edit move.
330                edit_move.start = Some(mouse_pos);
331            }
332
333            ButtonState::Released => {
334                // Release is only meaningful if we started an edit move.
335                let Some(start) = edit_move.start else {
336                    continue;
337                };
338
339                let (camera, camera_transform) = *camera;
340
341                // Convert the starting point and end point (current mouse pos) into world coords:
342                let Ok(point) = camera.viewport_to_world_2d(camera_transform, start) else {
343                    continue;
344                };
345                let Ok(end_point) = camera.viewport_to_world_2d(camera_transform, mouse_pos) else {
346                    continue;
347                };
348                let tangent = end_point - point;
349
350                // The start of the click-and-drag motion represents the point to add,
351                // while the difference with the current position represents the tangent.
352                control_points.points_and_tangents.push((point, tangent));
353
354                // Reset the edit move since we've consumed it.
355                edit_move.start = None;
356            }
357        }
358    }
359}
360
361/// This system handles drawing the "preview" control point based on the state of [`MouseEditMove`].
362fn draw_edit_move(
363    edit_move: Res<MouseEditMove>,
364    mouse_position: Res<MousePosition>,
365    mut gizmos: Gizmos,
366    camera: Single<(&Camera, &GlobalTransform)>,
367) {
368    let Some(start) = edit_move.start else {
369        return;
370    };
371    let Some(mouse_pos) = mouse_position.0 else {
372        return;
373    };
374
375    let (camera, camera_transform) = *camera;
376
377    // Resources store data in viewport coordinates, so we need to convert to world coordinates
378    // to display them:
379    let Ok(start) = camera.viewport_to_world_2d(camera_transform, start) else {
380        return;
381    };
382    let Ok(end) = camera.viewport_to_world_2d(camera_transform, mouse_pos) else {
383        return;
384    };
385
386    gizmos.circle_2d(start, 10.0, Color::srgb(0.0, 1.0, 0.7));
387    gizmos.circle_2d(start, 7.0, Color::srgb(0.0, 1.0, 0.7));
388    gizmos.arrow_2d(start, end, Color::srgb(1.0, 0.0, 0.7));
389}
More examples
Hide additional examples
examples/gizmos/2d_gizmos.rs (lines 108-112)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn axes(&mut self, transform: impl TransformPoint, base_length: f32)

Draw a set of axes local to the given transform (transform), with length scaled by a factor of base_length.

This should be called for each frame the axes need to be rendered.

§Example
fn draw_axes(
    mut gizmos: Gizmos,
    query: Query<&Transform, With<MyComponent>>,
) {
    for &transform in &query {
        gizmos.axes(transform, 1.);
    }
}
Examples found in repository?
examples/gizmos/axes.rs (line 102)
99fn draw_axes(mut gizmos: Gizmos, query: Query<(&Transform, &Aabb), With<ShowAxes>>) {
100    for (&transform, &aabb) in &query {
101        let length = aabb.half_extents.length();
102        gizmos.axes(transform, length);
103    }
104}
More examples
Hide additional examples
examples/animation/custom_skinned_mesh.rs (line 233)
188fn joint_animation(
189    time: Res<Time>,
190    mut query: Query<(&mut Transform, &AnimatedJoint)>,
191    mut gizmos: Gizmos,
192) {
193    for (mut transform, animated_joint) in &mut query {
194        match animated_joint.0 {
195            -5 => {
196                transform.rotation =
197                    Quat::from_rotation_x(FRAC_PI_2 * ops::sin(time.elapsed_secs()));
198            }
199            -4 => {
200                transform.rotation =
201                    Quat::from_rotation_y(FRAC_PI_2 * ops::sin(time.elapsed_secs()));
202            }
203            -3 => {
204                transform.rotation =
205                    Quat::from_rotation_z(FRAC_PI_2 * ops::sin(time.elapsed_secs()));
206            }
207            -2 => {
208                transform.scale.x = ops::sin(time.elapsed_secs()) + 1.0;
209            }
210            -1 => {
211                transform.scale.y = ops::sin(time.elapsed_secs()) + 1.0;
212            }
213            0 => {
214                transform.translation.x = 0.5 * ops::sin(time.elapsed_secs());
215                transform.translation.y = ops::cos(time.elapsed_secs());
216            }
217            1 => {
218                transform.translation.y = ops::sin(time.elapsed_secs());
219                transform.translation.z = ops::cos(time.elapsed_secs());
220            }
221            2 => {
222                transform.translation.x = ops::sin(time.elapsed_secs());
223            }
224            3 => {
225                transform.translation.y = ops::sin(time.elapsed_secs());
226                transform.scale.x = ops::sin(time.elapsed_secs()) + 1.0;
227            }
228            _ => (),
229        }
230        // Show transform
231        let mut axis = *transform;
232        axis.translation.x += animated_joint.0 as f32 * 1.5;
233        gizmos.axes(axis, 1.0);
234    }
235}
Source

pub fn axes_2d(&mut self, transform: impl TransformPoint, base_length: f32)

Draw a set of axes local to the given transform (transform), with length scaled by a factor of base_length.

This should be called for each frame the axes need to be rendered.

§Example
fn draw_axes_2d(
    mut gizmos: Gizmos,
    query: Query<&Transform, With<AxesComponent>>,
) {
    for &transform in &query {
        gizmos.axes_2d(transform, 1.);
    }
}
Source

pub fn ellipse( &mut self, isometry: impl Into<Isometry3d>, half_size: Vec2, color: impl Into<Color>, ) -> EllipseBuilder<'_, Config, Clear>

Draw an ellipse in 3D with the given isometry applied.

If isometry == Isometry3d::IDENTITY then

  • the center is at Vec3::ZERO
  • the half_sizes are aligned with the Vec3::X and Vec3::Y axes.

This should be called for each frame the ellipse needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.ellipse(Isometry3d::IDENTITY, Vec2::new(1., 2.), GREEN);

    // Ellipses have 32 line-segments by default.
    // You may want to increase this for larger ellipses.
    gizmos
        .ellipse(Isometry3d::IDENTITY, Vec2::new(5., 1.), RED)
        .resolution(64);
}
Source

pub fn ellipse_2d( &mut self, isometry: impl Into<Isometry2d>, half_size: Vec2, color: impl Into<Color>, ) -> Ellipse2dBuilder<'_, Config, Clear>

Draw an ellipse in 2D with the given isometry applied.

If isometry == Isometry2d::IDENTITY then

  • the center is at Vec2::ZERO
  • the half_sizes are aligned with the Vec2::X and Vec2::Y axes.

This should be called for each frame the ellipse needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.ellipse_2d(Isometry2d::from_rotation(Rot2::degrees(180.0)), Vec2::new(2., 1.), GREEN);

    // Ellipses have 32 line-segments by default.
    // You may want to increase this for larger ellipses.
    gizmos
        .ellipse_2d(Isometry2d::from_rotation(Rot2::degrees(180.0)), Vec2::new(5., 1.), RED)
        .resolution(64);
}
Examples found in repository?
examples/gizmos/2d_gizmos.rs (lines 90-94)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn circle( &mut self, isometry: impl Into<Isometry3d>, radius: f32, color: impl Into<Color>, ) -> EllipseBuilder<'_, Config, Clear>

Draw a circle in 3D with the given isometry applied.

If isometry == Isometry3d::IDENTITY then

  • the center is at Vec3::ZERO
  • the radius is aligned with the Vec3::X and Vec3::Y axes.
§Example
fn system(mut gizmos: Gizmos) {
    gizmos.circle(Isometry3d::IDENTITY, 1., GREEN);

    // Circles have 32 line-segments by default.
    // You may want to increase this for larger circles.
    gizmos
        .circle(Isometry3d::IDENTITY, 5., RED)
        .resolution(64);
}
Examples found in repository?
examples/3d/3d_viewport_to_world.rs (lines 43-50)
13fn draw_cursor(
14    camera_query: Single<(&Camera, &GlobalTransform)>,
15    ground: Single<&GlobalTransform, With<Ground>>,
16    windows: Query<&Window>,
17    mut gizmos: Gizmos,
18) {
19    let Ok(windows) = windows.single() else {
20        return;
21    };
22
23    let (camera, camera_transform) = *camera_query;
24
25    let Some(cursor_position) = windows.cursor_position() else {
26        return;
27    };
28
29    // Calculate a ray pointing from the camera into the world based on the cursor's position.
30    let Ok(ray) = camera.viewport_to_world(camera_transform, cursor_position) else {
31        return;
32    };
33
34    // Calculate if and where the ray is hitting the ground plane.
35    let Some(distance) =
36        ray.intersect_plane(ground.translation(), InfinitePlane3d::new(ground.up()))
37    else {
38        return;
39    };
40    let point = ray.get_point(distance);
41
42    // Draw a circle just above the ground plane at that position.
43    gizmos.circle(
44        Isometry3d::new(
45            point + ground.up() * 0.01,
46            Quat::from_rotation_arc(Vec3::Z, ground.up().as_vec3()),
47        ),
48        0.2,
49        Color::WHITE,
50    );
51}
More examples
Hide additional examples
examples/gizmos/3d_gizmos.rs (line 187)
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}
Source

pub fn circle_2d( &mut self, isometry: impl Into<Isometry2d>, radius: f32, color: impl Into<Color>, ) -> Ellipse2dBuilder<'_, Config, Clear>

Draw a circle in 2D with the given isometry applied.

If isometry == Isometry2d::IDENTITY then

  • the center is at Vec2::ZERO
  • the radius is aligned with the Vec2::X and Vec2::Y axes.

This should be called for each frame the circle needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.circle_2d(Isometry2d::IDENTITY, 1., GREEN);

    // Circles have 32 line-segments by default.
    // You may want to increase this for larger circles.
    gizmos
        .circle_2d(Isometry2d::IDENTITY, 5., RED)
        .resolution(64);
}
Examples found in repository?
examples/testbed/2d.rs (line 283)
280    pub fn draw_gizmos(mut gizmos: Gizmos) {
281        gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::new(200.0, 200.0), RED);
282        gizmos
283            .circle_2d(Isometry2d::IDENTITY, 200.0, GREEN)
284            .resolution(64);
285    }
More examples
Hide additional examples
examples/ecs/observers.rs (lines 163-167)
161fn draw_shapes(mut gizmos: Gizmos, mines: Query<&Mine>) {
162    for mine in &mines {
163        gizmos.circle_2d(
164            mine.pos,
165            mine.size,
166            Color::hsl((mine.size - 4.0) / 16.0 * 360.0, 1.0, 0.8),
167        );
168    }
169}
examples/math/cubic_splines.rs (line 191)
185fn draw_control_points(
186    control_points: Res<ControlPoints>,
187    spline_mode: Res<SplineMode>,
188    mut gizmos: Gizmos,
189) {
190    for &(point, tangent) in &control_points.points_and_tangents {
191        gizmos.circle_2d(point, 10.0, Color::srgb(0.0, 1.0, 0.0));
192
193        if matches!(*spline_mode, SplineMode::Hermite) {
194            gizmos.arrow_2d(point, point + tangent, Color::srgb(1.0, 0.0, 0.0));
195        }
196    }
197}
198
199/// Helper function for generating a [`Curve`] from [control points] and selected modes.
200///
201/// [control points]: ControlPoints
202fn form_curve(
203    control_points: &ControlPoints,
204    spline_mode: SplineMode,
205    cycling_mode: CyclingMode,
206) -> Curve {
207    let (points, tangents): (Vec<_>, Vec<_>) =
208        control_points.points_and_tangents.iter().copied().unzip();
209
210    match spline_mode {
211        SplineMode::Hermite => {
212            let spline = CubicHermite::new(points, tangents);
213            Curve(match cycling_mode {
214                CyclingMode::NotCyclic => spline.to_curve().ok(),
215                CyclingMode::Cyclic => spline.to_curve_cyclic().ok(),
216            })
217        }
218        SplineMode::Cardinal => {
219            let spline = CubicCardinalSpline::new_catmull_rom(points);
220            Curve(match cycling_mode {
221                CyclingMode::NotCyclic => spline.to_curve().ok(),
222                CyclingMode::Cyclic => spline.to_curve_cyclic().ok(),
223            })
224        }
225        SplineMode::B => {
226            let spline = CubicBSpline::new(points);
227            Curve(match cycling_mode {
228                CyclingMode::NotCyclic => spline.to_curve().ok(),
229                CyclingMode::Cyclic => spline.to_curve_cyclic().ok(),
230            })
231        }
232    }
233}
234
235// --------------------
236// Text-related Components and Systems
237// --------------------
238
239/// Marker component for the text node that displays the current [`SplineMode`].
240#[derive(Component)]
241struct SplineModeText;
242
243/// Marker component for the text node that displays the current [`CyclingMode`].
244#[derive(Component)]
245struct CyclingModeText;
246
247fn update_spline_mode_text(
248    spline_mode: Res<SplineMode>,
249    mut spline_mode_text: Query<&mut Text, With<SplineModeText>>,
250) {
251    if !spline_mode.is_changed() {
252        return;
253    }
254
255    let new_text = format!("Spline: {}", *spline_mode);
256
257    for mut spline_mode_text in spline_mode_text.iter_mut() {
258        (**spline_mode_text).clone_from(&new_text);
259    }
260}
261
262fn update_cycling_mode_text(
263    cycling_mode: Res<CyclingMode>,
264    mut cycling_mode_text: Query<&mut Text, With<CyclingModeText>>,
265) {
266    if !cycling_mode.is_changed() {
267        return;
268    }
269
270    let new_text = format!("{}", *cycling_mode);
271
272    for mut cycling_mode_text in cycling_mode_text.iter_mut() {
273        (**cycling_mode_text).clone_from(&new_text);
274    }
275}
276
277// -----------------------------------
278// Input-related Resources and Systems
279// -----------------------------------
280
281/// A small state machine which tracks a click-and-drag motion used to create new control points.
282///
283/// When the user is not doing a click-and-drag motion, the `start` field is `None`. When the user
284/// presses the left mouse button, the location of that press is temporarily stored in the field.
285#[derive(Clone, Default, Resource)]
286struct MouseEditMove {
287    start: Option<Vec2>,
288}
289
290/// The current mouse position, if known.
291#[derive(Clone, Default, Resource)]
292struct MousePosition(Option<Vec2>);
293
294/// Update the current cursor position and track it in the [`MousePosition`] resource.
295fn handle_mouse_move(
296    mut cursor_events: EventReader<CursorMoved>,
297    mut mouse_position: ResMut<MousePosition>,
298) {
299    if let Some(cursor_event) = cursor_events.read().last() {
300        mouse_position.0 = Some(cursor_event.position);
301    }
302}
303
304/// This system handles updating the [`MouseEditMove`] resource, orchestrating the logical part
305/// of the click-and-drag motion which actually creates new control points.
306fn handle_mouse_press(
307    mut button_events: EventReader<MouseButtonInput>,
308    mouse_position: Res<MousePosition>,
309    mut edit_move: ResMut<MouseEditMove>,
310    mut control_points: ResMut<ControlPoints>,
311    camera: Single<(&Camera, &GlobalTransform)>,
312) {
313    let Some(mouse_pos) = mouse_position.0 else {
314        return;
315    };
316
317    // Handle click and drag behavior
318    for button_event in button_events.read() {
319        if button_event.button != MouseButton::Left {
320            continue;
321        }
322
323        match button_event.state {
324            ButtonState::Pressed => {
325                if edit_move.start.is_some() {
326                    // If the edit move already has a start, press event should do nothing.
327                    continue;
328                }
329                // This press represents the start of the edit move.
330                edit_move.start = Some(mouse_pos);
331            }
332
333            ButtonState::Released => {
334                // Release is only meaningful if we started an edit move.
335                let Some(start) = edit_move.start else {
336                    continue;
337                };
338
339                let (camera, camera_transform) = *camera;
340
341                // Convert the starting point and end point (current mouse pos) into world coords:
342                let Ok(point) = camera.viewport_to_world_2d(camera_transform, start) else {
343                    continue;
344                };
345                let Ok(end_point) = camera.viewport_to_world_2d(camera_transform, mouse_pos) else {
346                    continue;
347                };
348                let tangent = end_point - point;
349
350                // The start of the click-and-drag motion represents the point to add,
351                // while the difference with the current position represents the tangent.
352                control_points.points_and_tangents.push((point, tangent));
353
354                // Reset the edit move since we've consumed it.
355                edit_move.start = None;
356            }
357        }
358    }
359}
360
361/// This system handles drawing the "preview" control point based on the state of [`MouseEditMove`].
362fn draw_edit_move(
363    edit_move: Res<MouseEditMove>,
364    mouse_position: Res<MousePosition>,
365    mut gizmos: Gizmos,
366    camera: Single<(&Camera, &GlobalTransform)>,
367) {
368    let Some(start) = edit_move.start else {
369        return;
370    };
371    let Some(mouse_pos) = mouse_position.0 else {
372        return;
373    };
374
375    let (camera, camera_transform) = *camera;
376
377    // Resources store data in viewport coordinates, so we need to convert to world coordinates
378    // to display them:
379    let Ok(start) = camera.viewport_to_world_2d(camera_transform, start) else {
380        return;
381    };
382    let Ok(end) = camera.viewport_to_world_2d(camera_transform, mouse_pos) else {
383        return;
384    };
385
386    gizmos.circle_2d(start, 10.0, Color::srgb(0.0, 1.0, 0.7));
387    gizmos.circle_2d(start, 7.0, Color::srgb(0.0, 1.0, 0.7));
388    gizmos.arrow_2d(start, end, Color::srgb(1.0, 0.0, 0.7));
389}
examples/math/bounding_2d.rs (line 190)
182fn render_volumes(mut gizmos: Gizmos, query: Query<(&CurrentVolume, &Intersects)>) {
183    for (volume, intersects) in query.iter() {
184        let color = if **intersects { AQUA } else { ORANGE_RED };
185        match volume {
186            CurrentVolume::Aabb(a) => {
187                gizmos.rect_2d(a.center(), a.half_size() * 2., color);
188            }
189            CurrentVolume::Circle(c) => {
190                gizmos.circle_2d(c.center(), c.radius(), color);
191            }
192        }
193    }
194}
195
196#[derive(Component, Deref, DerefMut, Default)]
197struct Intersects(bool);
198
199const OFFSET_X: f32 = 125.;
200const OFFSET_Y: f32 = 75.;
201
202fn setup(mut commands: Commands) {
203    commands.spawn(Camera2d);
204
205    commands.spawn((
206        Transform::from_xyz(-OFFSET_X, OFFSET_Y, 0.),
207        Shape::Circle(Circle::new(45.)),
208        DesiredVolume::Aabb,
209        Intersects::default(),
210    ));
211
212    commands.spawn((
213        Transform::from_xyz(0., OFFSET_Y, 0.),
214        Shape::Rectangle(Rectangle::new(80., 80.)),
215        Spin,
216        DesiredVolume::Circle,
217        Intersects::default(),
218    ));
219
220    commands.spawn((
221        Transform::from_xyz(OFFSET_X, OFFSET_Y, 0.),
222        Shape::Triangle(Triangle2d::new(
223            Vec2::new(-40., -40.),
224            Vec2::new(-20., 40.),
225            Vec2::new(40., 50.),
226        )),
227        Spin,
228        DesiredVolume::Aabb,
229        Intersects::default(),
230    ));
231
232    commands.spawn((
233        Transform::from_xyz(-OFFSET_X, -OFFSET_Y, 0.),
234        Shape::Line(Segment2d::from_direction_and_length(
235            Dir2::from_xy(1., 0.3).unwrap(),
236            90.,
237        )),
238        Spin,
239        DesiredVolume::Circle,
240        Intersects::default(),
241    ));
242
243    commands.spawn((
244        Transform::from_xyz(0., -OFFSET_Y, 0.),
245        Shape::Capsule(Capsule2d::new(25., 50.)),
246        Spin,
247        DesiredVolume::Aabb,
248        Intersects::default(),
249    ));
250
251    commands.spawn((
252        Transform::from_xyz(OFFSET_X, -OFFSET_Y, 0.),
253        Shape::Polygon(RegularPolygon::new(50., 6)),
254        Spin,
255        DesiredVolume::Circle,
256        Intersects::default(),
257    ));
258
259    commands.spawn((
260        Text::default(),
261        Node {
262            position_type: PositionType::Absolute,
263            top: Val::Px(12.0),
264            left: Val::Px(12.0),
265            ..default()
266        },
267    ));
268}
269
270fn draw_filled_circle(gizmos: &mut Gizmos, position: Vec2, color: Srgba) {
271    for r in [1., 2., 3.] {
272        gizmos.circle_2d(position, r, color);
273    }
274}
275
276fn draw_ray(gizmos: &mut Gizmos, ray: &RayCast2d) {
277    gizmos.line_2d(
278        ray.ray.origin,
279        ray.ray.origin + *ray.ray.direction * ray.max,
280        WHITE,
281    );
282    draw_filled_circle(gizmos, ray.ray.origin, FUCHSIA);
283}
284
285fn get_and_draw_ray(gizmos: &mut Gizmos, time: &Time) -> RayCast2d {
286    let ray = Vec2::new(ops::cos(time.elapsed_secs()), ops::sin(time.elapsed_secs()));
287    let dist = 150. + ops::sin(0.5 * time.elapsed_secs()).abs() * 500.;
288
289    let aabb_ray = Ray2d {
290        origin: ray * 250.,
291        direction: Dir2::new_unchecked(-ray),
292    };
293    let ray_cast = RayCast2d::from_ray(aabb_ray, dist - 20.);
294
295    draw_ray(gizmos, &ray_cast);
296    ray_cast
297}
298
299fn ray_cast_system(
300    mut gizmos: Gizmos,
301    time: Res<Time>,
302    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
303) {
304    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
305
306    for (volume, mut intersects) in volumes.iter_mut() {
307        let toi = match volume {
308            CurrentVolume::Aabb(a) => ray_cast.aabb_intersection_at(a),
309            CurrentVolume::Circle(c) => ray_cast.circle_intersection_at(c),
310        };
311        **intersects = toi.is_some();
312        if let Some(toi) = toi {
313            draw_filled_circle(
314                &mut gizmos,
315                ray_cast.ray.origin + *ray_cast.ray.direction * toi,
316                LIME,
317            );
318        }
319    }
320}
321
322fn aabb_cast_system(
323    mut gizmos: Gizmos,
324    time: Res<Time>,
325    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
326) {
327    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
328    let aabb_cast = AabbCast2d {
329        aabb: Aabb2d::new(Vec2::ZERO, Vec2::splat(15.)),
330        ray: ray_cast,
331    };
332
333    for (volume, mut intersects) in volumes.iter_mut() {
334        let toi = match *volume {
335            CurrentVolume::Aabb(a) => aabb_cast.aabb_collision_at(a),
336            CurrentVolume::Circle(_) => None,
337        };
338
339        **intersects = toi.is_some();
340        if let Some(toi) = toi {
341            gizmos.rect_2d(
342                aabb_cast.ray.ray.origin + *aabb_cast.ray.ray.direction * toi,
343                aabb_cast.aabb.half_size() * 2.,
344                LIME,
345            );
346        }
347    }
348}
349
350fn bounding_circle_cast_system(
351    mut gizmos: Gizmos,
352    time: Res<Time>,
353    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
354) {
355    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
356    let circle_cast = BoundingCircleCast {
357        circle: BoundingCircle::new(Vec2::ZERO, 15.),
358        ray: ray_cast,
359    };
360
361    for (volume, mut intersects) in volumes.iter_mut() {
362        let toi = match *volume {
363            CurrentVolume::Aabb(_) => None,
364            CurrentVolume::Circle(c) => circle_cast.circle_collision_at(c),
365        };
366
367        **intersects = toi.is_some();
368        if let Some(toi) = toi {
369            gizmos.circle_2d(
370                circle_cast.ray.ray.origin + *circle_cast.ray.ray.direction * toi,
371                circle_cast.circle.radius(),
372                LIME,
373            );
374        }
375    }
376}
377
378fn get_intersection_position(time: &Time) -> Vec2 {
379    let x = ops::cos(0.8 * time.elapsed_secs()) * 250.;
380    let y = ops::sin(0.4 * time.elapsed_secs()) * 100.;
381    Vec2::new(x, y)
382}
383
384fn aabb_intersection_system(
385    mut gizmos: Gizmos,
386    time: Res<Time>,
387    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
388) {
389    let center = get_intersection_position(&time);
390    let aabb = Aabb2d::new(center, Vec2::splat(50.));
391    gizmos.rect_2d(center, aabb.half_size() * 2., YELLOW);
392
393    for (volume, mut intersects) in volumes.iter_mut() {
394        let hit = match volume {
395            CurrentVolume::Aabb(a) => aabb.intersects(a),
396            CurrentVolume::Circle(c) => aabb.intersects(c),
397        };
398
399        **intersects = hit;
400    }
401}
402
403fn circle_intersection_system(
404    mut gizmos: Gizmos,
405    time: Res<Time>,
406    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
407) {
408    let center = get_intersection_position(&time);
409    let circle = BoundingCircle::new(center, 50.);
410    gizmos.circle_2d(center, circle.radius(), YELLOW);
411
412    for (volume, mut intersects) in volumes.iter_mut() {
413        let hit = match volume {
414            CurrentVolume::Aabb(a) => circle.intersects(a),
415            CurrentVolume::Circle(c) => circle.intersects(c),
416        };
417
418        **intersects = hit;
419    }
420}
examples/2d/mesh2d_arcs.rs (line 118)
104fn draw_bounds<Shape: Bounded2d + Send + Sync + 'static>(
105    q: Query<(&DrawBounds<Shape>, &GlobalTransform)>,
106    mut gizmos: Gizmos,
107) {
108    for (shape, transform) in &q {
109        let (_, rotation, translation) = transform.to_scale_rotation_translation();
110        let translation = translation.truncate();
111        let rotation = rotation.to_euler(EulerRot::XYZ).2;
112        let isometry = Isometry2d::new(translation, Rot2::radians(rotation));
113
114        let aabb = shape.0.aabb_2d(isometry);
115        gizmos.rect_2d(aabb.center(), aabb.half_size() * 2.0, RED);
116
117        let bounding_circle = shape.0.bounding_circle(isometry);
118        gizmos.circle_2d(bounding_circle.center, bounding_circle.radius(), BLUE);
119    }
120}
examples/2d/2d_viewport_to_world.rs (line 53)
25fn draw_cursor(
26    camera_query: Single<(&Camera, &GlobalTransform)>,
27    window: Query<&Window>,
28    mut gizmos: Gizmos,
29) {
30    let (camera, camera_transform) = *camera_query;
31    let Ok(window) = window.single() else {
32        return;
33    };
34
35    let Some(cursor_position) = window.cursor_position() else {
36        return;
37    };
38
39    // Calculate a world position based on the cursor's position.
40    let Ok(world_pos) = camera.viewport_to_world_2d(camera_transform, cursor_position) else {
41        return;
42    };
43
44    // To test Camera::world_to_viewport, convert result back to viewport space and then back to world space.
45    let Ok(viewport_check) = camera.world_to_viewport(camera_transform, world_pos.extend(0.0))
46    else {
47        return;
48    };
49    let Ok(world_check) = camera.viewport_to_world_2d(camera_transform, viewport_check.xy()) else {
50        return;
51    };
52
53    gizmos.circle_2d(world_pos, 10., WHITE);
54    // Should be the same as world_pos
55    gizmos.circle_2d(world_check, 8., RED);
56}
Source

pub fn sphere( &mut self, isometry: impl Into<Isometry3d>, radius: f32, color: impl Into<Color>, ) -> SphereBuilder<'_, Config, Clear>

Draw a wireframe sphere in 3D made out of 3 circles around the axes with the given isometry applied.

If isometry == Isometry3d::IDENTITY then

  • the center is at Vec3::ZERO
  • the 3 circles are in the XY, YZ and XZ planes.

This should be called for each frame the sphere needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.sphere(Isometry3d::IDENTITY, 1., Color::BLACK);

    // Each circle has 32 line-segments by default.
    // You may want to increase this for larger spheres.
    gizmos
        .sphere(Isometry3d::IDENTITY, 5., Color::BLACK)
        .resolution(64);
}
Examples found in repository?
examples/testbed/3d.rs (line 323)
317    pub fn draw_gizmos(mut gizmos: Gizmos) {
318        gizmos.cuboid(
319            Transform::from_translation(Vec3::X * 2.0).with_scale(Vec3::splat(2.0)),
320            RED,
321        );
322        gizmos
323            .sphere(Isometry3d::from_translation(Vec3::X * -2.0), 1.0, GREEN)
324            .resolution(30_000 / 3);
325    }
More examples
Hide additional examples
examples/picking/mesh_picking.rs (line 180)
174fn draw_mesh_intersections(pointers: Query<&PointerInteraction>, mut gizmos: Gizmos) {
175    for (point, normal) in pointers
176        .iter()
177        .filter_map(|interaction| interaction.get_nearest_hit())
178        .filter_map(|(_entity, hit)| hit.position.zip(hit.normal))
179    {
180        gizmos.sphere(point, 0.05, RED_500);
181        gizmos.arrow(point, point + normal.normalize() * 0.5, PINK_100);
182    }
183}
examples/3d/mesh_ray_cast.rs (line 38)
26fn bouncing_raycast(
27    mut ray_cast: MeshRayCast,
28    mut gizmos: Gizmos,
29    time: Res<Time>,
30    // The ray map stores rays cast by the cursor
31    ray_map: Res<RayMap>,
32) {
33    // Cast an automatically moving ray and bounce it off of surfaces
34    let t = ops::cos((time.elapsed_secs() - 4.0).max(0.0) * LASER_SPEED) * PI;
35    let ray_pos = Vec3::new(ops::sin(t), ops::cos(3.0 * t) * 0.5, ops::cos(t)) * 0.5;
36    let ray_dir = Dir3::new(-ray_pos).unwrap();
37    let ray = Ray3d::new(ray_pos, ray_dir);
38    gizmos.sphere(ray_pos, 0.1, Color::WHITE);
39    bounce_ray(ray, &mut ray_cast, &mut gizmos, Color::from(css::RED));
40
41    // Cast a ray from the cursor and bounce it off of surfaces
42    for (_, ray) in ray_map.iter() {
43        bounce_ray(*ray, &mut ray_cast, &mut gizmos, Color::from(css::GREEN));
44    }
45}
46
47// Bounces a ray off of surfaces `MAX_BOUNCES` times.
48fn bounce_ray(mut ray: Ray3d, ray_cast: &mut MeshRayCast, gizmos: &mut Gizmos, color: Color) {
49    let mut intersections = Vec::with_capacity(MAX_BOUNCES + 1);
50    intersections.push((ray.origin, Color::srgb(30.0, 0.0, 0.0)));
51
52    for i in 0..MAX_BOUNCES {
53        // Cast the ray and get the first hit
54        let Some((_, hit)) = ray_cast
55            .cast_ray(ray, &MeshRayCastSettings::default())
56            .first()
57        else {
58            break;
59        };
60
61        // Draw the point of intersection and add it to the list
62        let brightness = 1.0 + 10.0 * (1.0 - i as f32 / MAX_BOUNCES as f32);
63        intersections.push((hit.point, Color::BLACK.mix(&color, brightness)));
64        gizmos.sphere(hit.point, 0.005, Color::BLACK.mix(&color, brightness * 2.0));
65
66        // Reflect the ray off of the surface
67        ray.direction = Dir3::new(ray.direction.reflect(hit.normal)).unwrap();
68        ray.origin = hit.point + ray.direction * 1e-6;
69    }
70    gizmos.linestrip_gradient(intersections);
71}
examples/math/custom_primitives.rs (line 243)
221fn bounding_shapes_3d(
222    shapes: Query<&Transform, With<Shape3d>>,
223    mut gizmos: Gizmos,
224    bounding_shape: Res<State<BoundingShape>>,
225) {
226    for transform in shapes.iter() {
227        match bounding_shape.get() {
228            BoundingShape::None => (),
229            BoundingShape::BoundingBox => {
230                // Get the AABB of the extrusion with the rotation and translation of the mesh.
231                let aabb = EXTRUSION.aabb_3d(transform.to_isometry());
232
233                gizmos.primitive_3d(
234                    &Cuboid::from_size(Vec3::from(aabb.half_size()) * 2.),
235                    aabb.center(),
236                    WHITE,
237                );
238            }
239            BoundingShape::BoundingSphere => {
240                // Get the bounding sphere of the extrusion with the rotation and translation of the mesh.
241                let bounding_sphere = EXTRUSION.bounding_sphere(transform.to_isometry());
242
243                gizmos.sphere(bounding_sphere.center(), bounding_sphere.radius(), WHITE);
244            }
245        }
246    }
247}
examples/gizmos/3d_gizmos.rs (line 37)
23fn setup(
24    mut commands: Commands,
25    mut gizmo_assets: ResMut<Assets<GizmoAsset>>,
26    mut meshes: ResMut<Assets<Mesh>>,
27    mut materials: ResMut<Assets<StandardMaterial>>,
28) {
29    let mut gizmo = GizmoAsset::new();
30
31    // When drawing a lot of static lines a Gizmo component can have
32    // far better performance than the Gizmos system parameter,
33    // but the system parameter will perform better for smaller lines that update often.
34
35    // A sphere made out of 30_000 lines!
36    gizmo
37        .sphere(Isometry3d::IDENTITY, 0.5, CRIMSON)
38        .resolution(30_000 / 3);
39
40    commands.spawn((
41        Gizmo {
42            handle: gizmo_assets.add(gizmo),
43            line_config: GizmoLineConfig {
44                width: 5.,
45                ..default()
46            },
47            ..default()
48        },
49        Transform::from_xyz(4., 1., 0.),
50    ));
51
52    commands.spawn((
53        Camera3d::default(),
54        Transform::from_xyz(0., 1.5, 6.).looking_at(Vec3::ZERO, Vec3::Y),
55        CameraController::default(),
56    ));
57    // plane
58    commands.spawn((
59        Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
60        MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
61    ));
62    // cube
63    commands.spawn((
64        Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
65        MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
66        Transform::from_xyz(0.0, 0.5, 0.0),
67    ));
68    // light
69    commands.spawn((
70        PointLight {
71            shadows_enabled: true,
72            ..default()
73        },
74        Transform::from_xyz(4.0, 8.0, 4.0),
75    ));
76
77    // example instructions
78    commands.spawn((
79        Text::new(
80            "Press 'T' to toggle drawing gizmos on top of everything else in the scene\n\
81            Press 'P' to toggle perspective for line gizmos\n\
82            Hold 'Left' or 'Right' to change the line width of straight gizmos\n\
83            Hold 'Up' or 'Down' to change the line width of round gizmos\n\
84            Press '1' or '2' to toggle the visibility of straight gizmos or round gizmos\n\
85            Press 'B' to show all AABB boxes\n\
86            Press 'U' or 'I' to cycle through line styles for straight or round gizmos\n\
87            Press 'J' or 'K' to cycle through line joins for straight or round gizmos",
88        ),
89        Node {
90            position_type: PositionType::Absolute,
91            top: Val::Px(12.0),
92            left: Val::Px(12.0),
93            ..default()
94        },
95    ));
96}
97
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}
Source

pub fn cross( &mut self, isometry: impl Into<Isometry3d>, half_size: f32, color: impl Into<Color>, )

Draw a cross in 3D with the given isometry applied.

If isometry == Isometry3d::IDENTITY then

  • the center is at Vec3::ZERO
  • the half_sizes are aligned with the Vec3::X, Vec3::Y and Vec3::Z axes.

This should be called for each frame the cross needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.cross(Isometry3d::IDENTITY, 0.5, WHITE);
}
Examples found in repository?
examples/gizmos/3d_gizmos.rs (line 146)
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}
Source

pub fn cross_2d( &mut self, isometry: impl Into<Isometry2d>, half_size: f32, color: impl Into<Color>, )

Draw a cross in 2D with the given isometry applied.

If isometry == Isometry2d::IDENTITY then

  • the center is at Vec3::ZERO
  • the half_sizes are aligned with the Vec3::X and Vec3::Y axes.

This should be called for each frame the cross needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.cross_2d(Isometry2d::IDENTITY, 0.5, WHITE);
}
Examples found in repository?
examples/gizmos/2d_gizmos.rs (line 69)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn curve_2d( &mut self, curve_2d: impl Curve<Vec2>, times: impl IntoIterator<Item = f32>, color: impl Into<Color>, )

Draw a curve, at the given time points, sampling in 2D.

This should be called for each frame the curve needs to be rendered.

Samples of time points outside of the curve’s domain will be filtered out and won’t contribute to the rendering. If you wish to render the curve outside of its domain you need to create a new curve with an extended domain.

§Arguments
  • curve_2d some type that implements the Curve trait and samples Vec2s
  • times some iterable type yielding f32 which will be used for sampling the curve
  • color the color of the curve
§Example
fn system(mut gizmos: Gizmos) {
    let domain = Interval::UNIT;
    let curve = FunctionCurve::new(domain, |t| Vec2::from(t.sin_cos()));
    gizmos.curve_2d(curve, (0..=100).map(|n| n as f32 / 100.0), RED);
}
Examples found in repository?
examples/animation/easing_functions.rs (lines 167-171)
129fn display_curves(
130    mut gizmos: Gizmos,
131    ease_functions: Query<(&EaseFunctionPlot, &Transform, &Children)>,
132    mut transforms: Query<&mut Transform, Without<EaseFunctionPlot>>,
133    mut ui_text: Single<&mut Text>,
134    time: Res<Time>,
135) {
136    let samples = 100;
137    let duration = 2.5;
138    let time_margin = 0.5;
139
140    let now = ((time.elapsed_secs() % (duration + time_margin * 2.0) - time_margin) / duration)
141        .clamp(0.0, 1.0);
142
143    ui_text.0 = format!("Progress: {:.2}", now);
144
145    for (EaseFunctionPlot(function, color), transform, children) in &ease_functions {
146        let center = transform.translation.xy();
147        let half_size = PLOT_SIZE / 2.0;
148
149        // Draw a box around the curve
150        gizmos.linestrip_2d(
151            [
152                center + half_size,
153                center + half_size * Vec2::new(-1., 1.),
154                center + half_size * Vec2::new(-1., -1.),
155                center + half_size * Vec2::new(1., -1.),
156                center + half_size,
157            ],
158            color.darker(0.4),
159        );
160
161        // Draw the curve
162        let f = EasingCurve::new(0.0, 1.0, *function);
163        let drawn_curve = f
164            .by_ref()
165            .graph()
166            .map(|(x, y)| center - half_size + Vec2::new(x, y) * PLOT_SIZE);
167        gizmos.curve_2d(
168            &drawn_curve,
169            drawn_curve.domain().spaced_points(samples).unwrap(),
170            *color,
171        );
172
173        // Show progress along the curve for the current time
174        let y = f.sample(now).unwrap() * PLOT_SIZE.y;
175        transforms.get_mut(children[0]).unwrap().translation.y = -half_size.y + y;
176        transforms.get_mut(children[1]).unwrap().translation =
177            -half_size.extend(0.0) + Vec3::new(now * PLOT_SIZE.x, y, 0.0);
178
179        // Show horizontal bar at y value
180        gizmos.linestrip_2d(
181            [
182                center - half_size + Vec2::Y * y,
183                center - half_size + Vec2::new(PLOT_SIZE.x, y),
184            ],
185            color.darker(0.2),
186        );
187    }
188}
Source

pub fn curve_3d( &mut self, curve_3d: impl Curve<Vec3>, times: impl IntoIterator<Item = f32>, color: impl Into<Color>, )

Draw a curve, at the given time points, sampling in 3D.

This should be called for each frame the curve needs to be rendered.

Samples of time points outside of the curve’s domain will be filtered out and won’t contribute to the rendering. If you wish to render the curve outside of its domain you need to create a new curve with an extended domain.

§Arguments
  • curve_3d some type that implements the Curve trait and samples Vec3s
  • times some iterable type yielding f32 which will be used for sampling the curve
  • color the color of the curve
§Example
fn system(mut gizmos: Gizmos) {
    let domain = Interval::UNIT;
    let curve = FunctionCurve::new(domain, |t| {
        let (x,y) = t.sin_cos();
        Vec3::new(x, y, t)
    });
    gizmos.curve_3d(curve, (0..=100).map(|n| n as f32 / 100.0), RED);
}
Source

pub fn curve_gradient_2d<C>( &mut self, curve_2d: impl Curve<Vec2>, times_with_colors: impl IntoIterator<Item = (f32, C)>, )
where C: Into<Color>,

Draw a curve, at the given time points, sampling in 2D, with a color gradient.

This should be called for each frame the curve needs to be rendered.

Samples of time points outside of the curve’s domain will be filtered out and won’t contribute to the rendering. If you wish to render the curve outside of its domain you need to create a new curve with an extended domain.

§Arguments
  • curve_2d some type that implements the Curve trait and samples Vec2s
  • times_with_colors some iterable type yielding f32 which will be used for sampling the curve together with the color at this position
§Example
fn system(mut gizmos: Gizmos) {
    let domain = Interval::UNIT;
    let curve = FunctionCurve::new(domain, |t| Vec2::from(t.sin_cos()));
    gizmos.curve_gradient_2d(
        curve,
        (0..=100).map(|n| n as f32 / 100.0)
                 .map(|t| (t, GREEN.mix(&RED, t)))
    );
}
Examples found in repository?
examples/gizmos/2d_gizmos.rs (line 78)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn curve_gradient_3d<C>( &mut self, curve_3d: impl Curve<Vec3>, times_with_colors: impl IntoIterator<Item = (f32, C)>, )
where C: Into<Color>,

Draw a curve, at the given time points, sampling in 3D, with a color gradient.

This should be called for each frame the curve needs to be rendered.

Samples of time points outside of the curve’s domain will be filtered out and won’t contribute to the rendering. If you wish to render the curve outside of its domain you need to create a new curve with an extended domain.

§Arguments
  • curve_3d some type that implements the Curve trait and samples Vec3s
  • times_with_colors some iterable type yielding f32 which will be used for sampling the curve together with the color at this position
§Example
fn system(mut gizmos: Gizmos) {
    let domain = Interval::UNIT;
    let curve = FunctionCurve::new(domain, |t| {
        let (x,y) = t.sin_cos();
        Vec3::new(x, y, t)
    });
    gizmos.curve_gradient_3d(
        curve,
        (0..=100).map(|n| n as f32 / 100.0)
                 .map(|t| (t, GREEN.mix(&RED, t)))
    );
}
Examples found in repository?
examples/gizmos/3d_gizmos.rs (line 157)
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}
Source

pub fn clear(&mut self)

Clear all data.

Source

pub fn buffer(&self) -> GizmoBufferView<'_>

Read-only view into the buffers data.

Source

pub fn line(&mut self, start: Vec3, end: Vec3, color: impl Into<Color>)

Draw a line in 3D from start to end.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.line(Vec3::ZERO, Vec3::X, GREEN);
}
Examples found in repository?
examples/stress_tests/many_gizmos.rs (line 68)
65fn system(config: Res<Config>, time: Res<Time>, mut draw: Gizmos) {
66    if !config.fancy {
67        for _ in 0..(config.line_count / SYSTEM_COUNT) {
68            draw.line(Vec3::NEG_Y, Vec3::Y, Color::BLACK);
69        }
70    } else {
71        for i in 0..(config.line_count / SYSTEM_COUNT) {
72            let angle = i as f32 / (config.line_count / SYSTEM_COUNT) as f32 * TAU;
73
74            let vector = Vec2::from(ops::sin_cos(angle)).extend(ops::sin(time.elapsed_secs()));
75            let start_color = LinearRgba::rgb(vector.x, vector.z, 0.5);
76            let end_color = LinearRgba::rgb(-vector.z, -vector.y, 0.5);
77
78            draw.line_gradient(vector, -vector, start_color, end_color);
79        }
80    }
81}
Source

pub fn line_gradient<C>( &mut self, start: Vec3, end: Vec3, start_color: C, end_color: C, )
where C: Into<Color>,

Draw a line in 3D with a color gradient from start to end.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.line_gradient(Vec3::ZERO, Vec3::X, GREEN, RED);
}
Examples found in repository?
examples/stress_tests/many_gizmos.rs (line 78)
65fn system(config: Res<Config>, time: Res<Time>, mut draw: Gizmos) {
66    if !config.fancy {
67        for _ in 0..(config.line_count / SYSTEM_COUNT) {
68            draw.line(Vec3::NEG_Y, Vec3::Y, Color::BLACK);
69        }
70    } else {
71        for i in 0..(config.line_count / SYSTEM_COUNT) {
72            let angle = i as f32 / (config.line_count / SYSTEM_COUNT) as f32 * TAU;
73
74            let vector = Vec2::from(ops::sin_cos(angle)).extend(ops::sin(time.elapsed_secs()));
75            let start_color = LinearRgba::rgb(vector.x, vector.z, 0.5);
76            let end_color = LinearRgba::rgb(-vector.z, -vector.y, 0.5);
77
78            draw.line_gradient(vector, -vector, start_color, end_color);
79        }
80    }
81}
Source

pub fn ray(&mut self, start: Vec3, vector: Vec3, color: impl Into<Color>)

Draw a line in 3D from start to start + vector.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.ray(Vec3::Y, Vec3::X, GREEN);
}
Examples found in repository?
examples/gizmos/3d_gizmos.rs (lines 167-171)
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}
Source

pub fn ray_gradient<C>( &mut self, start: Vec3, vector: Vec3, start_color: C, end_color: C, )
where C: Into<Color>,

Draw a line in 3D with a color gradient from start to start + vector.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.ray_gradient(Vec3::Y, Vec3::X, GREEN, RED);
}
Source

pub fn linestrip( &mut self, positions: impl IntoIterator<Item = Vec3>, color: impl Into<Color>, )

Draw a line in 3D made of straight segments between the points.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.linestrip([Vec3::ZERO, Vec3::X, Vec3::Y], GREEN);
}
Examples found in repository?
examples/math/cubic_splines.rs (lines 175-178)
169fn draw_curve(curve: Res<Curve>, mut gizmos: Gizmos) {
170    let Some(ref curve) = curve.0 else {
171        return;
172    };
173    // Scale resolution with curve length so it doesn't degrade as the length increases.
174    let resolution = 100 * curve.segments().len();
175    gizmos.linestrip(
176        curve.iter_positions(resolution).map(|pt| pt.extend(0.0)),
177        Color::srgb(1.0, 1.0, 1.0),
178    );
179}
Source

pub fn linestrip_gradient<C>( &mut self, points: impl IntoIterator<Item = (Vec3, C)>, )
where C: Into<Color>,

Draw a line in 3D made of straight segments between the points, with a color gradient.

This should be called for each frame the lines need to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.linestrip_gradient([
        (Vec3::ZERO, GREEN),
        (Vec3::X, RED),
        (Vec3::Y, BLUE)
    ]);
}
Examples found in repository?
examples/3d/mesh_ray_cast.rs (line 70)
48fn bounce_ray(mut ray: Ray3d, ray_cast: &mut MeshRayCast, gizmos: &mut Gizmos, color: Color) {
49    let mut intersections = Vec::with_capacity(MAX_BOUNCES + 1);
50    intersections.push((ray.origin, Color::srgb(30.0, 0.0, 0.0)));
51
52    for i in 0..MAX_BOUNCES {
53        // Cast the ray and get the first hit
54        let Some((_, hit)) = ray_cast
55            .cast_ray(ray, &MeshRayCastSettings::default())
56            .first()
57        else {
58            break;
59        };
60
61        // Draw the point of intersection and add it to the list
62        let brightness = 1.0 + 10.0 * (1.0 - i as f32 / MAX_BOUNCES as f32);
63        intersections.push((hit.point, Color::BLACK.mix(&color, brightness)));
64        gizmos.sphere(hit.point, 0.005, Color::BLACK.mix(&color, brightness * 2.0));
65
66        // Reflect the ray off of the surface
67        ray.direction = Dir3::new(ray.direction.reflect(hit.normal)).unwrap();
68        ray.origin = hit.point + ray.direction * 1e-6;
69    }
70    gizmos.linestrip_gradient(intersections);
71}
Source

pub fn rect( &mut self, isometry: impl Into<Isometry3d>, size: Vec2, color: impl Into<Color>, )

Draw a wireframe rectangle in 3D with the given isometry applied.

If isometry == Isometry3d::IDENTITY then

  • the center is at Vec3::ZERO
  • the sizes are aligned with the Vec3::X and Vec3::Y axes.

This should be called for each frame the rectangle needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.rect(Isometry3d::IDENTITY, Vec2::ONE, GREEN);
}
Examples found in repository?
examples/gizmos/3d_gizmos.rs (lines 137-144)
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}
Source

pub fn cuboid( &mut self, transform: impl TransformPoint, color: impl Into<Color>, )

Draw a wireframe cube in 3D.

This should be called for each frame the cube needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.cuboid(Transform::IDENTITY, GREEN);
}
Examples found in repository?
examples/3d/irradiance_volumes.rs (line 605)
598fn draw_gizmo(
599    mut gizmos: Gizmos,
600    irradiance_volume_query: Query<&GlobalTransform, With<IrradianceVolume>>,
601    app_status: Res<AppStatus>,
602) {
603    if app_status.voxels_visible {
604        for transform in irradiance_volume_query.iter() {
605            gizmos.cuboid(*transform, GIZMO_COLOR);
606        }
607    }
608}
More examples
Hide additional examples
examples/testbed/3d.rs (lines 318-321)
317    pub fn draw_gizmos(mut gizmos: Gizmos) {
318        gizmos.cuboid(
319            Transform::from_translation(Vec3::X * 2.0).with_scale(Vec3::splat(2.0)),
320            RED,
321        );
322        gizmos
323            .sphere(Isometry3d::from_translation(Vec3::X * -2.0), 1.0, GREEN)
324            .resolution(30_000 / 3);
325    }
examples/gizmos/3d_gizmos.rs (lines 133-136)
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}
Source

pub fn line_2d(&mut self, start: Vec2, end: Vec2, color: impl Into<Color>)

Draw a line in 2D from start to end.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.line_2d(Vec2::ZERO, Vec2::X, GREEN);
}
Examples found in repository?
examples/math/bounding_2d.rs (lines 277-281)
276fn draw_ray(gizmos: &mut Gizmos, ray: &RayCast2d) {
277    gizmos.line_2d(
278        ray.ray.origin,
279        ray.ray.origin + *ray.ray.direction * ray.max,
280        WHITE,
281    );
282    draw_filled_circle(gizmos, ray.ray.origin, FUCHSIA);
283}
More examples
Hide additional examples
examples/gizmos/2d_gizmos.rs (line 46)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn line_gradient_2d<C>( &mut self, start: Vec2, end: Vec2, start_color: C, end_color: C, )
where C: Into<Color>,

Draw a line in 2D with a color gradient from start to end.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.line_gradient_2d(Vec2::ZERO, Vec2::X, GREEN, RED);
}
Source

pub fn linestrip_2d( &mut self, positions: impl IntoIterator<Item = Vec2>, color: impl Into<Color>, )

Draw a line in 2D made of straight segments between the points.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.linestrip_2d([Vec2::ZERO, Vec2::X, Vec2::Y], GREEN);
}
Examples found in repository?
examples/animation/easing_functions.rs (lines 150-159)
129fn display_curves(
130    mut gizmos: Gizmos,
131    ease_functions: Query<(&EaseFunctionPlot, &Transform, &Children)>,
132    mut transforms: Query<&mut Transform, Without<EaseFunctionPlot>>,
133    mut ui_text: Single<&mut Text>,
134    time: Res<Time>,
135) {
136    let samples = 100;
137    let duration = 2.5;
138    let time_margin = 0.5;
139
140    let now = ((time.elapsed_secs() % (duration + time_margin * 2.0) - time_margin) / duration)
141        .clamp(0.0, 1.0);
142
143    ui_text.0 = format!("Progress: {:.2}", now);
144
145    for (EaseFunctionPlot(function, color), transform, children) in &ease_functions {
146        let center = transform.translation.xy();
147        let half_size = PLOT_SIZE / 2.0;
148
149        // Draw a box around the curve
150        gizmos.linestrip_2d(
151            [
152                center + half_size,
153                center + half_size * Vec2::new(-1., 1.),
154                center + half_size * Vec2::new(-1., -1.),
155                center + half_size * Vec2::new(1., -1.),
156                center + half_size,
157            ],
158            color.darker(0.4),
159        );
160
161        // Draw the curve
162        let f = EasingCurve::new(0.0, 1.0, *function);
163        let drawn_curve = f
164            .by_ref()
165            .graph()
166            .map(|(x, y)| center - half_size + Vec2::new(x, y) * PLOT_SIZE);
167        gizmos.curve_2d(
168            &drawn_curve,
169            drawn_curve.domain().spaced_points(samples).unwrap(),
170            *color,
171        );
172
173        // Show progress along the curve for the current time
174        let y = f.sample(now).unwrap() * PLOT_SIZE.y;
175        transforms.get_mut(children[0]).unwrap().translation.y = -half_size.y + y;
176        transforms.get_mut(children[1]).unwrap().translation =
177            -half_size.extend(0.0) + Vec3::new(now * PLOT_SIZE.x, y, 0.0);
178
179        // Show horizontal bar at y value
180        gizmos.linestrip_2d(
181            [
182                center - half_size + Vec2::Y * y,
183                center - half_size + Vec2::new(PLOT_SIZE.x, y),
184            ],
185            color.darker(0.2),
186        );
187    }
188}
Source

pub fn linestrip_gradient_2d<C>( &mut self, positions: impl IntoIterator<Item = (Vec2, C)>, )
where C: Into<Color>,

Draw a line in 2D made of straight segments between the points, with a color gradient.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.linestrip_gradient_2d([
        (Vec2::ZERO, GREEN),
        (Vec2::X, RED),
        (Vec2::Y, BLUE)
    ]);
}
Examples found in repository?
examples/gizmos/2d_gizmos.rs (lines 60-65)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn ray_2d(&mut self, start: Vec2, vector: Vec2, color: impl Into<Color>)

Draw a line in 2D from start to start + vector.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.ray_2d(Vec2::Y, Vec2::X, GREEN);
}
Examples found in repository?
examples/gizmos/2d_gizmos.rs (line 47)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn ray_gradient_2d<C>( &mut self, start: Vec2, vector: Vec2, start_color: C, end_color: C, )
where C: Into<Color>,

Draw a line in 2D with a color gradient from start to start + vector.

This should be called for each frame the line needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.line_gradient(Vec3::Y, Vec3::X, GREEN, RED);
}
Source

pub fn rect_2d( &mut self, isometry: impl Into<Isometry2d>, size: Vec2, color: impl Into<Color>, )

Draw a wireframe rectangle in 2D with the given isometry applied.

If isometry == Isometry2d::IDENTITY then

  • the center is at Vec2::ZERO
  • the sizes are aligned with the Vec2::X and Vec2::Y axes.

This should be called for each frame the rectangle needs to be rendered.

§Example
fn system(mut gizmos: Gizmos) {
    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::ONE, GREEN);
}
Examples found in repository?
examples/testbed/2d.rs (line 281)
280    pub fn draw_gizmos(mut gizmos: Gizmos) {
281        gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::new(200.0, 200.0), RED);
282        gizmos
283            .circle_2d(Isometry2d::IDENTITY, 200.0, GREEN)
284            .resolution(64);
285    }
More examples
Hide additional examples
examples/math/bounding_2d.rs (line 187)
182fn render_volumes(mut gizmos: Gizmos, query: Query<(&CurrentVolume, &Intersects)>) {
183    for (volume, intersects) in query.iter() {
184        let color = if **intersects { AQUA } else { ORANGE_RED };
185        match volume {
186            CurrentVolume::Aabb(a) => {
187                gizmos.rect_2d(a.center(), a.half_size() * 2., color);
188            }
189            CurrentVolume::Circle(c) => {
190                gizmos.circle_2d(c.center(), c.radius(), color);
191            }
192        }
193    }
194}
195
196#[derive(Component, Deref, DerefMut, Default)]
197struct Intersects(bool);
198
199const OFFSET_X: f32 = 125.;
200const OFFSET_Y: f32 = 75.;
201
202fn setup(mut commands: Commands) {
203    commands.spawn(Camera2d);
204
205    commands.spawn((
206        Transform::from_xyz(-OFFSET_X, OFFSET_Y, 0.),
207        Shape::Circle(Circle::new(45.)),
208        DesiredVolume::Aabb,
209        Intersects::default(),
210    ));
211
212    commands.spawn((
213        Transform::from_xyz(0., OFFSET_Y, 0.),
214        Shape::Rectangle(Rectangle::new(80., 80.)),
215        Spin,
216        DesiredVolume::Circle,
217        Intersects::default(),
218    ));
219
220    commands.spawn((
221        Transform::from_xyz(OFFSET_X, OFFSET_Y, 0.),
222        Shape::Triangle(Triangle2d::new(
223            Vec2::new(-40., -40.),
224            Vec2::new(-20., 40.),
225            Vec2::new(40., 50.),
226        )),
227        Spin,
228        DesiredVolume::Aabb,
229        Intersects::default(),
230    ));
231
232    commands.spawn((
233        Transform::from_xyz(-OFFSET_X, -OFFSET_Y, 0.),
234        Shape::Line(Segment2d::from_direction_and_length(
235            Dir2::from_xy(1., 0.3).unwrap(),
236            90.,
237        )),
238        Spin,
239        DesiredVolume::Circle,
240        Intersects::default(),
241    ));
242
243    commands.spawn((
244        Transform::from_xyz(0., -OFFSET_Y, 0.),
245        Shape::Capsule(Capsule2d::new(25., 50.)),
246        Spin,
247        DesiredVolume::Aabb,
248        Intersects::default(),
249    ));
250
251    commands.spawn((
252        Transform::from_xyz(OFFSET_X, -OFFSET_Y, 0.),
253        Shape::Polygon(RegularPolygon::new(50., 6)),
254        Spin,
255        DesiredVolume::Circle,
256        Intersects::default(),
257    ));
258
259    commands.spawn((
260        Text::default(),
261        Node {
262            position_type: PositionType::Absolute,
263            top: Val::Px(12.0),
264            left: Val::Px(12.0),
265            ..default()
266        },
267    ));
268}
269
270fn draw_filled_circle(gizmos: &mut Gizmos, position: Vec2, color: Srgba) {
271    for r in [1., 2., 3.] {
272        gizmos.circle_2d(position, r, color);
273    }
274}
275
276fn draw_ray(gizmos: &mut Gizmos, ray: &RayCast2d) {
277    gizmos.line_2d(
278        ray.ray.origin,
279        ray.ray.origin + *ray.ray.direction * ray.max,
280        WHITE,
281    );
282    draw_filled_circle(gizmos, ray.ray.origin, FUCHSIA);
283}
284
285fn get_and_draw_ray(gizmos: &mut Gizmos, time: &Time) -> RayCast2d {
286    let ray = Vec2::new(ops::cos(time.elapsed_secs()), ops::sin(time.elapsed_secs()));
287    let dist = 150. + ops::sin(0.5 * time.elapsed_secs()).abs() * 500.;
288
289    let aabb_ray = Ray2d {
290        origin: ray * 250.,
291        direction: Dir2::new_unchecked(-ray),
292    };
293    let ray_cast = RayCast2d::from_ray(aabb_ray, dist - 20.);
294
295    draw_ray(gizmos, &ray_cast);
296    ray_cast
297}
298
299fn ray_cast_system(
300    mut gizmos: Gizmos,
301    time: Res<Time>,
302    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
303) {
304    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
305
306    for (volume, mut intersects) in volumes.iter_mut() {
307        let toi = match volume {
308            CurrentVolume::Aabb(a) => ray_cast.aabb_intersection_at(a),
309            CurrentVolume::Circle(c) => ray_cast.circle_intersection_at(c),
310        };
311        **intersects = toi.is_some();
312        if let Some(toi) = toi {
313            draw_filled_circle(
314                &mut gizmos,
315                ray_cast.ray.origin + *ray_cast.ray.direction * toi,
316                LIME,
317            );
318        }
319    }
320}
321
322fn aabb_cast_system(
323    mut gizmos: Gizmos,
324    time: Res<Time>,
325    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
326) {
327    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
328    let aabb_cast = AabbCast2d {
329        aabb: Aabb2d::new(Vec2::ZERO, Vec2::splat(15.)),
330        ray: ray_cast,
331    };
332
333    for (volume, mut intersects) in volumes.iter_mut() {
334        let toi = match *volume {
335            CurrentVolume::Aabb(a) => aabb_cast.aabb_collision_at(a),
336            CurrentVolume::Circle(_) => None,
337        };
338
339        **intersects = toi.is_some();
340        if let Some(toi) = toi {
341            gizmos.rect_2d(
342                aabb_cast.ray.ray.origin + *aabb_cast.ray.ray.direction * toi,
343                aabb_cast.aabb.half_size() * 2.,
344                LIME,
345            );
346        }
347    }
348}
349
350fn bounding_circle_cast_system(
351    mut gizmos: Gizmos,
352    time: Res<Time>,
353    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
354) {
355    let ray_cast = get_and_draw_ray(&mut gizmos, &time);
356    let circle_cast = BoundingCircleCast {
357        circle: BoundingCircle::new(Vec2::ZERO, 15.),
358        ray: ray_cast,
359    };
360
361    for (volume, mut intersects) in volumes.iter_mut() {
362        let toi = match *volume {
363            CurrentVolume::Aabb(_) => None,
364            CurrentVolume::Circle(c) => circle_cast.circle_collision_at(c),
365        };
366
367        **intersects = toi.is_some();
368        if let Some(toi) = toi {
369            gizmos.circle_2d(
370                circle_cast.ray.ray.origin + *circle_cast.ray.ray.direction * toi,
371                circle_cast.circle.radius(),
372                LIME,
373            );
374        }
375    }
376}
377
378fn get_intersection_position(time: &Time) -> Vec2 {
379    let x = ops::cos(0.8 * time.elapsed_secs()) * 250.;
380    let y = ops::sin(0.4 * time.elapsed_secs()) * 100.;
381    Vec2::new(x, y)
382}
383
384fn aabb_intersection_system(
385    mut gizmos: Gizmos,
386    time: Res<Time>,
387    mut volumes: Query<(&CurrentVolume, &mut Intersects)>,
388) {
389    let center = get_intersection_position(&time);
390    let aabb = Aabb2d::new(center, Vec2::splat(50.));
391    gizmos.rect_2d(center, aabb.half_size() * 2., YELLOW);
392
393    for (volume, mut intersects) in volumes.iter_mut() {
394        let hit = match volume {
395            CurrentVolume::Aabb(a) => aabb.intersects(a),
396            CurrentVolume::Circle(c) => aabb.intersects(c),
397        };
398
399        **intersects = hit;
400    }
401}
examples/2d/mesh2d_arcs.rs (line 115)
104fn draw_bounds<Shape: Bounded2d + Send + Sync + 'static>(
105    q: Query<(&DrawBounds<Shape>, &GlobalTransform)>,
106    mut gizmos: Gizmos,
107) {
108    for (shape, transform) in &q {
109        let (_, rotation, translation) = transform.to_scale_rotation_translation();
110        let translation = translation.truncate();
111        let rotation = rotation.to_euler(EulerRot::XYZ).2;
112        let isometry = Isometry2d::new(translation, Rot2::radians(rotation));
113
114        let aabb = shape.0.aabb_2d(isometry);
115        gizmos.rect_2d(aabb.center(), aabb.half_size() * 2.0, RED);
116
117        let bounding_circle = shape.0.bounding_circle(isometry);
118        gizmos.circle_2d(bounding_circle.center, bounding_circle.radius(), BLUE);
119    }
120}
examples/math/custom_primitives.rs (line 198)
182fn bounding_shapes_2d(
183    shapes: Query<&Transform, With<Shape2d>>,
184    mut gizmos: Gizmos,
185    bounding_shape: Res<State<BoundingShape>>,
186) {
187    for transform in shapes.iter() {
188        // Get the rotation angle from the 3D rotation.
189        let rotation = transform.rotation.to_scaled_axis().z;
190        let rotation = Rot2::radians(rotation);
191        let isometry = Isometry2d::new(transform.translation.xy(), rotation);
192
193        match bounding_shape.get() {
194            BoundingShape::None => (),
195            BoundingShape::BoundingBox => {
196                // Get the AABB of the primitive with the rotation and translation of the mesh.
197                let aabb = HEART.aabb_2d(isometry);
198                gizmos.rect_2d(aabb.center(), aabb.half_size() * 2., WHITE);
199            }
200            BoundingShape::BoundingSphere => {
201                // Get the bounding sphere of the primitive with the rotation and translation of the mesh.
202                let bounding_circle = HEART.bounding_circle(isometry);
203                gizmos
204                    .circle_2d(bounding_circle.center(), bounding_circle.radius(), WHITE)
205                    .resolution(64);
206            }
207        }
208    }
209}
examples/gizmos/2d_gizmos.rs (line 67)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn grid( &mut self, isometry: impl Into<Isometry3d>, cell_count: UVec2, spacing: Vec2, color: impl Into<Color>, ) -> GridBuilder2d<'_, Config, Clear>

Draw a 2D grid in 3D.

This should be called for each frame the grid needs to be rendered.

The grid’s default orientation aligns with the XY-plane.

§Arguments
  • isometry defines the translation and rotation of the grid.
    • the translation specifies the center of the grid
    • defines the orientation of the grid, by default we assume the grid is contained in a plane parallel to the XY plane
  • cell_count: defines the amount of cells in the x and y axes
  • spacing: defines the distance between cells along the x and y axes
  • color: color of the grid
§Builder methods
  • The skew of the grid can be adjusted using the .skew(...), .skew_x(...) or .skew_y(...) methods. They behave very similar to their CSS equivalents.
  • All outer edges can be toggled on or off using .outer_edges(...). Alternatively you can use .outer_edges_x(...) or .outer_edges_y(...) to toggle the outer edges along an axis.
§Example
fn system(mut gizmos: Gizmos) {
    gizmos.grid(
        Isometry3d::IDENTITY,
        UVec2::new(10, 10),
        Vec2::splat(2.),
        GREEN
        )
        .skew_x(0.25)
        .outer_edges();
}
Examples found in repository?
examples/gizmos/3d_gizmos.rs (lines 103-109)
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}
Source

pub fn grid_3d( &mut self, isometry: impl Into<Isometry3d>, cell_count: UVec3, spacing: Vec3, color: impl Into<Color>, ) -> GridBuilder3d<'_, Config, Clear>

Draw a 3D grid of voxel-like cells.

This should be called for each frame the grid needs to be rendered.

§Arguments
  • isometry defines the translation and rotation of the grid.
    • the translation specifies the center of the grid
    • defines the orientation of the grid, by default we assume the grid is aligned with all axes
  • cell_count: defines the amount of cells in the x, y and z axes
  • spacing: defines the distance between cells along the x, y and z axes
  • color: color of the grid
§Builder methods
  • The skew of the grid can be adjusted using the .skew(...), .skew_x(...), .skew_y(...) or .skew_z(...) methods. They behave very similar to their CSS equivalents.
  • All outer edges can be toggled on or off using .outer_edges(...). Alternatively you can use .outer_edges_x(...), .outer_edges_y(...) or .outer_edges_z(...) to toggle the outer edges along an axis.
§Example
fn system(mut gizmos: Gizmos) {
    gizmos.grid_3d(
        Isometry3d::IDENTITY,
        UVec3::new(10, 2, 10),
        Vec3::splat(2.),
        GREEN
        )
        .skew_x(0.25)
        .outer_edges();
}
Source

pub fn grid_2d( &mut self, isometry: impl Into<Isometry2d>, cell_count: UVec2, spacing: Vec2, color: impl Into<Color>, ) -> GridBuilder2d<'_, Config, Clear>

Draw a grid in 2D.

This should be called for each frame the grid needs to be rendered.

§Arguments
  • isometry defines the translation and rotation of the grid.
    • the translation specifies the center of the grid
    • defines the orientation of the grid, by default we assume the grid is aligned with all axes
  • cell_count: defines the amount of cells in the x and y axes
  • spacing: defines the distance between cells along the x and y axes
  • color: color of the grid
§Builder methods
  • The skew of the grid can be adjusted using the .skew(...), .skew_x(...) or .skew_y(...) methods. They behave very similar to their CSS equivalents.
  • All outer edges can be toggled on or off using .outer_edges(...). Alternatively you can use .outer_edges_x(...) or .outer_edges_y(...) to toggle the outer edges along an axis.
§Example
fn system(mut gizmos: Gizmos) {
    gizmos.grid_2d(
        Isometry2d::IDENTITY,
        UVec2::new(10, 10),
        Vec2::splat(1.),
        GREEN
        )
        .skew_x(0.25)
        .outer_edges();
}
Examples found in repository?
examples/gizmos/2d_gizmos.rs (lines 50-56)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn rounded_rect( &mut self, isometry: impl Into<Isometry3d>, size: Vec2, color: impl Into<Color>, ) -> RoundedRectBuilder<'_, Config, Clear>

Draw a wireframe rectangle with rounded corners in 3D.

This should be called for each frame the rectangle needs to be rendered.

§Arguments
  • isometry defines the translation and rotation of the rectangle.
    • the translation specifies the center of the rectangle
    • defines orientation of the rectangle, by default we assume the rectangle is contained in a plane parallel to the XY plane.
  • size: defines the size of the rectangle. This refers to the ‘outer size’, similar to a bounding box.
  • color: color of the rectangle
§Builder methods
  • The corner radius can be adjusted with the .corner_radius(...) method.
  • The resolution of the arcs at each corner (i.e. the level of detail) can be adjusted with the .arc_resolution(...) method.
§Example
fn system(mut gizmos: Gizmos) {
    gizmos.rounded_rect(
        Isometry3d::IDENTITY,
        Vec2::ONE,
        GREEN
        )
        .corner_radius(0.25)
        .arc_resolution(10);
}
Source

pub fn rounded_rect_2d( &mut self, isometry: impl Into<Isometry2d>, size: Vec2, color: impl Into<Color>, ) -> RoundedRectBuilder<'_, Config, Clear>

Draw a wireframe rectangle with rounded corners in 2D.

This should be called for each frame the rectangle needs to be rendered.

§Arguments
  • isometry defines the translation and rotation of the rectangle.
    • the translation specifies the center of the rectangle
    • defines orientation of the rectangle, by default we assume the rectangle aligned with all axes.
  • size: defines the size of the rectangle. This refers to the ‘outer size’, similar to a bounding box.
  • color: color of the rectangle
§Builder methods
  • The corner radius can be adjusted with the .corner_radius(...) method.
  • The resolution of the arcs at each corner (i.e. the level of detail) can be adjusted with the .arc_resolution(...) method.
§Example
fn system(mut gizmos: Gizmos) {
    gizmos.rounded_rect_2d(
        Isometry2d::IDENTITY,
        Vec2::ONE,
        GREEN
        )
        .corner_radius(0.25)
        .arc_resolution(10);
}
Examples found in repository?
examples/gizmos/2d_gizmos.rs (line 81)
40fn draw_example_collection(
41    mut gizmos: Gizmos,
42    mut my_gizmos: Gizmos<MyRoundGizmos>,
43    time: Res<Time>,
44) {
45    let sin_t_scaled = ops::sin(time.elapsed_secs()) * 50.;
46    gizmos.line_2d(Vec2::Y * -sin_t_scaled, Vec2::splat(-80.), RED);
47    gizmos.ray_2d(Vec2::Y * sin_t_scaled, Vec2::splat(80.), LIME);
48
49    gizmos
50        .grid_2d(
51            Isometry2d::IDENTITY,
52            UVec2::new(16, 9),
53            Vec2::new(80., 80.),
54            // Dark gray
55            LinearRgba::gray(0.05),
56        )
57        .outer_edges();
58
59    // Triangle
60    gizmos.linestrip_gradient_2d([
61        (Vec2::Y * 300., BLUE),
62        (Vec2::new(-255., -155.), RED),
63        (Vec2::new(255., -155.), LIME),
64        (Vec2::Y * 300., BLUE),
65    ]);
66
67    gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::splat(650.), BLACK);
68
69    gizmos.cross_2d(Vec2::new(-160., 120.), 12., FUCHSIA);
70
71    let domain = Interval::EVERYWHERE;
72    let curve = FunctionCurve::new(domain, |t| Vec2::new(t, ops::sin(t / 25.0) * 100.0));
73    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 50.0) as usize;
74    let times_and_colors = (0..=resolution)
75        .map(|n| n as f32 / resolution as f32)
76        .map(|t| (t - 0.5) * 600.0)
77        .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0)));
78    gizmos.curve_gradient_2d(curve, times_and_colors);
79
80    my_gizmos
81        .rounded_rect_2d(Isometry2d::IDENTITY, Vec2::splat(630.), BLACK)
82        .corner_radius(ops::cos(time.elapsed_secs() / 3.) * 100.);
83
84    // Circles have 32 line-segments by default.
85    // You may want to increase this for larger circles.
86    my_gizmos
87        .circle_2d(Isometry2d::IDENTITY, 300., NAVY)
88        .resolution(64);
89
90    my_gizmos.ellipse_2d(
91        Rot2::radians(time.elapsed_secs() % TAU),
92        Vec2::new(100., 200.),
93        YELLOW_GREEN,
94    );
95
96    // Arcs default resolution is linearly interpolated between
97    // 1 and 32, using the arc length as scalar.
98    my_gizmos.arc_2d(
99        Rot2::radians(sin_t_scaled / 10.),
100        FRAC_PI_2,
101        310.,
102        ORANGE_RED,
103    );
104    my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 80.0, ORANGE_RED);
105    my_gizmos.long_arc_2d_between(Vec2::ZERO, Vec2::X * 20.0, Vec2::Y * 20.0, ORANGE_RED);
106    my_gizmos.short_arc_2d_between(Vec2::ZERO, Vec2::X * 40.0, Vec2::Y * 40.0, ORANGE_RED);
107
108    gizmos.arrow_2d(
109        Vec2::ZERO,
110        Vec2::from_angle(sin_t_scaled / -10. + PI / 2.) * 50.,
111        YELLOW,
112    );
113
114    // You can create more complex arrows using the arrow builder.
115    gizmos
116        .arrow_2d(
117            Vec2::ZERO,
118            Vec2::from_angle(sin_t_scaled / -10.) * 50.,
119            GREEN,
120        )
121        .with_double_end()
122        .with_tip_length(10.);
123}
Source

pub fn rounded_cuboid( &mut self, isometry: impl Into<Isometry3d>, size: Vec3, color: impl Into<Color>, ) -> RoundedCuboidBuilder<'_, Config, Clear>

Draw a wireframe cuboid with rounded corners in 3D.

This should be called for each frame the cuboid needs to be rendered.

§Arguments
  • isometry defines the translation and rotation of the cuboid.
    • the translation specifies the center of the cuboid
    • defines orientation of the cuboid, by default we assume the cuboid aligned with all axes.
  • size: defines the size of the cuboid. This refers to the ‘outer size’, similar to a bounding box.
  • color: color of the cuboid
§Builder methods
  • The edge radius can be adjusted with the .edge_radius(...) method.
  • The resolution of the arcs at each edge (i.e. the level of detail) can be adjusted with the .arc_resolution(...) method.
§Example
fn system(mut gizmos: Gizmos) {
    gizmos.rounded_cuboid(
        Isometry3d::IDENTITY,
        Vec3::ONE,
        GREEN
        )
        .edge_radius(0.25)
        .arc_resolution(10);
}
Examples found in repository?
examples/gizmos/3d_gizmos.rs (line 162)
98fn draw_example_collection(
99    mut gizmos: Gizmos,
100    mut my_gizmos: Gizmos<MyRoundGizmos>,
101    time: Res<Time>,
102) {
103    gizmos.grid(
104        Quat::from_rotation_x(PI / 2.),
105        UVec2::splat(20),
106        Vec2::new(2., 2.),
107        // Light gray
108        LinearRgba::gray(0.65),
109    );
110    gizmos.grid(
111        Isometry3d::new(Vec3::splat(10.0), Quat::from_rotation_x(PI / 3. * 2.)),
112        UVec2::splat(20),
113        Vec2::new(2., 2.),
114        PURPLE,
115    );
116    gizmos.sphere(Vec3::splat(10.0), 1.0, PURPLE);
117
118    gizmos
119        .primitive_3d(
120            &Plane3d {
121                normal: Dir3::Y,
122                half_size: Vec2::splat(1.0),
123            },
124            Isometry3d::new(
125                Vec3::splat(4.0) + Vec2::from(ops::sin_cos(time.elapsed_secs())).extend(0.0),
126                Quat::from_rotation_x(PI / 2. + time.elapsed_secs()),
127            ),
128            GREEN,
129        )
130        .cell_count(UVec2::new(5, 10))
131        .spacing(Vec2::new(0.2, 0.1));
132
133    gizmos.cuboid(
134        Transform::from_translation(Vec3::Y * 0.5).with_scale(Vec3::splat(1.25)),
135        BLACK,
136    );
137    gizmos.rect(
138        Isometry3d::new(
139            Vec3::new(ops::cos(time.elapsed_secs()) * 2.5, 1., 0.),
140            Quat::from_rotation_y(PI / 2.),
141        ),
142        Vec2::splat(2.),
143        LIME,
144    );
145
146    gizmos.cross(Vec3::new(-1., 1., 1.), 0.5, FUCHSIA);
147
148    let domain = Interval::EVERYWHERE;
149    let curve = FunctionCurve::new(domain, |t| {
150        (Vec2::from(ops::sin_cos(t * 10.0))).extend(t - 6.0)
151    });
152    let resolution = ((ops::sin(time.elapsed_secs()) + 1.0) * 100.0) as usize;
153    let times_and_colors = (0..=resolution)
154        .map(|n| n as f32 / resolution as f32)
155        .map(|t| t * 5.0)
156        .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0)));
157    gizmos.curve_gradient_3d(curve, times_and_colors);
158
159    my_gizmos.sphere(Vec3::new(1., 0.5, 0.), 0.5, RED);
160
161    my_gizmos
162        .rounded_cuboid(Vec3::new(-2.0, 0.75, -0.75), Vec3::splat(0.9), TURQUOISE)
163        .edge_radius(0.1)
164        .arc_resolution(4);
165
166    for y in [0., 0.5, 1.] {
167        gizmos.ray(
168            Vec3::new(1., y, 0.),
169            Vec3::new(-3., ops::sin(time.elapsed_secs() * 3.), 0.),
170            BLUE,
171        );
172    }
173
174    my_gizmos
175        .arc_3d(
176            180.0_f32.to_radians(),
177            0.2,
178            Isometry3d::new(
179                Vec3::ONE,
180                Quat::from_rotation_arc(Vec3::Y, Vec3::ONE.normalize()),
181            ),
182            ORANGE,
183        )
184        .resolution(10);
185
186    // Circles have 32 line-segments by default.
187    my_gizmos.circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3., BLACK);
188
189    // You may want to increase this for larger circles or spheres.
190    my_gizmos
191        .circle(Quat::from_rotation_arc(Vec3::Z, Vec3::Y), 3.1, NAVY)
192        .resolution(64);
193    my_gizmos
194        .sphere(Isometry3d::IDENTITY, 3.2, BLACK)
195        .resolution(64);
196
197    gizmos.arrow(Vec3::ZERO, Vec3::splat(1.5), YELLOW);
198
199    // You can create more complex arrows using the arrow builder.
200    gizmos
201        .arrow(Vec3::new(2., 0., 2.), Vec3::new(2., 2., 2.), ORANGE_RED)
202        .with_double_end()
203        .with_tip_length(0.5);
204}

Trait Implementations§

Source§

impl<'w, 's, Config, Clear> Deref for Gizmos<'w, 's, Config, Clear>
where Config: GizmoConfigGroup, Clear: 'static + Send + Sync,

Source§

type Target = GizmoBuffer<Config, Clear>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &<Gizmos<'w, 's, Config, Clear> as Deref>::Target

Dereferences the value.
Source§

impl<'w, 's, Config, Clear> DerefMut for Gizmos<'w, 's, Config, Clear>
where Config: GizmoConfigGroup, Clear: 'static + Send + Sync,

Source§

fn deref_mut(&mut self) -> &mut <Gizmos<'w, 's, Config, Clear> as Deref>::Target

Mutably dereferences the value.
Source§

impl<Config, Clear> SystemParam for Gizmos<'_, '_, Config, Clear>
where Config: GizmoConfigGroup, Clear: 'static + Send + Sync,

Source§

type State = GizmosFetchState<Config, Clear>

Used to store data which persists across invocations of a system.
Source§

type Item<'w, 's> = Gizmos<'w, 's, Config, Clear>

The item type returned when constructing this system param. The value of this associated type should be Self, instantiated with new lifetimes. Read more
Source§

fn init_state( world: &mut World, system_meta: &mut SystemMeta, ) -> <Gizmos<'_, '_, Config, Clear> as SystemParam>::State

Registers any World access used by this SystemParam and creates a new instance of this param’s State.
Source§

unsafe fn new_archetype( state: &mut <Gizmos<'_, '_, Config, Clear> as SystemParam>::State, archetype: &Archetype, system_meta: &mut SystemMeta, )

For the specified Archetype, registers the components accessed by this SystemParam (if applicable).a Read more
Source§

fn apply( state: &mut <Gizmos<'_, '_, Config, Clear> as SystemParam>::State, system_meta: &SystemMeta, world: &mut World, )

Applies any deferred mutations stored in this SystemParam’s state. This is used to apply Commands during ApplyDeferred.
Source§

unsafe fn validate_param( state: &<Gizmos<'_, '_, Config, Clear> as SystemParam>::State, system_meta: &SystemMeta, world: UnsafeWorldCell<'_>, ) -> Result<(), SystemParamValidationError>

Validates that the param can be acquired by the get_param. Read more
Source§

unsafe fn get_param<'w, 's>( state: &'s mut <Gizmos<'_, '_, Config, Clear> as SystemParam>::State, system_meta: &SystemMeta, world: UnsafeWorldCell<'w>, change_tick: Tick, ) -> <Gizmos<'_, '_, Config, Clear> as SystemParam>::Item<'w, 's>

Creates a parameter to be passed into a SystemParamFunction. Read more
Source§

fn queue( state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld<'_>, )

Queues any deferred mutations to be applied at the next ApplyDeferred.
Source§

impl<'w, 's, Config, Clear> ReadOnlySystemParam for Gizmos<'w, 's, Config, Clear>
where Config: GizmoConfigGroup, Clear: 'static + Send + Sync, Deferred<'s, GizmoBuffer<Config, Clear>>: ReadOnlySystemParam, Res<'w, GizmoConfigStore>: ReadOnlySystemParam,

Auto Trait Implementations§

§

impl<'w, 's, Config, Clear> Freeze for Gizmos<'w, 's, Config, Clear>

§

impl<'w, 's, Config, Clear> RefUnwindSafe for Gizmos<'w, 's, Config, Clear>
where Config: RefUnwindSafe, Clear: RefUnwindSafe,

§

impl<'w, 's, Config, Clear> Send for Gizmos<'w, 's, Config, Clear>

§

impl<'w, 's, Config, Clear> Sync for Gizmos<'w, 's, Config, Clear>

§

impl<'w, 's, Config, Clear> Unpin for Gizmos<'w, 's, Config, Clear>

§

impl<'w, 's, Config = DefaultGizmoConfigGroup, Clear = ()> !UnwindSafe for Gizmos<'w, 's, Config, Clear>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ConditionalSend for T
where T: Send,

Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> Settings for T
where T: 'static + Send + Sync,

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,