Skip to content

Commit 69c48e0

Browse files
committed
bop
1 parent 77588a0 commit 69c48e0

File tree

4 files changed

+138
-70
lines changed

4 files changed

+138
-70
lines changed

crates/bevy_debug_draw/src/gizmos.rs renamed to crates/bevy_debug_draw/src/gizmo_draw.rs

Lines changed: 122 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,39 @@ use bevy_math::{Mat2, Quat, Vec2, Vec3};
44
use bevy_render::prelude::Color;
55
use crossbeam_channel::{unbounded, Receiver, Sender};
66

7-
use crate::SendItem;
7+
use crate::{SendItem, GIZMO};
88

99
pub struct GizmoDraw {
1010
sender: Sender<SendItem>,
1111
pub(crate) receiver: Receiver<SendItem>,
12-
circle_segments: usize,
1312
}
1413

1514
impl GizmoDraw {
1615
pub(crate) fn new() -> Self {
1716
let (sender, receiver) = unbounded();
18-
GizmoDraw {
19-
sender,
20-
receiver,
21-
circle_segments: 32,
22-
}
17+
GizmoDraw { sender, receiver }
2318
}
2419
}
2520

21+
const CIRCLE_SEGMENTS: usize = 32;
22+
2623
impl GizmoDraw {
2724
/// Draw a line from `start` to `end`.
2825
#[inline]
2926
pub fn line(&self, start: Vec3, end: Vec3, color: Color) {
30-
self.send_line([start, end], [color, color]);
27+
self.line_gradient(start, end, color, color);
3128
}
3229

3330
/// Draw a line from `start` to `end`.
3431
#[inline]
3532
pub fn line_gradient(&self, start: Vec3, end: Vec3, start_color: Color, end_color: Color) {
36-
self.send_line([start, end], [start_color, end_color]);
33+
let _ = self.sender.send(SendItem::Single((
34+
[start.to_array(), end.to_array()],
35+
[
36+
start_color.as_linear_rgba_f32(),
37+
end_color.as_linear_rgba_f32(),
38+
],
39+
)));
3740
}
3841

3942
/// Draw a line from `start` to `start + vector`.
@@ -61,39 +64,49 @@ impl GizmoDraw {
6164
let _ = self.sender.send(SendItem::Strip(iter.unzip()));
6265
}
6366

64-
/// Draw a circle at `position` with the flat side facing `normal`.
6567
#[inline]
66-
pub fn circle(&self, position: Vec3, normal: Vec3, radius: f32, color: Color) {
67-
let rotation = Quat::from_rotation_arc(Vec3::Z, normal);
68-
69-
let positions = self
70-
.circle_inner(radius)
71-
.map(|vec2| (position + rotation * vec2.extend(0.)));
68+
fn linelist(&self, list: impl IntoIterator<Item = Vec3>, color: Color) {
69+
let iter = list
70+
.into_iter()
71+
.map(|p| p.to_array())
72+
.zip(iter::repeat(color.as_linear_rgba_f32()));
73+
let _ = self.sender.send(SendItem::List(iter.unzip()));
74+
}
7275

73-
self.linestrip(positions, color);
76+
/// Draw a circle at `position` with the flat side facing `normal`.
77+
#[inline]
78+
pub fn circle(&self, position: Vec3, normal: Vec3, radius: f32, color: Color) -> DrawCircle {
79+
DrawCircle {
80+
position,
81+
normal,
82+
radius,
83+
color,
84+
segments: CIRCLE_SEGMENTS,
85+
}
7486
}
7587

7688
/// Draw a sphere.
7789
#[inline]
78-
pub fn sphere(&self, position: Vec3, radius: f32, color: Color) {
79-
self.circle(position, Vec3::X, radius, color);
80-
self.circle(position, Vec3::Y, radius, color);
81-
self.circle(position, Vec3::Z, radius, color);
90+
pub fn sphere(&self, position: Vec3, radius: f32, color: Color) -> DrawSphere {
91+
DrawSphere {
92+
position,
93+
radius,
94+
color,
95+
circle_segments: CIRCLE_SEGMENTS,
96+
}
8297
}
8398

8499
/// Draw a rectangle.
85100
#[inline]
86101
pub fn rect(&self, position: Vec3, rotation: Quat, size: Vec2, color: Color) {
87-
let [tl, tr, br, bl] = self
88-
.rect_inner(size)
89-
.map(|vec2| position + rotation * vec2.extend(0.));
102+
let [tl, tr, br, bl] = rect_inner(size).map(|vec2| position + rotation * vec2.extend(0.));
90103
self.linestrip([tl, tr, br, bl, tl], color);
91104
}
92105

93106
/// Draw a box.
94107
#[inline]
95108
pub fn cuboid(&self, position: Vec3, rotation: Quat, size: Vec3, color: Color) {
96-
let rect = self.rect_inner(size.truncate());
109+
let rect = rect_inner(size.truncate());
97110
// Front
98111
let [tlf, trf, brf, blf] = rect.map(|vec2| position + rotation * vec2.extend(size.z / 2.));
99112
// Back
@@ -147,50 +160,104 @@ impl GizmoDraw {
147160

148161
// Draw a circle.
149162
#[inline]
150-
pub fn circle_2d(&self, position: Vec2, radius: f32, color: Color) {
151-
let positions = self.circle_inner(radius).map(|vec2| (vec2 + position));
152-
self.linestrip_2d(positions, color);
163+
pub fn circle_2d(&self, position: Vec2, radius: f32, color: Color) -> DrawCircle2d {
164+
DrawCircle2d {
165+
position,
166+
radius,
167+
color,
168+
segments: CIRCLE_SEGMENTS,
169+
}
153170
}
154171

155172
/// Draw a rectangle.
156173
#[inline]
157174
pub fn rect_2d(&self, position: Vec2, rotation: f32, size: Vec2, color: Color) {
158175
let rotation = Mat2::from_angle(rotation);
159-
let [tl, tr, br, bl] = self.rect_inner(size).map(|vec2| position + rotation * vec2);
176+
let [tl, tr, br, bl] = rect_inner(size).map(|vec2| position + rotation * vec2);
160177
self.linestrip_2d([tl, tr, br, bl, tl], color);
161178
}
179+
}
180+
181+
pub struct DrawCircle {
182+
position: Vec3,
183+
normal: Vec3,
184+
radius: f32,
185+
color: Color,
186+
segments: usize,
187+
}
188+
189+
impl DrawCircle {
190+
pub fn segments(mut self, segments: usize) -> Self {
191+
self.segments = segments;
192+
self
193+
}
194+
}
195+
196+
impl Drop for DrawCircle {
197+
fn drop(&mut self) {
198+
let rotation = Quat::from_rotation_arc(Vec3::Z, self.normal);
199+
let positions = circle_inner(self.radius, self.segments)
200+
.map(|vec2| (self.position + rotation * vec2.extend(0.)));
201+
GIZMO.linestrip(positions, self.color);
202+
}
203+
}
204+
pub struct DrawCircle2d {
205+
position: Vec2,
206+
radius: f32,
207+
color: Color,
208+
segments: usize,
209+
}
162210

163-
fn circle_inner(&self, radius: f32) -> impl Iterator<Item = Vec2> {
164-
let circle_segments = self.circle_segments;
165-
(0..(circle_segments + 1)).into_iter().map(move |i| {
166-
let angle = i as f32 * TAU / circle_segments as f32;
167-
Vec2::from(angle.sin_cos()) * radius
168-
})
211+
impl DrawCircle2d {
212+
pub fn segments(mut self, segments: usize) -> Self {
213+
self.segments = segments;
214+
self
169215
}
216+
}
170217

171-
fn rect_inner(&self, size: Vec2) -> [Vec2; 4] {
172-
let half_size = size / 2.;
173-
let tl = Vec2::new(-half_size.x, half_size.y);
174-
let tr = Vec2::new(half_size.x, half_size.y);
175-
let bl = Vec2::new(-half_size.x, -half_size.y);
176-
let br = Vec2::new(half_size.x, -half_size.y);
177-
[tl, tr, br, bl]
218+
impl Drop for DrawCircle2d {
219+
fn drop(&mut self) {
220+
let positions = circle_inner(self.radius, self.segments).map(|vec2| (vec2 + self.position));
221+
GIZMO.linestrip_2d(positions, self.color);
178222
}
223+
}
179224

180-
#[inline]
181-
fn send_line(&self, [p0, p1]: [Vec3; 2], [c0, c1]: [Color; 2]) {
182-
let _ = self.sender.send(SendItem::Single((
183-
[p0.to_array(), p1.to_array()],
184-
[c0.as_linear_rgba_f32(), c1.as_linear_rgba_f32()],
185-
)));
225+
pub struct DrawSphere {
226+
position: Vec3,
227+
radius: f32,
228+
color: Color,
229+
circle_segments: usize,
230+
}
231+
232+
impl DrawSphere {
233+
pub fn circle_segments(mut self, segments: usize) -> Self {
234+
self.circle_segments = segments;
235+
self
186236
}
237+
}
187238

188-
#[inline]
189-
fn linelist(&self, list: impl IntoIterator<Item = Vec3>, color: Color) {
190-
let iter = list
191-
.into_iter()
192-
.map(|p| p.to_array())
193-
.zip(iter::repeat(color.as_linear_rgba_f32()));
194-
let _ = self.sender.send(SendItem::List(iter.unzip()));
239+
impl Drop for DrawSphere {
240+
fn drop(&mut self) {
241+
for axis in Vec3::AXES {
242+
GIZMO
243+
.circle(self.position, axis, self.radius, self.color)
244+
.segments(self.circle_segments);
245+
}
195246
}
196247
}
248+
249+
fn circle_inner(radius: f32, segments: usize) -> impl Iterator<Item = Vec2> {
250+
(0..segments + 1).into_iter().map(move |i| {
251+
let angle = i as f32 * TAU / segments as f32;
252+
Vec2::from(angle.sin_cos()) * radius
253+
})
254+
}
255+
256+
fn rect_inner(size: Vec2) -> [Vec2; 4] {
257+
let half_size = size / 2.;
258+
let tl = Vec2::new(-half_size.x, half_size.y);
259+
let tr = Vec2::new(half_size.x, half_size.y);
260+
let bl = Vec2::new(-half_size.x, -half_size.y);
261+
let br = Vec2::new(half_size.x, -half_size.y);
262+
[tl, tr, br, bl]
263+
}

crates/bevy_debug_draw/src/lib.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use bevy_ecs::{
88
world::{FromWorld, World},
99
};
1010
use bevy_math::Mat4;
11-
use bevy_pbr::MeshUniform;
1211
use bevy_reflect::TypeUuid;
1312
use bevy_render::{
1413
mesh::Mesh,
@@ -17,20 +16,21 @@ use bevy_render::{
1716
Extract, RenderApp, RenderStage,
1817
};
1918

19+
#[cfg(feature = "bevy_pbr")]
20+
use bevy_pbr::MeshUniform;
2021
#[cfg(feature = "bevy_sprite")]
21-
use bevy_sprite::Mesh2dHandle;
22+
use bevy_sprite::{Mesh2dHandle, Mesh2dUniform};
2223

23-
use bevy_sprite::Mesh2dUniform;
2424
use once_cell::sync::Lazy;
2525

26-
pub mod gizmos;
26+
pub mod gizmo_draw;
2727

2828
#[cfg(feature = "bevy_sprite")]
2929
mod pipeline_2d;
3030
#[cfg(feature = "bevy_pbr")]
3131
mod pipeline_3d;
3232

33-
use crate::gizmos::GizmoDraw;
33+
use crate::gizmo_draw::GizmoDraw;
3434

3535
/// The `bevy_debug_draw` prelude.
3636
pub mod prelude {
@@ -185,21 +185,21 @@ fn extract(
185185
GizmoDrawMesh,
186186
#[cfg(feature = "bevy_pbr")]
187187
(
188+
handle.clone(),
188189
MeshUniform {
189190
flags: 0,
190191
transform,
191192
inverse_transpose_model,
192193
},
193-
handle.clone(),
194194
),
195195
#[cfg(feature = "bevy_sprite")]
196196
(
197+
Mesh2dHandle(handle.clone()),
197198
Mesh2dUniform {
198199
flags: 0,
199200
transform,
200201
inverse_transpose_model,
201202
},
202-
Mesh2dHandle(handle.clone()),
203203
),
204204
)
205205
}));

examples/2d/2d_debug_draw.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,9 @@ fn system(time: Res<Time>) {
3333
Vec2::splat(300.),
3434
Color::BLACK,
3535
);
36+
3637
// The circles have 32 line-segments by default.
3738
GIZMO.circle_2d(Vec2::ZERO, 120., Color::BLACK);
3839
// You may want to increase this for larger circles.
39-
// GIZMOS.circle_segments = 64;
40-
// GIZMOS.circle_2d(Vec2::ZERO, 300., Color::NAVY);
41-
// GIZMOS.circle_segments = 32;
40+
GIZMO.circle_2d(Vec2::ZERO, 300., Color::NAVY).segments(64);
4241
}

examples/3d/3d_debug_draw.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ fn system(time: Res<Time>) {
3939
GIZMO.ray(Vec3::new(1., f, 0.), vector, Color::BLUE);
4040
}
4141

42-
// The circles have 32 line-segments by default.
42+
// Circles have 32 line-segments by default.
4343
GIZMO.circle(Vec3::ZERO, Vec3::Y, 3., Color::BLACK);
4444
// You may want to increase this for larger circles or spheres.
45-
// GIZMOS.circle_segments = 64;
46-
// GIZMOS.circle(Vec3::ZERO, Vec3::Y, 3.1, Color::NAVY);
47-
// GIZMOS.sphere(Vec3::ZERO, 3.2, Color::BLACK);
48-
// GIZMOS.circle_segments = 32;
45+
GIZMO
46+
.circle(Vec3::ZERO, Vec3::Y, 3.1, Color::NAVY)
47+
.segments(64);
48+
GIZMO
49+
.sphere(Vec3::ZERO, 3.2, Color::BLACK)
50+
.circle_segments(64);
4951
}
5052

5153
fn rotate_camera(mut query: Query<&mut Transform, With<Camera>>, time: Res<Time>) {

0 commit comments

Comments
 (0)