Translating FastLED pixel maps to Pixelblaze

Hey all. I’m also curious on how to translate a FastLED XY Map Generator set of code to Pixelblaze, if possible. I’ve used the FastLED XY Map Generator for my map, and would love to be able to work with it. @JasonAsbahr , did you have any luck in your effort? Here’s my output from FastLED XY Map Generator.

Hi @Folzams ,
Sure, the key here is that this code gives you a way to find the index for a given (x, y) coordinate, and Pixelblaze pixel maps are the inverse of that, you specify an array of (x,y) coordinates for each pixel (with the index implicitly provided as the position in that array).

So for a trivial example, let’s say you have a 3x2 map. These are encoded as rows, stacked end to end. For a tiny zigzag wired matrix the array might look like this [0, 1, 2, 5, 4, 3]. That’s for a map that went left to right, down, the left. Lets look at that arranged visually:

[0, 1, 2
 5, 4, 3]

In Pixelblaze map terms, the coordinates are given instead for (x,y), which would be

[
[0,0], //top left
[1,0], //top mid
[2,0], //top right
[2,1], //bottom right
[1,1], //bottom mid
[0,1] //bottom left
]

OK, but how to convert these automatically? Convert the the XYTable array to JavaScript, which is mostly just syntax changes, then with some for loops, calculate every (x,y) combination, get the index with the XY function and put that into a PB style coordinate array.

function (pixelCount) {
  var kMatrixWidth = 34;
  var kMatrixHeight = 36;
  var LAST_VISIBLE_LED = 683;

  var XYTable = [
    684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705,
  723, 722, 721, 720, 719, 718, 717, 716, 715,  27,  26,  25,  24,  23,  22,  21,  20,  19,  18,  17,  16,  15,  14,  13,  12, 714, 713, 712, 711, 710, 709, 708, 707, 706,
  724, 725, 726, 727, 728, 729, 730, 731,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45, 732, 733, 734, 735, 736, 737, 738, 739,
  753, 752, 751, 750, 749, 748, 747,  65,  64,  63,  62,  61,  60,  59,  58,  57,  56,  55,  54,  53,  52,  51,  50,  49,  48,  47,  46, 746, 745, 744, 743, 742, 741, 740,
  754, 755, 756, 757, 758, 759,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87, 760, 761, 762, 763, 764, 765,
  775, 774, 773, 772, 771, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100,  99,  98,  97,  96,  95,  94,  93,  92,  91,  90,  89,  88, 770, 769, 768, 767, 766,
  776, 777, 778, 779, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 780, 781, 782, 783,
  803, 802, 801, 151, 150, 149, 148, 147, 146, 145, 800, 799, 798, 797, 796, 795, 794, 793, 792, 791, 790, 789, 788, 787, 144, 143, 142, 141, 140, 139, 138, 786, 785, 784,
  804, 805, 806, 152, 153, 154, 155, 156, 157, 158, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 159, 160, 161, 162, 163, 164, 165, 821, 822, 823,
  841, 840, 181, 180, 179, 178, 177, 176, 175, 174, 839, 838, 837, 836, 835, 834, 833, 832, 831, 830, 829, 828, 827, 826, 173, 172, 171, 170, 169, 168, 167, 166, 825, 824,
  842, 182, 183, 184, 185, 843, 844, 845, 846, 847, 848, 849, 850, 851, 186, 187, 852, 853, 188, 189, 854, 855, 856, 857, 858, 859, 860, 861, 862, 190, 191, 192, 193, 863,
  885, 205, 204, 203, 202, 884, 883, 882, 881, 880, 879, 878, 877, 876, 201, 200, 875, 874, 199, 198, 873, 872, 871, 870, 869, 868, 867, 866, 865, 197, 196, 195, 194, 864,
  206, 207, 208, 209, 210, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 211, 212, 213, 214, 215,
  233, 232, 231, 230, 229, 228, 227, 226, 225, 925, 924, 923, 922, 921, 920, 919, 918, 917, 916, 915, 914, 913, 912, 911, 910, 224, 223, 222, 221, 220, 219, 218, 217, 216,
  234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
  277, 276, 275, 274, 273, 272, 271, 270, 269, 268, 267, 949, 948, 947, 946, 945, 944, 943, 942, 941, 940, 939, 938, 266, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256,
  278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299,
  323, 322, 321, 320, 319, 318, 317, 316, 315, 314, 313, 312, 971, 970, 969, 968, 967, 966, 965, 964, 963, 962, 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, 300,
  324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357,
  391, 390, 389, 388, 387, 386, 385, 384, 383, 382, 381, 380, 379, 378, 377, 376, 375, 374, 373, 372, 371, 370, 369, 368, 367, 366, 365, 364, 363, 362, 361, 360, 359, 358,
  972, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 973,
  975, 455, 454, 453, 452, 451, 450, 449, 448, 447, 446, 445, 444, 443, 442, 441, 440, 439, 438, 437, 436, 435, 434, 433, 432, 431, 430, 429, 428, 427, 426, 425, 424, 974,
  976, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 977,
  981, 980, 517, 516, 515, 514, 513, 512, 511, 510, 509, 508, 507, 506, 505, 504, 503, 502, 501, 500, 499, 498, 497, 496, 495, 494, 493, 492, 491, 490, 489, 488, 979, 978,
  982, 983, 984, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 985, 986, 987,
  993, 992, 991, 573, 572, 571, 570, 569, 568, 567, 566, 565, 564, 563, 562, 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, 550, 549, 548, 547, 546, 990, 989, 988,
  994, 995, 996, 997, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 998, 999,1000,1001,
  1013,1012,1011,1010,1009,1008, 621, 620, 619, 618, 617, 616, 615, 614, 613, 612, 611, 610, 609, 608, 607, 606, 605, 604, 603, 602, 601, 600,1007,1006,1005,1004,1003,1002,
  1014,1015,1016,1017,1018,1019,1020,1021, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639,1022,1023,1024,1025,1026,1027,1028,1029,
  1055,1054,1053,1052,1051,1050,1049,1048,1047,1046,1045, 647, 646, 645, 644,1044,1043,1042,1041, 643, 642, 641, 640,1040,1039,1038,1037,1036,1035,1034,1033,1032,1031,1030,
  1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067, 648, 649, 650,1068,1069,1070,1071, 651, 652, 653,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,
  1111,1110,1109,1108,1107,1106,1105,1104,1103,1102,1101,1100, 659, 658, 657,1099,1098,1097,1096, 656, 655, 654,1095,1094,1093,1092,1091,1090,1089,1088,1087,1086,1085,1084,
  1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123, 660, 661, 662,1124,1125,1126,1127, 663, 664, 665,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,
  1167,1166,1165,1164,1163,1162,1161,1160,1159,1158,1157,1156, 671, 670, 669,1155,1154,1153,1152, 668, 667, 666,1151,1150,1149,1148,1147,1146,1145,1144,1143,1142,1141,1140,
  1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179, 672, 673, 674,1180,1181,1182,1183, 675, 676, 677,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,
  1223,1222,1221,1220,1219,1218,1217,1216,1215,1214,1213,1212, 683, 682, 681,1211,1210,1209,1208, 680, 679, 678,1207,1206,1205,1204,1203,1202,1201,1200,1199,1198,1197,1196
  ];


  function XY(x,y) {
    // any out of bounds address maps to the first hidden pixel
    if ( (x >= kMatrixWidth) || (y >= kMatrixHeight) ) {
      return (LAST_VISIBLE_LED + 1);
    }

    var i = (y * kMatrixWidth) + x;
    var j = XYTable[i];
    return j;
  }
  
  var map = new Array(kMatrixWidth * kMatrixHeight);
  for (var y = 0; y < kMatrixHeight; y++) {
    for (var x = 0; x < kMatrixWidth; x++) {
      var pixelIndex = XY(x,y)
      map[pixelIndex] = [x,y]
    }
  }

  return map
}

To me, this looks like a complicated way to wire up an LED sheep matrix. There’s the foreground sheep, wired zigzag, then the background pixels as well, wired up separately? Here’s an animation showing the wire path, watch the pulse travel through these pixels.

Tacking this onto the thread where you ask about rendering these parts differently

Using Z makes a lot of sense, and would be pretty easy to add. I wasn’t sure what the LAST_VISIBLE_LED in your FastLED map was for, but it seems to be a pretty good indicator of the split between the foreground and background.

Modifying the code above slightly to add a Z, with a value based on that:

map[pixelIndex] = [x,y, pixelIndex > LAST_VISIBLE_LED ? 0 : 5]

Note that without much modification, most 3D patterns will use the Z and make sheep-shaped differences in animation.

(for this preview I turned off the 3D focal length so I can visually overlap the sheep layers, and turned on gapFill, these are hackable using a browser console in the previewSettings global)

2 Likes

Thanks a million, Wizard. I really appreciate this detail. I’m going to hopefully get back to the matrix tonight, if not at the latest tomorrow, and will try the suggestion. As I recently mentioned in the other thread, my matrix is actually just a plain old rectangle, 34x36LED, powered in parallel with the data line as serpentine. I have the board split up into 4 segments.

OK, that makes more sense. In that case you want a regular matrix type map, but you can still mix in the Z coordinate trick to make the sheep pop out.

1 Like

Alternatively, you could add in a B&W bitmap of the sheep into patterns. This would let you have different images more easily, no hackery with the pixel map.

Check this post on how to use simple black and white bitmaps using the XBM format

1 Like

I thought the Fast LED output was a regular matrix type map (albeit for Fast LED). I will try the Z coordinate trick tonight. When you say ‘pop out’, are you saying that this part will drop out altogether, with no pixels on? that’s what I’m aiming for. I want just the body and eyes lights on, and all others off.
image

No, not quite exactly.

A pixel map isn’t the same as an image. It’s a way to tell the system where your pixels are physically, using some coordinate system. That is true for both fastled and pixelblaze. They just go about it differently.

Since you have a regular matrix, you will need a different way to express the sheep in the pixel map than the one above, it won’t do the right things on a regular matrix.

When I say pop out above, I mean that the sheep pixels are on a higher z level than the other background pixels. Both sets of pixels still exist and patterns will render both. One set is just popped up above the others.

If you want the non-sheep background pixels to be black, this isn’t something that is achievable with only a pixel map. You’d also need to modify patterns to leverage the z height from the map, like @sorceror was showing.

What I was suggesting is that if you ever wanted a different image then it might make sense to do everything in the pattern instead of the map. No z bright tricks, but a bit more code for the XBM.

1 Like

Thank you Sir. I think I’ll opt to try @sorceror 's suggestion of modifying patterns to leverage the z height from the map. I likely won’t be using any other images, and I can just store those patterns for use in next year’s event, once created. I’m in over my head, codewise, but am going to give it a college try tonight. Thank you both.