GithubHelp home page GithubHelp logo

bevy_prototype_lyon's Introduction

Bevy + Lyon = โค

Crates.io Crates.io Downloads GitHub Repo stars CI Bevy tracking

bevy_prototype_lyon enables Bevy users to draw 2D shapes and paths, like triangles, circles, rectangles, lines, arcs and beziers.

Try out the live demo! Regular polygon demo

How does it work?

Currently Bevy does not support drawing custom shapes in an easy way. This crate uses a variation of Bevy's SpriteBundle with custom meshes to draw shapes. The lyon crate is used to generate those custom meshes.

Usage

Add bevy_prototype_lyon to your cargo project:

cargo add bevy_prototype_lyon

Then, you can start by drawing simple shapes:

use bevy::prelude::*;
use bevy_prototype_lyon::prelude::*;

fn main() {
    App::new()
        .insert_resource(Msaa::Sample4)
        .add_plugins(DefaultPlugins)
        .add_plugins(ShapePlugin)
        .add_systems(Startup, setup_system)
        .run();
}

fn setup_system(mut commands: Commands) {
    let shape = shapes::RegularPolygon {
        sides: 6,
        feature: shapes::RegularPolygonFeature::Radius(200.0),
        ..shapes::RegularPolygon::default()
    };

    commands.spawn(Camera2dBundle::default());
    commands.spawn((
        ShapeBundle {
            path: GeometryBuilder::build_as(&shape),
            ..default()
        },
        Fill::color(Color::CYAN),
        Stroke::new(Color::BLACK, 10.0),
    ));
}

Don't forget to check out the examples to learn more!

Bevy versions supported

I strive to support the latest version of Bevy. Support for a version of Bevy is dropped as soon as a new one is released.

The following table shows the latest version of bevy_prototype_lyon that supports a certain version of Bevy.

bevy bevy_prototype_lyon license
0.13 0.11 MIT/Apache 2.0
0.12 0.10 MIT/Apache 2.0
0.11 0.9 MIT/Apache 2.0
0.10 0.8 MIT/Apache 2.0
0.9 0.7 MIT/Apache 2.0
0.8 0.6 MIT/Apache 2.0
0.7 0.5 MIT/Apache 2.0
0.6 0.4 MIT/Apache 2.0
0.5 0.3 MIT
0.4 0.2 MIT

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

bevy_prototype_lyon's People

Contributors

agluszak avatar alec-deason avatar alyti avatar azorlogh avatar carrascomj avatar davidb avatar enaut avatar faassen avatar jojojet avatar manankarnik avatar mockersf avatar nilirad avatar nside avatar pka avatar rparrett avatar schneiderfelipe avatar shatur avatar ssbr avatar striezel avatar theleonsver1 avatar wainwrightmark avatar weasy666 avatar will-hart avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

bevy_prototype_lyon's Issues

example with GLSL

hello,
could you give examples with GLSL on the background and on textured surfaces ?
thanks !

Add option to reduce number of meshes

Currently, each piece of geometry you add, creates a mesh. In some cases this adds unnecessary draw calls. This can be solved by adding APIs that add geometry and builds the mesh separately.

EDIT: There are actually two ways to reduce the number of meshes:

  • change the 1:1=shape:mesh constraint to n:1=shape:mesh (see original message),
  • Reuse a mesh that has already been created. (e.g. SpriteBundle, by default, uses the same quad mesh).

Drawing a 1px wide line

I'm not sure how to actually do this with Lyon, but it seems it should be possible looking at its output. What I'm doing at the moment is basically drawing a very thin rectangle, but there's a slight problem that if it becomes too thin it's actually invisible.

It would be great if there was an API to draw a line which just renders as thin as possible, but always visible.

Removing the ShapeBundle generates warnings

I need to regularly replace a single shape with another, which I am achieving with Commands::<ShapeBundle>::remove(shape_entity). However, this often but not always triggers the following warning log: WARN bevy_ecs::system::commands: Failed to remove components "bevy_prototype_lyon::entity::ShapeBundle" with error: missing lyon_path::path::Path component. Falling back to inefficient one-by-one component removing..

Related to #11 perhaps?

[IMPORTANT] Relicense bevy_prototype_lyon under dual MIT/Apache 2.0

I, as the repository owner, would like to make a few simple but important changes to bevy_prototype_lyon:

  1. relicense it under the "dual MIT / Apache 2.0 license",
  2. remove the copyright notice that now resides in the LICENSE file, which incorrectly attributes the work to only me.

Each contributor holds copyright for their additions. Therefore, I cannot relicense without explicit consent from past contributors, unless I remove their contributions. The purpose of this issue is seeking compliance for these changes from all the contributors.

Why I am going to relicense

The Bevy game engine, which this library depends on, is currently under the same process (bevyengine/bevy#2373) and its current contribution guidelines suggests to license eligible assets under the same license as Bevy. Also, there is a remote possibility that at least some parts of bevy_prototype_lyon will be included in a future version of Bevy. Relicensing would be of great help in this case.

How to comply

If you decided to comply to the changes described in the first paragraph of this issue, I really appreciate it. Thanks! You just need to post the following comment as a reply to this issue:

I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to choose either at their option.

By posting this comment, everyone can safely assume that you agree with the relicense process. Please notice that other forms of support, like reacting with a ๐Ÿ‘๐Ÿป or posting a comment with a different formula will NOT be considered valid.

What if you don't want to comply

I don't want to force you to comply to these changes. You will need to know however that if you don't comply, your contributions will be removed (or reimplemented in a way that respects your copyright) in order to keep the relicense process going on. Please let me know under this issue or privately if you take this choice. It would help me a lot speeding up the process. Still, thanks for having contributed to this repository!

Changes after the relicense

README.md

the following paragraphs will be added to the end of the file:

### License

Licensed under either of

 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.

License files

LICENSE will be replaced by LICENSE-MIT and LICENSE-APACHE with their respective contents.

Rust package manifest (Cargo.toml)

the license field will be changed to the following:

license = "MIT OR Apache-2.0"

Contributor checklist

The following is a checklist featuring every GitHub account that have committed at least once in this repository, aside from myself (order is alphabetical):

This issue will be closed once a pull request with the needed changes will be merged to the master branch.

using a Lyon Path in a GeometryBuilder results in a panic

The resulting Mesh has a Vertex_Position attribute, but not a Vertex_Position_2D attribute:

[src/main.rs:70] meshes.get(&trail.mesh).unwrap() = Mesh {
    primitive_topology: TriangleList,
    attributes: {
        "Vertex_Normal": Float3([ โ€ฆ ]),
        "Vertex_Position": Float3([ โ€ฆ ]),
        "Vertex_Uv": Float2([ โ€ฆ ]),
    }
    indices: Some(U32([ โ€ฆ ])),
}
thread 'Compute Task Pool (4)' panicked at 'Attribute Vertex_Position_2D is required by shader, but not supplied by mesh. Either remove the attribute from the shader or supply the attribute (Vertex_Position_2D) to the mesh.', /home/db48x/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_render-0.5.0/src/pipeline/pipeline_compiler.rs:231:17

Narrower prelude

Export less things in the prelude (for example, you don't need to export every single basic shape, but just the module).

Reintroduce Path again

Recently I removed paths because they were just a wrapper over Lyon and used an old implementation of the library that I removed. However, I must make sure that the user is able to at least use lyon paths directly if I won't reintroduce special code.

`Path` no longer implement `Geometry`?

It looks like in 0.4.0 Path no longer implement Geometry.

As a result this code, which used to compile, no longer do:

GeometryBuilder::new().add(&PathBuilder::new().build());

I don't see any related information in the changelog. Was that on purpose? If yes, what is the new way to add an arbitrary path to the GeometryBuilder?

Add draw type option?

Currently Bevy considers a (0.0,0.0) x,y cursor location to be on the bottom left of the screen. Your position would consider this to be the center of the screen.

The solution would seem to then be set some kind of draw type option that allowed you to do your coordinates based on center bottom left top right or whatever is convenient.

Recoloring a shape or tinting

I like using geometric shapes for prototyping game mechanics.
I have the use case where I want to draw a lot of shapes having the same path but different colors.
Those entities are created and removed on mass.
Think of like items on a belt like https://shapez.io

๐Ÿ‘‰ Creating one shape bundle / mesh and tinting it would be what I would have expected, but it did not look like this is possible right now by changing the ShapeColors, since colors are backed into vertex attributes and shaders only look at vertex attributes.

I currently rely on creating lots of shape bundles with freshly build meshes but on color change I mutate the color vertex attributes like in following code snippet. To distinguish stroke vertices from filling vertices I use a black stroke only and check for this color. ๐Ÿคช

               for mesh in meshes.get_mut(&*mesh) {
                    if let Some(VertexAttributeValues::Float4(colors)) = mesh.attribute_mut(Mesh::ATTRIBUTE_COLOR) {
                        for color in colors {
                            if color[..3] != [0.0, 0.0, 0.0] {
                                *color = item.color().as_rgba_f32();
                            }
                        }
                    }
                }

I think what I am doing is fragile but I lack an API to support this use case. How would this look like?

Major version updates on dependency major version updates?

Hi! Love the work this is doing.

Would you consider bumping the major version of this plugin, though, when you upgrade major versions of dependencies? By that I mean the second number; for 0.x.y pre-1.0 versions, cargo treats x as major and y as minor.

The reasoning for this is that Cargo treats minor versions as practically identical. cargo update will update things with the assumption that version 0.1.4 is backwards compatible with 0.1.3. But upgrading bevy in this project is a breaking change, since bevy_prototype_lyon returns types from bevy in its interface.

To put it more concretely, if someone depends on bevy = "0.3.0" and bevy_prototype_lyon = "0.1.3", then upgrading to bevy_prototype_lyon 0.1.4 will break their build. They'll get an error "expected bevy (0.3.0)::SpriteComponents, found bevy (0.4.0)::SpriteBundle. Breaking changes are fine, but they should be denoted by major version updates so that cargo can treat them appropriately (and not automatically apply them).

I don't think this is too big of a deal since everything's in alpha phase right now, but it would still be nice! If you could either yank 0.1.4/0.1.5 and publish as 0.2.0, or just bump to 0.2.0 when upgrading to the next bevy version, that would be awesome. It'd let cargo's versioning work for users, and keep the semantic versioning accurate.

Regardless, thanks for making this! Glad to have it here :)

Draw shape helper function

Currently, to draw a shape you call the draw method of a type that implements ShapeSprite:

let circle = shapes::Circle {
    radius: 100.0,
    ..Default::default()
};

commands.spawn(Camera2dBundle::default()).spawn(circle.draw(
    materials.add(ColorMaterial::color(Color::AQUAMARINE)),
    TessellationMode::Fill(FillOptions::default()),
    Transform::default(),
));

But it may be better to use a helper function instead, that takes the ShapeSprite as input:

commands.spawn(Camera2dBundle::default()).spawn(draw_shape(
    Box::new(shapes::Circle {
        radius: 100.0,
        ..Default::default()
    }),
    materials.add(ColorMaterial::color(Color::AQUAMARINE)),
    TessellationMode::Fill(FillOptions::default()),
    Transform::default(),
));

The problem is, I can't find a way to satisfy trait bounds when I add a Box<dyn ShapeSprite> type as argument to the function.

Shapes do not respect Z index in 2D

Typically with sprites in bevy, you can draw on top of other things by using the Z translation as ordering.

Shapes drawn with this crate don't seem to respect the Z ordering provided in the translation.

Stuttering on some hardware

Just as an FYI, I'm experiencing stutter in Bevy 0.6 when I add plugins for projects like this one. Literally just adding the plugin introduces stutter -- I don't even need to do anything.

I reported it upstream to Bevy here. I just wanted to make you aware in case other users of this plugin experience it, or if you are interested in looking into the problem.

Feel free to close this issue unless you feel like it provides some value while the problem persists.

WASM builds no longer work?

Thanks for the library.

I started a fresh project with bevy 0.5, bevy_webgl 0.5 and (forked bevy_prototype_lyon, see my PR) based on bevy_webgl2_app_template.

Things are working great in native builds, but panicking in chrome and firefox when compiling shaders in web builds:

wasm.js:369 panicked at 'called `Result::unwrap()` on an `Err` value: "ERROR: 0:1: \'\n\' : invalid version directive\nERROR: 0:5: \'layout\' : syntax error\n\u{0}"', /Users/robparrett/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_webgl2-0.5.0/src/renderer/webgl2_render_resource_context.rs:77:81

I guess this is due to the new rendering pipeline that (became necessary for bevy 0.5 for some reason)?

I'd be happy to contribute something like a "web" feature that swaps in some opengl es compatible shaders, if that contribution would be welcome.

Regular polygon shape

Add a generic regular polygon shape that you can construct by giving the number of sides and specifying its size by inputting the side length, the apothem or the radius.

The shape should contain an option to choose if the base of the shape lie flat on the x-axis.

Version 0.3 does not work with bevy 0.5

cargo.toml

bevy = "0.5"
bevy_prototype_lyon = "0.3"

main.rs

use bevy::prelude::*;
use bevy_prototype_lyon::prelude::*;

fn main() {
    App::build()
        .add_plugins(DefaultPlugins)
        .add_plugins(ShapePlugin)
        .run();
}

cargo run (edit: oops, previous text had wrong error here)

    Compiling delete-me v0.1.0 (/Users/robparrett/src/delete-me)
error[E0277]: the trait bound `bevy_prototype_lyon::plugin::ShapePlugin: bevy::prelude::PluginGroup` is not satisfied
 --> src/main.rs:7:22
  |
7 |         .add_plugins(ShapePlugin)
  |                      ^^^^^^^^^^^ the trait `bevy::prelude::PluginGroup` is not implemented for `bevy_prototype_lyon::plugin::ShapePlugin`

error: aborting due to previous error

This is due to version 0.3 depending on a git version of bevy instead of the crates.io 0.5 release.

Update to latest branch

Hello! This crate is awesome. I'm using it for implementing a tool for myself https://github.com/carrascomj/bevy_svg_map/tree/bevy-lyon.

As of now, in order to be compatible with bevy's master, I had to change two lines to make it work. Are you interseted in having the master branch up to date with bevy's HEAD? If so, I can just submit the PR. Some may prefer to just wait for the next version of bevy anyways.

Does this crate allow for transparency?

Hello there!

I've been playing around with this crate, and I wanted to have some coloured circles overlap with some transparency.
I saw that I had to activate the transparency on the SpriteComponents's draw attribute but it still doesn't seem to work?

I'm probably doing something wrong, but I can't seem to be finding what.

Here's a minimal example using bevy 3.0 and bevy_lyon 0.1.3 (and running on Linux if that helps) :

use bevy::prelude::*;
use bevy_prototype_lyon::prelude::*;

fn build_transparent_circles(
    mut commands: Commands,
    mut materials: ResMut<Assets<ColorMaterial>>,
    mut meshes: ResMut<Assets<Mesh>>,
) {
    for (i, color) in vec![Color::GREEN, Color::RED, Color::BLUE]
        .iter()
        .enumerate()
    {
        let material = materials.add(ColorMaterial::color(*color));
        let mut sprite = primitive(
            material,
            &mut meshes,
            ShapeType::Circle(100.0),
            TessellationMode::Fill(&FillOptions::default()),
            Vec3::new(i as f32 * 60.0, 0.0, 0.0),
        );
        sprite.draw = Draw {
            is_transparent: false,
            ..Default::default()
        };

        commands.spawn(sprite);
    }
}

fn setup_system(
    mut commands: Commands,
    materials: ResMut<Assets<ColorMaterial>>,
    meshes: ResMut<Assets<Mesh>>,
) {
    commands
        .spawn(UiCameraComponents::default())
        .spawn(Camera2dComponents::default());

    build_transparent_circles(commands, materials, meshes);
}

fn main() {
    App::build()
        .add_plugins(DefaultPlugins)
        .add_startup_system(setup_system.system())
        .run();
}

Visibility.is_visible is always overwritten after mesh building

So it's seemingly impossible to spawn a shape in an initially invisible state.

I toyed with removing this behavior by setting is_visible to true in impl Default for ShapeBundle and removing the visible.is_visible = true in complete_shape_bundle. This didn't seem to harm anything, but it seems like this must be happening for a reason.

In my own code, I've worked around this with

struct ShapeStartsInvisible;

// ...

app.add_stage_after(
        bevy_prototype_lyon::plugin::Stage::Shape,
        "after_shape",
        SystemStage::parallel(),
    );
app.add_system_to_stage("after_shape", shape_visibility_fix.system());

// ...

fn shape_visibility_fix(
    mut invis: Query<&mut Visible, (Changed<Handle<Mesh>>, With<ShapeStartsInvisible>)>,
) {
    for mut visible in invis.iter_mut() {
        visible.is_visible = false;
    }
}

But adding a similar component to bevy_prototype_lyon to control initial visibility seems like an option if it turns out that having a visible shape without a mesh hanging around for a bit is harmful.

If you'd like to point me in one direction or the other I'd be happy to send a PR over.

Remove shape suffix

After fixing #33, you should rename shapes like CircleShape to Circle, since there is no name clashes when using namespaces.

Does not compile as dependency?

Does this project work with bevy 0.5? It seems bevy's "main"-branch is being tracked, but doing

[dependencies]
bevy = { version = "0.5.0", features = ["dynamic"] }
bevy_prototype_lyon = { git = "https://github.com/Nilirad/bevy_prototype_lyon.git", branch = "master" }

throws compilation errors inside bevy_prototype_lyon for me.

Edit: Current master commit when I tried this: 5c92ee5

Edit: The errors can be reproduced by leaving out the bevy dependency, so just running cargo new and adding

[dependencies]
bevy_prototype_lyon = { git = "https://github.com/Nilirad/bevy_prototype_lyon.git", branch = "master" }

at commit 5c92ee5 already causes the bevy_prototype_lyon crate to not compile.

All of this is on windows btw., cargo & rust versions:

cargo 1.52.0-nightly (90691f2bf 2021-03-16)
rustc 1.53.0-nightly (07e0e2ec2 2021-03-24)

But I also tried stable 1.51., which also failed.

cargo 1.51.0 (43b129a20 2021-03-16)
rustc 1.51.0 (2fd73fabe 2021-03-23)

However, when cloning this repo (at the same commit), cargo build as well as cargo check both work.

Compatibility with bevy ui

If I am not mistaken, it is currently not possible to combine this crates functionality with bevy ui components.
It seems like NodeComponents always renders in front of a primitive. It is also not possible to add a primitive as a child to a NodeComponent.

Modifying shapes after creation

Not sure if I'm doing it incorrectly, but right now it seems difficult if not impossible to modify the shapes at runtime after they've been created.

E.g. if I have a simple path shape like this...

    let points = vec![point(0.0, 0.0), point(100.0, 100.0), point(500.0, 000.0)];

    let shape = ShapeType::Polyline {
        points,
        closed: false,
    };
    let mut stroke_options = StrokeOptions::default();
    stroke_options.line_width = 1.0;

    cmd.spawn(primitive(
        material,
        &mut meshes,
        shape,
        TessellationMode::Stroke(&stroke_options),
        Vec3::zero(),
    ))

It seems if I want to change the shape afterwards, I need to use its Mesh component...

fn update(mut meshes: ResMut<Assets<Mesh>>, h: &Handle<Mesh>) {
    let mesh = meshes.get_mut(h).unwrap();
    let attributes = &mut mesh.attributes;

    for att in &mut attributes.iter_mut() {
        //TODO do something with attr
    }
}

But it seems the points it returns are the ones after tessellating the shape, which is not very useful if you want to move the original points before tessellation. E.g. it seems to return 6 points instead of the expected 3.

I assume the only way to do this right now is to create a new primitive every frame and delete the old one?

Demo example

I should add a demo example that shows the capabilities of the library. I imagine it as a bevy app where there is a slideshow of each feature, and you move the slides with the arrow keys (or WASD).

Colors do not match bevy sprites

Not really sure if this is expected behavior, user error, a bevy bug, or a bevy_prototype_lyon bug. Apologies if it's one of the first things.

Here's a screenshot showing the 38 bevy builtin colors in two columns. The left squares in each column are shapes, and the right are sprites.

Curiously, ShapeColors::new(color.as_rgba_linear()) makes them match.

image

Using MacOS (AMD). Haven't tested elsewhere.

Here's the code to reproduce the screenshot.

[dependencies]
bevy = "0.5"
bevy_prototype_lyon = "0.3.1"
use bevy::prelude::*;
use bevy_prototype_lyon::prelude::*;

const COLORS: [Color; 38] = [
    Color::ALICE_BLUE,
    Color::ANTIQUE_WHITE,
    Color::AQUAMARINE,
    Color::AZURE,
    Color::BEIGE,
    Color::BISQUE,
    Color::BLACK,
    Color::BLUE,
    Color::CRIMSON,
    Color::CYAN,
    Color::DARK_GRAY,
    Color::DARK_GREEN,
    Color::FUCHSIA,
    Color::GOLD,
    Color::GRAY,
    Color::GREEN,
    Color::INDIGO,
    Color::LIME_GREEN,
    Color::MAROON,
    Color::MIDNIGHT_BLUE,
    Color::NAVY,
    Color::NONE,
    Color::OLIVE,
    Color::ORANGE,
    Color::ORANGE_RED,
    Color::PINK,
    Color::PURPLE,
    Color::RED,
    Color::SALMON,
    Color::SEA_GREEN,
    Color::SILVER,
    Color::TEAL,
    Color::TOMATO,
    Color::TURQUOISE,
    Color::VIOLET,
    Color::WHITE,
    Color::YELLOW,
    Color::YELLOW_GREEN,
];

fn main() {
    App::build()
        .insert_resource(Msaa { samples: 4 })
        .add_plugins(DefaultPlugins)
        .add_plugin(ShapePlugin)
        .add_startup_system(setup.system())
        .run();
}

fn setup(mut commands: Commands, mut materials: ResMut<Assets<ColorMaterial>>) {
    commands.spawn_bundle(OrthographicCameraBundle::new_2d());

    let width = 30.0;
    let height = 30.0;

    for (ix, chunk) in COLORS.chunks(COLORS.len() / 2).enumerate() {
        for (iy, color) in chunk.iter().enumerate() {
            let shape = shapes::Rectangle {
                width,
                height,
                ..Default::default()
            };
            commands.spawn_bundle(GeometryBuilder::build_as(
                &shape,
                //ShapeColors::new(color.as_rgba_linear()),
                ShapeColors::new(*color),
                DrawMode::Fill(FillOptions::default()),
                Transform::from_xyz(
                    -1.0 * (width * 2.0 + 10.0) + (width * 2.0 + 10.0) * ix as f32,
                    -1.0 * COLORS.len() as f32 / 4.0 * height + height * iy as f32,
                    0.0,
                ),
            ));
            commands.spawn_bundle(SpriteBundle {
                material: materials.add((*color).into()),
                sprite: Sprite::new(Vec2::new(width, height)),
                transform: Transform::from_xyz(
                    -1.0 * (width + 10.0) + (width * 2.0 + 10.0) * ix as f32,
                    -1.0 * COLORS.len() as f32 / 4.0 * height + height * iy as f32,
                    0.0,
                ),
                ..Default::default()
            });
        }
    }
}

Rethink the way sprites are added to the World

The current implementation relies on two systems:

  1. The client system: The user uses the method ShapeSprite::draw to spawn a (ShapeDescriptor, ) bundle.
  2. The shapesprite_maker system: Queries the ShapeDescriptors, generates the corresponding sprites, and despawns the descriptors.

The problem

While this approach removes a lot of boilerplate, the indirect creation of a sprite creates problems to users who call Commands::{with, with_bundle, current_entity}, since those functions point to the ShapeDescriptor entity that gets deleted.

Possible solutions:

Custom command

That's the most interesting solution, because it completely removes the necessity of relying on an external system to spawn entities without boilerplate. If that is possible, the current implementation should be considered an anti-pattern. The thing is, I never made a custom command, so I don't know if it's possible.
EDIT: The way the Command trait and the Commands struct are currently designed makes it impossible to draw a shape without boilerplate.

Direct API

In addition to the ShapeDescriptor based API, it's possible to add an API similar to the old one to directly draw shapes. So each user chooses what to do. This however puts the user in front of a design choice.

Refactor crate

Currently the crate isn't at its optimal state. A good refactoring may fix.

Conflict with bevy?

โฏ cargo check
error: failed to select a version for `wasm-bindgen`.
    ... required by package `wgpu v0.7.0`
    ... which satisfies dependency `wgpu = "^0.7"` of package `bevy_wgpu v0.5.0`
    ... which satisfies dependency `bevy_wgpu = "^0.5.0"` of package `bevy_internal v0.5.0`
    ... which satisfies dependency `bevy_internal = "=0.5.0"` of package `bevy v0.5.0`
    ... which satisfies dependency `bevy = "=0.5.0"` of package `bevy_prototype_lyon v0.3.1`
    ... which satisfies dependency `bevy_prototype_lyon = "=0.3.1"` of package `tp_client v3.0.0 (/home/ryan/Programming/tp/tp-platform/client)`
versions that meet the requirements `=0.2.69` are: 0.2.69

all possible versions conflict with previously selected packages.

  previously selected package `wasm-bindgen v0.2.72`
    ... which satisfies dependency `wasm-bindgen = "=0.2.72"` of package `bevy_app v0.5.0`
    ... which satisfies dependency `bevy_app = "=0.5.0"` of package `bevy_asset v0.5.1`
    ... which satisfies dependency `bevy_asset = "=0.5.1"` of package `bevy_audio v0.5.0`
    ... which satisfies dependency `bevy_audio = "^0.5.0"` of package `bevy_internal v0.5.0`
    ... which satisfies dependency `bevy_internal = "=0.5.0"` of package `bevy v0.5.0`
    ... which satisfies dependency `bevy = "=0.5.0"` of package `bevy_prototype_lyon v0.3.1`
    ... which satisfies dependency `bevy_prototype_lyon = "=0.3.1"` of package `tp_client v3.0.0 (/home/ryan/Programming/tp/tp-platform/client)`

failed to select a version for `wasm-bindgen` which could resolve this conflict

Cargo.toml:

[package]
name = "tp_client"
version = "3.0.0"
edition = "2021"
rust-version = "1.56"  # Rust 2021

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rand = "0.8"
eyre = "0.6"
arena = {path = "../datastructures/arena"}
typemap = "0.3"
crossbeam-channel = "0.5"

[dev-dependencies]
bevy_prototype_lyon = "0.3.1"
bevy = "0.5"

How to check whether buffer around geometry contains cursor?

For interacting with a drawing, it is often useful to check whether some geometry (or, more generally, a buffer around some geometry, in the case of thin lines) contains the mouse cursor coordinates.
Is it within the scope of this crate to provide a function that checks, given a Geometry, whether a point is inside the geometry?
If so, how can I help?
If not, how and where do you imagine something like that might be implemented?

I had a look at bevy_interact_2d, which lists bevy_prototype_lyon as a dependency, but only uses simple bounding box matching; and I tried to understand what methods inside bevy_prototype_lyon I might use to implement something more general, but down the rabbit hole I only found lyon::Triangle::contains_point as a starting point. (This is my first attempt at doing something graphical in Rust, so I may have missed something important.)

rust-toolchain file

While working on #17 : It seemed that rust compiler needs to be nightly ?

A word about that on the readme and/or a rustup-toolchain file would make it clear and self documented.

Could arcs be added to shapes?

Hi, I just saw you published this, thanks for creating it, having a way of drawing shapes in Bevy without needing sprites is exactly what I was waiting for.

I was wondering if drawing arcs (i.e. shapes like half of a circle, or a different fraction of a circle) is possible yet, and in case not, if you have plans to add this in the future?

Rendering breaks when used with bevy_webgl2

I'm running the setup system from the readme example along with the bevy_webgl2_app_template.
In the native build, the shape renders properly.
In the wasm build, the shape is not visible on screen.

For giggles, we can add the shape to the webgl2 template scene. In native, the shape cuts the cube and plane in half as expected. In the wasm build, nothing renders at all!

For completeness, I've tested in Firefox and Edge.
When the shape is included, I see the following warning in the Edge console:
[.WebGL-0000177809F82080] GL_INVALID_OPERATION: It is undefined behaviour to have a used but unbound uniform buffer.
and in the Firefox console:
WebGL warning: drawElementsInstanced: Buffer for uniform block is smaller than UNIFORM_BLOCK_DATA_SIZE.
Though to be honest I don't know if these are relevant.

can't show 2D and 3D models at the same time

Here is a simple example which demonstrate the problem:

use bevy::prelude::*;
use bevy_prototype_lyon::prelude::*;

const SHOW_2D: bool = true;
const SHOW_3D: bool = true;

fn main() {
    App::new()
        .insert_resource(Msaa { samples: 4 })
        .add_plugins(DefaultPlugins)
        .add_plugin(ShapePlugin)
        .add_startup_system(setup_system)
        .run();
}

fn setup_system(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    if SHOW_2D {
        let shape = shapes::RegularPolygon {
            sides: 6,
            feature: shapes::RegularPolygonFeature::Radius(200.0),
            ..shapes::RegularPolygon::default()
        };
        commands.spawn_bundle(OrthographicCameraBundle::new_2d());
        commands.spawn_bundle(GeometryBuilder::build_as(
            &shape,
            DrawMode::Outlined {
                fill_mode: FillMode::color(Color::CYAN),
                outline_mode: StrokeMode::new(Color::BLACK, 10.0),
            },
            Transform::default(),
        ));
    }

    if SHOW_3D {
        // cube
        commands.spawn_bundle(PbrBundle {
            mesh: meshes.add(Mesh::from(shape::Cube { size: 2.0 })),
            material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
            ..Default::default()
        });
        // light
        commands.spawn_bundle(PointLightBundle {
            transform: Transform::from_xyz(4.0, 8.0, 4.0),
            ..Default::default()
        });
        // camera
        commands.spawn_bundle(PerspectiveCameraBundle {
            transform: Transform::from_xyz(-3.0, 3.0, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
            ..Default::default()
        });
    }
}

and the Cargo.toml file:

[package]
name = "bevytest"
version = "0.1.0"
edition = "2021"

[dependencies]
bevy = {version="0.6", default-features=true}
bevy_prototype_lyon = "0.4.0"

When I start it, it shows only the cube. But when I set SHOW_3D to false, it shows the 2D triangle. How can I show both? The triangle in the foreground.

My shapes are no longer displayed in 0.2.0

First of all: thanks for this awesome crate!

I have been drawing shapes with version 0.1.5 and decided to update to 0.2.0 today. After fixing all compilation issues, the Entities are spawned, but nothing is visible on the screen. Example code:

    let rectangle = shapes::Rectangle {
        width: 18.0,
        height: 18.0,
        ..shapes::Rectangle::default()
    };
    let mut builder = GeometryBuilder::new();
    builder.add(&rectangle);
    let mut enemy = Enemy {
      // some stuff
    };
    commands
        .spawn(builder.build(
            enemy.get_color_handle(materials),
            TessellationMode::Fill(FillOptions::default()),
            Transform::from_translation(Vec3::new(map.spawn.x, map.spawn.y, 0.)),
        ))
        .with(enemy);

Am I missing something? In case you would like to run it yourself: https://github.com/NiklasEi/oicana/tree/bevy_prototype_lyon_v0.2.0

Change color (transparency) for existing shape?

Hey and thanks for this little nice project. I'm building some simple little particle effects with it, and as such I want to fade out my particles as they get closer to the end of their lives.

I have no problem creating already transparent shapes, but to change an existing color or transparency seems to be not that easy. I thought I could just query for &mut ShapeColors and call it a day but because that doesn't work I get the feeling that it's only used upon creation of the mesh.

I can query the mesh and get hold of the vertex data I think(?) mesh.get_vertex_buffer_data() but from there I'm stuck. So what I'm asking for is either a small example of how to modify the colors in the vertex data, OR perhaps a feature request for a simpler way to change a shapes color. Maybe make shapes react to changes to ShapeColors? Or maybe I'm missing something obvious? Anyway, thanks again!

Conflicts with `bevy_console`?

When using bevy_prototype_lyon together with bevy_console it seems to crash with

thread 'main' panicked at 'Stage already exists: UiFrameEnd.', /home/darth/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/schedule/mod.rs:137:13

Removing bevy_console from the project fixes the issue. Not sure if the problem is on the side of bevy_console or bevy_prototype_lyon or both?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.