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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ bevy_winit = ["bevy_internal/bevy_winit"]
trace_chrome = ["bevy_internal/trace_chrome"]
trace = ["bevy_internal/trace"]
wgpu_trace = ["bevy_internal/wgpu_trace"]
debug_draw = ["bevy_internal/debug_draw"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
debug_draw = ["bevy_internal/debug_draw"]
debug_draw = ["bevy_internal/bevy_debug_draw"]

I think it must be named this, to succesfully compile.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not seem to help. The other crates do not require a bevy_ prefix either.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is neccesary here, as you added it to bevy_internal this way:

bevy_debug_draw = { path = "../bevy_debug_draw", optional = true, version = "0.4.0" }

See the bevy_ prefix?
Those that don't need it, also don't have the prefix:

wgpu_trace = ["bevy_wgpu/trace"]
trace = [ "bevy_app/trace", "bevy_ecs/trace" ]
trace_chrome = [ "bevy_log/tracing-chrome" ]

For me applying that change allows cargo to compile, though there are still several compile errors:

  • The With<> I suggested below still needs to be imported.
  • The trait functions in the gizmo file, do not need a pub

But at least it's progress.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After fixing up the example, it also compiles successfully.
(Though I don't know why no Lines are drawn)
debug_lines

Copy link
Contributor

@MinerSebas MinerSebas Mar 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have sent you a PR on your Fork, with all the fixes. The5-1#1

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @MinerSebas .
I merged the PR on my fork and have the same behavior.
Will try and find the bug.


# Image format support for texture loading (PNG and HDR are enabled by default)
hdr = ["bevy_internal/hdr"]
Expand Down Expand Up @@ -119,6 +120,11 @@ path = "examples/2d/texture_atlas.rs"
name = "3d_scene"
path = "examples/3d/3d_scene.rs"

[[example]]
name = "debug_draw_3d"
path = "examples/3d/debug_draw_3d.rs"
required-features = ["debug_draw"]

[[example]]
name = "load_gltf"
path = "examples/3d/load_gltf.rs"
Expand Down
28 changes: 28 additions & 0 deletions crates/bevy_debug_draw/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "bevy_debug_draw"
version = "0.4.0"
edition = "2018"
authors = [
"Bevy Contributors <[email protected]>",
"Fabian Krauser <[email protected]>",
]
description = "Provides immediate mode debug drawing for the Bevy Engine"
homepage = "https://bevyengine.org"
repository = "https://github.com/bevyengine/bevy"
license = "MIT"
keywords = ["bevy"]


[dependencies]
# bevy
bevy_render = { path = "../bevy_render", version = "0.4.0" }
bevy_app = { path = "../bevy_app", version = "0.4.0" }
bevy_asset = { path = "../bevy_asset", version = "0.4.0" }
bevy_core = { path = "../bevy_core", version = "0.4.0" }
bevy_log = { path = "../bevy_log", version = "0.4.0" }
bevy_derive = { path = "../bevy_derive", version = "0.4.0" }
bevy_ecs = { path = "../bevy_ecs", version = "0.4.0" }
bevy_math = { path = "../bevy_math", version = "0.4.0" }
bevy_reflect = { path = "../bevy_reflect", version = "0.4.0", features = ["bevy"] }
bevy_transform = { path = "../bevy_transform", version = "0.4.0" }
bevy_utils = { path = "../bevy_utils", version = "0.4.0" }
190 changes: 190 additions & 0 deletions crates/bevy_debug_draw/src/debug_draw_3d.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
use bevy_app::{AppBuilder, CoreStage, Plugin};
use bevy_asset::{AddAsset, Assets, Handle};
use bevy_ecs::{
prelude::{Commands, Query, ResMut},
schedule::*,
system::*,
};
use bevy_log::info;
use bevy_math::*;
use bevy_reflect::TypeUuid;
use bevy_render::{
mesh::*,
pipeline::{CullMode, PipelineDescriptor, PrimitiveTopology},
prelude::{Color, MeshBundle},
render_graph::{base, AssetRenderResourcesNode, RenderGraph},
renderer::RenderResources,
shader::{Shader, ShaderStage, ShaderStages},
};
use bevy_transform::{components::GlobalTransform, TransformSystem};
/// Bevy immediate mode debug drawing:
/// This crate introduces a DebugDraw3D resource which provides functions such as `draw_line(start, end, color)`
/// Whenever such a draw_line function is called, a set of vertices is added to the DebugDraw3D objects data.
/// At the end of the frame the internal data is copied into a mesh entity for drawing and then cleared from the DebugDraw3D object.
/// With this, no persistent line drawing is possible and lines have to be added every frame (hence immediate mode).
/// For convenience a system called `debug_draw_all_gizmos` is provided that draws a coordinate gizmo for any `GlobalTransform`.
///
/// ToDo:
/// * Add more convenience functions such as `draw_arrow(start, end, head_size, color)`, `draw_circle(origin, radius, axis, color)`, `draw_aabb(min,max,color)`.
/// * Modify the shader and access the depth buffer and perform hidden-line rendering rather than a binary depth test for better line visualization.
/// * Add the `debug_draw_all_gizmos` system to the plugin, using a parameter to turn it on or off.
/// * Add transparent triangle drawing (useful to visually project a line down on a plane) and matching utility functions.
/// * Add timed or persistent drawing: This requires storing `Line` structs containing a lifetime rather than directly pushing to an array.
/// * Even though this is a debug feature, there current approach may likely not be the most performant solution and optimizations/refactoring should be applied.

pub struct DebugDrawPlugin;
impl Plugin for DebugDrawPlugin {
fn build(&self, app: &mut AppBuilder) {
app.add_asset::<DebugDraw3DMaterial>()
.init_resource::<DebugDraw3D>()
.add_startup_system(setup_debug_draw_3d.system())
.add_system_to_stage(
CoreStage::PostUpdate,
update_debug_draw_3d
.system()
.after(TransformSystem::TransformPropagate),
);
}
}

/// DebugDraw3D Resource providing functions for immediate mode drawing
pub struct DebugDraw3D {
// The mesh data is held as plain arrays here
// If we wish to extend to more than just lines we may need multiple pairs that will later be ass, e.g. vertices_line and vertices_triangle
vertices: Vec<[f32; 3]>,
colors: Vec<[f32; 4]>,
dirty: bool,
clear: bool,
}

impl Default for DebugDraw3D {
fn default() -> Self {
DebugDraw3D {
vertices: Default::default(),
colors: Default::default(),
dirty: true,
clear: true,
}
}
}

impl DebugDraw3D {
pub fn draw_line(&mut self, start: Vec3, end: Vec3, color: Color) {
self.vertices.push(start.into());
self.vertices.push(end.into());
self.colors.push(color.into());
self.colors.push(color.into());
self.set_dirty();
}

pub fn set_dirty(&mut self) {
self.dirty = true;
}

pub fn reset(&mut self) {
if self.clear {
self.vertices.clear();
self.colors.clear();
}
self.dirty = false;
}

pub fn set_clear(&mut self, clear: bool) {
self.clear = clear;
}
}
/// This component marks the internal entity that does the mesh drawing.
#[derive(Default)]
struct DebugDraw3DComponent;

/// The Material holding the shader for debug drawing
#[derive(RenderResources, Default, TypeUuid)]
#[uuid = "188f0f97-60b2-476a-a749-7a0103adeeba"]
pub struct DebugDraw3DMaterial;

///This system sets up the entity holding the actual mesh for drawing as well as the render pipeline step for the shader.
fn setup_debug_draw_3d(
mut commands: Commands,
mut shaders: ResMut<Assets<Shader>>,
mut materials: ResMut<Assets<DebugDraw3DMaterial>>,
mut render_graph: ResMut<RenderGraph>,
) {
// Crate a shader Pipeline
let mut p = PipelineDescriptor::default_config(ShaderStages {
vertex: shaders.add(Shader::from_glsl(
ShaderStage::Vertex,
include_str!("shaders/debugDrawLine.vert"),
)),
fragment: Some(shaders.add(Shader::from_glsl(
ShaderStage::Fragment,
include_str!("shaders/debugDrawLine.frag"),
))),
});
p.primitive.topology = PrimitiveTopology::LineList;
p.primitive.cull_mode = CullMode::None;

// add the material to the pipeline
render_graph.add_system_node(
"debug_draw_3d",
AssetRenderResourcesNode::<DebugDraw3DMaterial>::new(false),
);
// connect that node stage the MAIN_PASS node
render_graph
.add_node_edge("debug_draw_3d", base::node::MAIN_PASS)
.unwrap();

let material_instance = materials.add(DebugDraw3DMaterial {});

// Spawn a entity that will do the debug drawing with its mesh
commands
.spawn(MeshBundle::default())
.with(material_instance)
.with(DebugDraw3DComponent::default());

info!("Loaded debug lines plugin.");
}

/// This system updates the debug draw Entity with the data from
fn update_debug_draw_3d(
mut debug_draw: ResMut<DebugDraw3D>,
mut meshes: ResMut<Assets<Mesh>>,
query: Query<&Handle<Mesh>, With<DebugDraw3DComponent>>,
) {
if !debug_draw.dirty {
return;
} else {
for mesh in query.iter() {
if let Some(mesh) = meshes.get_mut(mesh) {
mesh.set_attribute(
Mesh::ATTRIBUTE_POSITION,
VertexAttributeValues::Float3(debug_draw.vertices.clone()),
);
mesh.set_attribute(
"Vertex_Color",
VertexAttributeValues::Float4(debug_draw.colors.clone()),
);
}
}
}
debug_draw.reset();
}

pub fn debug_draw_all_gizmos(mut debug_draw: ResMut<DebugDraw3D>, query: Query<&GlobalTransform>) {
for transform in query.iter() {
debug_draw.draw_line(
transform.translation,
transform.translation + transform.local_x(),
Color::RED,
);
debug_draw.draw_line(
transform.translation,
transform.translation + transform.local_y(),
Color::GREEN,
);
debug_draw.draw_line(
transform.translation,
transform.translation + transform.local_z(),
Color::BLUE,
);
}
}
45 changes: 45 additions & 0 deletions crates/bevy_debug_draw/src/gizmo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use bevy_render::{mesh::*, pipeline::PrimitiveTopology};

pub struct CoordinateGizmo {
pub size: f32,
}

impl CoordinateGizmo {
pub fn new(size: f32) -> CoordinateGizmo {
CoordinateGizmo { size }
}
}

impl Default for CoordinateGizmo {
pub fn default() -> Self {
CoordinateGizmo { size: 1.0 }
}
}

impl From<CoordinateGizmo> for Mesh {
pub fn from(shape: CoordinateGizmo) -> Self {
let mut mesh = Mesh::new(PrimitiveTopology::LineList);
let vertices = vec![
[0.0, 0.0, 0.0],
[shape.size, 0.0, 0.0],
[0.0, 0.0, 0.0],
[0.0, shape.size, 0.0],
[0.0, 0.0, 0.0],
[0.0, 0.0, shape.size],
];
mesh.set_attribute(
Mesh::ATTRIBUTE_POSITION,
VertexAttributeValues::Float3(vertices),
);
let colors = vec![
[1.0, 0.0, 0.0, 1.0],
[1.0, 0.0, 0.0, 1.0],
[0.0, 1.0, 0.0, 1.0],
[0.0, 1.0, 0.0, 1.0],
[0.0, 0.0, 1.0, 1.0],
[0.0, 0.0, 1.0, 1.0],
];
mesh.set_attribute("Vertex_Color", VertexAttributeValues::Float4(colors));
mesh
}
}
2 changes: 2 additions & 0 deletions crates/bevy_debug_draw/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod debug_draw_3d;
pub mod gizmo;
6 changes: 6 additions & 0 deletions crates/bevy_debug_draw/src/shaders/debugDrawLine.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#version 450
layout(location = 0) in vec4 vColor;
layout(location = 0) out vec4 o_Target;
void main() {
o_Target = vColor;
}
15 changes: 15 additions & 0 deletions crates/bevy_debug_draw/src/shaders/debugDrawLine.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#version 450
layout(location = 0) in vec3 Vertex_Position;
layout(location = 1) in vec4 Vertex_Color;
layout(location = 0) out vec4 vColor;

layout(set = 0, binding = 0) uniform Camera {
mat4 ViewProj;
};
layout(set = 1, binding = 0) uniform Transform {
mat4 Model;
};
void main() {
vColor = Vertex_Color;
gl_Position = ViewProj * Model * vec4(Vertex_Position, 1.0);
}
1 change: 1 addition & 0 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ bevy_audio = { path = "../bevy_audio", optional = true, version = "0.4.0" }
bevy_gltf = { path = "../bevy_gltf", optional = true, version = "0.4.0" }
bevy_pbr = { path = "../bevy_pbr", optional = true, version = "0.4.0" }
bevy_render = { path = "../bevy_render", optional = true, version = "0.4.0" }
bevy_debug_draw = { path = "../bevy_debug_draw", optional = true, version = "0.4.0" }
bevy_dynamic_plugin = { path = "../bevy_dynamic_plugin", optional = true, version = "0.4.0" }
bevy_sprite = { path = "../bevy_sprite", optional = true, version = "0.4.0" }
bevy_text = { path = "../bevy_text", optional = true, version = "0.4.0" }
Expand Down
6 changes: 6 additions & 0 deletions crates/bevy_internal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ pub mod render {
pub use bevy_render::*;
}

#[cfg(feature = "bevy_debug_draw")]
pub mod debug_draw {
//! Immediate mode debug drawing, like a visual println.
pub use bevy_debug_draw::*;
}

#[cfg(feature = "bevy_sprite")]
pub mod sprite {
//! Items for sprites, rects, texture atlases, etc.
Expand Down
44 changes: 44 additions & 0 deletions examples/3d/debug_draw_3d.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use bevy::prelude::*;
use bevy::debug_draw::*;

fn main() {
App::build()
.insert_resource(Msaa { samples: 4 })
.add_plugins(DefaultPlugins)
.add_startup_system(setup.system())
.add_system(debug_draw_all_gizmos.system()) //add the system to draw a coordinate gizmo for all Objects
.run();
}

/// set up a simple 3D scene
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// add entities to the world
commands
// plane
.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..Default::default()
})
// cube
.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..Default::default()
})
// light
.spawn(LightBundle {
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..Default::default()
})
// camera
.spawn(PerspectiveCameraBundle {
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::default(), Vec3::Y),
..Default::default()
});
}
1 change: 1 addition & 0 deletions tools/publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ crates=(
bevy_transform
bevy_window
bevy_render
bevy_debug_draw
bevy_input
bevy_gilrs
bevy_pbr
Expand Down