Low-level mapping

Hi,

I’m new to PixelBlaze after doing a fair bit of teensy, arduino, r-pi etc…

With regards to mapping, I have a project with non-linear pixels, and for these, sometimes i’ll want to drive them with spatial mapping, but at other times with my own mapping.

Could you advise, are both possible? - I’d love to set up my own mapping system and related structures, and then swap / merge with spatial mapping.

Thoughts?

Thanks
Jon

Absolutely! render2D(index,x,y) and render3D(index,x,y,z) mean you get both the LED index and the coordinates in the map. It’s up to you what to do with them. :smiley:

To put it another way…

Pixelblaze has a “Mapping” tab where, when configuring your LEDs, you can enter (or calculate) the X, Y and potentially Z positions of the pixels in 2D or 3D space. Those spatial coordinates, along with the index of the pixel along the data line, are then passed at runtime to the render2D(index, x, y) or render3D(index, x, y, z) function in your pattern, where you can use them to make rendering decisions. But the map is fixed at setup time; it can’t be changed from within a pattern.

At runtime, Pixelblaze decides which renderer to execute for each pattern depending on the presence or absence of the mapping data. If a map exists and the pattern has a render?D function that matches the dimensionality of the map, Pixelblaze will use it; otherwise it calls the linear render() function.

You can have a mixture of 1D and 2D/3D patterns on a Pixelblaze, but if you want to completely reorder pixels or change mapping on the fly, then you might need to ignore the mapping tab and do the mapping of pixels within the code of your own patterns.

Here’s a simple 1D remapping that changes the indexes of a 2D matrix so that the pixels spiral inwards instead of wrapping around at the edges:

//
//  This pattern is intended to run on a CJMCU 8x8 matrix where the LED order is left-to-right, top-to-bottom.
//  The remapped pixel order is concentric square rings, running clockwise:
//
mapIndex = [ 0, 1, 2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 55, 63, 62, 61, 60, 59, 58, 57, 56, 48, 40, 32, 24,16, 8, // outer ring
             9, 10, 11, 12, 13, 14, 22, 30, 38, 46, 54, 53, 52, 51, 50, 49, 41, 33, 25, 17, // 2nd ring inwards
             18, 19, 20, 21, 29, 37, 45, 44, 43, 42, 34, 26, // 3rd ring inwards
             27, 28, 35, 36 // inner ring
          ];
export var pixelCount = mapIndex.length;
function remapIndex(index) { for (var i = 0; i < mapIndex.length; i++) if (mapIndex[i] == index) return i; }

//
//  The pattern code (@jeff's KITT from https://forum.electromage.com/t/kitt-without-arrays/1219):
//
var t1;
export function beforeRender(delta) { t1 = time(.05) }

function pulse(x) {
  var tailPct = .4;
  return max(0, ((triangle(x - t1) * square(x - t1, .5)) - (1 - tailPct)) / tailPct)
}

export function render(index) {
  index = remapIndex(index);
  pct = index / pixelCount / 2; v = pulse(pct) + pulse(-pct); hsv(0, 1, v * v * v)
}

For more drastic 2D/3D remappings, you’d also need to store the X, Y and Z coordinates for each pixel into arrays and remap them at the top of the render2D or render3D function. For an extreme example of remapping, see here.

2 Likes

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.