Struct bevy_vector_shapes::painter::ShapeCommands
source · pub struct ShapeCommands<'w, 's> { /* private fields */ }
Expand description
A system param that allows ergonomic spawning of shape entities.
The ShapeConfig
used is initially extracted from the BaseShapeConfig
resource.
Subsequent calls to reset()
will reset the config back to whatever is currently stored within the BaseShapeConfig
resource.
Shapes will be spawned with commands during the next instance of [apply_deferred
]
Implementations§
source§impl<'w, 's> ShapeCommands<'w, 's>
impl<'w, 's> ShapeCommands<'w, 's>
sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Set the painter’s ShapeConfig
to the current value of the BaseShapeConfig
resource.
Methods from Deref<Target = ShapeConfig>§
sourcepub fn translate(&mut self, dir: Vec3)
pub fn translate(&mut self, dir: Vec3)
Helper method to modify the configs transform taking into account rotation and scale.
Examples found in repository?
32 33 34 35 36 37 38 39 40 41 42 43
fn draw_health_bar(painter: &mut ShapePainter, hp: f32) {
painter.translate(Vec3::Y * 0.7);
painter.corner_radii = Vec4::splat(0.3);
painter.color = Color::GREEN * hp + Color::RED * (1. - hp);
painter.rect(Vec2::new(0.2 + 0.8 * hp, 0.2));
painter.thickness = 0.02;
painter.hollow = true;
painter.color = Color::WHITE;
painter.rect(Vec2::new(1.06, 0.26));
}
More examples
43 44 45 46 47 48 49 50 51 52 53 54 55
fn draw_shapes(time: Res<Time>, mut painter: ShapePainter, canvas: Query<(Entity, &Canvas)>) {
let (canvas_e, canvas) = canvas.single();
painter.image(canvas.image.clone(), Vec2::splat(20.));
painter.set_canvas(canvas_e);
painter.hollow = true;
painter.thickness = 6.0;
painter.color = Color::CRIMSON;
painter.translate(Vec3::Y * time.elapsed_seconds().sin() * 256.0);
painter.circle(48.0);
painter.reset();
}
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
fn draw_canvas(time: Res<Time>, mut painter: ShapePainter, canvas: Query<(Entity, &Canvas)>) {
let (canvas, _) = canvas.single();
painter.rotate_z(time.elapsed_seconds().sin());
painter.set_canvas(canvas);
painter.color = Color::WHITE * 2.0;
painter.translate(Vec3::NEG_Y * 12.0 * 16.0);
painter.thickness = 16.0;
for _ in 0..12 {
painter.translate(Vec3::Y * 32.0);
painter.line(Vec3::NEG_X * 256.0, Vec3::X * 256.0);
}
painter.reset();
}
fn draw_shapes(time: Res<Time>, mut painter: ShapePainter, canvas: Query<(Entity, &Canvas)>) {
let (_, canvas) = canvas.single();
painter.texture = Some(canvas.image.clone());
painter.translate(Vec3::NEG_Y * 2.0);
gallery(painter, time.elapsed_seconds(), 0..10);
}
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
fn draw_circles(painter: &mut ShapePainter, radius: f32) {
painter.translate(-(Vec3::X + Vec3::NEG_Y) * f32::sqrt(radius) * 0.5);
painter.color = Color::rgba(1.0, 0.0, 0.0, 0.5);
painter.circle(radius);
painter.rotate_z(-TAU / 3.0);
painter.translate(Vec3::Y * radius * 1.2 + Vec3::Z * 0.0001);
painter.color = Color::rgba(0.0, 1.0, 0.0, 0.5);
painter.circle(radius);
painter.rotate_z(-TAU / 3.0);
painter.translate(Vec3::Y * radius * 1.2 + Vec3::Z * 0.0001);
painter.color = Color::rgba(0.0, 0.0, 1.0, 0.5);
painter.circle(radius);
}
fn draw_gallery(mut painter: ShapePainter) {
let radius = 2.0;
painter.reset();
painter.translate(Vec3::X * radius * -4.0);
painter.alpha_mode = AlphaMode::Add;
draw_circles(&mut painter, radius);
painter.reset();
painter.alpha_mode = AlphaMode::Multiply;
draw_circles(&mut painter, radius);
painter.reset();
painter.translate(Vec3::X * radius * 4.0);
painter.alpha_mode = AlphaMode::Blend;
draw_circles(&mut painter, radius);
}
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
fn draw_tree(time: f32, painter: &mut ShapePainter, depth: u32) {
if depth == 0 {
return;
}
let line_a = Vec3::Y + Vec3::X * 0.5;
painter.rotate_z(time.sin() * 0.2);
painter
.line(Vec3::ZERO, line_a)
.with_children(|child_painter| {
child_painter.translate(line_a);
draw_tree(time, child_painter, depth - 1);
});
let line_b = Vec3::Y + Vec3::NEG_X * 0.5;
painter.rotate_z(-time.sin() * 0.4);
painter
.line(Vec3::ZERO, line_b)
.with_children(|child_painter| {
child_painter.translate(line_b);
draw_tree(time, child_painter, depth - 1);
});
}
fn draw_gallery(
time: Res<Time>,
mut painter: ShapePainter,
mut tree: Query<&mut Transform, With<Tree>>,
) {
let mut tree = tree.single_mut();
tree.rotation = Quat::from_rotation_z(time.elapsed_seconds().sin() / 4.0);
// Position our painter relative to our tree entity
painter.transform = *tree;
painter.color = Color::SEA_GREEN + Color::WHITE * 0.25;
painter
.line(Vec3::ZERO, Vec3::Y)
.with_children(|child_painter| {
child_painter.translate(Vec3::Y);
draw_tree(time.elapsed_seconds(), child_painter, 10);
});
}
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
fn draw_shapes(time: Res<Time>, mut painter: ShapePainter) {
painter.reset();
painter.render_layers = Some(RenderLayers::layer(1));
painter.hollow = true;
painter.transform.scale = Vec3::ONE * 3.0;
let meter_fill = (time.elapsed_seconds().sin() + 1.0) / 2.0;
let meter_size = PI * 1.5;
let start_angle = -meter_size / 2.0;
let end_angle = -meter_size / 2.0 + meter_fill * meter_size;
painter.cap = Cap::Round;
painter.thickness = 0.4;
painter.color = Color::CRIMSON * (1.0 / (0.5 + meter_fill));
painter.arc(1.3, start_angle, end_angle);
painter.cap = Cap::None;
painter.thickness = 0.2;
painter.color = Color::DARK_GRAY;
painter.arc(1.6, start_angle, -start_angle);
painter.arc(0.8, start_angle, -start_angle);
let offset = Quat::from_rotation_z(start_angle) * Vec3::Y * 1.1;
painter.translate(offset);
painter.arc(0.5, start_angle + PI * 1.5, start_angle + 2.5 * PI);
painter.translate(-offset);
painter.translate(Quat::from_rotation_z(-start_angle) * Vec3::Y * 1.1);
painter.arc(0.5, start_angle + PI, start_angle + 2.0 * PI);
}
sourcepub fn set_translation(&mut self, translation: Vec3)
pub fn set_translation(&mut self, translation: Vec3)
Helper method to set the configs transform.
sourcepub fn rotate(&mut self, quat: Quat)
pub fn rotate(&mut self, quat: Quat)
Helper method to rotate the configs transform by a given Quat
.
sourcepub fn set_rotation(&mut self, rotation: Quat)
pub fn set_rotation(&mut self, rotation: Quat)
Helper method to set the configs rotation.
sourcepub fn rotate_x(&mut self, angle: f32)
pub fn rotate_x(&mut self, angle: f32)
Helper method to rotate the configs transform around the x axis.
sourcepub fn rotate_y(&mut self, angle: f32)
pub fn rotate_y(&mut self, angle: f32)
Helper method to rotate the configs transform around the y axis.
sourcepub fn rotate_z(&mut self, angle: f32)
pub fn rotate_z(&mut self, angle: f32)
Helper method to rotate the configs transform around the z axis.
Examples found in repository?
32 33 34 35 36 37 38 39 40 41 42 43 44 45
fn draw_canvas(time: Res<Time>, mut painter: ShapePainter, canvas: Query<(Entity, &Canvas)>) {
let (canvas, _) = canvas.single();
painter.rotate_z(time.elapsed_seconds().sin());
painter.set_canvas(canvas);
painter.color = Color::WHITE * 2.0;
painter.translate(Vec3::NEG_Y * 12.0 * 16.0);
painter.thickness = 16.0;
for _ in 0..12 {
painter.translate(Vec3::Y * 32.0);
painter.line(Vec3::NEG_X * 256.0, Vec3::X * 256.0);
}
painter.reset();
}
More examples
19 20 21 22 23 24 25 26 27 28 29 30 31 32
fn setup(mut commands: Commands, mut shapes: ShapeCommands) {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0., 0.0, 16.).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
// The ShapeCommands API is identical to the ShapePainter API so can be used almost interchangably
shapes.circle(1.0).with_children(|parent| {
for _ in 0..4 {
parent.rotate_z(PI / 2.0);
parent.line(Vec3::ZERO, Vec3::Y * 2.0);
}
});
}
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
fn draw_shapes(time: Res<Time>, mut painter: ShapePainter, canvas: Query<(Entity, &Canvas)>) {
let (canvas_e, canvas) = canvas.single();
painter.image(canvas.image.clone(), Vec2::splat(12.));
painter.set_canvas(canvas_e);
painter.hollow = true;
painter.thickness = 16.0;
painter.color = Color::SEA_GREEN + Color::WHITE * 0.25;
painter.rect(Vec2::splat(1024.0));
painter.rotate_z(time.elapsed_seconds().sin());
painter.image(canvas.image.clone(), Vec2::splat(980.0));
painter.reset();
}
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
fn draw_circles(painter: &mut ShapePainter, radius: f32) {
painter.translate(-(Vec3::X + Vec3::NEG_Y) * f32::sqrt(radius) * 0.5);
painter.color = Color::rgba(1.0, 0.0, 0.0, 0.5);
painter.circle(radius);
painter.rotate_z(-TAU / 3.0);
painter.translate(Vec3::Y * radius * 1.2 + Vec3::Z * 0.0001);
painter.color = Color::rgba(0.0, 1.0, 0.0, 0.5);
painter.circle(radius);
painter.rotate_z(-TAU / 3.0);
painter.translate(Vec3::Y * radius * 1.2 + Vec3::Z * 0.0001);
painter.color = Color::rgba(0.0, 0.0, 1.0, 0.5);
painter.circle(radius);
}
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
fn draw_tree(time: f32, painter: &mut ShapePainter, depth: u32) {
if depth == 0 {
return;
}
let line_a = Vec3::Y + Vec3::X * 0.5;
painter.rotate_z(time.sin() * 0.2);
painter
.line(Vec3::ZERO, line_a)
.with_children(|child_painter| {
child_painter.translate(line_a);
draw_tree(time, child_painter, depth - 1);
});
let line_b = Vec3::Y + Vec3::NEG_X * 0.5;
painter.rotate_z(-time.sin() * 0.4);
painter
.line(Vec3::ZERO, line_b)
.with_children(|child_painter| {
child_painter.translate(line_b);
draw_tree(time, child_painter, depth - 1);
});
}
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
fn setup(mut commands: Commands, mut shapes: ShapeCommands, mut meshes: ResMut<Assets<Mesh>>) {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0., 0.0, 16.).looking_at(Vec3::ZERO, Vec3::Y),
..default()
});
// When spawning shapes as children of non-shape entities you can use `with_shape_children`
// This requires passing in a ShapeConfig, you can construct one yourself or
// take an existing one from a ShapePainter or ShapeCommands with .config()
commands
.spawn((Target, SpatialBundle::default()))
.with_shape_children(shapes.config(), |child_builder| {
for _ in 0..4 {
child_builder.rotate_z(PI / 2.0);
child_builder.line(Vec3::Y, Vec3::Y * 2.0);
}
});
let cube_handle = meshes.add(Mesh::from(Cuboid::new(0.2, 0.2, 0.2)));
// When spawning non-shapes as children of shapes you can use `with_children` like normal
shapes
.circle(0.2)
.insert(Target)
.with_children(|child_builder| {
for i in 0..4 {
let transform = Transform::from_translation(
Quat::from_rotation_z(PI / 2.0 * i as f32 + PI / 4.0)
* Vec3::new(0.0, 1.0, 0.0),
);
child_builder.spawn(PbrBundle {
mesh: cube_handle.clone(),
transform,
..default()
});
}
});
}
sourcepub fn set_scale(&mut self, scale: Vec3)
pub fn set_scale(&mut self, scale: Vec3)
Helper method to set the configs scale.
Examples found in repository?
More examples
sourcepub fn set_canvas(&mut self, canvas: Entity)
pub fn set_canvas(&mut self, canvas: Entity)
Helper method to change shape render target to a canvas.
Also sets pipeline to Shape2d.
Examples found in repository?
More examples
43 44 45 46 47 48 49 50 51 52 53 54 55
fn draw_shapes(time: Res<Time>, mut painter: ShapePainter, canvas: Query<(Entity, &Canvas)>) {
let (canvas_e, canvas) = canvas.single();
painter.image(canvas.image.clone(), Vec2::splat(20.));
painter.set_canvas(canvas_e);
painter.hollow = true;
painter.thickness = 6.0;
painter.color = Color::CRIMSON;
painter.translate(Vec3::Y * time.elapsed_seconds().sin() * 256.0);
painter.circle(48.0);
painter.reset();
}
32 33 34 35 36 37 38 39 40 41 42 43 44 45
fn draw_canvas(time: Res<Time>, mut painter: ShapePainter, canvas: Query<(Entity, &Canvas)>) {
let (canvas, _) = canvas.single();
painter.rotate_z(time.elapsed_seconds().sin());
painter.set_canvas(canvas);
painter.color = Color::WHITE * 2.0;
painter.translate(Vec3::NEG_Y * 12.0 * 16.0);
painter.thickness = 16.0;
for _ in 0..12 {
painter.translate(Vec3::Y * 32.0);
painter.line(Vec3::NEG_X * 256.0, Vec3::X * 256.0);
}
painter.reset();
}
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
fn draw_shapes(time: Res<Time>, mut painter: ShapePainter, canvas: Query<(Entity, &Canvas)>) {
let (canvas_e, canvas) = canvas.single();
painter.image(canvas.image.clone(), Vec2::splat(12.));
painter.set_canvas(canvas_e);
painter.hollow = true;
painter.thickness = 16.0;
painter.color = Color::SEA_GREEN + Color::WHITE * 0.25;
painter.rect(Vec2::splat(1024.0));
painter.rotate_z(time.elapsed_seconds().sin());
painter.image(canvas.image.clone(), Vec2::splat(980.0));
painter.reset();
}
sourcepub fn without_transform(&self) -> Self
pub fn without_transform(&self) -> Self
Helper method to clone the config without it’s transform, useful when parenting.
Trait Implementations§
source§impl<'w, 's> Deref for ShapeCommands<'w, 's>
impl<'w, 's> Deref for ShapeCommands<'w, 's>
source§impl<'w, 's> DerefMut for ShapeCommands<'w, 's>
impl<'w, 's> DerefMut for ShapeCommands<'w, 's>
source§impl<'w, 's> ShapeSpawner<'w> for ShapeCommands<'w, 's>
impl<'w, 's> ShapeSpawner<'w> for ShapeCommands<'w, 's>
source§fn spawn_shape(&mut self, bundle: impl Bundle) -> ShapeEntityCommands<'_, '_>
fn spawn_shape(&mut self, bundle: impl Bundle) -> ShapeEntityCommands<'_, '_>
ShapeBundle
does not include RenderLayers
as there is no support for optional components
so instead it is inserted in this function conditionally depending on the ShapeConfig
in self
Prefer the function for the shape you want over ShapeSpawner::spawn_shape
, e.g. commands.rect(...)
fn config(&self) -> &ShapeConfig
fn set_config(&mut self, config: ShapeConfig)
source§impl SystemParam for ShapeCommands<'_, '_>
impl SystemParam for ShapeCommands<'_, '_>
§type Item<'w, 's> = ShapeCommands<'w, 's>
type Item<'w, 's> = ShapeCommands<'w, 's>
Self
, instantiated with new lifetimes. Read moresource§fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State
fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State
World
] access used by this [SystemParam
]
and creates a new instance of this param’s State
.source§fn new_archetype(
state: &mut Self::State,
archetype: &Archetype,
system_meta: &mut SystemMeta
)
fn new_archetype( state: &mut Self::State, archetype: &Archetype, system_meta: &mut SystemMeta )
Archetype
], registers the components accessed by this [SystemParam
] (if applicable).source§fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World)
fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World)
SystemParam
]’s state.
This is used to apply Commands
during apply_deferred
.source§unsafe fn get_param<'w, 's>(
state: &'s mut Self::State,
system_meta: &SystemMeta,
world: UnsafeWorldCell<'w>,
change_tick: Tick
) -> Self::Item<'w, 's>
unsafe fn get_param<'w, 's>( state: &'s mut Self::State, system_meta: &SystemMeta, world: UnsafeWorldCell<'w>, change_tick: Tick ) -> Self::Item<'w, 's>
SystemParamFunction
. Read moreimpl<'w, 's> ReadOnlySystemParam for ShapeCommands<'w, 's>where
&'s mut ShapeConfig: ReadOnlySystemParam,
Commands<'w, 's>: ReadOnlySystemParam,
Res<'w, BaseShapeConfig>: ReadOnlySystemParam,
Auto Trait Implementations§
impl<'w, 's> !RefUnwindSafe for ShapeCommands<'w, 's>
impl<'w, 's> Send for ShapeCommands<'w, 's>
impl<'w, 's> Sync for ShapeCommands<'w, 's>
impl<'w, 's> Unpin for ShapeCommands<'w, 's>
impl<'w, 's> !UnwindSafe for ShapeCommands<'w, 's>
Blanket Implementations§
§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
§fn as_bind_group_shader_type(&self, _images: &RenderAssets<Image>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<Image>) -> U
T
[ShaderType
] for self
. When used in [AsBindGroup
]
derives, it is safe to assume that all images in self
exist.source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<'w, T> DiscSpawner<'w> for Twhere
T: ShapeSpawner<'w>,
impl<'w, T> DiscSpawner<'w> for Twhere
T: ShapeSpawner<'w>,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.