Skip to content

Commit d2a07f9

Browse files
Retained Gizmos (#15473)
# Objective Add a way to use the gizmo API in a retained manner, for increased performance. ## Solution - Move gizmo API from `Gizmos` to `GizmoBuffer`, ~ab~using `Deref` to keep usage the same as before. - Merge non-strip and strip variant of `LineGizmo` into one, storing the data in a `GizmoBuffer` to have the same API for retained `LineGizmo`s. ### Review guide - The meat of the changes are in `lib.rs`, `retained.rs`, `gizmos.rs`, `pipeline_3d.rs` and `pipeline_2d.rs` - The other files contain almost exclusively the churn from moving the gizmo API from `Gizmos` to `GizmoBuffer` ## Testing ### Performance Performance compared to the immediate mode API is from 65 to 80 times better for static lines. ``` 7900 XTX, 3700X 1707.9k lines/ms: gizmos_retained (21.3ms) 3488.5k lines/ms: gizmos_retained_continuous_polyline (31.3ms) 0.5k lines/ms: gizmos_retained_separate (97.7ms) 3054.9k lines/ms: bevy_polyline_retained_nan (16.8ms) 3596.3k lines/ms: bevy_polyline_retained_continuous_polyline (14.2ms) 0.6k lines/ms: bevy_polyline_retained_separate (78.9ms) 26.9k lines/ms: gizmos_immediate (14.9ms) 43.8k lines/ms: gizmos_immediate_continuous_polyline (18.3ms) ``` Looks like performance is good enough, being close to par with `bevy_polyline`. Benchmarks can be found here: This branch: https://github.com/tim-blackbird/line_racing/tree/retained-gizmos Bevy 0.14: https://github.com/DGriffin91/line_racing ## Showcase ```rust fn setup( mut commands: Commands, mut gizmo_assets: ResMut<Assets<GizmoAsset>> ) { let mut gizmo = GizmoAsset::default(); // A sphere made out of one million lines! gizmo .sphere(default(), 1., CRIMSON) .resolution(1_000_000 / 3); commands.spawn(Gizmo { handle: gizmo_assets.add(gizmo), ..default() }); } ``` ## Follow-up work - Port over to the retained rendering world proper - Calculate visibility and cull `Gizmo`s
1 parent f59ae0f commit d2a07f9

22 files changed

+840
-462
lines changed

crates/bevy_dev_tools/src/ui_debug_overlay/inset.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,9 @@ impl<'w, 's> InsetGizmo<'w, 's> {
184184
Vec2::new(right, bottom),
185185
Vec2::new(right, top),
186186
Vec2::new(left, top),
187-
];
188-
self.draw
189-
.linestrip_2d(strip.map(|v| self.relative(v)), color);
187+
]
188+
.map(|v| self.relative(v));
189+
self.draw.linestrip_2d(strip, color);
190190
}
191191
}
192192
}

crates/bevy_dev_tools/src/ui_debug_overlay/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ fn outline_roots(
204204
let line_width = outline
205205
.gizmo_config
206206
.get_config_dyn(&UiGizmosDebug.type_id())
207-
.map_or(2., |(config, _)| config.line_width)
207+
.map_or(2., |(config, _)| config.line.width)
208208
/ window_scale;
209209
let mut draw = InsetGizmo::new(draw, cam.debug_camera, line_width);
210210
for (entity, trans, node, view_visibility, maybe_target_camera) in &roots {

crates/bevy_gizmos/src/arcs.rs

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
//! Additional [`Gizmos`] Functions -- Arcs
1+
//! Additional [`GizmoBuffer`] Functions -- Arcs
22
//!
3-
//! Includes the implementation of [`Gizmos::arc_2d`],
3+
//! Includes the implementation of [`GizmoBuffer::arc_2d`],
44
//! and assorted support items.
55
6-
use crate::{
7-
circles::DEFAULT_CIRCLE_RESOLUTION,
8-
prelude::{GizmoConfigGroup, Gizmos},
9-
};
6+
use crate::{circles::DEFAULT_CIRCLE_RESOLUTION, gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
107
use bevy_color::Color;
118
use bevy_math::{Isometry2d, Isometry3d, Quat, Rot2, Vec2, Vec3};
129
use core::f32::consts::{FRAC_PI_2, TAU};
1310

1411
// === 2D ===
1512

16-
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
13+
impl<Config, Clear> GizmoBuffer<Config, Clear>
1714
where
1815
Config: GizmoConfigGroup,
1916
Clear: 'static + Send + Sync,
@@ -54,7 +51,7 @@ where
5451
arc_angle: f32,
5552
radius: f32,
5653
color: impl Into<Color>,
57-
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
54+
) -> Arc2dBuilder<'_, Config, Clear> {
5855
Arc2dBuilder {
5956
gizmos: self,
6057
isometry: isometry.into(),
@@ -66,21 +63,21 @@ where
6663
}
6764
}
6865

69-
/// A builder returned by [`Gizmos::arc_2d`].
70-
pub struct Arc2dBuilder<'a, 'w, 's, Config, Clear>
66+
/// A builder returned by [`GizmoBuffer::arc_2d`].
67+
pub struct Arc2dBuilder<'a, Config, Clear>
7168
where
7269
Config: GizmoConfigGroup,
7370
Clear: 'static + Send + Sync,
7471
{
75-
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
72+
gizmos: &'a mut GizmoBuffer<Config, Clear>,
7673
isometry: Isometry2d,
7774
arc_angle: f32,
7875
radius: f32,
7976
color: Color,
8077
resolution: Option<u32>,
8178
}
8279

83-
impl<Config, Clear> Arc2dBuilder<'_, '_, '_, Config, Clear>
80+
impl<Config, Clear> Arc2dBuilder<'_, Config, Clear>
8481
where
8582
Config: GizmoConfigGroup,
8683
Clear: 'static + Send + Sync,
@@ -92,7 +89,7 @@ where
9289
}
9390
}
9491

95-
impl<Config, Clear> Drop for Arc2dBuilder<'_, '_, '_, Config, Clear>
92+
impl<Config, Clear> Drop for Arc2dBuilder<'_, Config, Clear>
9693
where
9794
Config: GizmoConfigGroup,
9895
Clear: 'static + Send + Sync,
@@ -122,7 +119,7 @@ fn arc_2d_inner(arc_angle: f32, radius: f32, resolution: u32) -> impl Iterator<I
122119

123120
// === 3D ===
124121

125-
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
122+
impl<Config, Clear> GizmoBuffer<Config, Clear>
126123
where
127124
Config: GizmoConfigGroup,
128125
Clear: 'static + Send + Sync,
@@ -178,7 +175,7 @@ where
178175
radius: f32,
179176
isometry: impl Into<Isometry3d>,
180177
color: impl Into<Color>,
181-
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
178+
) -> Arc3dBuilder<'_, Config, Clear> {
182179
Arc3dBuilder {
183180
gizmos: self,
184181
start_vertex: Vec3::X,
@@ -233,7 +230,7 @@ where
233230
from: Vec3,
234231
to: Vec3,
235232
color: impl Into<Color>,
236-
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
233+
) -> Arc3dBuilder<'_, Config, Clear> {
237234
self.arc_from_to(center, from, to, color, |x| x)
238235
}
239236

@@ -279,7 +276,7 @@ where
279276
from: Vec3,
280277
to: Vec3,
281278
color: impl Into<Color>,
282-
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
279+
) -> Arc3dBuilder<'_, Config, Clear> {
283280
self.arc_from_to(center, from, to, color, |angle| {
284281
if angle > 0.0 {
285282
TAU - angle
@@ -299,7 +296,7 @@ where
299296
to: Vec3,
300297
color: impl Into<Color>,
301298
angle_fn: impl Fn(f32) -> f32,
302-
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
299+
) -> Arc3dBuilder<'_, Config, Clear> {
303300
// `from` and `to` can be the same here since in either case nothing gets rendered and the
304301
// orientation ambiguity of `up` doesn't matter
305302
let from_axis = (from - center).normalize_or_zero();
@@ -366,7 +363,7 @@ where
366363
from: Vec2,
367364
to: Vec2,
368365
color: impl Into<Color>,
369-
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
366+
) -> Arc2dBuilder<'_, Config, Clear> {
370367
self.arc_2d_from_to(center, from, to, color, core::convert::identity)
371368
}
372369

@@ -412,7 +409,7 @@ where
412409
from: Vec2,
413410
to: Vec2,
414411
color: impl Into<Color>,
415-
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
412+
) -> Arc2dBuilder<'_, Config, Clear> {
416413
self.arc_2d_from_to(center, from, to, color, |angle| angle - TAU)
417414
}
418415

@@ -424,7 +421,7 @@ where
424421
to: Vec2,
425422
color: impl Into<Color>,
426423
angle_fn: impl Fn(f32) -> f32,
427-
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
424+
) -> Arc2dBuilder<'_, Config, Clear> {
428425
// `from` and `to` can be the same here since in either case nothing gets rendered and the
429426
// orientation ambiguity of `up` doesn't matter
430427
let from_axis = (from - center).normalize_or_zero();
@@ -446,13 +443,13 @@ where
446443
}
447444
}
448445

449-
/// A builder returned by [`Gizmos::arc_2d`].
450-
pub struct Arc3dBuilder<'a, 'w, 's, Config, Clear>
446+
/// A builder returned by [`GizmoBuffer::arc_2d`].
447+
pub struct Arc3dBuilder<'a, Config, Clear>
451448
where
452449
Config: GizmoConfigGroup,
453450
Clear: 'static + Send + Sync,
454451
{
455-
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
452+
gizmos: &'a mut GizmoBuffer<Config, Clear>,
456453
// this is the vertex the arc starts on in the XZ plane. For the normal arc_3d method this is
457454
// always starting at Vec3::X. For the short/long arc methods we actually need a way to start
458455
// at the from position and this is where this internal field comes into play. Some implicit
@@ -470,7 +467,7 @@ where
470467
resolution: Option<u32>,
471468
}
472469

473-
impl<Config, Clear> Arc3dBuilder<'_, '_, '_, Config, Clear>
470+
impl<Config, Clear> Arc3dBuilder<'_, Config, Clear>
474471
where
475472
Config: GizmoConfigGroup,
476473
Clear: 'static + Send + Sync,
@@ -482,7 +479,7 @@ where
482479
}
483480
}
484481

485-
impl<Config, Clear> Drop for Arc3dBuilder<'_, '_, '_, Config, Clear>
482+
impl<Config, Clear> Drop for Arc3dBuilder<'_, Config, Clear>
486483
where
487484
Config: GizmoConfigGroup,
488485
Clear: 'static + Send + Sync,

crates/bevy_gizmos/src/arrows.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1-
//! Additional [`Gizmos`] Functions -- Arrows
1+
//! Additional [`GizmoBuffer`] Functions -- Arrows
22
//!
3-
//! Includes the implementation of [`Gizmos::arrow`] and [`Gizmos::arrow_2d`],
3+
//! Includes the implementation of [`GizmoBuffer::arrow`] and [`GizmoBuffer::arrow_2d`],
44
//! and assorted support items.
55
6-
use crate::prelude::{GizmoConfigGroup, Gizmos};
6+
use crate::{gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
77
use bevy_color::{
88
palettes::basic::{BLUE, GREEN, RED},
99
Color,
1010
};
1111
use bevy_math::{Quat, Vec2, Vec3, Vec3Swizzles};
1212
use bevy_transform::TransformPoint;
1313

14-
/// A builder returned by [`Gizmos::arrow`] and [`Gizmos::arrow_2d`]
15-
pub struct ArrowBuilder<'a, 'w, 's, Config, Clear>
14+
/// A builder returned by [`GizmoBuffer::arrow`] and [`GizmoBuffer::arrow_2d`]
15+
pub struct ArrowBuilder<'a, Config, Clear>
1616
where
1717
Config: GizmoConfigGroup,
1818
Clear: 'static + Send + Sync,
1919
{
20-
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
20+
gizmos: &'a mut GizmoBuffer<Config, Clear>,
2121
start: Vec3,
2222
end: Vec3,
2323
color: Color,
2424
double_ended: bool,
2525
tip_length: f32,
2626
}
2727

28-
impl<Config, Clear> ArrowBuilder<'_, '_, '_, Config, Clear>
28+
impl<Config, Clear> ArrowBuilder<'_, Config, Clear>
2929
where
3030
Config: GizmoConfigGroup,
3131
Clear: 'static + Send + Sync,
@@ -58,12 +58,12 @@ where
5858
}
5959
}
6060

61-
impl<Config, Clear> Drop for ArrowBuilder<'_, '_, '_, Config, Clear>
61+
impl<Config, Clear> Drop for ArrowBuilder<'_, Config, Clear>
6262
where
6363
Config: GizmoConfigGroup,
6464
Clear: 'static + Send + Sync,
6565
{
66-
/// Draws the arrow, by drawing lines with the stored [`Gizmos`]
66+
/// Draws the arrow, by drawing lines with the stored [`GizmoBuffer`]
6767
fn drop(&mut self) {
6868
if !self.gizmos.enabled {
6969
return;
@@ -101,7 +101,7 @@ where
101101
}
102102
}
103103

104-
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
104+
impl<Config, Clear> GizmoBuffer<Config, Clear>
105105
where
106106
Config: GizmoConfigGroup,
107107
Clear: 'static + Send + Sync,
@@ -125,7 +125,7 @@ where
125125
start: Vec3,
126126
end: Vec3,
127127
color: impl Into<Color>,
128-
) -> ArrowBuilder<'_, 'w, 's, Config, Clear> {
128+
) -> ArrowBuilder<'_, Config, Clear> {
129129
let length = (end - start).length();
130130
ArrowBuilder {
131131
gizmos: self,
@@ -156,12 +156,12 @@ where
156156
start: Vec2,
157157
end: Vec2,
158158
color: impl Into<Color>,
159-
) -> ArrowBuilder<'_, 'w, 's, Config, Clear> {
159+
) -> ArrowBuilder<'_, Config, Clear> {
160160
self.arrow(start.extend(0.), end.extend(0.), color)
161161
}
162162
}
163163

164-
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
164+
impl<Config, Clear> GizmoBuffer<Config, Clear>
165165
where
166166
Config: GizmoConfigGroup,
167167
Clear: 'static + Send + Sync,

0 commit comments

Comments
 (0)