@@ -30,7 +30,7 @@ use std::ffi::c_void;
3030#[ cfg( feature="output_mode_jumbotron" ) ]
3131use gl_abstractions as gla;
3232#[ cfg( feature="output_mode_jumbotron" ) ]
33- use gla:: { UniformMat4F , Uniform1F , Uniform1UIV , Uniform3FV , Uniform1I , Uniform2F , UniformSampler2D , shader_struct, impl_shader} ;
33+ use gla:: { UniformMat4F , Uniform1F , Uniform1UIV , Uniform3FV , Uniform1I , Uniform1UI , Uniform2F , UniformSampler2D , shader_struct, impl_shader} ;
3434
3535#[ cfg( feature="output_mode_jumbotron" ) ]
3636use std:: sync:: { Arc , Mutex } ;
@@ -321,14 +321,14 @@ fn send_state_to_client(gui_sender: Option<&Sender<StreamEvent>>, cube: Cube, re
321321enum CubeDevice {
322322 PhysicalDevice { serial_port : Box < dyn SerialPort > } ,
323323 TestDevice { sequence : Vec < Twist > , buffer : Vec < u8 > , next_twist : Instant } ,
324- IdleDevice ( ) ,
324+ IdleDevice { } ,
325325}
326326
327327impl Read for CubeDevice {
328328 fn read ( & mut self , data : & mut [ u8 ] ) -> Result < usize , std:: io:: Error > {
329329 use CubeDevice :: * ;
330330 match self {
331- TestDevice { sequence, buffer, next_twist} => {
331+ TestDevice { sequence, buffer, next_twist, .. } => {
332332 if sequence. len ( ) <= 0 {
333333 // Generate a new sequence
334334 for _ in 0 ..20 {
@@ -341,7 +341,7 @@ impl Read for CubeDevice{
341341 }
342342 while * next_twist < Instant :: now ( ) {
343343 let next = sequence. remove ( 0 ) ;
344- * next_twist = * next_twist + Duration :: from_millis ( 500 ) ;
344+ * next_twist = * next_twist + Duration :: from_millis ( 3000 ) ;
345345 buffer. extend_from_slice ( format ! ( "*{};\n " , next) . as_bytes ( ) ) ;
346346 }
347347 let mut mdata = data;
@@ -352,7 +352,7 @@ impl Read for CubeDevice{
352352 Ok ( n)
353353 } ,
354354 PhysicalDevice { serial_port} => { serial_port. read ( data) } ,
355- IdleDevice ( ) => { Ok ( 0 ) } ,
355+ IdleDevice { .. } => { Ok ( 0 ) } ,
356356 }
357357 }
358358}
@@ -361,8 +361,7 @@ impl Write for CubeDevice{
361361 fn write ( & mut self , data : & [ u8 ] ) -> Result < usize , std:: io:: Error > {
362362 use CubeDevice :: * ;
363363 match self {
364- TestDevice { ..} => { Ok ( data. len ( ) ) } , // Currently does nothing, could make this display a test output perhaps?
365- IdleDevice { ..} => { Ok ( data. len ( ) ) } ,
364+ TestDevice { ..} | IdleDevice { ..} => { Ok ( data. len ( ) ) } ,
366365 PhysicalDevice { serial_port} => { serial_port. write ( data) } ,
367366 }
368367 }
@@ -388,7 +387,7 @@ impl CubeDevice{
388387 else if name == "idledevice" {
389388 // testdevice is a special name that refers to a fake cube controller that does not display anything, but will repeatedly apply and unapply
390389 // random sequences for testing purposes
391- Ok ( IdleDevice ( ) )
390+ Ok ( IdleDevice { } )
392391 }
393392 else {
394393 let result = serialport:: new ( name, 115200 ) . timeout ( Duration :: from_secs ( 10 ) ) . open ( ) ;
@@ -403,7 +402,7 @@ impl CubeDevice{
403402 use CubeDevice :: * ;
404403 match self {
405404 TestDevice { sequence, buffer, next_twist} => Ok ( TestDevice { sequence : sequence. clone ( ) , buffer : buffer. clone ( ) , next_twist : * next_twist} ) ,
406- IdleDevice ( ) => Ok ( IdleDevice ( ) ) ,
405+ IdleDevice { } => Ok ( IdleDevice { } ) ,
407406 PhysicalDevice { serial_port} => match serial_port. try_clone ( ) {
408407 Ok ( cloned) => Ok ( PhysicalDevice { serial_port : cloned} ) ,
409408 Err ( e) => Err ( ( ) ) , // TODO better error handling here
@@ -561,10 +560,15 @@ shader_struct!{
561560 uniform vec3 u_base_cols[6];
562561 uniform int u_cur_face;
563562 uniform vec2 u_facelet_coords;
563+ uniform float u_border_size;
564564 out vec4 FragColor;
565565 void main() {
566566 vec2 tc = (vec4(u_facelet_coords.xy+UV,0.0,0.0)*u_texture_transform).xy;
567567 FragColor = texture(u_texture,tc);
568+ float b = u_border_size;
569+ if (UV.x < b || UV.x > (1.0-b) || UV.y < b || UV.y > (1.0-b)){
570+ FragColor = vec4(u_base_cols[u_cur_face],1.0);
571+ }
568572 }
569573 "#
570574 , {
@@ -576,6 +580,7 @@ shader_struct!{
576580 u_base_cols: Uniform3FV ,
577581 u_cur_face: Uniform1I ,
578582 u_facelet_coords: Uniform2F ,
583+ u_border_size: Uniform1F ,
579584 }
580585}
581586
@@ -599,36 +604,59 @@ shader_struct!{
599604 uniform float u_anim_pos;
600605 uniform uint u_prev_colours[54];
601606 uniform uint u_cur_colours[54];
607+ uniform uint u_mapping[45];
608+ uniform uint u_map_facenum[45];
609+ uniform uint u_map_subfacenum[45];
602610 uniform vec3 u_base_cols[6];
603- /*
604- = {
605- vec3(1.0,1.0,1.0), // white
606- vec3(1.0,0.0,0.0), // red
607- vec3(0.0,0.0,1.0), // blue
608- vec3(0.0,1.0,0.0), // green
609- vec3(1.0,1.0,0.0), // yellow
610- vec3(1.0,0.5,0.0), // orange
611- };
612- */
611+ uniform uint u_twist_face;
612+ uniform float u_twist_dir;
613613 out vec4 FragColor;
614614 layout(location=0) out vec3 tFragColor;
615615
616+ const float PI = 3.1415;
617+
616618 float bulge(float a){
617619 a = (a-0.5)*2;
618620 return 1-a*a*a*a;
619621 }
620622
623+ mat3 translate(float x, float y){
624+ return mat3(
625+ 1.0,0.0,x,
626+ 0.0,1.0,y,
627+ 0.0,0.0,1.0
628+ );
629+ }
630+
631+ mat3 rotate(float a){
632+ return mat3(
633+ cos(a), -sin(a),0.0,
634+ sin(a), cos(a),0.0,
635+ 0.0,0.0,1.0
636+ );
637+ }
638+
621639 void main() {
622640 float fp = u_facelet_px;
623641 int ix = int(floor(px_pos.x / fp));
624642 int iy = int(floor(px_pos.y / fp));
625643 int i = iy * 9 + ix;
626644 if (i < 45 && px_pos.y > 0.0 && px_pos.x > 0.0 && px_pos.y < (fp*5) && px_pos.x < (fp*9)){
645+ bool this_face = u_map_facenum[i] == u_twist_face;
646+ bool is_centre = u_map_subfacenum[i] == 4u;
647+ uint j = u_mapping[i];
648+
627649 vec2 fl_coord = vec2(px_pos.x - (ix*u_facelet_px), px_pos.y - (iy*u_facelet_px)) / u_facelet_px;
628- vec3 prev_base = u_base_cols[u_prev_colours[i]];
650+ if (this_face && is_centre){
651+ float a = (PI/2) * u_anim_pos * -u_twist_dir;
652+ mat3 rot = translate(-0.5,-0.5)*rotate(a) *translate(0.5,0.5);
653+ fl_coord = (vec3(fl_coord,1.0) * rot).xy;
654+ }
655+
656+ vec3 prev_base = u_base_cols[u_prev_colours[j]];
629657 FragColor = vec4(prev_base*bulge(fl_coord.x)*bulge(fl_coord.y), 1.0) * (1.0-u_anim_pos);
630658
631- vec3 base = u_base_cols[u_cur_colours[i ]];
659+ vec3 base = u_base_cols[u_cur_colours[j ]];
632660 FragColor += vec4(base*bulge(fl_coord.x)*bulge(fl_coord.y), 1.0) * (u_anim_pos);
633661 }
634662 else{
@@ -644,12 +672,17 @@ shader_struct!{
644672 u_facelet_px: Uniform1F ,
645673 u_prev_colours: Uniform1UIV ,
646674 u_cur_colours: Uniform1UIV ,
675+ u_mapping: Uniform1UIV ,
676+ u_map_facenum: Uniform1UIV ,
677+ u_map_subfacenum: Uniform1UIV ,
647678 u_base_cols: Uniform3FV ,
679+ u_twist_face: Uniform1UI ,
680+ u_twist_dir: Uniform1F ,
648681 }
649682}
650683
651684#[ cfg( feature="output_mode_jumbotron" ) ]
652- fn jumbotron_thread_main ( config : & CubeConfig , cube_state : Arc < Mutex < Cube > > , prev_cube_state : Arc < Mutex < Cube > > , last_twist : Arc < Mutex < TwistInfo > > ) {
685+ fn jumbotron_thread_main ( config : & CubeConfig , cube_state : Arc < Mutex < Cube > > , prev_cube_state : Arc < Mutex < Cube > > , last_twist : Arc < Mutex < TwistInfo > > , led_map : Arc < Mutex < LedMap > > ) {
653686
654687 fn colour_num ( c : cube_model:: Colors ) -> u32 {
655688 use cube_model:: Colors :: * ;
@@ -660,7 +693,7 @@ fn jumbotron_thread_main(config: &CubeConfig, cube_state: Arc<Mutex<Cube>>, prev
660693 Green => 3 ,
661694 Yellow => 4 ,
662695 Orange => 5 ,
663- Blank => 0 ,
696+ Blank => 6 ,
664697 }
665698 }
666699
@@ -856,7 +889,6 @@ fn jumbotron_thread_main(config: &CubeConfig, cube_state: Arc<Mutex<Cube>>, prev
856889
857890 let start_time = Instant :: now ( ) ;
858891
859-
860892 while !window. should_close ( ) {
861893 unsafe {
862894 gl:: BindFramebuffer ( gl:: FRAMEBUFFER , main_buffer) ;
@@ -883,6 +915,7 @@ fn jumbotron_thread_main(config: &CubeConfig, cube_state: Arc<Mutex<Cube>>, prev
883915 0.0 , 1.0 , 0.0 , // green
884916 1.0 , 1.0 , 0.0 , // yellow
885917 1.0 , 0.5 , 0.0 , // orange
918+ 0.0 , 0.0 , 0.0 , // black (for blank cells)
886919 ] ) ;
887920 let screen_transform = [
888921 2.0 /winw as f32 , 0.0 , 0.0 , -1.0 ,
@@ -907,17 +940,27 @@ fn jumbotron_thread_main(config: &CubeConfig, cube_state: Arc<Mutex<Cube>>, prev
907940 colour_num ( cube. faces [ f] . subfaces [ s] . color )
908941 } ) . collect ( )
909942 } ;
943+ {
944+ let lm = led_map. lock ( ) . unwrap ( ) ;
945+ shader. u_mapping . set ( & lm. indexmap ) ;
946+ shader. u_map_facenum . set ( & lm. facemap ) ;
947+ shader. u_map_subfacenum . set ( & lm. subfacemap ) ;
948+ }
910949 shader. u_prev_colours . set ( prev_cols. as_slice ( ) ) ;
911950 shader. u_cur_colours . set ( cols. as_slice ( ) ) ;
912951 let lt = last_twist. lock ( ) . unwrap ( ) ;
913952 if let Some ( t) = lt. time {
914953 let d = Instant :: now ( ) - t;
915- let d = ( ( d. as_millis ( ) as f32 ) /300 .0) . min ( 1.0 ) ;
954+ let d = ( ( d. as_millis ( ) as f32 ) /1000 .0) . min ( 1.0 ) ;
916955 shader. u_anim_pos . set ( d) ;
917956 }
918957 else {
919958 shader. u_anim_pos . set ( 1.0 ) ;
920959 }
960+ if let Some ( twist) = lt. twist {
961+ shader. u_twist_face . set ( twist. face as u32 ) ;
962+ shader. u_twist_dir . set ( if twist. reverse { -1.0 } else { 1.0 } ) ;
963+ }
921964
922965 unsafe { gl:: DrawArrays ( gl:: TRIANGLE_FAN , 0 , 4 ) ; }
923966
@@ -972,11 +1015,12 @@ fn jumbotron_thread_main(config: &CubeConfig, cube_state: Arc<Mutex<Cube>>, prev
9721015 0.8 , 0.8 , 0.8 , // white
9731016 1.0 , 0.0 , 0.0 , // red
9741017 0.0 , 0.0 , 1.0 , // blue
975- 0.0 , 1.0 , 0.0 , // green
976- 1.0 , 1.0 , 0.0 , // yellow
9771018 1.0 , 0.5 , 0.0 , // orange
1019+ //1.0,1.0,0.0, // yellow
1020+ 0.0 , 1.0 , 0.0 , // green
1021+ //0.0,0.0,0.0, // black (for blank cells)
9781022 ] ) ;
979-
1023+ preview_cube . u_border_size . set ( - 0.1 ) ;
9801024 bind_cube_facelet ( ) ;
9811025 let sf = 0.3 ;
9821026 let base_trans = & Transform :: scale ( height as f32 /width as f32 , 1.0 , 1.0 ) * & Transform :: scale ( sf, sf, sf) ;
@@ -1006,6 +1050,37 @@ struct TwistInfo{
10061050 time : Option < Instant > ,
10071051}
10081052
1053+ struct LedMap {
1054+ indexmap : [ u32 ; 45 ] ,
1055+ facemap : [ u32 ; 45 ] ,
1056+ subfacemap : [ u32 ; 45 ] ,
1057+ }
1058+
1059+ impl LedMap {
1060+
1061+ fn new ( ) -> Self {
1062+ let mut lm = LedMap {
1063+ indexmap : [ 0 ; 45 ] ,
1064+ facemap : [ 0 ; 45 ] ,
1065+ subfacemap : [ 0 ; 45 ] ,
1066+ } ;
1067+ lm. set ( "000102030405060708101112131415161718202122232425262728303132333435363738404142434445464748505152535455565758" ) ;
1068+ lm
1069+ }
1070+
1071+ fn set ( & mut self , map : & str ) {
1072+ for i in 0 ..=44 {
1073+ let m = map. as_bytes ( ) ;
1074+ let fnum = ( m[ i* 2 ] - b'0' ) as u32 ;
1075+ let sfnum = ( m[ ( i* 2 ) +1 ] - b'0' ) as u32 ;
1076+ let num = fnum * 9 + sfnum;
1077+ self . indexmap [ i] = if num > 44 { 0 } else { num } ;
1078+ self . facemap [ i] = if num > 44 { 0 } else { fnum } ;
1079+ self . subfacemap [ i] = if num > 44 { 0 } else { sfnum } ;
1080+ }
1081+ }
1082+ }
1083+
10091084fn main ( ) {
10101085 println ! ( "Cube service" ) ;
10111086
@@ -1119,13 +1194,18 @@ fn main() {
11191194 let mut prev_cube = Arc :: new ( Mutex :: new ( Cube :: new ( ) ) ) ;
11201195 let mut last_twist = Arc :: new ( Mutex :: new ( TwistInfo { twist : None , time : None } ) ) ;
11211196
1197+ let mut led_map = Arc :: new ( Mutex :: new ( LedMap :: new ( ) ) ) ;
1198+
1199+ led_map. lock ( ) . unwrap ( ) . set ( & config. led_map ) ;
1200+
11221201 #[ cfg( feature="output_mode_jumbotron" ) ]
11231202 let jumbotron_thread = if args. jumbotron {
11241203 let cube_state = Arc :: clone ( & cube) ;
11251204 let prev_cube_state = Arc :: clone ( & prev_cube) ;
1205+ let led_map = Arc :: clone ( & led_map) ;
11261206 let config = config. clone ( ) ;
11271207 let last_twist = last_twist. clone ( ) ;
1128- Some ( std:: thread:: spawn ( move ||{ jumbotron_thread_main ( & config, cube_state, prev_cube_state, last_twist) ; } ) )
1208+ Some ( std:: thread:: spawn ( move ||{ jumbotron_thread_main ( & config, cube_state, prev_cube_state, last_twist, led_map ) ; } ) )
11291209 } else { None } ;
11301210
11311211 let mut gui_sender: Option < Sender < StreamEvent > > = None ;
@@ -1170,13 +1250,17 @@ fn main() {
11701250 // All subfaces blank
11711251 device_write. write ( b"u " ) ?;
11721252 device_write. flush ( ) ?;
1253+ let mut lm = led_map. lock ( ) . unwrap ( ) ;
1254+ lm. set ( "000102030405060708101112131415161718202122232425262728303132333435363738404142434445464748505152535455565758" ) ;
11731255 }
11741256 , ClientEvent :: UpdateLEDMap ( new_map) => {
11751257 println ! ( "led map update" ) ;
11761258 device_write. write ( b"cm" ) ?;
11771259 device_write. write ( new_map. as_bytes ( ) ) ?;
11781260 device_write. flush ( ) ?;
1179- config. led_map = new_map;
1261+ config. led_map = new_map. clone ( ) ;
1262+ let mut lm = led_map. lock ( ) . unwrap ( ) ;
1263+ lm. set ( & new_map) ;
11801264 persist_config ( & config, & args. config ) ;
11811265 }
11821266 , ClientEvent :: UpdateInputMap ( new_map) => {
0 commit comments