Skip to content

Commit d251dfb

Browse files
flesh out the visibility integration
- add a visibility class to the gizmo - calculate AABBs for the gizmos - start a new example for retained gizmos
1 parent 95e82d7 commit d251dfb

File tree

6 files changed

+178
-89
lines changed

6 files changed

+178
-89
lines changed

Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4123,6 +4123,18 @@ description = "A scene showcasing light gizmos"
41234123
category = "Gizmos"
41244124
wasm = true
41254125

4126+
[[example]]
4127+
name = "retained_gizmos"
4128+
path = "examples/gizmos/retained_gizmos.rs"
4129+
doc-scrape-examples = true
4130+
required-features = ["free_camera"]
4131+
4132+
[package.metadata.example.retained_gizmos]
4133+
name = "Retained Gizmos"
4134+
description = "A scene showcasing retained gizmos"
4135+
category = "Gizmos"
4136+
wasm = true
4137+
41264138
[[example]]
41274139
name = "custom_gltf_vertex_attribute"
41284140
path = "examples/gltf/custom_gltf_vertex_attribute.rs"

crates/bevy_gizmos_render/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ bevy_render = { path = "../bevy_render", version = "0.18.0-dev" }
2929
bevy_utils = { path = "../bevy_utils", version = "0.18.0-dev" }
3030
bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.18.0-dev" }
3131
bevy_transform = { path = "../bevy_transform", version = "0.18.0-dev" }
32+
bevy_platform = { path = "../bevy_platform", version = "0.18.0-dev" }
3233

3334
# other
3435
bytemuck = "1.0"

crates/bevy_gizmos_render/src/lib.rs

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,36 +24,39 @@ mod pipeline_2d;
2424
#[cfg(feature = "bevy_pbr")]
2525
mod pipeline_3d;
2626

27-
use bevy_app::{App, Plugin};
28-
use bevy_camera::visibility::{add_visibility_class, Visibility, VisibilityClass};
29-
use bevy_ecs::{
30-
resource::Resource,
31-
schedule::{IntoScheduleConfigs, SystemSet},
32-
system::Res,
33-
};
34-
35-
use {bevy_gizmos::config::GizmoMeshConfig, bevy_mesh::VertexBufferLayout};
36-
3727
use {
38-
crate::retained::extract_linegizmos,
39-
bevy_asset::AssetId,
28+
crate::retained::{
29+
calculate_bounds, extract_linegizmos, mark_gizmos_as_changed_if_their_assets_changed,
30+
},
31+
bevy_app::{App, Plugin, PostUpdate},
32+
bevy_asset::{AssetEventSystems, AssetId},
33+
bevy_camera::visibility::{self, Visibility, VisibilityClass, VisibilitySystems},
4034
bevy_ecs::{
4135
component::Component,
4236
entity::Entity,
4337
query::ROQueryItem,
38+
resource::Resource,
39+
schedule::{IntoScheduleConfigs, SystemSet},
4440
system::{
4541
lifetimeless::{Read, SRes},
46-
Commands, SystemParamItem,
42+
Commands, Res, SystemParamItem,
4743
},
4844
},
45+
bevy_gizmos::{
46+
config::{GizmoConfigStore, GizmoLineJoint, GizmoMeshConfig},
47+
prelude::Gizmo,
48+
GizmoAsset, GizmoHandles,
49+
},
4950
bevy_math::{Affine3, Affine3A, Vec4},
51+
bevy_mesh::VertexBufferLayout,
5052
bevy_render::{
5153
extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
5254
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
5355
render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass},
5456
render_resource::{
55-
binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayoutEntries,
56-
Buffer, BufferInitDescriptor, BufferUsages, ShaderStages, ShaderType, VertexFormat,
57+
binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayoutDescriptor,
58+
BindGroupLayoutEntries, Buffer, BufferInitDescriptor, BufferUsages, PipelineCache,
59+
ShaderStages, ShaderType, VertexAttribute, VertexFormat, VertexStepMode,
5760
},
5861
renderer::RenderDevice,
5962
sync_world::{MainEntity, TemporaryRenderEntity},
@@ -62,16 +65,6 @@ use {
6265
bytemuck::cast_slice,
6366
};
6467

65-
use bevy_render::render_resource::{
66-
BindGroupLayoutDescriptor, PipelineCache, VertexAttribute, VertexStepMode,
67-
};
68-
69-
use bevy_gizmos::{
70-
config::{GizmoConfigStore, GizmoLineJoint},
71-
prelude::Gizmo,
72-
GizmoAsset, GizmoHandles,
73-
};
74-
7568
/// A [`Plugin`] that provides an immediate mode drawing api for visual debugging.
7669
///
7770
/// Requires to be loaded after [`PbrPlugin`](bevy_pbr::PbrPlugin) or [`SpriteRenderPlugin`](bevy_sprite_render::SpriteRenderPlugin).
@@ -87,7 +80,20 @@ impl Plugin for GizmoRenderPlugin {
8780
}
8881

8982
app.add_plugins(UniformComponentPlugin::<LineGizmoUniform>::default())
90-
.add_plugins(RenderAssetPlugin::<GpuLineGizmo>::default());
83+
.add_plugins(RenderAssetPlugin::<GpuLineGizmo>::default())
84+
.register_required_components::<Gizmo, Visibility>()
85+
.register_required_components::<Gizmo, VisibilityClass>()
86+
.add_systems(
87+
PostUpdate,
88+
(
89+
calculate_bounds.in_set(VisibilitySystems::CalculateBounds),
90+
mark_gizmos_as_changed_if_their_assets_changed.after(AssetEventSystems),
91+
),
92+
);
93+
94+
app.world_mut()
95+
.register_component_hooks::<Gizmo>()
96+
.on_add(visibility::add_visibility_class::<Gizmo>);
9197

9298
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
9399
render_app.add_systems(RenderStartup, init_line_gizmo_uniform_bind_group_layout);
@@ -114,8 +120,6 @@ impl Plugin for GizmoRenderPlugin {
114120
} else {
115121
tracing::warn!("bevy_render feature is enabled but RenderApp was not detected. Are you sure you loaded GizmoPlugin after RenderPlugin?");
116122
}
117-
118-
app.register_required_components::<Gizmo, Visibility>();
119123
}
120124
}
121125

crates/bevy_gizmos_render/src/retained.rs

Lines changed: 77 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,35 @@
11
//! This module is for 'retained' alternatives to the 'immediate mode' [`Gizmos`](bevy_gizmos::gizmos::Gizmos) system parameter.
22
3-
use crate::LineGizmoUniform;
4-
use bevy_camera::visibility::{InheritedVisibility, RenderLayers, ViewVisibility};
5-
use bevy_gizmos::retained::Gizmo;
6-
use bevy_math::Affine3;
7-
use bevy_render::{
8-
sync_world::{MainEntity, TemporaryRenderEntity},
9-
view,
10-
};
11-
use bevy_utils::once;
12-
use tracing::warn;
133
use {
4+
crate::LineGizmoUniform,
5+
bevy_asset::{AssetEvent, AssetId, Assets},
6+
bevy_camera::{
7+
primitives::Aabb,
8+
visibility::{NoFrustumCulling, RenderLayers, ViewVisibility},
9+
},
1410
bevy_ecs::{
11+
change_detection::DetectChangesMut,
1512
entity::Entity,
16-
system::{Commands, Local, Query},
13+
message::MessageReader,
14+
query::{Changed, Or, Without},
15+
system::{Commands, Local, Query, Res},
16+
},
17+
bevy_gizmos::{
18+
config::{GizmoLineJoint, GizmoLineStyle},
19+
retained::Gizmo,
20+
GizmoAsset,
21+
},
22+
bevy_math::{bounding::Aabb3d, Affine3, Isometry3d, Vec3A},
23+
bevy_platform::{collections::HashSet, hash::FixedHasher},
24+
bevy_render::{
25+
sync_world::{MainEntity, TemporaryRenderEntity},
26+
Extract,
1727
},
18-
bevy_gizmos::config::GizmoLineJoint,
19-
bevy_render::Extract,
2028
bevy_transform::components::GlobalTransform,
29+
bevy_utils::once,
30+
tracing::warn,
2131
};
2232

23-
use bevy_gizmos::config::GizmoLineStyle;
24-
2533
pub(crate) fn extract_linegizmos(
2634
mut commands: Commands,
2735
mut previous_len: Local<usize>,
@@ -30,15 +38,13 @@ pub(crate) fn extract_linegizmos(
3038
Entity,
3139
&Gizmo,
3240
&GlobalTransform,
33-
&InheritedVisibility,
3441
&ViewVisibility,
3542
Option<&RenderLayers>,
3643
)>,
3744
>,
3845
) {
3946
let mut values = Vec::with_capacity(*previous_len);
40-
for (entity, gizmo, transform, visibility, view_visibility, render_layers) in &query {
41-
println!("{visibility:?} {view_visibility:?}");
47+
for (entity, gizmo, transform, view_visibility, render_layers) in &query {
4248
if !view_visibility.get() {
4349
continue;
4450
}
@@ -91,3 +97,56 @@ pub(crate) fn extract_linegizmos(
9197
*previous_len = values.len();
9298
commands.spawn_batch(values);
9399
}
100+
101+
pub(crate) fn calculate_bounds(
102+
mut commands: Commands,
103+
gizmo_assets: Res<Assets<GizmoAsset>>,
104+
without_aabb: Query<
105+
(Entity, &Gizmo),
106+
(
107+
Or<(Changed<Gizmo>, Without<Aabb>)>,
108+
Without<NoFrustumCulling>,
109+
),
110+
>,
111+
) {
112+
for (entity, gizmo) in &without_aabb {
113+
if let Some(gizmo_asset) = gizmo_assets.get(&gizmo.handle) {
114+
println!("Calculating AABB for gizmo entity {:?}", entity);
115+
let aabb_3d = Aabb3d::from_point_cloud(
116+
Isometry3d::IDENTITY,
117+
gizmo_asset
118+
.list_positions
119+
.iter()
120+
.chain(gizmo_asset.strip_positions.iter())
121+
// infinite points show up in here for some reason
122+
// i am brutally filtering them for now
123+
.filter(|p| p.is_finite())
124+
.map(|&p| Vec3A::from(p)),
125+
);
126+
let aabb: Aabb = aabb_3d.into();
127+
commands.entity(entity).insert(aabb);
128+
}
129+
}
130+
}
131+
132+
pub(crate) fn mark_gizmos_as_changed_if_their_assets_changed(
133+
mut gizmos: Query<&mut Gizmo>,
134+
mut gizmo_asset_events: MessageReader<AssetEvent<GizmoAsset>>,
135+
) {
136+
let mut changed_gizmos: HashSet<AssetId<GizmoAsset>, FixedHasher> = HashSet::default();
137+
for mesh_asset_event in gizmo_asset_events.read() {
138+
if let AssetEvent::Modified { id } = mesh_asset_event {
139+
changed_gizmos.insert(*id);
140+
}
141+
}
142+
143+
if changed_gizmos.is_empty() {
144+
return;
145+
}
146+
147+
for mut gizmo in &mut gizmos {
148+
if changed_gizmos.contains(&gizmo.handle.id()) {
149+
gizmo.set_changed();
150+
}
151+
}
152+
}

examples/gizmos/3d_gizmos.rs

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,7 @@ fn main() {
1212
.add_plugins((DefaultPlugins, FreeCameraPlugin))
1313
.init_gizmo_group::<MyRoundGizmos>()
1414
.add_systems(Startup, setup)
15-
.add_systems(
16-
Update,
17-
(
18-
draw_example_collection,
19-
update_config,
20-
update_retained_gizmo_visibility,
21-
),
22-
)
15+
.add_systems(Update, (draw_example_collection, update_config))
2316
.run();
2417
}
2518

@@ -33,29 +26,6 @@ fn setup(
3326
mut meshes: ResMut<Assets<Mesh>>,
3427
mut materials: ResMut<Assets<StandardMaterial>>,
3528
) {
36-
let mut gizmo = GizmoAsset::new();
37-
38-
// When drawing a lot of static lines a Gizmo component can have
39-
// far better performance than the Gizmos system parameter,
40-
// but the system parameter will perform better for smaller lines that update often.
41-
42-
// A sphere made out of 30_000 lines!
43-
gizmo
44-
.sphere(Isometry3d::IDENTITY, 0.5, LIGHT_GOLDENROD_YELLOW)
45-
.resolution(30_000 / 3);
46-
47-
commands.spawn((
48-
Gizmo {
49-
handle: gizmo_assets.add(gizmo),
50-
line_config: GizmoLineConfig {
51-
width: 5.,
52-
..default()
53-
},
54-
..default()
55-
},
56-
Transform::from_xyz(4., 1., 0.),
57-
));
58-
5929
commands.spawn((
6030
Camera3d::default(),
6131
Transform::from_xyz(0., 1.5, 6.).looking_at(Vec3::ZERO, Vec3::Y),
@@ -89,7 +59,6 @@ fn setup(
8959
Hold 'Left' or 'Right' to change the line width of straight gizmos\n\
9060
Hold 'Up' or 'Down' to change the line width of round gizmos\n\
9161
Press '1' or '2' to toggle the visibility of straight gizmos or round gizmos\n\
92-
Press '3' to toggle the visibility of retained gizmos\n\
9362
Press 'B' to show all AABB boxes\n\
9463
Press 'U' or 'I' to cycle through line styles for straight or round gizmos\n\
9564
Press 'J' or 'K' to cycle through line joins for straight or round gizmos",
@@ -298,14 +267,3 @@ fn update_config(
298267
config_store.config_mut::<AabbGizmoConfigGroup>().1.draw_all ^= true;
299268
}
300269
}
301-
302-
fn update_retained_gizmo_visibility(
303-
keyboard: Res<ButtonInput<KeyCode>>,
304-
mut gizmos: Query<&mut Visibility, With<Gizmo>>,
305-
) {
306-
if keyboard.just_pressed(KeyCode::Digit3) {
307-
for mut visibility in &mut gizmos {
308-
visibility.toggle_inherited_hidden();
309-
}
310-
}
311-
}

examples/gizmos/retained_gizmos.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//! This example demonstrates Bevy's visual debugging using retained gizmos.
2+
3+
use bevy::{
4+
camera_controller::free_camera::{FreeCamera, FreeCameraPlugin},
5+
color::palettes::css::*,
6+
prelude::*,
7+
};
8+
9+
fn main() {
10+
App::new()
11+
.add_plugins((DefaultPlugins, FreeCameraPlugin))
12+
//.init_gizmo_group::<MyRoundGizmos>()
13+
.add_systems(Startup, setup)
14+
// .add_systems(
15+
// Update,
16+
// (
17+
// draw_example_collection,
18+
// update_config,
19+
// update_retained_gizmo_visibility,
20+
// ),
21+
// )
22+
.run();
23+
}
24+
25+
fn setup(mut commands: Commands, mut gizmo_assets: ResMut<Assets<GizmoAsset>>) {
26+
commands.spawn((
27+
Camera3d::default(),
28+
Transform::from_xyz(0., 1.5, 6.).looking_at(Vec3::NEG_Z, Vec3::Y),
29+
FreeCamera::default(),
30+
));
31+
32+
let mut gizmo = GizmoAsset::new();
33+
34+
// When drawing a lot of static lines a Gizmo component can have
35+
// far better performance than the Gizmos system parameter,
36+
// but the system parameter will perform better for smaller lines that update often.
37+
38+
// we'll sprinkle spheres made of 3,000 lines throughout the scene
39+
// and make the blink
40+
gizmo
41+
.sphere(Isometry3d::IDENTITY, 0.5, LIGHT_GOLDENROD_YELLOW)
42+
.resolution(3_000 / 3);
43+
44+
commands.spawn((
45+
Gizmo {
46+
handle: gizmo_assets.add(gizmo),
47+
line_config: GizmoLineConfig {
48+
width: 2.,
49+
..default()
50+
},
51+
..default()
52+
},
53+
Transform::IDENTITY,
54+
));
55+
}

0 commit comments

Comments
 (0)