mirror of
https://github.com/bevyengine/bevy
synced 2024-12-18 09:03:07 +00:00
Retained Gizmo
s (#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
This commit is contained in:
parent
f59ae0f5e8
commit
d2a07f9f72
22 changed files with 840 additions and 462 deletions
|
@ -184,9 +184,9 @@ impl<'w, 's> InsetGizmo<'w, 's> {
|
|||
Vec2::new(right, bottom),
|
||||
Vec2::new(right, top),
|
||||
Vec2::new(left, top),
|
||||
];
|
||||
self.draw
|
||||
.linestrip_2d(strip.map(|v| self.relative(v)), color);
|
||||
]
|
||||
.map(|v| self.relative(v));
|
||||
self.draw.linestrip_2d(strip, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ fn outline_roots(
|
|||
let line_width = outline
|
||||
.gizmo_config
|
||||
.get_config_dyn(&UiGizmosDebug.type_id())
|
||||
.map_or(2., |(config, _)| config.line_width)
|
||||
.map_or(2., |(config, _)| config.line.width)
|
||||
/ window_scale;
|
||||
let mut draw = InsetGizmo::new(draw, cam.debug_camera, line_width);
|
||||
for (entity, trans, node, view_visibility, maybe_target_camera) in &roots {
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
//! Additional [`Gizmos`] Functions -- Arcs
|
||||
//! Additional [`GizmoBuffer`] Functions -- Arcs
|
||||
//!
|
||||
//! Includes the implementation of [`Gizmos::arc_2d`],
|
||||
//! Includes the implementation of [`GizmoBuffer::arc_2d`],
|
||||
//! and assorted support items.
|
||||
|
||||
use crate::{
|
||||
circles::DEFAULT_CIRCLE_RESOLUTION,
|
||||
prelude::{GizmoConfigGroup, Gizmos},
|
||||
};
|
||||
use crate::{circles::DEFAULT_CIRCLE_RESOLUTION, gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
|
||||
use bevy_color::Color;
|
||||
use bevy_math::{Isometry2d, Isometry3d, Quat, Rot2, Vec2, Vec3};
|
||||
use core::f32::consts::{FRAC_PI_2, TAU};
|
||||
|
||||
// === 2D ===
|
||||
|
||||
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -54,7 +51,7 @@ where
|
|||
arc_angle: f32,
|
||||
radius: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> Arc2dBuilder<'_, Config, Clear> {
|
||||
Arc2dBuilder {
|
||||
gizmos: self,
|
||||
isometry: isometry.into(),
|
||||
|
@ -66,13 +63,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A builder returned by [`Gizmos::arc_2d`].
|
||||
pub struct Arc2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
/// A builder returned by [`GizmoBuffer::arc_2d`].
|
||||
pub struct Arc2dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
isometry: Isometry2d,
|
||||
arc_angle: f32,
|
||||
radius: f32,
|
||||
|
@ -80,7 +77,7 @@ where
|
|||
resolution: Option<u32>,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Arc2dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Arc2dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -92,7 +89,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Arc2dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Arc2dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -122,7 +119,7 @@ fn arc_2d_inner(arc_angle: f32, radius: f32, resolution: u32) -> impl Iterator<I
|
|||
|
||||
// === 3D ===
|
||||
|
||||
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -178,7 +175,7 @@ where
|
|||
radius: f32,
|
||||
isometry: impl Into<Isometry3d>,
|
||||
color: impl Into<Color>,
|
||||
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> Arc3dBuilder<'_, Config, Clear> {
|
||||
Arc3dBuilder {
|
||||
gizmos: self,
|
||||
start_vertex: Vec3::X,
|
||||
|
@ -233,7 +230,7 @@ where
|
|||
from: Vec3,
|
||||
to: Vec3,
|
||||
color: impl Into<Color>,
|
||||
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> Arc3dBuilder<'_, Config, Clear> {
|
||||
self.arc_from_to(center, from, to, color, |x| x)
|
||||
}
|
||||
|
||||
|
@ -279,7 +276,7 @@ where
|
|||
from: Vec3,
|
||||
to: Vec3,
|
||||
color: impl Into<Color>,
|
||||
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> Arc3dBuilder<'_, Config, Clear> {
|
||||
self.arc_from_to(center, from, to, color, |angle| {
|
||||
if angle > 0.0 {
|
||||
TAU - angle
|
||||
|
@ -299,7 +296,7 @@ where
|
|||
to: Vec3,
|
||||
color: impl Into<Color>,
|
||||
angle_fn: impl Fn(f32) -> f32,
|
||||
) -> Arc3dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> Arc3dBuilder<'_, Config, Clear> {
|
||||
// `from` and `to` can be the same here since in either case nothing gets rendered and the
|
||||
// orientation ambiguity of `up` doesn't matter
|
||||
let from_axis = (from - center).normalize_or_zero();
|
||||
|
@ -366,7 +363,7 @@ where
|
|||
from: Vec2,
|
||||
to: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> Arc2dBuilder<'_, Config, Clear> {
|
||||
self.arc_2d_from_to(center, from, to, color, core::convert::identity)
|
||||
}
|
||||
|
||||
|
@ -412,7 +409,7 @@ where
|
|||
from: Vec2,
|
||||
to: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> Arc2dBuilder<'_, Config, Clear> {
|
||||
self.arc_2d_from_to(center, from, to, color, |angle| angle - TAU)
|
||||
}
|
||||
|
||||
|
@ -424,7 +421,7 @@ where
|
|||
to: Vec2,
|
||||
color: impl Into<Color>,
|
||||
angle_fn: impl Fn(f32) -> f32,
|
||||
) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> Arc2dBuilder<'_, Config, Clear> {
|
||||
// `from` and `to` can be the same here since in either case nothing gets rendered and the
|
||||
// orientation ambiguity of `up` doesn't matter
|
||||
let from_axis = (from - center).normalize_or_zero();
|
||||
|
@ -446,13 +443,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A builder returned by [`Gizmos::arc_2d`].
|
||||
pub struct Arc3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
/// A builder returned by [`GizmoBuffer::arc_2d`].
|
||||
pub struct Arc3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
// this is the vertex the arc starts on in the XZ plane. For the normal arc_3d method this is
|
||||
// always starting at Vec3::X. For the short/long arc methods we actually need a way to start
|
||||
// at the from position and this is where this internal field comes into play. Some implicit
|
||||
|
@ -470,7 +467,7 @@ where
|
|||
resolution: Option<u32>,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Arc3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Arc3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -482,7 +479,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Arc3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Arc3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//! Additional [`Gizmos`] Functions -- Arrows
|
||||
//! Additional [`GizmoBuffer`] Functions -- Arrows
|
||||
//!
|
||||
//! Includes the implementation of [`Gizmos::arrow`] and [`Gizmos::arrow_2d`],
|
||||
//! Includes the implementation of [`GizmoBuffer::arrow`] and [`GizmoBuffer::arrow_2d`],
|
||||
//! and assorted support items.
|
||||
|
||||
use crate::prelude::{GizmoConfigGroup, Gizmos};
|
||||
use crate::{gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
|
||||
use bevy_color::{
|
||||
palettes::basic::{BLUE, GREEN, RED},
|
||||
Color,
|
||||
|
@ -11,13 +11,13 @@ use bevy_color::{
|
|||
use bevy_math::{Quat, Vec2, Vec3, Vec3Swizzles};
|
||||
use bevy_transform::TransformPoint;
|
||||
|
||||
/// A builder returned by [`Gizmos::arrow`] and [`Gizmos::arrow_2d`]
|
||||
pub struct ArrowBuilder<'a, 'w, 's, Config, Clear>
|
||||
/// A builder returned by [`GizmoBuffer::arrow`] and [`GizmoBuffer::arrow_2d`]
|
||||
pub struct ArrowBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
start: Vec3,
|
||||
end: Vec3,
|
||||
color: Color,
|
||||
|
@ -25,7 +25,7 @@ where
|
|||
tip_length: f32,
|
||||
}
|
||||
|
||||
impl<Config, Clear> ArrowBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> ArrowBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -58,12 +58,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for ArrowBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for ArrowBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Draws the arrow, by drawing lines with the stored [`Gizmos`]
|
||||
/// Draws the arrow, by drawing lines with the stored [`GizmoBuffer`]
|
||||
fn drop(&mut self) {
|
||||
if !self.gizmos.enabled {
|
||||
return;
|
||||
|
@ -101,7 +101,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -125,7 +125,7 @@ where
|
|||
start: Vec3,
|
||||
end: Vec3,
|
||||
color: impl Into<Color>,
|
||||
) -> ArrowBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> ArrowBuilder<'_, Config, Clear> {
|
||||
let length = (end - start).length();
|
||||
ArrowBuilder {
|
||||
gizmos: self,
|
||||
|
@ -156,12 +156,12 @@ where
|
|||
start: Vec2,
|
||||
end: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> ArrowBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> ArrowBuilder<'_, Config, Clear> {
|
||||
self.arrow(start.extend(0.), end.extend(0.), color)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//! Additional [`Gizmos`] Functions -- Circles
|
||||
//! Additional [`GizmoBuffer`] Functions -- Circles
|
||||
//!
|
||||
//! Includes the implementation of [`Gizmos::circle`] and [`Gizmos::circle_2d`],
|
||||
//! Includes the implementation of [`GizmoBuffer::circle`] and [`GizmoBuffer::circle_2d`],
|
||||
//! and assorted support items.
|
||||
|
||||
use crate::prelude::{GizmoConfigGroup, Gizmos};
|
||||
use crate::{gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
|
||||
use bevy_color::Color;
|
||||
use bevy_math::{ops, Isometry2d, Isometry3d, Quat, Vec2, Vec3};
|
||||
use core::f32::consts::TAU;
|
||||
|
@ -18,7 +18,7 @@ fn ellipse_inner(half_size: Vec2, resolution: u32) -> impl Iterator<Item = Vec2>
|
|||
})
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -54,7 +54,7 @@ where
|
|||
isometry: impl Into<Isometry3d>,
|
||||
half_size: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> EllipseBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> EllipseBuilder<'_, Config, Clear> {
|
||||
EllipseBuilder {
|
||||
gizmos: self,
|
||||
isometry: isometry.into(),
|
||||
|
@ -95,7 +95,7 @@ where
|
|||
isometry: impl Into<Isometry2d>,
|
||||
half_size: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> Ellipse2dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> Ellipse2dBuilder<'_, Config, Clear> {
|
||||
Ellipse2dBuilder {
|
||||
gizmos: self,
|
||||
isometry: isometry.into(),
|
||||
|
@ -134,7 +134,7 @@ where
|
|||
isometry: impl Into<Isometry3d>,
|
||||
radius: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> EllipseBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> EllipseBuilder<'_, Config, Clear> {
|
||||
EllipseBuilder {
|
||||
gizmos: self,
|
||||
isometry: isometry.into(),
|
||||
|
@ -175,7 +175,7 @@ where
|
|||
isometry: impl Into<Isometry2d>,
|
||||
radius: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> Ellipse2dBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> Ellipse2dBuilder<'_, Config, Clear> {
|
||||
Ellipse2dBuilder {
|
||||
gizmos: self,
|
||||
isometry: isometry.into(),
|
||||
|
@ -217,7 +217,7 @@ where
|
|||
isometry: impl Into<Isometry3d>,
|
||||
radius: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> SphereBuilder<'_, 'w, 's, Config, Clear> {
|
||||
) -> SphereBuilder<'_, Config, Clear> {
|
||||
SphereBuilder {
|
||||
gizmos: self,
|
||||
radius,
|
||||
|
@ -228,20 +228,20 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A builder returned by [`Gizmos::ellipse`].
|
||||
pub struct EllipseBuilder<'a, 'w, 's, Config, Clear>
|
||||
/// A builder returned by [`GizmoBuffer::ellipse`].
|
||||
pub struct EllipseBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
isometry: Isometry3d,
|
||||
half_size: Vec2,
|
||||
color: Color,
|
||||
resolution: u32,
|
||||
}
|
||||
|
||||
impl<Config, Clear> EllipseBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> EllipseBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -253,7 +253,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for EllipseBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for EllipseBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -269,20 +269,20 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A builder returned by [`Gizmos::ellipse_2d`].
|
||||
pub struct Ellipse2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
/// A builder returned by [`GizmoBuffer::ellipse_2d`].
|
||||
pub struct Ellipse2dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
isometry: Isometry2d,
|
||||
half_size: Vec2,
|
||||
color: Color,
|
||||
resolution: u32,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Ellipse2dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Ellipse2dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -294,7 +294,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Ellipse2dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Ellipse2dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -311,13 +311,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A builder returned by [`Gizmos::sphere`].
|
||||
pub struct SphereBuilder<'a, 'w, 's, Config, Clear>
|
||||
/// A builder returned by [`GizmoBuffer::sphere`].
|
||||
pub struct SphereBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
|
||||
// Radius of the sphere
|
||||
radius: f32,
|
||||
|
@ -330,7 +330,7 @@ where
|
|||
resolution: u32,
|
||||
}
|
||||
|
||||
impl<Config, Clear> SphereBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> SphereBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -342,7 +342,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for SphereBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for SphereBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
|
|
@ -7,7 +7,7 @@ pub use bevy_gizmos_macros::GizmoConfigGroup;
|
|||
feature = "bevy_render",
|
||||
any(feature = "bevy_pbr", feature = "bevy_sprite")
|
||||
))]
|
||||
use {crate::LineGizmo, bevy_asset::Handle, bevy_ecs::component::Component};
|
||||
use {crate::GizmoAsset, bevy_asset::Handle, bevy_ecs::component::Component};
|
||||
|
||||
use bevy_ecs::{reflect::ReflectResource, system::Resource};
|
||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath};
|
||||
|
@ -57,6 +57,11 @@ pub trait GizmoConfigGroup: Reflect + TypePath + Default {}
|
|||
#[derive(Default, Reflect, GizmoConfigGroup)]
|
||||
pub struct DefaultGizmoConfigGroup;
|
||||
|
||||
/// Used when the gizmo config group needs to be type-erased.
|
||||
/// Also used for retained gizmos, which can't have a gizmo config group.
|
||||
#[derive(Default, Reflect, GizmoConfigGroup, Debug, Clone)]
|
||||
pub struct ErasedGizmoConfigGroup;
|
||||
|
||||
/// A [`Resource`] storing [`GizmoConfig`] and [`GizmoConfigGroup`] structs
|
||||
///
|
||||
/// Use `app.init_gizmo_group::<T>()` to register a custom config group.
|
||||
|
@ -133,27 +138,15 @@ impl GizmoConfigStore {
|
|||
}
|
||||
|
||||
/// A struct that stores configuration for gizmos.
|
||||
#[derive(Clone, Reflect)]
|
||||
#[derive(Clone, Reflect, Debug)]
|
||||
pub struct GizmoConfig {
|
||||
/// Set to `false` to stop drawing gizmos.
|
||||
///
|
||||
/// Defaults to `true`.
|
||||
pub enabled: bool,
|
||||
/// Line width specified in pixels.
|
||||
///
|
||||
/// If `line_perspective` is `true` then this is the size in pixels at the camera's near plane.
|
||||
///
|
||||
/// Defaults to `2.0`.
|
||||
pub line_width: f32,
|
||||
/// Apply perspective to gizmo lines.
|
||||
///
|
||||
/// This setting only affects 3D, non-orthographic cameras.
|
||||
///
|
||||
/// Defaults to `false`.
|
||||
pub line_perspective: bool,
|
||||
/// Determine the style of gizmo lines.
|
||||
pub line_style: GizmoLineStyle,
|
||||
/// How closer to the camera than real geometry the line should be.
|
||||
/// Line settings.
|
||||
pub line: GizmoLineConfig,
|
||||
/// How closer to the camera than real geometry the gizmos should be.
|
||||
///
|
||||
/// In 2D this setting has no effect and is effectively always -1.
|
||||
///
|
||||
|
@ -171,23 +164,48 @@ pub struct GizmoConfig {
|
|||
/// Gizmos will only be rendered to cameras with intersecting layers.
|
||||
#[cfg(feature = "bevy_render")]
|
||||
pub render_layers: bevy_render::view::RenderLayers,
|
||||
|
||||
/// Describe how lines should join
|
||||
pub line_joints: GizmoLineJoint,
|
||||
}
|
||||
|
||||
impl Default for GizmoConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: true,
|
||||
line_width: 2.,
|
||||
line_perspective: false,
|
||||
line_style: GizmoLineStyle::Solid,
|
||||
line: Default::default(),
|
||||
depth_bias: 0.,
|
||||
#[cfg(feature = "bevy_render")]
|
||||
render_layers: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
line_joints: GizmoLineJoint::None,
|
||||
/// A struct that stores configuration for gizmos.
|
||||
#[derive(Clone, Reflect, Debug)]
|
||||
pub struct GizmoLineConfig {
|
||||
/// Line width specified in pixels.
|
||||
///
|
||||
/// If `perspective` is `true` then this is the size in pixels at the camera's near plane.
|
||||
///
|
||||
/// Defaults to `2.0`.
|
||||
pub width: f32,
|
||||
/// Apply perspective to gizmo lines.
|
||||
///
|
||||
/// This setting only affects 3D, non-orthographic cameras.
|
||||
///
|
||||
/// Defaults to `false`.
|
||||
pub perspective: bool,
|
||||
/// Determine the style of gizmo lines.
|
||||
pub style: GizmoLineStyle,
|
||||
/// Describe how lines should join.
|
||||
pub joints: GizmoLineJoint,
|
||||
}
|
||||
|
||||
impl Default for GizmoLineConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
width: 2.,
|
||||
perspective: false,
|
||||
style: GizmoLineStyle::Solid,
|
||||
joints: GizmoLineJoint::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,6 +218,7 @@ impl Default for GizmoConfig {
|
|||
pub(crate) struct GizmoMeshConfig {
|
||||
pub line_perspective: bool,
|
||||
pub line_style: GizmoLineStyle,
|
||||
pub line_joints: GizmoLineJoint,
|
||||
pub render_layers: bevy_render::view::RenderLayers,
|
||||
pub handle: Handle<LineGizmo>,
|
||||
pub handle: Handle<GizmoAsset>,
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
//! Additional [`Gizmos`] Functions -- Crosses
|
||||
//! Additional [`GizmoBuffer`] Functions -- Crosses
|
||||
//!
|
||||
//! Includes the implementation of [`Gizmos::cross`] and [`Gizmos::cross_2d`],
|
||||
//! Includes the implementation of [`GizmoBuffer::cross`] and [`GizmoBuffer::cross_2d`],
|
||||
//! and assorted support items.
|
||||
|
||||
use crate::prelude::{GizmoConfigGroup, Gizmos};
|
||||
use crate::{gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
|
||||
use bevy_color::Color;
|
||||
use bevy_math::{Isometry2d, Isometry3d, Vec2, Vec3};
|
||||
|
||||
impl<Config> Gizmos<'_, '_, Config>
|
||||
impl<Config, Clear> GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Draw a cross in 3D with the given `isometry` applied.
|
||||
///
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
//! Additional [`Gizmos`] Functions -- Curves
|
||||
//! Additional [`GizmoBuffer`] Functions -- Curves
|
||||
//!
|
||||
//! Includes the implementation of [`Gizmos::curve_2d`],
|
||||
//! [`Gizmos::curve_3d`] and assorted support items.
|
||||
//! Includes the implementation of [`GizmoBuffer::curve_2d`],
|
||||
//! [`GizmoBuffer::curve_3d`] and assorted support items.
|
||||
|
||||
use bevy_color::Color;
|
||||
use bevy_math::{curve::Curve, Vec2, Vec3};
|
||||
|
||||
use crate::prelude::{GizmoConfigGroup, Gizmos};
|
||||
use crate::{gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
|
||||
|
||||
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
//! A module for the [`Gizmos`] [`SystemParam`].
|
||||
|
||||
use core::{iter, marker::PhantomData, mem};
|
||||
use core::{
|
||||
iter,
|
||||
marker::PhantomData,
|
||||
mem,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
use bevy_color::{Color, LinearRgba};
|
||||
use bevy_ecs::{
|
||||
|
@ -9,6 +14,7 @@ use bevy_ecs::{
|
|||
world::{unsafe_world_cell::UnsafeWorldCell, World},
|
||||
};
|
||||
use bevy_math::{Isometry2d, Isometry3d, Vec2, Vec3};
|
||||
use bevy_reflect::Reflect;
|
||||
use bevy_transform::TransformPoint;
|
||||
use bevy_utils::default;
|
||||
|
||||
|
@ -135,13 +141,34 @@ where
|
|||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
buffer: Deferred<'s, GizmoBuffer<Config, Clear>>,
|
||||
pub(crate) enabled: bool,
|
||||
/// The currently used [`GizmoConfig`]
|
||||
pub config: &'w GizmoConfig,
|
||||
/// The currently used [`GizmoConfigGroup`]
|
||||
pub config_ext: &'w Config,
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> Deref for Gizmos<'w, 's, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Target = GizmoBuffer<Config, Clear>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.buffer
|
||||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> DerefMut for Gizmos<'w, 's, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.buffer
|
||||
}
|
||||
}
|
||||
|
||||
type GizmosState<Config, Clear> = (
|
||||
Deferred<'static, GizmoBuffer<Config, Clear>>,
|
||||
Res<'static, GizmoConfigStore>,
|
||||
|
@ -204,7 +231,7 @@ where
|
|||
change_tick: Tick,
|
||||
) -> Self::Item<'w, 's> {
|
||||
// SAFETY: Delegated to existing `SystemParam` implementations.
|
||||
let (f0, f1) = unsafe {
|
||||
let (mut f0, f1) = unsafe {
|
||||
GizmosState::<Config, Clear>::get_param(
|
||||
&mut state.state,
|
||||
system_meta,
|
||||
|
@ -212,13 +239,15 @@ where
|
|||
change_tick,
|
||||
)
|
||||
};
|
||||
// Accessing the GizmoConfigStore in the immediate mode API reduces performance significantly.
|
||||
// Implementing SystemParam manually allows us to do it to here
|
||||
// Having config available allows for early returns when gizmos are disabled
|
||||
|
||||
// Accessing the GizmoConfigStore in every API call reduces performance significantly.
|
||||
// Implementing SystemParam manually allows us to cache whether the config is currently enabled.
|
||||
// Having this available allows for cheap early returns when gizmos are disabled.
|
||||
let (config, config_ext) = f1.into_inner().config::<Config>();
|
||||
f0.enabled = config.enabled;
|
||||
|
||||
Gizmos {
|
||||
buffer: f0,
|
||||
enabled: config.enabled,
|
||||
config,
|
||||
config_ext,
|
||||
}
|
||||
|
@ -236,16 +265,20 @@ where
|
|||
{
|
||||
}
|
||||
|
||||
struct GizmoBuffer<Config, Clear>
|
||||
/// Buffer for gizmo vertex data.
|
||||
#[derive(Debug, Clone, Reflect)]
|
||||
pub struct GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
list_positions: Vec<Vec3>,
|
||||
list_colors: Vec<LinearRgba>,
|
||||
strip_positions: Vec<Vec3>,
|
||||
strip_colors: Vec<LinearRgba>,
|
||||
marker: PhantomData<(Config, Clear)>,
|
||||
pub(crate) enabled: bool,
|
||||
pub(crate) list_positions: Vec<Vec3>,
|
||||
pub(crate) list_colors: Vec<LinearRgba>,
|
||||
pub(crate) strip_positions: Vec<Vec3>,
|
||||
pub(crate) strip_colors: Vec<LinearRgba>,
|
||||
#[reflect(ignore)]
|
||||
pub(crate) marker: PhantomData<(Config, Clear)>,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Default for GizmoBuffer<Config, Clear>
|
||||
|
@ -254,16 +287,29 @@ where
|
|||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
list_positions: default(),
|
||||
list_colors: default(),
|
||||
strip_positions: default(),
|
||||
strip_colors: default(),
|
||||
GizmoBuffer {
|
||||
enabled: true,
|
||||
list_positions: Vec::new(),
|
||||
list_colors: Vec::new(),
|
||||
strip_positions: Vec::new(),
|
||||
strip_colors: Vec::new(),
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read-only view into [`GizmoBuffer`] data.
|
||||
pub struct GizmoBufferView<'a> {
|
||||
/// Vertex positions for line-list topology.
|
||||
pub list_positions: &'a Vec<Vec3>,
|
||||
/// Vertex colors for line-list topology.
|
||||
pub list_colors: &'a Vec<LinearRgba>,
|
||||
/// Vertex positions for line-strip topology.
|
||||
pub strip_positions: &'a Vec<Vec3>,
|
||||
/// Vertex colors for line-strip topology.
|
||||
pub strip_colors: &'a Vec<LinearRgba>,
|
||||
}
|
||||
|
||||
impl<Config, Clear> SystemBuffer for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
|
@ -278,11 +324,35 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Clear all data.
|
||||
pub fn clear(&mut self) {
|
||||
self.list_positions.clear();
|
||||
self.list_colors.clear();
|
||||
self.strip_positions.clear();
|
||||
self.strip_colors.clear();
|
||||
}
|
||||
|
||||
/// Read-only view into the buffers data.
|
||||
pub fn buffer(&self) -> GizmoBufferView {
|
||||
let GizmoBuffer {
|
||||
list_positions,
|
||||
list_colors,
|
||||
strip_positions,
|
||||
strip_colors,
|
||||
..
|
||||
} = self;
|
||||
GizmoBufferView {
|
||||
list_positions,
|
||||
list_colors,
|
||||
strip_positions,
|
||||
strip_colors,
|
||||
}
|
||||
}
|
||||
/// Draw a line in 3D from `start` to `end`.
|
||||
///
|
||||
/// This should be called for each frame the line needs to be rendered.
|
||||
|
@ -409,10 +479,10 @@ where
|
|||
return;
|
||||
}
|
||||
self.extend_strip_positions(positions);
|
||||
let len = self.buffer.strip_positions.len();
|
||||
let len = self.strip_positions.len();
|
||||
let linear_color = LinearRgba::from(color.into());
|
||||
self.buffer.strip_colors.resize(len - 1, linear_color);
|
||||
self.buffer.strip_colors.push(LinearRgba::NAN);
|
||||
self.strip_colors.resize(len - 1, linear_color);
|
||||
self.strip_colors.push(LinearRgba::NAN);
|
||||
}
|
||||
|
||||
/// Draw a line in 3D made of straight segments between the points, with a color gradient.
|
||||
|
@ -447,7 +517,7 @@ where
|
|||
strip_positions,
|
||||
strip_colors,
|
||||
..
|
||||
} = &mut *self.buffer;
|
||||
} = self;
|
||||
|
||||
let (min, _) = points.size_hint();
|
||||
strip_positions.reserve(min);
|
||||
|
@ -726,12 +796,12 @@ where
|
|||
|
||||
#[inline]
|
||||
fn extend_list_positions(&mut self, positions: impl IntoIterator<Item = Vec3>) {
|
||||
self.buffer.list_positions.extend(positions);
|
||||
self.list_positions.extend(positions);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn extend_list_colors(&mut self, colors: impl IntoIterator<Item = impl Into<Color>>) {
|
||||
self.buffer.list_colors.extend(
|
||||
self.list_colors.extend(
|
||||
colors
|
||||
.into_iter()
|
||||
.map(|color| LinearRgba::from(color.into())),
|
||||
|
@ -743,15 +813,14 @@ where
|
|||
let polymorphic_color: Color = color.into();
|
||||
let linear_color = LinearRgba::from(polymorphic_color);
|
||||
|
||||
self.buffer
|
||||
.list_colors
|
||||
self.list_colors
|
||||
.extend(iter::repeat(linear_color).take(count));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn extend_strip_positions(&mut self, positions: impl IntoIterator<Item = Vec3>) {
|
||||
self.buffer.strip_positions.extend(positions);
|
||||
self.buffer.strip_positions.push(Vec3::NAN);
|
||||
self.strip_positions.extend(positions);
|
||||
self.strip_positions.push(Vec3::NAN);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
//! Additional [`Gizmos`] Functions -- Grids
|
||||
//! Additional [`GizmoBuffer`] Functions -- Grids
|
||||
//!
|
||||
//! Includes the implementation of [`Gizmos::grid`] and [`Gizmos::grid_2d`].
|
||||
//! Includes the implementation of [`GizmoBuffer::grid`] and [`GizmoBuffer::grid_2d`].
|
||||
//! and assorted support items.
|
||||
|
||||
use crate::prelude::{GizmoConfigGroup, Gizmos};
|
||||
use crate::{gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
|
||||
use bevy_color::Color;
|
||||
use bevy_math::{ops, Isometry2d, Isometry3d, Quat, UVec2, UVec3, Vec2, Vec3, Vec3Swizzles};
|
||||
|
||||
/// A builder returned by [`Gizmos::grid_3d`]
|
||||
pub struct GridBuilder3d<'a, 'w, 's, Config, Clear>
|
||||
/// A builder returned by [`GizmoBuffer::grid_3d`]
|
||||
pub struct GridBuilder3d<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
isometry: Isometry3d,
|
||||
spacing: Vec3,
|
||||
cell_count: UVec3,
|
||||
|
@ -21,13 +21,13 @@ where
|
|||
outer_edges: [bool; 3],
|
||||
color: Color,
|
||||
}
|
||||
/// A builder returned by [`Gizmos::grid`] and [`Gizmos::grid_2d`]
|
||||
pub struct GridBuilder2d<'a, 'w, 's, Config, Clear>
|
||||
/// A builder returned by [`GizmoBuffer::grid`] and [`GizmoBuffer::grid_2d`]
|
||||
pub struct GridBuilder2d<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
isometry: Isometry3d,
|
||||
spacing: Vec2,
|
||||
cell_count: UVec2,
|
||||
|
@ -36,7 +36,7 @@ where
|
|||
color: Color,
|
||||
}
|
||||
|
||||
impl<Config, Clear> GridBuilder3d<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> GridBuilder3d<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -92,7 +92,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> GridBuilder2d<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> GridBuilder2d<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -136,12 +136,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for GridBuilder3d<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for GridBuilder3d<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Draws a grid, by drawing lines with the stored [`Gizmos`]
|
||||
/// Draws a grid, by drawing lines with the stored [`GizmoBuffer`]
|
||||
fn drop(&mut self) {
|
||||
draw_grid(
|
||||
self.gizmos,
|
||||
|
@ -155,7 +155,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for GridBuilder2d<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for GridBuilder2d<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -172,7 +172,7 @@ where
|
|||
);
|
||||
}
|
||||
}
|
||||
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -222,7 +222,7 @@ where
|
|||
cell_count: UVec2,
|
||||
spacing: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> GridBuilder2d<'_, 'w, 's, Config, Clear> {
|
||||
) -> GridBuilder2d<'_, Config, Clear> {
|
||||
GridBuilder2d {
|
||||
gizmos: self,
|
||||
isometry: isometry.into(),
|
||||
|
@ -276,7 +276,7 @@ where
|
|||
cell_count: UVec3,
|
||||
spacing: Vec3,
|
||||
color: impl Into<Color>,
|
||||
) -> GridBuilder3d<'_, 'w, 's, Config, Clear> {
|
||||
) -> GridBuilder3d<'_, Config, Clear> {
|
||||
GridBuilder3d {
|
||||
gizmos: self,
|
||||
isometry: isometry.into(),
|
||||
|
@ -330,7 +330,7 @@ where
|
|||
cell_count: UVec2,
|
||||
spacing: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> GridBuilder2d<'_, 'w, 's, Config, Clear> {
|
||||
) -> GridBuilder2d<'_, Config, Clear> {
|
||||
let isometry = isometry.into();
|
||||
GridBuilder2d {
|
||||
gizmos: self,
|
||||
|
@ -349,7 +349,7 @@ where
|
|||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn draw_grid<Config, Clear>(
|
||||
gizmos: &mut Gizmos<'_, '_, Config, Clear>,
|
||||
gizmos: &mut GizmoBuffer<Config, Clear>,
|
||||
isometry: Isometry3d,
|
||||
spacing: Vec3,
|
||||
cell_count: UVec3,
|
||||
|
|
|
@ -41,6 +41,7 @@ pub mod curves;
|
|||
pub mod gizmos;
|
||||
pub mod grid;
|
||||
pub mod primitives;
|
||||
pub mod retained;
|
||||
pub mod rounded_box;
|
||||
|
||||
#[cfg(all(feature = "bevy_pbr", feature = "bevy_render"))]
|
||||
|
@ -62,11 +63,12 @@ pub mod prelude {
|
|||
pub use crate::{
|
||||
config::{
|
||||
DefaultGizmoConfigGroup, GizmoConfig, GizmoConfigGroup, GizmoConfigStore,
|
||||
GizmoLineJoint, GizmoLineStyle,
|
||||
GizmoLineConfig, GizmoLineJoint, GizmoLineStyle,
|
||||
},
|
||||
gizmos::Gizmos,
|
||||
primitives::{dim2::GizmoPrimitive2d, dim3::GizmoPrimitive3d},
|
||||
AppGizmoBuilder,
|
||||
retained::Gizmo,
|
||||
AppGizmoBuilder, GizmoAsset,
|
||||
};
|
||||
|
||||
#[cfg(all(feature = "bevy_pbr", feature = "bevy_render"))]
|
||||
|
@ -75,12 +77,11 @@ pub mod prelude {
|
|||
|
||||
use bevy_app::{App, FixedFirst, FixedLast, Last, Plugin, RunFixedMainLoop};
|
||||
use bevy_asset::{Asset, AssetApp, AssetId, Assets, Handle};
|
||||
use bevy_color::LinearRgba;
|
||||
use bevy_ecs::{
|
||||
schedule::{IntoSystemConfigs, SystemSet},
|
||||
system::{Res, ResMut, Resource},
|
||||
};
|
||||
use bevy_math::Vec3;
|
||||
use bevy_math::Vec4;
|
||||
use bevy_reflect::TypePath;
|
||||
|
||||
#[cfg(all(
|
||||
|
@ -89,8 +90,11 @@ use bevy_reflect::TypePath;
|
|||
))]
|
||||
use crate::config::GizmoMeshConfig;
|
||||
|
||||
use crate::{config::ErasedGizmoConfigGroup, gizmos::GizmoBuffer};
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
use {
|
||||
crate::retained::extract_linegizmos,
|
||||
bevy_ecs::{
|
||||
component::Component,
|
||||
entity::Entity,
|
||||
|
@ -100,6 +104,7 @@ use {
|
|||
Commands, SystemParamItem,
|
||||
},
|
||||
},
|
||||
bevy_math::{Affine3, Affine3A},
|
||||
bevy_render::{
|
||||
extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
|
||||
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
|
||||
|
@ -126,7 +131,7 @@ use bevy_utils::TypeIdMap;
|
|||
use config::{
|
||||
DefaultGizmoConfigGroup, GizmoConfig, GizmoConfigGroup, GizmoConfigStore, GizmoLineJoint,
|
||||
};
|
||||
use core::{any::TypeId, mem};
|
||||
use core::{any::TypeId, marker::PhantomData, mem};
|
||||
use gizmos::{GizmoStorage, Swap};
|
||||
#[cfg(all(feature = "bevy_pbr", feature = "bevy_render"))]
|
||||
use light::LightGizmoPlugin;
|
||||
|
@ -158,8 +163,8 @@ impl Plugin for GizmoPlugin {
|
|||
|
||||
app.register_type::<GizmoConfig>()
|
||||
.register_type::<GizmoConfigStore>()
|
||||
.init_asset::<LineGizmo>()
|
||||
.init_resource::<LineGizmoHandles>()
|
||||
.init_asset::<GizmoAsset>()
|
||||
.init_resource::<GizmoHandles>()
|
||||
// We insert the Resource GizmoConfigStore into the world implicitly here if it does not exist.
|
||||
.init_gizmo_group::<DefaultGizmoConfigGroup>();
|
||||
|
||||
|
@ -178,7 +183,7 @@ impl Plugin for GizmoPlugin {
|
|||
prepare_line_gizmo_bind_group.in_set(RenderSet::PrepareBindGroups),
|
||||
);
|
||||
|
||||
render_app.add_systems(ExtractSchedule, extract_gizmo_data);
|
||||
render_app.add_systems(ExtractSchedule, (extract_gizmo_data, extract_linegizmos));
|
||||
|
||||
#[cfg(feature = "bevy_sprite")]
|
||||
if app.is_plugin_added::<bevy_sprite::SpritePlugin>() {
|
||||
|
@ -245,13 +250,12 @@ impl AppGizmoBuilder for App {
|
|||
.get_resource_or_init::<GizmoConfigStore>()
|
||||
.register::<Config>();
|
||||
|
||||
let mut handles = self.world_mut().get_resource_or_init::<LineGizmoHandles>();
|
||||
let mut handles = self.world_mut().get_resource_or_init::<GizmoHandles>();
|
||||
|
||||
handles.list.insert(TypeId::of::<Config>(), None);
|
||||
handles.strip.insert(TypeId::of::<Config>(), None);
|
||||
handles.handles.insert(TypeId::of::<Config>(), None);
|
||||
|
||||
// These handles are safe to mutate in any order
|
||||
self.allow_ambiguous_resource::<LineGizmoHandles>();
|
||||
self.allow_ambiguous_resource::<GizmoHandles>();
|
||||
|
||||
self.init_resource::<GizmoStorage<Config, ()>>()
|
||||
.init_resource::<GizmoStorage<Config, Fixed>>()
|
||||
|
@ -300,9 +304,8 @@ impl AppGizmoBuilder for App {
|
|||
// That way iteration order is stable across executions and depends on the order of configuration
|
||||
// group creation.
|
||||
#[derive(Resource, Default)]
|
||||
struct LineGizmoHandles {
|
||||
list: TypeIdMap<Option<Handle<LineGizmo>>>,
|
||||
strip: TypeIdMap<Option<Handle<LineGizmo>>>,
|
||||
struct GizmoHandles {
|
||||
handles: TypeIdMap<Option<Handle<GizmoAsset>>>,
|
||||
}
|
||||
|
||||
/// Start a new gizmo clearing context.
|
||||
|
@ -378,52 +381,34 @@ pub struct UpdateGizmoMeshes;
|
|||
///
|
||||
/// This also clears the default `GizmoStorage`.
|
||||
fn update_gizmo_meshes<Config: GizmoConfigGroup>(
|
||||
mut line_gizmos: ResMut<Assets<LineGizmo>>,
|
||||
mut handles: ResMut<LineGizmoHandles>,
|
||||
mut gizmo_assets: ResMut<Assets<GizmoAsset>>,
|
||||
mut handles: ResMut<GizmoHandles>,
|
||||
mut storage: ResMut<GizmoStorage<Config, ()>>,
|
||||
config_store: Res<GizmoConfigStore>,
|
||||
) {
|
||||
if storage.list_positions.is_empty() {
|
||||
handles.list.insert(TypeId::of::<Config>(), None);
|
||||
} else if let Some(handle) = handles.list.get_mut(&TypeId::of::<Config>()) {
|
||||
if storage.list_positions.is_empty() && storage.strip_positions.is_empty() {
|
||||
handles.handles.insert(TypeId::of::<Config>(), None);
|
||||
} else if let Some(handle) = handles.handles.get_mut(&TypeId::of::<Config>()) {
|
||||
if let Some(handle) = handle {
|
||||
let list = line_gizmos.get_mut(handle.id()).unwrap();
|
||||
let gizmo = gizmo_assets.get_mut(handle.id()).unwrap();
|
||||
|
||||
list.positions = mem::take(&mut storage.list_positions);
|
||||
list.colors = mem::take(&mut storage.list_colors);
|
||||
gizmo.buffer.list_positions = mem::take(&mut storage.list_positions);
|
||||
gizmo.buffer.list_colors = mem::take(&mut storage.list_colors);
|
||||
gizmo.buffer.strip_positions = mem::take(&mut storage.strip_positions);
|
||||
gizmo.buffer.strip_colors = mem::take(&mut storage.strip_colors);
|
||||
} else {
|
||||
let list = LineGizmo {
|
||||
strip: false,
|
||||
let gizmo = GizmoAsset {
|
||||
config_ty: TypeId::of::<Config>(),
|
||||
positions: mem::take(&mut storage.list_positions),
|
||||
colors: mem::take(&mut storage.list_colors),
|
||||
joints: GizmoLineJoint::None,
|
||||
buffer: GizmoBuffer {
|
||||
enabled: true,
|
||||
list_positions: mem::take(&mut storage.list_positions),
|
||||
list_colors: mem::take(&mut storage.list_colors),
|
||||
strip_positions: mem::take(&mut storage.strip_positions),
|
||||
strip_colors: mem::take(&mut storage.strip_colors),
|
||||
marker: PhantomData,
|
||||
},
|
||||
};
|
||||
|
||||
*handle = Some(line_gizmos.add(list));
|
||||
}
|
||||
}
|
||||
|
||||
let (config, _) = config_store.config::<Config>();
|
||||
if storage.strip_positions.is_empty() {
|
||||
handles.strip.insert(TypeId::of::<Config>(), None);
|
||||
} else if let Some(handle) = handles.strip.get_mut(&TypeId::of::<Config>()) {
|
||||
if let Some(handle) = handle {
|
||||
let strip = line_gizmos.get_mut(handle.id()).unwrap();
|
||||
|
||||
strip.positions = mem::take(&mut storage.strip_positions);
|
||||
strip.colors = mem::take(&mut storage.strip_colors);
|
||||
strip.joints = config.line_joints;
|
||||
} else {
|
||||
let strip = LineGizmo {
|
||||
strip: true,
|
||||
joints: config.line_joints,
|
||||
config_ty: TypeId::of::<Config>(),
|
||||
positions: mem::take(&mut storage.strip_positions),
|
||||
colors: mem::take(&mut storage.strip_colors),
|
||||
};
|
||||
|
||||
*handle = Some(line_gizmos.add(strip));
|
||||
*handle = Some(gizmo_assets.add(gizmo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -431,10 +416,10 @@ fn update_gizmo_meshes<Config: GizmoConfigGroup>(
|
|||
#[cfg(feature = "bevy_render")]
|
||||
fn extract_gizmo_data(
|
||||
mut commands: Commands,
|
||||
handles: Extract<Res<LineGizmoHandles>>,
|
||||
handles: Extract<Res<GizmoHandles>>,
|
||||
config: Extract<Res<GizmoConfigStore>>,
|
||||
) {
|
||||
for (group_type_id, handle) in handles.list.iter().chain(handles.strip.iter()) {
|
||||
for (group_type_id, handle) in &handles.handles {
|
||||
let Some((config, _)) = config.get_config_dyn(group_type_id) else {
|
||||
continue;
|
||||
};
|
||||
|
@ -447,7 +432,7 @@ fn extract_gizmo_data(
|
|||
continue;
|
||||
};
|
||||
|
||||
let joints_resolution = if let GizmoLineJoint::Round(resolution) = config.line_joints {
|
||||
let joints_resolution = if let GizmoLineJoint::Round(resolution) = config.line.joints {
|
||||
resolution
|
||||
} else {
|
||||
0
|
||||
|
@ -455,7 +440,8 @@ fn extract_gizmo_data(
|
|||
|
||||
commands.spawn((
|
||||
LineGizmoUniform {
|
||||
line_width: config.line_width,
|
||||
world_from_local: Affine3::from(&Affine3A::IDENTITY).to_transpose(),
|
||||
line_width: config.line.width,
|
||||
depth_bias: config.depth_bias,
|
||||
joints_resolution,
|
||||
#[cfg(feature = "webgl")]
|
||||
|
@ -463,8 +449,9 @@ fn extract_gizmo_data(
|
|||
},
|
||||
#[cfg(any(feature = "bevy_pbr", feature = "bevy_sprite"))]
|
||||
GizmoMeshConfig {
|
||||
line_perspective: config.line_perspective,
|
||||
line_style: config.line_style,
|
||||
line_perspective: config.line.perspective,
|
||||
line_style: config.line.style,
|
||||
line_joints: config.line.joints,
|
||||
render_layers: config.render_layers.clone(),
|
||||
handle: handle.clone(),
|
||||
},
|
||||
|
@ -479,6 +466,7 @@ fn extract_gizmo_data(
|
|||
#[cfg(feature = "bevy_render")]
|
||||
#[derive(Component, ShaderType, Clone, Copy)]
|
||||
struct LineGizmoUniform {
|
||||
world_from_local: [Vec4; 3],
|
||||
line_width: f32,
|
||||
depth_bias: f32,
|
||||
// Only used by gizmo line t if the current configs `line_joints` is set to `GizmoLineJoint::Round(_)`
|
||||
|
@ -488,34 +476,51 @@ struct LineGizmoUniform {
|
|||
_padding: f32,
|
||||
}
|
||||
|
||||
/// A gizmo asset that represents a line.
|
||||
/// A collection of gizmos.
|
||||
///
|
||||
/// Has the same gizmo drawing API as [`Gizmos`](crate::gizmos::Gizmos).
|
||||
#[derive(Asset, Debug, Clone, TypePath)]
|
||||
pub struct LineGizmo {
|
||||
/// Positions of the gizmo's vertices
|
||||
pub positions: Vec<Vec3>,
|
||||
/// Colors of the gizmo's vertices
|
||||
pub colors: Vec<LinearRgba>,
|
||||
/// Whether this gizmo's topology is a line-strip or line-list
|
||||
pub strip: bool,
|
||||
/// Whether this gizmo should draw line joints. This is only applicable if the gizmo's topology is line-strip.
|
||||
pub joints: GizmoLineJoint,
|
||||
/// The type of the gizmo's configuration group
|
||||
pub config_ty: TypeId,
|
||||
pub struct GizmoAsset {
|
||||
/// vertex buffers.
|
||||
buffer: GizmoBuffer<ErasedGizmoConfigGroup, ()>,
|
||||
config_ty: TypeId,
|
||||
}
|
||||
|
||||
impl GizmoAsset {
|
||||
/// Create a new [`GizmoAsset`].
|
||||
pub fn new() -> Self {
|
||||
GizmoAsset {
|
||||
buffer: GizmoBuffer::default(),
|
||||
config_ty: TypeId::of::<ErasedGizmoConfigGroup>(),
|
||||
}
|
||||
}
|
||||
|
||||
/// The type of the gizmo's configuration group.
|
||||
pub fn config_typeid(&self) -> TypeId {
|
||||
self.config_ty
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GizmoAsset {
|
||||
fn default() -> Self {
|
||||
GizmoAsset::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
#[derive(Debug, Clone)]
|
||||
struct GpuLineGizmo {
|
||||
position_buffer: Buffer,
|
||||
color_buffer: Buffer,
|
||||
vertex_count: u32,
|
||||
strip: bool,
|
||||
joints: GizmoLineJoint,
|
||||
list_position_buffer: Buffer,
|
||||
list_color_buffer: Buffer,
|
||||
list_vertex_count: u32,
|
||||
strip_position_buffer: Buffer,
|
||||
strip_color_buffer: Buffer,
|
||||
strip_vertex_count: u32,
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
impl RenderAsset for GpuLineGizmo {
|
||||
type SourceAsset = LineGizmo;
|
||||
type SourceAsset = GizmoAsset;
|
||||
type Param = SRes<RenderDevice>;
|
||||
|
||||
fn prepare_asset(
|
||||
|
@ -523,26 +528,37 @@ impl RenderAsset for GpuLineGizmo {
|
|||
_: AssetId<Self::SourceAsset>,
|
||||
render_device: &mut SystemParamItem<Self::Param>,
|
||||
) -> Result<Self, PrepareAssetError<Self::SourceAsset>> {
|
||||
let position_buffer_data = cast_slice(&gizmo.positions);
|
||||
let position_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
let list_position_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
usage: BufferUsages::VERTEX,
|
||||
label: Some("LineGizmo Position Buffer"),
|
||||
contents: position_buffer_data,
|
||||
contents: cast_slice(&gizmo.buffer.list_positions),
|
||||
});
|
||||
|
||||
let color_buffer_data = cast_slice(&gizmo.colors);
|
||||
let color_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
let list_color_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
usage: BufferUsages::VERTEX,
|
||||
label: Some("LineGizmo Color Buffer"),
|
||||
contents: color_buffer_data,
|
||||
contents: cast_slice(&gizmo.buffer.list_colors),
|
||||
});
|
||||
|
||||
let strip_position_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
usage: BufferUsages::VERTEX,
|
||||
label: Some("LineGizmo Strip Position Buffer"),
|
||||
contents: cast_slice(&gizmo.buffer.strip_positions),
|
||||
});
|
||||
|
||||
let strip_color_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||
usage: BufferUsages::VERTEX,
|
||||
label: Some("LineGizmo Strip Color Buffer"),
|
||||
contents: cast_slice(&gizmo.buffer.strip_colors),
|
||||
});
|
||||
|
||||
Ok(GpuLineGizmo {
|
||||
position_buffer,
|
||||
color_buffer,
|
||||
vertex_count: gizmo.positions.len() as u32,
|
||||
strip: gizmo.strip,
|
||||
joints: gizmo.joints,
|
||||
list_position_buffer,
|
||||
list_color_buffer,
|
||||
list_vertex_count: gizmo.buffer.list_positions.len() as u32,
|
||||
strip_position_buffer,
|
||||
strip_color_buffer,
|
||||
strip_vertex_count: gizmo.buffer.strip_positions.len() as u32,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -606,12 +622,12 @@ impl<const I: usize, P: PhaseItem> RenderCommand<P> for SetLineGizmoBindGroup<I>
|
|||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
struct DrawLineGizmo;
|
||||
struct DrawLineGizmo<const STRIP: bool>;
|
||||
#[cfg(all(
|
||||
feature = "bevy_render",
|
||||
any(feature = "bevy_pbr", feature = "bevy_sprite")
|
||||
))]
|
||||
impl<P: PhaseItem> RenderCommand<P> for DrawLineGizmo {
|
||||
impl<P: PhaseItem, const STRIP: bool> RenderCommand<P> for DrawLineGizmo<STRIP> {
|
||||
type Param = SRes<RenderAssets<GpuLineGizmo>>;
|
||||
type ViewQuery = ();
|
||||
type ItemQuery = Read<GizmoMeshConfig>;
|
||||
|
@ -631,28 +647,35 @@ impl<P: PhaseItem> RenderCommand<P> for DrawLineGizmo {
|
|||
return RenderCommandResult::Skip;
|
||||
};
|
||||
|
||||
if line_gizmo.vertex_count < 2 {
|
||||
let vertex_count = if STRIP {
|
||||
line_gizmo.strip_vertex_count
|
||||
} else {
|
||||
line_gizmo.list_vertex_count
|
||||
};
|
||||
|
||||
if vertex_count < 2 {
|
||||
return RenderCommandResult::Success;
|
||||
}
|
||||
|
||||
let instances = if line_gizmo.strip {
|
||||
let instances = if STRIP {
|
||||
let item_size = VertexFormat::Float32x3.size();
|
||||
let buffer_size = line_gizmo.position_buffer.size() - item_size;
|
||||
let buffer_size = line_gizmo.strip_position_buffer.size() - item_size;
|
||||
|
||||
pass.set_vertex_buffer(0, line_gizmo.position_buffer.slice(..buffer_size));
|
||||
pass.set_vertex_buffer(1, line_gizmo.position_buffer.slice(item_size..));
|
||||
pass.set_vertex_buffer(0, line_gizmo.strip_position_buffer.slice(..buffer_size));
|
||||
pass.set_vertex_buffer(1, line_gizmo.strip_position_buffer.slice(item_size..));
|
||||
|
||||
let item_size = VertexFormat::Float32x4.size();
|
||||
let buffer_size = line_gizmo.color_buffer.size() - item_size;
|
||||
pass.set_vertex_buffer(2, line_gizmo.color_buffer.slice(..buffer_size));
|
||||
pass.set_vertex_buffer(3, line_gizmo.color_buffer.slice(item_size..));
|
||||
let buffer_size = line_gizmo.strip_color_buffer.size() - item_size;
|
||||
|
||||
u32::max(line_gizmo.vertex_count, 1) - 1
|
||||
pass.set_vertex_buffer(2, line_gizmo.strip_color_buffer.slice(..buffer_size));
|
||||
pass.set_vertex_buffer(3, line_gizmo.strip_color_buffer.slice(item_size..));
|
||||
|
||||
vertex_count - 1
|
||||
} else {
|
||||
pass.set_vertex_buffer(0, line_gizmo.position_buffer.slice(..));
|
||||
pass.set_vertex_buffer(1, line_gizmo.color_buffer.slice(..));
|
||||
pass.set_vertex_buffer(0, line_gizmo.list_position_buffer.slice(..));
|
||||
pass.set_vertex_buffer(1, line_gizmo.list_color_buffer.slice(..));
|
||||
|
||||
line_gizmo.vertex_count / 2
|
||||
vertex_count / 2
|
||||
};
|
||||
|
||||
pass.draw(0..6, 0..instances);
|
||||
|
@ -687,38 +710,43 @@ impl<P: PhaseItem> RenderCommand<P> for DrawLineJointGizmo {
|
|||
return RenderCommandResult::Skip;
|
||||
};
|
||||
|
||||
if line_gizmo.vertex_count <= 2 || !line_gizmo.strip {
|
||||
if line_gizmo.strip_vertex_count <= 2 {
|
||||
return RenderCommandResult::Success;
|
||||
};
|
||||
|
||||
if line_gizmo.joints == GizmoLineJoint::None {
|
||||
if config.line_joints == GizmoLineJoint::None {
|
||||
return RenderCommandResult::Success;
|
||||
};
|
||||
|
||||
let instances = {
|
||||
let item_size = VertexFormat::Float32x3.size();
|
||||
// position_a
|
||||
let buffer_size_a = line_gizmo.position_buffer.size() - item_size * 2;
|
||||
pass.set_vertex_buffer(0, line_gizmo.position_buffer.slice(..buffer_size_a));
|
||||
let buffer_size_a = line_gizmo.strip_position_buffer.size() - item_size * 2;
|
||||
pass.set_vertex_buffer(0, line_gizmo.strip_position_buffer.slice(..buffer_size_a));
|
||||
// position_b
|
||||
let buffer_size_b = line_gizmo.position_buffer.size() - item_size;
|
||||
let buffer_size_b = line_gizmo.strip_position_buffer.size() - item_size;
|
||||
pass.set_vertex_buffer(
|
||||
1,
|
||||
line_gizmo.position_buffer.slice(item_size..buffer_size_b),
|
||||
line_gizmo
|
||||
.strip_position_buffer
|
||||
.slice(item_size..buffer_size_b),
|
||||
);
|
||||
// position_c
|
||||
pass.set_vertex_buffer(2, line_gizmo.position_buffer.slice(item_size * 2..));
|
||||
pass.set_vertex_buffer(2, line_gizmo.strip_position_buffer.slice(item_size * 2..));
|
||||
|
||||
// color
|
||||
let item_size = VertexFormat::Float32x4.size();
|
||||
let buffer_size = line_gizmo.color_buffer.size() - item_size;
|
||||
let buffer_size = line_gizmo.strip_color_buffer.size() - item_size;
|
||||
// This corresponds to the color of position_b, hence starts from `item_size`
|
||||
pass.set_vertex_buffer(3, line_gizmo.color_buffer.slice(item_size..buffer_size));
|
||||
pass.set_vertex_buffer(
|
||||
3,
|
||||
line_gizmo.strip_color_buffer.slice(item_size..buffer_size),
|
||||
);
|
||||
|
||||
u32::max(line_gizmo.vertex_count, 2) - 2
|
||||
line_gizmo.strip_vertex_count - 2
|
||||
};
|
||||
|
||||
let vertices = match line_gizmo.joints {
|
||||
let vertices = match config.line_joints {
|
||||
GizmoLineJoint::None => unreachable!(),
|
||||
GizmoLineJoint::Miter => 6,
|
||||
GizmoLineJoint::Round(resolution) => resolution * 3,
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#import bevy_render::view::View
|
||||
#import bevy_render::{view::View, maths::affine3_to_square}
|
||||
|
||||
@group(0) @binding(0) var<uniform> view: View;
|
||||
|
||||
|
||||
struct LineGizmoUniform {
|
||||
world_from_local: mat3x4<f32>,
|
||||
line_width: f32,
|
||||
depth_bias: f32,
|
||||
resolution: u32,
|
||||
|
@ -39,9 +40,11 @@ fn vertex_bevel(vertex: VertexInput) -> VertexOutput {
|
|||
);
|
||||
var position = positions[vertex.index];
|
||||
|
||||
var clip_a = view.clip_from_world * vec4(vertex.position_a, 1.);
|
||||
var clip_b = view.clip_from_world * vec4(vertex.position_b, 1.);
|
||||
var clip_c = view.clip_from_world * vec4(vertex.position_c, 1.);
|
||||
let world_from_local = affine3_to_square(joints_gizmo.world_from_local);
|
||||
|
||||
var clip_a = view.clip_from_world * world_from_local * vec4(vertex.position_a, 1.);
|
||||
var clip_b = view.clip_from_world * world_from_local * vec4(vertex.position_b, 1.);
|
||||
var clip_c = view.clip_from_world * world_from_local * vec4(vertex.position_c, 1.);
|
||||
|
||||
// Manual near plane clipping to avoid errors when doing the perspective divide inside this shader.
|
||||
clip_a = clip_near_plane(clip_a, clip_c);
|
||||
|
@ -98,9 +101,11 @@ fn vertex_miter(vertex: VertexInput) -> VertexOutput {
|
|||
);
|
||||
var position = positions[vertex.index];
|
||||
|
||||
var clip_a = view.clip_from_world * vec4(vertex.position_a, 1.);
|
||||
var clip_b = view.clip_from_world * vec4(vertex.position_b, 1.);
|
||||
var clip_c = view.clip_from_world * vec4(vertex.position_c, 1.);
|
||||
let world_from_local = affine3_to_square(joints_gizmo.world_from_local);
|
||||
|
||||
var clip_a = view.clip_from_world * world_from_local * vec4(vertex.position_a, 1.);
|
||||
var clip_b = view.clip_from_world * world_from_local * vec4(vertex.position_b, 1.);
|
||||
var clip_c = view.clip_from_world * world_from_local * vec4(vertex.position_c, 1.);
|
||||
|
||||
// Manual near plane clipping to avoid errors when doing the perspective divide inside this shader.
|
||||
clip_a = clip_near_plane(clip_a, clip_c);
|
||||
|
@ -148,9 +153,11 @@ fn vertex_miter(vertex: VertexInput) -> VertexOutput {
|
|||
|
||||
@vertex
|
||||
fn vertex_round(vertex: VertexInput) -> VertexOutput {
|
||||
var clip_a = view.clip_from_world * vec4(vertex.position_a, 1.);
|
||||
var clip_b = view.clip_from_world * vec4(vertex.position_b, 1.);
|
||||
var clip_c = view.clip_from_world * vec4(vertex.position_c, 1.);
|
||||
let world_from_local = affine3_to_square(joints_gizmo.world_from_local);
|
||||
|
||||
var clip_a = view.clip_from_world * world_from_local * vec4(vertex.position_a, 1.);
|
||||
var clip_b = view.clip_from_world * world_from_local * vec4(vertex.position_b, 1.);
|
||||
var clip_c = view.clip_from_world * world_from_local * vec4(vertex.position_c, 1.);
|
||||
|
||||
// Manual near plane clipping to avoid errors when doing the perspective divide inside this shader.
|
||||
clip_a = clip_near_plane(clip_a, clip_c);
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// TODO use common view binding
|
||||
#import bevy_render::view::View
|
||||
#import bevy_render::{view::View, maths::affine3_to_square}
|
||||
|
||||
@group(0) @binding(0) var<uniform> view: View;
|
||||
|
||||
|
||||
struct LineGizmoUniform {
|
||||
world_from_local: mat3x4<f32>,
|
||||
line_width: f32,
|
||||
depth_bias: f32,
|
||||
#ifdef SIXTEEN_BYTE_ALIGNMENT
|
||||
|
@ -43,9 +44,11 @@ fn vertex(vertex: VertexInput) -> VertexOutput {
|
|||
);
|
||||
let position = positions[vertex.index];
|
||||
|
||||
let world_from_local = affine3_to_square(line_gizmo.world_from_local);
|
||||
|
||||
// algorithm based on https://wwwtyro.net/2019/11/18/instanced-lines.html
|
||||
var clip_a = view.clip_from_world * vec4(vertex.position_a, 1.);
|
||||
var clip_b = view.clip_from_world * vec4(vertex.position_b, 1.);
|
||||
var clip_a = view.clip_from_world * world_from_local * vec4(vertex.position_a, 1.);
|
||||
var clip_b = view.clip_from_world * world_from_local * vec4(vertex.position_b, 1.);
|
||||
|
||||
// Manual near plane clipping to avoid errors when doing the perspective divide inside this shader.
|
||||
clip_a = clip_near_plane(clip_a, clip_b);
|
||||
|
|
|
@ -39,6 +39,7 @@ impl Plugin for LineGizmo2dPlugin {
|
|||
|
||||
render_app
|
||||
.add_render_command::<Transparent2d, DrawLineGizmo2d>()
|
||||
.add_render_command::<Transparent2d, DrawLineGizmo2dStrip>()
|
||||
.add_render_command::<Transparent2d, DrawLineJointGizmo2d>()
|
||||
.init_resource::<SpecializedRenderPipelines<LineGizmoPipeline>>()
|
||||
.init_resource::<SpecializedRenderPipelines<LineJointGizmoPipeline>>()
|
||||
|
@ -271,7 +272,13 @@ type DrawLineGizmo2d = (
|
|||
SetItemPipeline,
|
||||
SetMesh2dViewBindGroup<0>,
|
||||
SetLineGizmoBindGroup<1>,
|
||||
DrawLineGizmo,
|
||||
DrawLineGizmo<false>,
|
||||
);
|
||||
type DrawLineGizmo2dStrip = (
|
||||
SetItemPipeline,
|
||||
SetMesh2dViewBindGroup<0>,
|
||||
SetLineGizmoBindGroup<1>,
|
||||
DrawLineGizmo<true>,
|
||||
);
|
||||
type DrawLineJointGizmo2d = (
|
||||
SetItemPipeline,
|
||||
|
@ -292,6 +299,10 @@ fn queue_line_gizmos_2d(
|
|||
mut views: Query<(Entity, &ExtractedView, &Msaa, Option<&RenderLayers>)>,
|
||||
) {
|
||||
let draw_function = draw_functions.read().get_id::<DrawLineGizmo2d>().unwrap();
|
||||
let draw_function_strip = draw_functions
|
||||
.read()
|
||||
.get_id::<DrawLineGizmo2dStrip>()
|
||||
.unwrap();
|
||||
|
||||
for (view_entity, view, msaa, render_layers) in &mut views {
|
||||
let Some(transparent_phase) = transparent_render_phases.get_mut(&view_entity) else {
|
||||
|
@ -311,24 +322,45 @@ fn queue_line_gizmos_2d(
|
|||
continue;
|
||||
};
|
||||
|
||||
let pipeline = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&pipeline,
|
||||
LineGizmoPipelineKey {
|
||||
mesh_key,
|
||||
strip: line_gizmo.strip,
|
||||
line_style: config.line_style,
|
||||
},
|
||||
);
|
||||
if line_gizmo.list_vertex_count > 0 {
|
||||
let pipeline = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&pipeline,
|
||||
LineGizmoPipelineKey {
|
||||
mesh_key,
|
||||
strip: false,
|
||||
line_style: config.line_style,
|
||||
},
|
||||
);
|
||||
transparent_phase.add(Transparent2d {
|
||||
entity: (entity, *main_entity),
|
||||
draw_function,
|
||||
pipeline,
|
||||
sort_key: FloatOrd(f32::INFINITY),
|
||||
batch_range: 0..1,
|
||||
extra_index: PhaseItemExtraIndex::NONE,
|
||||
});
|
||||
}
|
||||
|
||||
transparent_phase.add(Transparent2d {
|
||||
entity: (entity, *main_entity),
|
||||
draw_function,
|
||||
pipeline,
|
||||
sort_key: FloatOrd(f32::INFINITY),
|
||||
batch_range: 0..1,
|
||||
extra_index: PhaseItemExtraIndex::NONE,
|
||||
});
|
||||
if line_gizmo.strip_vertex_count >= 2 {
|
||||
let pipeline = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&pipeline,
|
||||
LineGizmoPipelineKey {
|
||||
mesh_key,
|
||||
strip: true,
|
||||
line_style: config.line_style,
|
||||
},
|
||||
);
|
||||
transparent_phase.add(Transparent2d {
|
||||
entity: (entity, *main_entity),
|
||||
draw_function: draw_function_strip,
|
||||
pipeline,
|
||||
sort_key: FloatOrd(f32::INFINITY),
|
||||
batch_range: 0..1,
|
||||
extra_index: PhaseItemExtraIndex::NONE,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -367,7 +399,7 @@ fn queue_line_joint_gizmos_2d(
|
|||
continue;
|
||||
};
|
||||
|
||||
if !line_gizmo.strip || line_gizmo.joints == GizmoLineJoint::None {
|
||||
if line_gizmo.strip_vertex_count < 3 || config.line_joints == GizmoLineJoint::None {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -376,7 +408,7 @@ fn queue_line_joint_gizmos_2d(
|
|||
&pipeline,
|
||||
LineJointGizmoPipelineKey {
|
||||
mesh_key,
|
||||
joints: line_gizmo.joints,
|
||||
joints: config.line_joints,
|
||||
},
|
||||
);
|
||||
transparent_phase.add(Transparent2d {
|
||||
|
|
|
@ -41,6 +41,7 @@ impl Plugin for LineGizmo3dPlugin {
|
|||
|
||||
render_app
|
||||
.add_render_command::<Transparent3d, DrawLineGizmo3d>()
|
||||
.add_render_command::<Transparent3d, DrawLineGizmo3dStrip>()
|
||||
.add_render_command::<Transparent3d, DrawLineJointGizmo3d>()
|
||||
.init_resource::<SpecializedRenderPipelines<LineGizmoPipeline>>()
|
||||
.init_resource::<SpecializedRenderPipelines<LineJointGizmoPipeline>>()
|
||||
|
@ -156,7 +157,7 @@ impl SpecializedRenderPipeline for LineGizmoPipeline {
|
|||
mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
},
|
||||
label: Some("LineGizmo Pipeline".into()),
|
||||
label: Some("LineGizmo 3d Pipeline".into()),
|
||||
push_constant_ranges: vec![],
|
||||
zero_initialize_workgroup_memory: false,
|
||||
}
|
||||
|
@ -255,7 +256,7 @@ impl SpecializedRenderPipeline for LineJointGizmoPipeline {
|
|||
mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
},
|
||||
label: Some("LineJointGizmo Pipeline".into()),
|
||||
label: Some("LineJointGizmo 3d Pipeline".into()),
|
||||
push_constant_ranges: vec![],
|
||||
zero_initialize_workgroup_memory: false,
|
||||
}
|
||||
|
@ -266,7 +267,13 @@ type DrawLineGizmo3d = (
|
|||
SetItemPipeline,
|
||||
SetMeshViewBindGroup<0>,
|
||||
SetLineGizmoBindGroup<1>,
|
||||
DrawLineGizmo,
|
||||
DrawLineGizmo<false>,
|
||||
);
|
||||
type DrawLineGizmo3dStrip = (
|
||||
SetItemPipeline,
|
||||
SetMeshViewBindGroup<0>,
|
||||
SetLineGizmoBindGroup<1>,
|
||||
DrawLineGizmo<true>,
|
||||
);
|
||||
type DrawLineJointGizmo3d = (
|
||||
SetItemPipeline,
|
||||
|
@ -298,6 +305,10 @@ fn queue_line_gizmos_3d(
|
|||
)>,
|
||||
) {
|
||||
let draw_function = draw_functions.read().get_id::<DrawLineGizmo3d>().unwrap();
|
||||
let draw_function_strip = draw_functions
|
||||
.read()
|
||||
.get_id::<DrawLineGizmo3dStrip>()
|
||||
.unwrap();
|
||||
|
||||
for (
|
||||
view_entity,
|
||||
|
@ -341,25 +352,47 @@ fn queue_line_gizmos_3d(
|
|||
continue;
|
||||
};
|
||||
|
||||
let pipeline = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&pipeline,
|
||||
LineGizmoPipelineKey {
|
||||
view_key,
|
||||
strip: line_gizmo.strip,
|
||||
perspective: config.line_perspective,
|
||||
line_style: config.line_style,
|
||||
},
|
||||
);
|
||||
if line_gizmo.list_vertex_count > 0 {
|
||||
let pipeline = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&pipeline,
|
||||
LineGizmoPipelineKey {
|
||||
view_key,
|
||||
strip: false,
|
||||
perspective: config.line_perspective,
|
||||
line_style: config.line_style,
|
||||
},
|
||||
);
|
||||
transparent_phase.add(Transparent3d {
|
||||
entity: (entity, *main_entity),
|
||||
draw_function,
|
||||
pipeline,
|
||||
distance: 0.,
|
||||
batch_range: 0..1,
|
||||
extra_index: PhaseItemExtraIndex::NONE,
|
||||
});
|
||||
}
|
||||
|
||||
transparent_phase.add(Transparent3d {
|
||||
entity: (entity, *main_entity),
|
||||
draw_function,
|
||||
pipeline,
|
||||
distance: 0.,
|
||||
batch_range: 0..1,
|
||||
extra_index: PhaseItemExtraIndex::NONE,
|
||||
});
|
||||
if line_gizmo.strip_vertex_count >= 2 {
|
||||
let pipeline = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&pipeline,
|
||||
LineGizmoPipelineKey {
|
||||
view_key,
|
||||
strip: true,
|
||||
perspective: config.line_perspective,
|
||||
line_style: config.line_style,
|
||||
},
|
||||
);
|
||||
transparent_phase.add(Transparent3d {
|
||||
entity: (entity, *main_entity),
|
||||
draw_function: draw_function_strip,
|
||||
pipeline,
|
||||
distance: 0.,
|
||||
batch_range: 0..1,
|
||||
extra_index: PhaseItemExtraIndex::NONE,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -433,7 +466,7 @@ fn queue_line_joint_gizmos_3d(
|
|||
continue;
|
||||
};
|
||||
|
||||
if !line_gizmo.strip || line_gizmo.joints == GizmoLineJoint::None {
|
||||
if line_gizmo.strip_vertex_count < 3 || config.line_joints == GizmoLineJoint::None {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -443,7 +476,7 @@ fn queue_line_joint_gizmos_3d(
|
|||
LineJointGizmoPipelineKey {
|
||||
view_key,
|
||||
perspective: config.line_perspective,
|
||||
joints: line_gizmo.joints,
|
||||
joints: config.line_joints,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! A module for rendering each of the 2D [`bevy_math::primitives`] with [`Gizmos`].
|
||||
//! A module for rendering each of the 2D [`bevy_math::primitives`] with [`GizmoBuffer`].
|
||||
|
||||
use core::f32::consts::{FRAC_PI_2, PI};
|
||||
|
||||
|
@ -14,7 +14,7 @@ use bevy_math::{
|
|||
Dir2, Isometry2d, Rot2, Vec2,
|
||||
};
|
||||
|
||||
use crate::prelude::{GizmoConfigGroup, Gizmos};
|
||||
use crate::{gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
|
||||
|
||||
// some magic number since using directions as offsets will result in lines of length 1 pixel
|
||||
const MIN_LINE_LEN: f32 = 50.0;
|
||||
|
@ -22,7 +22,7 @@ const HALF_MIN_LINE_LEN: f32 = 25.0;
|
|||
// length used to simulate infinite lines
|
||||
const INFINITE_LEN: f32 = 100_000.0;
|
||||
|
||||
/// A trait for rendering 2D geometric primitives (`P`) with [`Gizmos`].
|
||||
/// A trait for rendering 2D geometric primitives (`P`) with [`GizmoBuffer`].
|
||||
pub trait GizmoPrimitive2d<P: Primitive2d> {
|
||||
/// The output of `primitive_2d`. This is a builder to set non-default values.
|
||||
type Output<'a>
|
||||
|
@ -40,7 +40,7 @@ pub trait GizmoPrimitive2d<P: Primitive2d> {
|
|||
|
||||
// direction 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Dir2> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Dir2> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -68,7 +68,7 @@ where
|
|||
|
||||
// arc 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Arc2d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Arc2d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -102,13 +102,13 @@ where
|
|||
|
||||
// circle 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Circle> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Circle> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= crate::circles::Ellipse2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= crate::circles::Ellipse2dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -124,7 +124,7 @@ where
|
|||
|
||||
// circular sector 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<CircularSector> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<CircularSector> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -167,7 +167,7 @@ where
|
|||
|
||||
// circular segment 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<CircularSegment> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<CircularSegment> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -209,13 +209,13 @@ where
|
|||
|
||||
// ellipse 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Ellipse> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Ellipse> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= crate::circles::Ellipse2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= crate::circles::Ellipse2dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -232,12 +232,12 @@ where
|
|||
// annulus 2d
|
||||
|
||||
/// Builder for configuring the drawing options of [`Annulus`].
|
||||
pub struct Annulus2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
pub struct Annulus2dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
isometry: Isometry2d,
|
||||
inner_radius: f32,
|
||||
outer_radius: f32,
|
||||
|
@ -246,7 +246,7 @@ where
|
|||
outer_resolution: u32,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Annulus2dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Annulus2dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -271,13 +271,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Annulus> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Annulus> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= Annulus2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= Annulus2dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -299,7 +299,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Annulus2dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Annulus2dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -331,7 +331,7 @@ where
|
|||
|
||||
// rhombus 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Rhombus> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Rhombus> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -365,7 +365,7 @@ where
|
|||
|
||||
// capsule 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Capsule2d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Capsule2d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -431,12 +431,12 @@ where
|
|||
// line 2d
|
||||
//
|
||||
/// Builder for configuring the drawing options of [`Line2d`].
|
||||
pub struct Line2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
pub struct Line2dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
|
||||
direction: Dir2, // Direction of the line
|
||||
|
||||
|
@ -446,7 +446,7 @@ where
|
|||
draw_arrow: bool, // decides whether to indicate the direction of the line with an arrow
|
||||
}
|
||||
|
||||
impl<Config, Clear> Line2dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Line2dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -458,13 +458,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Line2d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Line2d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= Line2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= Line2dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -484,7 +484,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Line2dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Line2dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -516,7 +516,7 @@ where
|
|||
|
||||
// plane 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Plane2d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Plane2d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -570,12 +570,12 @@ where
|
|||
// segment 2d
|
||||
|
||||
/// Builder for configuring the drawing options of [`Segment2d`].
|
||||
pub struct Segment2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
pub struct Segment2dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
|
||||
direction: Dir2, // Direction of the line segment
|
||||
half_length: f32, // Half-length of the line segment
|
||||
|
@ -586,7 +586,7 @@ where
|
|||
draw_arrow: bool, // decides whether to draw just a line or an arrow
|
||||
}
|
||||
|
||||
impl<Config, Clear> Segment2dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Segment2dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -598,13 +598,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Segment2d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Segment2d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= Segment2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= Segment2dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -627,7 +627,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Segment2dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Segment2dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -651,8 +651,7 @@ where
|
|||
|
||||
// polyline 2d
|
||||
|
||||
impl<'w, 's, const N: usize, Config, Clear> GizmoPrimitive2d<Polyline2d<N>>
|
||||
for Gizmos<'w, 's, Config, Clear>
|
||||
impl<const N: usize, Config, Clear> GizmoPrimitive2d<Polyline2d<N>> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -687,7 +686,7 @@ where
|
|||
|
||||
// boxed polyline 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<BoxedPolyline2d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<BoxedPolyline2d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -722,7 +721,7 @@ where
|
|||
|
||||
// triangle 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Triangle2d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Triangle2d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -752,7 +751,7 @@ where
|
|||
|
||||
// rectangle 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Rectangle> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<Rectangle> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -788,8 +787,7 @@ where
|
|||
|
||||
// polygon 2d
|
||||
|
||||
impl<'w, 's, const N: usize, Config, Clear> GizmoPrimitive2d<Polygon<N>>
|
||||
for Gizmos<'w, 's, Config, Clear>
|
||||
impl<const N: usize, Config, Clear> GizmoPrimitive2d<Polygon<N>> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -834,7 +832,7 @@ where
|
|||
|
||||
// boxed polygon 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<BoxedPolygon> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<BoxedPolygon> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -877,7 +875,7 @@ where
|
|||
|
||||
// regular polygon 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<RegularPolygon> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive2d<RegularPolygon> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! A module for rendering each of the 3D [`bevy_math::primitives`] with [`Gizmos`].
|
||||
//! A module for rendering each of the 3D [`bevy_math::primitives`] with [`GizmoBuffer`].
|
||||
|
||||
use super::helpers::*;
|
||||
|
||||
|
@ -11,16 +11,13 @@ use bevy_math::{
|
|||
Dir3, Isometry3d, Quat, UVec2, Vec2, Vec3,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
circles::SphereBuilder,
|
||||
prelude::{GizmoConfigGroup, Gizmos},
|
||||
};
|
||||
use crate::{circles::SphereBuilder, gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
|
||||
|
||||
const DEFAULT_RESOLUTION: u32 = 5;
|
||||
// length used to simulate infinite lines
|
||||
const INFINITE_LEN: f32 = 10_000.0;
|
||||
|
||||
/// A trait for rendering 3D geometric primitives (`P`) with [`Gizmos`].
|
||||
/// A trait for rendering 3D geometric primitives (`P`) with [`GizmoBuffer`].
|
||||
pub trait GizmoPrimitive3d<P: Primitive3d> {
|
||||
/// The output of `primitive_3d`. This is a builder to set non-default values.
|
||||
type Output<'a>
|
||||
|
@ -38,7 +35,7 @@ pub trait GizmoPrimitive3d<P: Primitive3d> {
|
|||
|
||||
// direction 3d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Dir3> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Dir3> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -63,13 +60,13 @@ where
|
|||
|
||||
// sphere
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Sphere> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Sphere> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= SphereBuilder<'a, 'w, 's, Config, Clear>
|
||||
= SphereBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -86,12 +83,12 @@ where
|
|||
// plane 3d
|
||||
|
||||
/// Builder for configuring the drawing options of [`Plane3d`].
|
||||
pub struct Plane3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
pub struct Plane3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
|
||||
// Direction of the normal orthogonal to the plane
|
||||
normal: Dir3,
|
||||
|
@ -106,7 +103,7 @@ where
|
|||
spacing: Vec2,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Plane3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Plane3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -124,13 +121,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Plane3d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Plane3d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= Plane3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= Plane3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -151,7 +148,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Plane3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Plane3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -176,7 +173,7 @@ where
|
|||
|
||||
// line 3d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Line3d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Line3d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -211,7 +208,7 @@ where
|
|||
|
||||
// segment 3d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Segment3d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Segment3d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -239,8 +236,7 @@ where
|
|||
|
||||
// polyline 3d
|
||||
|
||||
impl<'w, 's, const N: usize, Config, Clear> GizmoPrimitive3d<Polyline3d<N>>
|
||||
for Gizmos<'w, 's, Config, Clear>
|
||||
impl<const N: usize, Config, Clear> GizmoPrimitive3d<Polyline3d<N>> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -267,7 +263,7 @@ where
|
|||
|
||||
// boxed polyline 3d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<BoxedPolyline3d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<BoxedPolyline3d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -301,7 +297,7 @@ where
|
|||
|
||||
// triangle 3d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Triangle3d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Triangle3d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -329,7 +325,7 @@ where
|
|||
|
||||
// cuboid
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Cuboid> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Cuboid> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -392,12 +388,12 @@ where
|
|||
// cylinder 3d
|
||||
|
||||
/// Builder for configuring the drawing options of [`Cylinder`].
|
||||
pub struct Cylinder3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
pub struct Cylinder3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
|
||||
// Radius of the cylinder
|
||||
radius: f32,
|
||||
|
@ -412,7 +408,7 @@ where
|
|||
resolution: u32,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Cylinder3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Cylinder3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -424,13 +420,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Cylinder> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Cylinder> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= Cylinder3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= Cylinder3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -451,7 +447,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Cylinder3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Cylinder3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -478,12 +474,12 @@ where
|
|||
// capsule 3d
|
||||
|
||||
/// Builder for configuring the drawing options of [`Capsule3d`].
|
||||
pub struct Capsule3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
pub struct Capsule3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
|
||||
// Radius of the capsule
|
||||
radius: f32,
|
||||
|
@ -498,7 +494,7 @@ where
|
|||
resolution: u32,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Capsule3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Capsule3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -510,13 +506,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Capsule3d> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Capsule3d> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= Capsule3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= Capsule3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -537,7 +533,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Capsule3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Capsule3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -596,12 +592,12 @@ where
|
|||
// cone 3d
|
||||
|
||||
/// Builder for configuring the drawing options of [`Cone`].
|
||||
pub struct Cone3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
pub struct Cone3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
|
||||
// Radius of the cone
|
||||
radius: f32,
|
||||
|
@ -619,7 +615,7 @@ where
|
|||
height_resolution: u32,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Cone3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Cone3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -650,13 +646,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Cone> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Cone> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= Cone3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= Cone3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -678,7 +674,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Cone3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Cone3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -718,12 +714,12 @@ where
|
|||
// conical frustum 3d
|
||||
|
||||
/// Builder for configuring the drawing options of [`ConicalFrustum`].
|
||||
pub struct ConicalFrustum3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
pub struct ConicalFrustum3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
|
||||
// Radius of the top circle
|
||||
radius_top: f32,
|
||||
|
@ -740,7 +736,7 @@ where
|
|||
resolution: u32,
|
||||
}
|
||||
|
||||
impl<Config, Clear> ConicalFrustum3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> ConicalFrustum3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -752,13 +748,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<ConicalFrustum> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<ConicalFrustum> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= ConicalFrustum3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= ConicalFrustum3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -780,7 +776,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for ConicalFrustum3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for ConicalFrustum3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -816,12 +812,12 @@ where
|
|||
// torus 3d
|
||||
|
||||
/// Builder for configuring the drawing options of [`Torus`].
|
||||
pub struct Torus3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
pub struct Torus3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
|
||||
// Radius of the minor circle (tube)
|
||||
minor_radius: f32,
|
||||
|
@ -838,7 +834,7 @@ where
|
|||
major_resolution: u32,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Torus3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Torus3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -856,13 +852,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Torus> for Gizmos<'w, 's, Config, Clear>
|
||||
impl<Config, Clear> GizmoPrimitive3d<Torus> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= Torus3dBuilder<'a, 'w, 's, Config, Clear>
|
||||
= Torus3dBuilder<'a, Config, Clear>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -884,7 +880,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Torus3dBuilder<'_, '_, '_, Config, Clear>
|
||||
impl<Config, Clear> Drop for Torus3dBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
|
@ -936,7 +932,11 @@ where
|
|||
|
||||
// tetrahedron
|
||||
|
||||
impl<'w, 's, T: GizmoConfigGroup> GizmoPrimitive3d<Tetrahedron> for Gizmos<'w, 's, T> {
|
||||
impl<Config, Clear> GizmoPrimitive3d<Tetrahedron> for GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a>
|
||||
= ()
|
||||
where
|
||||
|
|
138
crates/bevy_gizmos/src/retained.rs
Normal file
138
crates/bevy_gizmos/src/retained.rs
Normal file
|
@ -0,0 +1,138 @@
|
|||
//! This module is for 'retained' alternatives to the 'immediate mode' [`Gizmos`](crate::gizmos::Gizmos) system parameter.
|
||||
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
use bevy_asset::Handle;
|
||||
use bevy_ecs::component::{require, Component};
|
||||
use bevy_reflect::Reflect;
|
||||
use bevy_transform::components::Transform;
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
use {
|
||||
crate::{config::GizmoLineJoint, LineGizmoUniform},
|
||||
bevy_ecs::{
|
||||
entity::Entity,
|
||||
system::{Commands, Local, Query},
|
||||
},
|
||||
bevy_render::{view::RenderLayers, Extract},
|
||||
bevy_transform::components::GlobalTransform,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
config::{ErasedGizmoConfigGroup, GizmoLineConfig},
|
||||
gizmos::GizmoBuffer,
|
||||
GizmoAsset,
|
||||
};
|
||||
|
||||
impl Deref for GizmoAsset {
|
||||
type Target = GizmoBuffer<ErasedGizmoConfigGroup, ()>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.buffer
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for GizmoAsset {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.buffer
|
||||
}
|
||||
}
|
||||
|
||||
/// A component that draws the gizmos of a [`GizmoAsset`].
|
||||
///
|
||||
/// When drawing a greater number 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.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// # use bevy_gizmos::prelude::*;
|
||||
/// # use bevy_asset::prelude::*;
|
||||
/// # use bevy_color::palettes::css::*;
|
||||
/// # use bevy_utils::default;
|
||||
/// # use bevy_math::prelude::*;
|
||||
/// fn system(
|
||||
/// mut commands: Commands,
|
||||
/// mut gizmo_assets: ResMut<Assets<GizmoAsset>>,
|
||||
/// ) {
|
||||
/// let mut gizmo = GizmoAsset::default();
|
||||
///
|
||||
/// gizmo.sphere(Vec3::ZERO, 1., RED);
|
||||
///
|
||||
/// commands.spawn(Gizmo {
|
||||
/// handle: gizmo_assets.add(gizmo),
|
||||
/// line_config: GizmoLineConfig {
|
||||
/// width: 4.,
|
||||
/// ..default()
|
||||
/// },
|
||||
/// ..default()
|
||||
/// });
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`Gizmos`]: crate::gizmos::Gizmos
|
||||
#[derive(Component, Clone, Debug, Default, Reflect)]
|
||||
#[require(Transform)]
|
||||
pub struct Gizmo {
|
||||
/// The handle to the gizmo to draw.
|
||||
pub handle: Handle<GizmoAsset>,
|
||||
/// The line specific configuration for this gizmo.
|
||||
pub line_config: GizmoLineConfig,
|
||||
/// How closer to the camera than real geometry the gizmo should be.
|
||||
///
|
||||
/// In 2D this setting has no effect and is effectively always -1.
|
||||
///
|
||||
/// Value between -1 and 1 (inclusive).
|
||||
/// * 0 means that there is no change to the gizmo position when rendering
|
||||
/// * 1 means it is furthest away from camera as possible
|
||||
/// * -1 means that it will always render in front of other things.
|
||||
///
|
||||
/// This is typically useful if you are drawing wireframes on top of polygons
|
||||
/// and your wireframe is z-fighting (flickering on/off) with your main model.
|
||||
/// You would set this value to a negative number close to 0.
|
||||
pub depth_bias: f32,
|
||||
}
|
||||
|
||||
#[cfg(feature = "bevy_render")]
|
||||
pub(crate) fn extract_linegizmos(
|
||||
mut commands: Commands,
|
||||
mut previous_len: Local<usize>,
|
||||
query: Extract<Query<(Entity, &Gizmo, &GlobalTransform, Option<&RenderLayers>)>>,
|
||||
) {
|
||||
use bevy_math::Affine3;
|
||||
use bevy_render::sync_world::{MainEntity, TemporaryRenderEntity};
|
||||
|
||||
let mut values = Vec::with_capacity(*previous_len);
|
||||
for (entity, gizmo, transform, render_layers) in &query {
|
||||
let joints_resolution = if let GizmoLineJoint::Round(resolution) = gizmo.line_config.joints
|
||||
{
|
||||
resolution
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
values.push((
|
||||
LineGizmoUniform {
|
||||
world_from_local: Affine3::from(&transform.affine()).to_transpose(),
|
||||
line_width: gizmo.line_config.width,
|
||||
depth_bias: gizmo.depth_bias,
|
||||
joints_resolution,
|
||||
#[cfg(feature = "webgl")]
|
||||
_padding: Default::default(),
|
||||
},
|
||||
#[cfg(any(feature = "bevy_pbr", feature = "bevy_sprite"))]
|
||||
crate::config::GizmoMeshConfig {
|
||||
line_perspective: gizmo.line_config.perspective,
|
||||
line_style: gizmo.line_config.style,
|
||||
line_joints: gizmo.line_config.joints,
|
||||
render_layers: render_layers.cloned().unwrap_or_default(),
|
||||
handle: gizmo.handle.clone_weak(),
|
||||
},
|
||||
MainEntity::from(entity),
|
||||
TemporaryRenderEntity,
|
||||
));
|
||||
}
|
||||
*previous_len = values.len();
|
||||
commands.spawn_batch(values);
|
||||
}
|
|
@ -1,25 +1,33 @@
|
|||
//! Additional [`Gizmos`] Functions -- Rounded cuboids and rectangles
|
||||
//! Additional [`GizmoBuffer`] Functions -- Rounded cuboids and rectangles
|
||||
//!
|
||||
//! Includes the implementation of [`Gizmos::rounded_rect`], [`Gizmos::rounded_rect_2d`] and [`Gizmos::rounded_cuboid`].
|
||||
//! Includes the implementation of [`GizmoBuffer::rounded_rect`], [`GizmoBuffer::rounded_rect_2d`] and [`GizmoBuffer::rounded_cuboid`].
|
||||
//! and assorted support items.
|
||||
|
||||
use core::f32::consts::FRAC_PI_2;
|
||||
|
||||
use crate::prelude::{GizmoConfigGroup, Gizmos};
|
||||
use crate::{gizmos::GizmoBuffer, prelude::GizmoConfigGroup};
|
||||
use bevy_color::Color;
|
||||
use bevy_math::{Isometry2d, Isometry3d, Quat, Vec2, Vec3};
|
||||
use bevy_transform::components::Transform;
|
||||
|
||||
/// A builder returned by [`Gizmos::rounded_rect`] and [`Gizmos::rounded_rect_2d`]
|
||||
pub struct RoundedRectBuilder<'a, 'w, 's, T: GizmoConfigGroup> {
|
||||
/// A builder returned by [`GizmoBuffer::rounded_rect`] and [`GizmoBuffer::rounded_rect_2d`]
|
||||
pub struct RoundedRectBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
size: Vec2,
|
||||
gizmos: &'a mut Gizmos<'w, 's, T>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
config: RoundedBoxConfig,
|
||||
}
|
||||
/// A builder returned by [`Gizmos::rounded_cuboid`]
|
||||
pub struct RoundedCuboidBuilder<'a, 'w, 's, T: GizmoConfigGroup> {
|
||||
/// A builder returned by [`GizmoBuffer::rounded_cuboid`]
|
||||
pub struct RoundedCuboidBuilder<'a, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
size: Vec3,
|
||||
gizmos: &'a mut Gizmos<'w, 's, T>,
|
||||
gizmos: &'a mut GizmoBuffer<Config, Clear>,
|
||||
config: RoundedBoxConfig,
|
||||
}
|
||||
struct RoundedBoxConfig {
|
||||
|
@ -29,7 +37,11 @@ struct RoundedBoxConfig {
|
|||
arc_resolution: u32,
|
||||
}
|
||||
|
||||
impl<T: GizmoConfigGroup> RoundedRectBuilder<'_, '_, '_, T> {
|
||||
impl<Config, Clear> RoundedRectBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Change the radius of the corners to be `corner_radius`.
|
||||
/// The default corner radius is [min axis of size] / 10.0
|
||||
pub fn corner_radius(mut self, corner_radius: f32) -> Self {
|
||||
|
@ -44,7 +56,12 @@ impl<T: GizmoConfigGroup> RoundedRectBuilder<'_, '_, '_, T> {
|
|||
self
|
||||
}
|
||||
}
|
||||
impl<T: GizmoConfigGroup> RoundedCuboidBuilder<'_, '_, '_, T> {
|
||||
|
||||
impl<Config, Clear> RoundedCuboidBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Change the radius of the edges to be `edge_radius`.
|
||||
/// The default edge radius is [min axis of size] / 10.0
|
||||
pub fn edge_radius(mut self, edge_radius: f32) -> Self {
|
||||
|
@ -60,7 +77,11 @@ impl<T: GizmoConfigGroup> RoundedCuboidBuilder<'_, '_, '_, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: GizmoConfigGroup> Drop for RoundedRectBuilder<'_, '_, '_, T> {
|
||||
impl<Config, Clear> Drop for RoundedRectBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
if !self.gizmos.enabled {
|
||||
return;
|
||||
|
@ -140,7 +161,11 @@ impl<T: GizmoConfigGroup> Drop for RoundedRectBuilder<'_, '_, '_, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: GizmoConfigGroup> Drop for RoundedCuboidBuilder<'_, '_, '_, T> {
|
||||
impl<Config, Clear> Drop for RoundedCuboidBuilder<'_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
if !self.gizmos.enabled {
|
||||
return;
|
||||
|
@ -201,7 +226,11 @@ impl<T: GizmoConfigGroup> Drop for RoundedCuboidBuilder<'_, '_, '_, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
|
||||
impl<Config, Clear> GizmoBuffer<Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Draw a wireframe rectangle with rounded corners in 3D.
|
||||
///
|
||||
/// This should be called for each frame the rectangle needs to be rendered.
|
||||
|
@ -243,7 +272,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
|
|||
isometry: impl Into<Isometry3d>,
|
||||
size: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> RoundedRectBuilder<'_, 'w, 's, T> {
|
||||
) -> RoundedRectBuilder<'_, Config, Clear> {
|
||||
let corner_radius = size.min_element() * DEFAULT_CORNER_RADIUS;
|
||||
RoundedRectBuilder {
|
||||
gizmos: self,
|
||||
|
@ -297,7 +326,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
|
|||
isometry: impl Into<Isometry2d>,
|
||||
size: Vec2,
|
||||
color: impl Into<Color>,
|
||||
) -> RoundedRectBuilder<'_, 'w, 's, T> {
|
||||
) -> RoundedRectBuilder<'_, Config, Clear> {
|
||||
let isometry = isometry.into();
|
||||
let corner_radius = size.min_element() * DEFAULT_CORNER_RADIUS;
|
||||
RoundedRectBuilder {
|
||||
|
@ -355,7 +384,7 @@ impl<'w, 's, T: GizmoConfigGroup> Gizmos<'w, 's, T> {
|
|||
isometry: impl Into<Isometry3d>,
|
||||
size: Vec3,
|
||||
color: impl Into<Color>,
|
||||
) -> RoundedCuboidBuilder<'_, 'w, 's, T> {
|
||||
) -> RoundedCuboidBuilder<'_, Config, Clear> {
|
||||
let corner_radius = size.min_element() * DEFAULT_CORNER_RADIUS;
|
||||
RoundedCuboidBuilder {
|
||||
gizmos: self,
|
||||
|
|
|
@ -129,24 +129,24 @@ fn update_config(
|
|||
) {
|
||||
let (config, _) = config_store.config_mut::<DefaultGizmoConfigGroup>();
|
||||
if keyboard.pressed(KeyCode::ArrowRight) {
|
||||
config.line_width += 5. * time.delta_secs();
|
||||
config.line_width = config.line_width.clamp(0., 50.);
|
||||
config.line.width += 5. * time.delta_secs();
|
||||
config.line.width = config.line.width.clamp(0., 50.);
|
||||
}
|
||||
if keyboard.pressed(KeyCode::ArrowLeft) {
|
||||
config.line_width -= 5. * time.delta_secs();
|
||||
config.line_width = config.line_width.clamp(0., 50.);
|
||||
config.line.width -= 5. * time.delta_secs();
|
||||
config.line.width = config.line.width.clamp(0., 50.);
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::Digit1) {
|
||||
config.enabled ^= true;
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::KeyU) {
|
||||
config.line_style = match config.line_style {
|
||||
config.line.style = match config.line.style {
|
||||
GizmoLineStyle::Solid => GizmoLineStyle::Dotted,
|
||||
_ => GizmoLineStyle::Solid,
|
||||
};
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::KeyJ) {
|
||||
config.line_joints = match config.line_joints {
|
||||
config.line.joints = match config.line.joints {
|
||||
GizmoLineJoint::Bevel => GizmoLineJoint::Miter,
|
||||
GizmoLineJoint::Miter => GizmoLineJoint::Round(4),
|
||||
GizmoLineJoint::Round(_) => GizmoLineJoint::None,
|
||||
|
@ -156,24 +156,24 @@ fn update_config(
|
|||
|
||||
let (my_config, _) = config_store.config_mut::<MyRoundGizmos>();
|
||||
if keyboard.pressed(KeyCode::ArrowUp) {
|
||||
my_config.line_width += 5. * time.delta_secs();
|
||||
my_config.line_width = my_config.line_width.clamp(0., 50.);
|
||||
my_config.line.width += 5. * time.delta_secs();
|
||||
my_config.line.width = my_config.line.width.clamp(0., 50.);
|
||||
}
|
||||
if keyboard.pressed(KeyCode::ArrowDown) {
|
||||
my_config.line_width -= 5. * time.delta_secs();
|
||||
my_config.line_width = my_config.line_width.clamp(0., 50.);
|
||||
my_config.line.width -= 5. * time.delta_secs();
|
||||
my_config.line.width = my_config.line.width.clamp(0., 50.);
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::Digit2) {
|
||||
my_config.enabled ^= true;
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::KeyI) {
|
||||
my_config.line_style = match my_config.line_style {
|
||||
my_config.line.style = match my_config.line.style {
|
||||
GizmoLineStyle::Solid => GizmoLineStyle::Dotted,
|
||||
_ => GizmoLineStyle::Solid,
|
||||
};
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::KeyK) {
|
||||
my_config.line_joints = match my_config.line_joints {
|
||||
my_config.line.joints = match my_config.line.joints {
|
||||
GizmoLineJoint::Bevel => GizmoLineJoint::Miter,
|
||||
GizmoLineJoint::Miter => GizmoLineJoint::Round(4),
|
||||
GizmoLineJoint::Round(_) => GizmoLineJoint::None,
|
||||
|
|
|
@ -18,13 +18,37 @@ fn main() {
|
|||
|
||||
// We can create our own gizmo config group!
|
||||
#[derive(Default, Reflect, GizmoConfigGroup)]
|
||||
struct MyRoundGizmos {}
|
||||
struct MyRoundGizmos;
|
||||
|
||||
fn setup(
|
||||
mut commands: Commands,
|
||||
mut gizmo_assets: ResMut<Assets<GizmoAsset>>,
|
||||
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),
|
||||
|
@ -191,33 +215,33 @@ fn update_config(
|
|||
}
|
||||
if keyboard.just_pressed(KeyCode::KeyP) {
|
||||
for (_, config, _) in config_store.iter_mut() {
|
||||
// Toggle line_perspective
|
||||
config.line_perspective ^= true;
|
||||
// Increase the line width when line_perspective is on
|
||||
config.line_width *= if config.line_perspective { 5. } else { 1. / 5. };
|
||||
// Toggle line perspective
|
||||
config.line.perspective ^= true;
|
||||
// Increase the line width when line perspective is on
|
||||
config.line.width *= if config.line.perspective { 5. } else { 1. / 5. };
|
||||
}
|
||||
}
|
||||
|
||||
let (config, _) = config_store.config_mut::<DefaultGizmoConfigGroup>();
|
||||
if keyboard.pressed(KeyCode::ArrowRight) {
|
||||
config.line_width += 5. * time.delta_secs();
|
||||
config.line_width = config.line_width.clamp(0., 50.);
|
||||
config.line.width += 5. * time.delta_secs();
|
||||
config.line.width = config.line.width.clamp(0., 50.);
|
||||
}
|
||||
if keyboard.pressed(KeyCode::ArrowLeft) {
|
||||
config.line_width -= 5. * time.delta_secs();
|
||||
config.line_width = config.line_width.clamp(0., 50.);
|
||||
config.line.width -= 5. * time.delta_secs();
|
||||
config.line.width = config.line.width.clamp(0., 50.);
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::Digit1) {
|
||||
config.enabled ^= true;
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::KeyU) {
|
||||
config.line_style = match config.line_style {
|
||||
config.line.style = match config.line.style {
|
||||
GizmoLineStyle::Solid => GizmoLineStyle::Dotted,
|
||||
_ => GizmoLineStyle::Solid,
|
||||
};
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::KeyJ) {
|
||||
config.line_joints = match config.line_joints {
|
||||
config.line.joints = match config.line.joints {
|
||||
GizmoLineJoint::Bevel => GizmoLineJoint::Miter,
|
||||
GizmoLineJoint::Miter => GizmoLineJoint::Round(4),
|
||||
GizmoLineJoint::Round(_) => GizmoLineJoint::None,
|
||||
|
@ -227,24 +251,24 @@ fn update_config(
|
|||
|
||||
let (my_config, _) = config_store.config_mut::<MyRoundGizmos>();
|
||||
if keyboard.pressed(KeyCode::ArrowUp) {
|
||||
my_config.line_width += 5. * time.delta_secs();
|
||||
my_config.line_width = my_config.line_width.clamp(0., 50.);
|
||||
my_config.line.width += 5. * time.delta_secs();
|
||||
my_config.line.width = my_config.line.width.clamp(0., 50.);
|
||||
}
|
||||
if keyboard.pressed(KeyCode::ArrowDown) {
|
||||
my_config.line_width -= 5. * time.delta_secs();
|
||||
my_config.line_width = my_config.line_width.clamp(0., 50.);
|
||||
my_config.line.width -= 5. * time.delta_secs();
|
||||
my_config.line.width = my_config.line.width.clamp(0., 50.);
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::Digit2) {
|
||||
my_config.enabled ^= true;
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::KeyI) {
|
||||
my_config.line_style = match my_config.line_style {
|
||||
my_config.line.style = match my_config.line.style {
|
||||
GizmoLineStyle::Solid => GizmoLineStyle::Dotted,
|
||||
_ => GizmoLineStyle::Solid,
|
||||
};
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::KeyK) {
|
||||
my_config.line_joints = match my_config.line_joints {
|
||||
my_config.line.joints = match my_config.line.joints {
|
||||
GizmoLineJoint::Bevel => GizmoLineJoint::Miter,
|
||||
GizmoLineJoint::Miter => GizmoLineJoint::Round(4),
|
||||
GizmoLineJoint::Round(_) => GizmoLineJoint::None,
|
||||
|
|
|
@ -155,12 +155,12 @@ fn update_config(
|
|||
|
||||
let (config, light_config) = config_store.config_mut::<LightGizmoConfigGroup>();
|
||||
if keyboard.pressed(KeyCode::ArrowRight) {
|
||||
config.line_width += 5. * time.delta_secs();
|
||||
config.line_width = config.line_width.clamp(0., 50.);
|
||||
config.line.width += 5. * time.delta_secs();
|
||||
config.line.width = config.line.width.clamp(0., 50.);
|
||||
}
|
||||
if keyboard.pressed(KeyCode::ArrowLeft) {
|
||||
config.line_width -= 5. * time.delta_secs();
|
||||
config.line_width = config.line_width.clamp(0., 50.);
|
||||
config.line.width -= 5. * time.delta_secs();
|
||||
config.line.width = config.line.width.clamp(0., 50.);
|
||||
}
|
||||
if keyboard.just_pressed(KeyCode::KeyA) {
|
||||
config.enabled ^= true;
|
||||
|
|
Loading…
Reference in a new issue