1- use std:: { f32:: consts:: TAU , mem } ;
1+ use std:: { f32:: consts:: TAU , iter } ;
22
33use bevy_asset:: Handle ;
44use bevy_ecs:: system:: Resource ;
@@ -9,22 +9,28 @@ use bevy_render::prelude::{Color, Mesh};
99/// Useful for visual debugging.
1010#[ derive( Resource ) ]
1111pub struct DebugDraw {
12- positions : Vec < [ f32 ; 3 ] > ,
13- colors : Vec < [ f32 ; 4 ] > ,
14- pub ( crate ) mesh_handle : Option < Handle < Mesh > > ,
12+ pub ( crate ) list_mesh_handle : Option < Handle < Mesh > > ,
13+ pub ( crate ) list_positions : Vec < [ f32 ; 3 ] > ,
14+ pub ( crate ) list_colors : Vec < [ f32 ; 4 ] > ,
15+ pub ( crate ) strip_mesh_handle : Option < Handle < Mesh > > ,
16+ pub ( crate ) strip_positions : Vec < [ f32 ; 3 ] > ,
17+ pub ( crate ) strip_colors : Vec < [ f32 ; 4 ] > ,
1518 /// The amount of line segments to use when drawing a circle.
1619 ///
17- /// Defaults to `24 `.
20+ /// Defaults to `32 `.
1821 pub circle_segments : u32 ,
1922}
2023
2124impl Default for DebugDraw {
2225 fn default ( ) -> Self {
2326 DebugDraw {
24- positions : Vec :: new ( ) ,
25- colors : Vec :: new ( ) ,
26- mesh_handle : None ,
27- circle_segments : 24 ,
27+ list_mesh_handle : None ,
28+ list_positions : Vec :: new ( ) ,
29+ list_colors : Vec :: new ( ) ,
30+ strip_mesh_handle : None ,
31+ strip_positions : Vec :: new ( ) ,
32+ strip_colors : Vec :: new ( ) ,
33+ circle_segments : 32 ,
2834 }
2935 }
3036}
@@ -39,8 +45,9 @@ impl DebugDraw {
3945 /// Draw a line from `start` to `end`.
4046 #[ inline]
4147 pub fn line_gradient ( & mut self , start : Vec3 , end : Vec3 , start_color : Color , end_color : Color ) {
42- self . positions . extend ( [ start. to_array ( ) , end. to_array ( ) ] ) ;
43- self . colors . extend ( [
48+ self . list_positions
49+ . extend ( [ start. to_array ( ) , end. to_array ( ) ] ) ;
50+ self . list_colors . extend ( [
4451 start_color. as_linear_rgba_f32 ( ) ,
4552 end_color. as_linear_rgba_f32 ( ) ,
4653 ] ) ;
@@ -49,7 +56,7 @@ impl DebugDraw {
4956 /// Draw a line from `start` to `start + vector`.
5057 #[ inline]
5158 pub fn ray ( & mut self , start : Vec3 , vector : Vec3 , color : Color ) {
52- self . ray_gradient ( start, vector , color , color) ;
59+ self . line ( start, start + vector , color) ;
5360 }
5461
5562 /// Draw a line from `start` to `start + vector`.
@@ -68,25 +75,23 @@ impl DebugDraw {
6875 #[ inline]
6976 pub fn circle ( & mut self , position : Vec3 , normal : Vec3 , radius : f32 , color : Color ) {
7077 let rotation = Quat :: from_rotation_arc ( Vec3 :: Z , normal) ;
71- self . positions
72- . extend ( ( 0 ..self . circle_segments ) . into_iter ( ) . flat_map ( |i| {
73- let mut angle = i as f32 * TAU / self . circle_segments as f32 ;
74- let start = rotation * ( Vec2 :: from ( angle. sin_cos ( ) ) * radius) . extend ( 0. ) + position;
7578
76- angle += TAU / self . circle_segments as f32 ;
77- let end = rotation * ( Vec2 :: from ( angle. sin_cos ( ) ) * radius) . extend ( 0. ) + position;
79+ let positions = self
80+ . circle_inner ( radius)
81+ . map ( |vec2| ( rotation * vec2. extend ( 0. ) + position) . to_array ( ) )
82+ . chain ( iter:: once ( Vec3 :: NAN . to_array ( ) ) ) ;
7883
79- [ start. to_array ( ) , end. to_array ( ) ]
80- } ) ) ;
81-
82- self . colors . extend (
83- std:: iter:: repeat ( color. as_linear_rgba_f32 ( ) ) . take ( self . circle_segments as usize * 2 ) ,
84- ) ;
84+ self . strip_positions . extend ( positions) ;
85+ self . add_strip_color ( color, ( self . circle_segments + 1 ) as usize ) ;
8586 }
8687
8788 /// Draw a sphere.
8889 #[ inline]
8990 pub fn sphere ( & mut self , position : Vec3 , radius : f32 , color : Color ) {
91+ self . strip_colors
92+ . reserve ( ( self . circle_segments + 1 ) as usize * 3 ) ;
93+ self . strip_positions
94+ . reserve ( ( self . circle_segments + 1 ) as usize * 3 ) ;
9095 self . circle ( position, Vec3 :: X , radius, color) ;
9196 self . circle ( position, Vec3 :: Y , radius, color) ;
9297 self . circle ( position, Vec3 :: Z , radius, color) ;
@@ -100,9 +105,10 @@ impl DebugDraw {
100105 let tr = ( position + rotation * vec3 ( half_size. x , half_size. y , 0. ) ) . to_array ( ) ;
101106 let bl = ( position + rotation * vec3 ( -half_size. x , -half_size. y , 0. ) ) . to_array ( ) ;
102107 let br = ( position + rotation * vec3 ( half_size. x , -half_size. y , 0. ) ) . to_array ( ) ;
103- self . positions . extend ( [ tl, tr, tr, br, br, bl, bl, tl] ) ;
104- self . colors
105- . extend ( std:: iter:: repeat ( color. as_linear_rgba_f32 ( ) ) . take ( 8 ) ) ;
108+
109+ self . strip_positions
110+ . extend ( [ tl, tr, br, bl, tl, [ f32:: NAN ; 3 ] ] ) ;
111+ self . add_strip_color ( color, 5 ) ;
106112 }
107113
108114 /// Draw a box.
@@ -119,19 +125,19 @@ impl DebugDraw {
119125 let trb = ( position + rotation * vec3 ( half_size. x , half_size. y , -half_size. z ) ) . to_array ( ) ;
120126 let blb = ( position + rotation * vec3 ( -half_size. x , -half_size. y , -half_size. z ) ) . to_array ( ) ;
121127 let brb = ( position + rotation * vec3 ( half_size. x , -half_size. y , -half_size. z ) ) . to_array ( ) ;
122- self . positions . extend ( [
128+
129+ self . list_positions . extend ( [
123130 tlf, trf, trf, brf, brf, blf, blf, tlf, // Front
124131 tlb, trb, trb, brb, brb, blb, blb, tlb, // Back
125132 tlf, tlb, trf, trb, brf, brb, blf, blb, // Front to back
126133 ] ) ;
127- self . colors
128- . extend ( std:: iter:: repeat ( color. as_linear_rgba_f32 ( ) ) . take ( 24 ) ) ;
134+ self . add_list_color ( color, 24 ) ;
129135 }
130136
131137 /// Draw a line from `start` to `end`.
132138 #[ inline]
133139 pub fn line_2d ( & mut self , start : Vec2 , end : Vec2 , color : Color ) {
134- self . line_gradient_2d ( start, end, color , color) ;
140+ self . line ( start. extend ( 0. ) , end. extend ( 0. ) , color) ;
135141 }
136142
137143 /// Draw a line from `start` to `end`.
@@ -149,7 +155,7 @@ impl DebugDraw {
149155 /// Draw a line from `start` to `start + vector`.
150156 #[ inline]
151157 pub fn ray_2d ( & mut self , start : Vec2 , vector : Vec2 , color : Color ) {
152- self . ray_gradient_2d ( start, vector , color , color) ;
158+ self . line_2d ( start, start + vector , color) ;
153159 }
154160
155161 /// Draw a line from `start` to `start + vector`.
@@ -167,7 +173,13 @@ impl DebugDraw {
167173 // Draw a circle.
168174 #[ inline]
169175 pub fn circle_2d ( & mut self , position : Vec2 , radius : f32 , color : Color ) {
170- self . circle ( position. extend ( 0. ) , Vec3 :: Z , radius, color) ;
176+ let positions = self
177+ . circle_inner ( radius)
178+ . map ( |vec2| ( vec2 + position) . extend ( 0. ) . to_array ( ) )
179+ . chain ( iter:: once ( [ f32:: NAN ; 3 ] ) ) ;
180+
181+ self . strip_positions . extend ( positions) ;
182+ self . add_strip_color ( color, ( self . circle_segments + 1 ) as usize ) ;
171183 }
172184
173185 /// Draw a rectangle.
@@ -181,17 +193,35 @@ impl DebugDraw {
181193 ) ;
182194 }
183195
184- /// Clear everything drawn up to this point, this frame.
185196 #[ inline]
186- pub fn clear ( & mut self ) {
187- self . positions . clear ( ) ;
188- self . colors . clear ( ) ;
197+ fn add_strip_color ( & mut self , color : Color , amount : usize ) {
198+ self . strip_colors . extend (
199+ iter:: repeat ( color. as_linear_rgba_f32 ( ) )
200+ . take ( amount)
201+ . chain ( iter:: once ( [ f32:: NAN ; 4 ] ) ) ,
202+ ) ;
189203 }
190204
191- /// Take the positions and colors data from `self` and overwrite the `mesh`'s vertex positions and colors.
192205 #[ inline]
193- pub ( crate ) fn update_mesh ( & mut self , mesh : & mut Mesh ) {
194- mesh. insert_attribute ( Mesh :: ATTRIBUTE_POSITION , mem:: take ( & mut self . positions ) ) ;
195- mesh. insert_attribute ( Mesh :: ATTRIBUTE_COLOR , mem:: take ( & mut self . colors ) ) ;
206+ fn add_list_color ( & mut self , color : Color , amount : usize ) {
207+ self . list_colors
208+ . extend ( iter:: repeat ( color. as_linear_rgba_f32 ( ) ) . take ( amount) ) ;
209+ }
210+
211+ fn circle_inner ( & self , radius : f32 ) -> impl Iterator < Item = Vec2 > {
212+ let circle_segments = self . circle_segments ;
213+ ( 0 ..( circle_segments + 1 ) ) . into_iter ( ) . map ( move |i| {
214+ let angle = i as f32 * TAU / circle_segments as f32 ;
215+ Vec2 :: from ( angle. sin_cos ( ) ) * radius
216+ } )
217+ }
218+
219+ /// Clear everything drawn up to this point, this frame.
220+ #[ inline]
221+ pub fn clear ( & mut self ) {
222+ self . list_positions . clear ( ) ;
223+ self . list_colors . clear ( ) ;
224+ self . strip_positions . clear ( ) ;
225+ self . strip_colors . clear ( ) ;
196226 }
197227}
0 commit comments