@@ -128,27 +128,10 @@ impl ClientMessage {
128
128
129
129
buf
130
130
}
131
-
132
- pub fn encode_internal ( & self ) -> u32 {
133
- let mut buf = [ 0 ; 4 ] ;
134
-
135
- buf[ 0 ] = Self :: encode_u3 ( match self . action {
136
- Action :: Erase => 0 ,
137
- Action :: DrawCubeNormal => 1 ,
138
- Action :: DrawCubeHollow => 2 ,
139
- Action :: DrawCircleNormal => 3 ,
140
- Action :: DrawCircleHollow => 4 ,
141
- Action :: DrawTriangleNormal => 5 ,
142
- Action :: DrawTriangleHollow => 6 ,
143
- } ) | Self :: encode_u5 ( self . height ) ;
144
- buf[ 1 ..4 ] . copy_from_slice ( & self . color ) ;
145
-
146
- u32:: from_le_bytes ( buf)
147
- }
148
131
}
149
132
150
133
pub struct Data {
151
- pub data : Arc < Mutex < Vec < u32 > > > ,
134
+ pub data : Arc < Mutex < Vec < u8 > > > ,
152
135
pub listeners : Vec < tokio:: sync:: mpsc:: Sender < Vec < u8 > > > ,
153
136
}
154
137
@@ -170,20 +153,9 @@ impl Data {
170
153
None => None ,
171
154
} ;
172
155
173
- let mut data: Vec < u32 > = vec ! [ 0 ; RESOLUTION ] ;
156
+ let mut data: Vec < u8 > = vec ! [ 0xff ; RESOLUTION * 3 ] ;
174
157
if file. is_some ( ) {
175
- let mut file_data: Vec < u8 > = Vec :: with_capacity ( RESOLUTION * 4 ) ;
176
- file. as_mut ( )
177
- . unwrap ( )
178
- . read_to_end ( & mut file_data)
179
- . await
180
- . unwrap ( ) ;
181
-
182
- data. iter_mut ( )
183
- . zip ( file_data. chunks_exact ( 4 ) )
184
- . for_each ( |( data, chunk) | {
185
- * data = u32:: from_le_bytes ( [ chunk[ 0 ] , chunk[ 1 ] , chunk[ 2 ] , chunk[ 3 ] ] ) ;
186
- } ) ;
158
+ file. as_mut ( ) . unwrap ( ) . read_to_end ( & mut data) . await . unwrap ( ) ;
187
159
}
188
160
189
161
let data = Arc :: new ( Mutex :: new ( data) ) ;
@@ -236,21 +208,211 @@ impl Data {
236
208
let mut self_data = self_data. lock ( ) . await ;
237
209
238
210
for message in data {
239
- let index = ( message. y as usize * RESOLUTION_WIDTH ) + message. x as usize ;
240
- self_data[ index] = message. encode_internal ( ) ;
211
+ match message. action {
212
+ Action :: Erase => {
213
+ let height = ( message. height as f64 ) * 1.5 * 4.0 ;
214
+
215
+ let start_x = message. x . saturating_sub ( height as u16 ) as usize ;
216
+ let end_x =
217
+ ( ( message. x + height as u16 ) . min ( RESOLUTION_WIDTH as u16 - 1 ) ) as usize ;
218
+ let start_y = message. y . saturating_sub ( height as u16 ) as usize ;
219
+ let end_y =
220
+ ( ( message. y + height as u16 ) . min ( RESOLUTION_HEIGHT as u16 - 1 ) ) as usize ;
221
+
222
+ for y in start_y..=end_y {
223
+ let row_start = y * RESOLUTION_WIDTH * 3 ;
224
+ for x in start_x..=end_x {
225
+ let index = row_start + x * 3 ;
226
+ self_data[ index] = 0xff ;
227
+ self_data[ index + 1 ] = 0xff ;
228
+ self_data[ index + 2 ] = 0xff ;
229
+ }
230
+ }
231
+ }
232
+ Action :: DrawCubeNormal => {
233
+ let height = message. height as usize * 4 ;
234
+ println ! ( "height: {}" , height) ;
235
+ let start_x = message. x as usize ;
236
+ let end_x =
237
+ ( ( message. x + height as u16 ) . min ( RESOLUTION_WIDTH as u16 - 1 ) ) as usize ;
238
+ let start_y = message. y as usize ;
239
+ let end_y =
240
+ ( ( message. y + height as u16 ) . min ( RESOLUTION_HEIGHT as u16 - 1 ) ) as usize ;
241
+
242
+ for y in start_y..=end_y {
243
+ let row_start = y * RESOLUTION_WIDTH * 3 ;
244
+ for x in start_x..=end_x {
245
+ let index = row_start + x * 3 ;
246
+ self_data[ index..index + 3 ] . copy_from_slice ( & message. color ) ;
247
+ }
248
+ }
249
+ }
250
+ Action :: DrawCubeHollow => {
251
+ let height = message. height as usize * 4 ;
252
+ let start_x = message. x as usize ;
253
+ let end_x =
254
+ ( ( message. x + height as u16 ) . min ( RESOLUTION_WIDTH as u16 - 1 ) ) as usize ;
255
+ let start_y = message. y as usize ;
256
+ let end_y =
257
+ ( ( message. y + height as u16 ) . min ( RESOLUTION_HEIGHT as u16 - 1 ) ) as usize ;
258
+
259
+ for x in start_x..=end_x {
260
+ let top_index = start_y * RESOLUTION_WIDTH * 3 + x * 3 ;
261
+ let bottom_index = end_y * RESOLUTION_WIDTH * 3 + x * 3 ;
262
+ self_data[ top_index..top_index + 3 ] . copy_from_slice ( & message. color ) ;
263
+ self_data[ bottom_index..bottom_index + 3 ] . copy_from_slice ( & message. color ) ;
264
+ }
265
+
266
+ for y in start_y..=end_y {
267
+ let left_index = y * RESOLUTION_WIDTH * 3 + start_x * 3 ;
268
+ let right_index = y * RESOLUTION_WIDTH * 3 + end_x * 3 ;
269
+ self_data[ left_index..left_index + 3 ] . copy_from_slice ( & message. color ) ;
270
+ self_data[ right_index..right_index + 3 ] . copy_from_slice ( & message. color ) ;
271
+ }
272
+ }
273
+ Action :: DrawCircleNormal | Action :: DrawCircleHollow => {
274
+ let radius = message. height as usize * 4 ;
275
+ let is_hollow = matches ! ( message. action, Action :: DrawCircleHollow ) ;
276
+
277
+ let start_x = message. x . saturating_sub ( radius as u16 ) as usize ;
278
+ let end_x =
279
+ ( ( message. x + radius as u16 ) . min ( RESOLUTION_WIDTH as u16 - 1 ) ) as usize ;
280
+ let start_y = message. y . saturating_sub ( radius as u16 ) as usize ;
281
+ let end_y =
282
+ ( ( message. y + radius as u16 ) . min ( RESOLUTION_HEIGHT as u16 - 1 ) ) as usize ;
283
+
284
+ let center_x = message. x as f32 ;
285
+ let center_y = message. y as f32 ;
286
+ let radius_sq = ( radius * radius) as f32 ;
287
+ let inner_radius_sq = ( ( radius - 1 ) * ( radius - 1 ) ) as f32 ;
288
+
289
+ for y in start_y..=end_y {
290
+ let dy = y as f32 - center_y;
291
+ let dy_sq = dy * dy;
292
+ let row_start = y * RESOLUTION_WIDTH * 3 ;
293
+
294
+ for x in start_x..=end_x {
295
+ let dx = x as f32 - center_x;
296
+ let dist_sq = dx * dx + dy_sq;
297
+
298
+ if ( !is_hollow && dist_sq <= radius_sq)
299
+ || ( is_hollow && dist_sq <= radius_sq && dist_sq >= inner_radius_sq)
300
+ {
301
+ let index = row_start + x * 3 ;
302
+ self_data[ index..index + 3 ] . copy_from_slice ( & message. color ) ;
303
+ }
304
+ }
305
+ }
306
+ }
307
+ Action :: DrawTriangleNormal | Action :: DrawTriangleHollow => {
308
+ let height = message. height as usize * 4 ;
309
+ let is_hollow = matches ! ( message. action, Action :: DrawTriangleHollow ) ;
310
+
311
+ let x1 = message. x as i32 ;
312
+ let y1 = message. y as i32 ;
313
+ let x2 = ( message. x as i32 ) - ( height as i32 ) ;
314
+ let y2 = message. y as i32 + ( height as i32 * 2 ) ;
315
+ let x3 = message. x as i32 + height as i32 ;
316
+ let y3 = y2;
317
+
318
+ if is_hollow {
319
+ draw_line_fast ( & mut self_data, x1, y1, x2, y2, & message. color ) ;
320
+ draw_line_fast ( & mut self_data, x2, y2, x3, y3, & message. color ) ;
321
+ draw_line_fast ( & mut self_data, x3, y3, x1, y1, & message. color ) ;
322
+ } else {
323
+ let min_x = x2. min ( x3) . min ( x1) . max ( 0 ) as usize ;
324
+ let max_x = x2. max ( x3) . max ( x1) . min ( RESOLUTION_WIDTH as i32 - 1 ) as usize ;
325
+ let min_y = y1. min ( y2) . min ( y3) . max ( 0 ) as usize ;
326
+ let max_y = y1. max ( y2) . max ( y3) . min ( RESOLUTION_HEIGHT as i32 - 1 ) as usize ;
327
+
328
+ for y in min_y..=max_y {
329
+ let row_start = y * RESOLUTION_WIDTH * 3 ;
330
+ for x in min_x..=max_x {
331
+ if point_in_triangle_fast (
332
+ x as i32 , y as i32 , x1, y1, x2, y2, x3, y3,
333
+ ) {
334
+ let index = row_start + x * 3 ;
335
+ self_data[ index..index + 3 ] . copy_from_slice ( & message. color ) ;
336
+ }
337
+ }
338
+ }
339
+ }
340
+ }
341
+ }
241
342
}
242
343
243
- let mut encoded = Vec :: with_capacity ( 7 * data. len ( ) ) ;
244
- for message in data {
245
- encoded. extend_from_slice ( & message. encode ( ) ) ;
246
- }
344
+ if !self . listeners . is_empty ( ) {
345
+ let mut encoded = Vec :: with_capacity ( 7 * data. len ( ) ) ;
346
+ encoded. extend ( data. iter ( ) . flat_map ( |msg| msg. encode ( ) ) ) ;
347
+
348
+ self . listeners . retain ( |listener| !listener. is_closed ( ) ) ;
247
349
248
- for listener in & self . listeners {
249
- if listener. is_closed ( ) {
250
- continue ;
350
+ for listener in & self . listeners {
351
+ listener. send ( encoded. clone ( ) ) . await . unwrap ( ) ;
251
352
}
353
+ }
354
+ }
355
+ }
252
356
253
- listener. send ( encoded. to_vec ( ) ) . await . unwrap ( ) ;
357
+ #[ inline( always) ]
358
+ fn draw_line_fast ( data : & mut Vec < u8 > , x1 : i32 , y1 : i32 , x2 : i32 , y2 : i32 , color : & [ u8 ; 3 ] ) {
359
+ draw_single_line ( data, x1, y1, x2, y2, color) ;
360
+ draw_single_line ( data, x1 + 1 , y1, x2 + 1 , y2, color) ;
361
+ draw_single_line ( data, x1, y1 + 1 , x2, y2 + 1 , color) ;
362
+ draw_single_line ( data, x1 + 1 , y1 + 1 , x2 + 1 , y2 + 1 , color) ;
363
+ }
364
+
365
+ #[ inline( always) ]
366
+ fn draw_single_line (
367
+ data : & mut Vec < u8 > ,
368
+ mut x1 : i32 ,
369
+ mut y1 : i32 ,
370
+ x2 : i32 ,
371
+ y2 : i32 ,
372
+ color : & [ u8 ; 3 ] ,
373
+ ) {
374
+ let dx = ( x2 - x1) . abs ( ) ;
375
+ let dy = -( y2 - y1) . abs ( ) ;
376
+ let sx = if x1 < x2 { 1 } else { -1 } ;
377
+ let sy = if y1 < y2 { 1 } else { -1 } ;
378
+ let mut err = dx + dy;
379
+
380
+ loop {
381
+ if x1 >= 0 && x1 < RESOLUTION_WIDTH as i32 && y1 >= 0 && y1 < RESOLUTION_HEIGHT as i32 {
382
+ let index = ( y1 as usize * RESOLUTION_WIDTH + x1 as usize ) * 3 ;
383
+ data[ index..index + 3 ] . copy_from_slice ( color) ;
384
+ }
385
+
386
+ if x1 == x2 && y1 == y2 {
387
+ break ;
388
+ }
389
+
390
+ let e2 = err * 2 ;
391
+ if e2 >= dy {
392
+ err += dy;
393
+ x1 += sx;
394
+ }
395
+ if e2 <= dx {
396
+ err += dx;
397
+ y1 += sy;
254
398
}
255
399
}
256
400
}
401
+
402
+ #[ inline( always) ]
403
+ fn point_in_triangle_fast (
404
+ px : i32 ,
405
+ py : i32 ,
406
+ x1 : i32 ,
407
+ y1 : i32 ,
408
+ x2 : i32 ,
409
+ y2 : i32 ,
410
+ x3 : i32 ,
411
+ y3 : i32 ,
412
+ ) -> bool {
413
+ let edge1 = ( px - x1) * ( y2 - y1) - ( py - y1) * ( x2 - x1) ;
414
+ let edge2 = ( px - x2) * ( y3 - y2) - ( py - y2) * ( x3 - x2) ;
415
+ let edge3 = ( px - x3) * ( y1 - y3) - ( py - y3) * ( x1 - x3) ;
416
+
417
+ ( edge1 >= 0 && edge2 >= 0 && edge3 >= 0 ) || ( edge1 <= 0 && edge2 <= 0 && edge3 <= 0 )
418
+ }
0 commit comments