Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4123,6 +4123,18 @@ description = "A scene showcasing light gizmos"
category = "Gizmos"
wasm = true

[[example]]
name = "retained_gizmos"
path = "examples/gizmos/retained_gizmos.rs"
doc-scrape-examples = true
required-features = ["free_camera"]

[package.metadata.example.retained_gizmos]
name = "Retained Gizmos"
description = "A scene showcasing retained gizmos"
category = "Gizmos"
wasm = true

[[example]]
name = "custom_gltf_vertex_attribute"
path = "examples/gltf/custom_gltf_vertex_attribute.rs"
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_gizmos_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ bevy_render = { path = "../bevy_render", version = "0.18.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.18.0-dev" }
bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.18.0-dev" }
bevy_transform = { path = "../bevy_transform", version = "0.18.0-dev" }
bevy_platform = { path = "../bevy_platform", version = "0.18.0-dev" }

# other
bytemuck = "1.0"
Expand Down
56 changes: 32 additions & 24 deletions crates/bevy_gizmos_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,39 @@ mod pipeline_2d;
#[cfg(feature = "bevy_pbr")]
mod pipeline_3d;

use bevy_app::{App, Plugin};
use bevy_ecs::{
resource::Resource,
schedule::{IntoScheduleConfigs, SystemSet},
system::Res,
};

use {bevy_gizmos::config::GizmoMeshConfig, bevy_mesh::VertexBufferLayout};

use {
crate::retained::extract_linegizmos,
bevy_asset::AssetId,
crate::retained::{
calculate_bounds, extract_linegizmos, mark_gizmos_as_changed_if_their_assets_changed,
},
bevy_app::{App, Plugin, PostUpdate},
bevy_asset::{AssetEventSystems, AssetId},
bevy_camera::visibility::{self, Visibility, VisibilityClass, VisibilitySystems},
bevy_ecs::{
component::Component,
entity::Entity,
query::ROQueryItem,
resource::Resource,
schedule::{IntoScheduleConfigs, SystemSet},
system::{
lifetimeless::{Read, SRes},
Commands, SystemParamItem,
Commands, Res, SystemParamItem,
},
},
bevy_gizmos::{
config::{GizmoConfigStore, GizmoLineJoint, GizmoMeshConfig},
prelude::Gizmo,
GizmoAsset, GizmoHandles,
},
bevy_math::{Affine3, Affine3A, Vec4},
bevy_mesh::VertexBufferLayout,
bevy_render::{
extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass},
render_resource::{
binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayoutEntries,
Buffer, BufferInitDescriptor, BufferUsages, ShaderStages, ShaderType, VertexFormat,
binding_types::uniform_buffer, BindGroup, BindGroupEntries, BindGroupLayoutDescriptor,
BindGroupLayoutEntries, Buffer, BufferInitDescriptor, BufferUsages, PipelineCache,
ShaderStages, ShaderType, VertexAttribute, VertexFormat, VertexStepMode,
},
renderer::RenderDevice,
sync_world::{MainEntity, TemporaryRenderEntity},
Expand All @@ -61,15 +65,6 @@ use {
bytemuck::cast_slice,
};

use bevy_render::render_resource::{
BindGroupLayoutDescriptor, PipelineCache, VertexAttribute, VertexStepMode,
};

use bevy_gizmos::{
config::{GizmoConfigStore, GizmoLineJoint},
GizmoAsset, GizmoHandles,
};

/// A [`Plugin`] that provides an immediate mode drawing api for visual debugging.
///
/// Requires to be loaded after [`PbrPlugin`](bevy_pbr::PbrPlugin) or [`SpriteRenderPlugin`](bevy_sprite_render::SpriteRenderPlugin).
Expand All @@ -85,7 +80,20 @@ impl Plugin for GizmoRenderPlugin {
}

app.add_plugins(UniformComponentPlugin::<LineGizmoUniform>::default())
.add_plugins(RenderAssetPlugin::<GpuLineGizmo>::default());
.add_plugins(RenderAssetPlugin::<GpuLineGizmo>::default())
.register_required_components::<Gizmo, Visibility>()
.register_required_components::<Gizmo, VisibilityClass>()
.add_systems(
PostUpdate,
(
calculate_bounds.in_set(VisibilitySystems::CalculateBounds),
mark_gizmos_as_changed_if_their_assets_changed.after(AssetEventSystems),
),
);

app.world_mut()
.register_component_hooks::<Gizmo>()
.on_add(visibility::add_visibility_class::<Gizmo>);

if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
render_app.add_systems(RenderStartup, init_line_gizmo_uniform_bind_group_layout);
Expand Down
101 changes: 87 additions & 14 deletions crates/bevy_gizmos_render/src/retained.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,54 @@
//! This module is for 'retained' alternatives to the 'immediate mode' [`Gizmos`](bevy_gizmos::gizmos::Gizmos) system parameter.

use crate::LineGizmoUniform;
use bevy_camera::visibility::RenderLayers;
use bevy_gizmos::retained::Gizmo;
use bevy_math::Affine3;
use bevy_render::sync_world::{MainEntity, TemporaryRenderEntity};
use bevy_utils::once;
use tracing::warn;
use {
crate::LineGizmoUniform,
bevy_asset::{AssetEvent, AssetId, Assets},
bevy_camera::{
primitives::Aabb,
visibility::{NoFrustumCulling, RenderLayers, ViewVisibility},
},
bevy_ecs::{
change_detection::DetectChangesMut,
entity::Entity,
system::{Commands, Local, Query},
message::MessageReader,
query::{Changed, Or, Without},
system::{Commands, Local, Query, Res},
},
bevy_gizmos::{
config::{GizmoLineJoint, GizmoLineStyle},
retained::Gizmo,
GizmoAsset,
},
bevy_math::{bounding::Aabb3d, Affine3, Isometry3d, Vec3A},
bevy_platform::{collections::HashSet, hash::FixedHasher},
bevy_render::{
sync_world::{MainEntity, TemporaryRenderEntity},
Extract,
},
bevy_gizmos::config::GizmoLineJoint,
bevy_render::Extract,
bevy_transform::components::GlobalTransform,
bevy_utils::once,
tracing::warn,
};

use bevy_gizmos::config::GizmoLineStyle;

pub(crate) fn extract_linegizmos(
mut commands: Commands,
mut previous_len: Local<usize>,
query: Extract<Query<(Entity, &Gizmo, &GlobalTransform, Option<&RenderLayers>)>>,
query: Extract<
Query<(
Entity,
&Gizmo,
&GlobalTransform,
&ViewVisibility,
Option<&RenderLayers>,
)>,
>,
) {
let mut values = Vec::with_capacity(*previous_len);
for (entity, gizmo, transform, render_layers) in &query {
for (entity, gizmo, transform, view_visibility, render_layers) in &query {
if !view_visibility.get() {
continue;
}

let joints_resolution = if let GizmoLineJoint::Round(resolution) = gizmo.line_config.joints
{
resolution
Expand Down Expand Up @@ -74,3 +97,53 @@ pub(crate) fn extract_linegizmos(
*previous_len = values.len();
commands.spawn_batch(values);
}

pub(crate) fn calculate_bounds(
mut commands: Commands,
gizmo_assets: Res<Assets<GizmoAsset>>,
needs_aabb: Query<
(Entity, &Gizmo),
(
Or<(Changed<Gizmo>, Without<Aabb>)>,
Without<NoFrustumCulling>,
),
>,
) {
for (entity, gizmo) in &needs_aabb {
if let Some(gizmo_asset) = gizmo_assets.get(&gizmo.handle) {
let aabb_3d = Aabb3d::from_point_cloud(
Isometry3d::IDENTITY,
gizmo_asset
.list_positions
.iter()
.chain(gizmo_asset.strip_positions.iter())
.filter(|p| p.is_finite())
.map(|&p| Vec3A::from(p)),
);
let aabb: Aabb = aabb_3d.into();
commands.entity(entity).insert(aabb);
}
}
}

pub(crate) fn mark_gizmos_as_changed_if_their_assets_changed(
mut gizmos: Query<&mut Gizmo>,
mut gizmo_asset_events: MessageReader<AssetEvent<GizmoAsset>>,
) {
let mut changed_gizmos: HashSet<AssetId<GizmoAsset>, FixedHasher> = HashSet::default();
for mesh_asset_event in gizmo_asset_events.read() {
if let AssetEvent::Modified { id } = mesh_asset_event {
changed_gizmos.insert(*id);
}
}

if changed_gizmos.is_empty() {
return;
}

for mut gizmo in &mut gizmos {
if changed_gizmos.contains(&gizmo.handle.id()) {
gizmo.set_changed();
}
}
}
23 changes: 0 additions & 23 deletions examples/gizmos/3d_gizmos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,6 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let mut gizmo = GizmoAsset::new();

// When drawing a lot of static lines a Gizmo component can have
// far better performance than the Gizmos system parameter,
// but the system parameter will perform better for smaller lines that update often.

// A sphere made out of 30_000 lines!
gizmo
.sphere(Isometry3d::IDENTITY, 0.5, CRIMSON)
.resolution(30_000 / 3);

commands.spawn((
Gizmo {
handle: gizmo_assets.add(gizmo),
line_config: GizmoLineConfig {
width: 5.,
..default()
},
..default()
},
Transform::from_xyz(4., 1., 0.),
));

commands.spawn((
Camera3d::default(),
Transform::from_xyz(0., 1.5, 6.).looking_at(Vec3::ZERO, Vec3::Y),
Expand Down
Loading
Loading