mirror of
https://github.com/wled/WLED.git
synced 2025-04-24 14:57:18 +00:00
Add some comments
This commit is contained in:
parent
8a31c57bfa
commit
0d279cb4dd
@ -1929,6 +1929,7 @@ static const char _data_FX_MODE_JUGGLE[] PROGMEM = "Juggle@!,Trail;;!;;sx=64,ix=
|
||||
|
||||
|
||||
uint16_t mode_palette() {
|
||||
// Set up some compile time constants so that we can handle integer and float based modes using the same code base.
|
||||
#ifdef ESP8266
|
||||
using mathType = int32_t;
|
||||
using wideMathType = int64_t;
|
||||
@ -1961,35 +1962,57 @@ uint16_t mode_palette() {
|
||||
const bool inputAnimateRotation = SEGMENT.check2;
|
||||
const bool inputAssumeSquare = SEGMENT.check3;
|
||||
|
||||
const int paletteOffset = (!inputAnimateShift) ? (inputShift-128) : (((strip.now * ((inputShift >> 3) +1)) & 0xFFFF) >> 8);
|
||||
|
||||
const angleType theta = (!inputAnimateRotation) ? (inputRotation * maxAngle / staticRotationScale) : (((strip.now * ((inputRotation >> 4) +1)) & 0xFFFF) * animatedRotationScale);
|
||||
const mathType sinTheta = sinFunction(theta);
|
||||
const mathType cosTheta = cosFunction(theta);
|
||||
|
||||
const mathType maxX = std::max(1, cols-1);
|
||||
const mathType maxY = std::max(1, rows-1);
|
||||
const mathType maxX = std::max(1, cols-1);
|
||||
const mathType maxY = std::max(1, rows-1);
|
||||
// Set up some parameters according to inputAssumeSquare, so that we can handle anamorphic mode using the same code base.
|
||||
const mathType maxXIn = inputAssumeSquare ? maxX : mathType(1);
|
||||
const mathType maxYIn = inputAssumeSquare ? maxY : mathType(1);
|
||||
const mathType maxXOut = !inputAssumeSquare ? maxX : mathType(1);
|
||||
const mathType maxYOut = !inputAssumeSquare ? maxY : mathType(1);
|
||||
const mathType centerX = sInt16Scale * maxXOut / mathType(2);
|
||||
const mathType centerY = sInt16Scale * maxYOut / mathType(2);
|
||||
// The basic idea for this effect is to rotate a rectangle that is filled with the palette along one axis, then map our
|
||||
// display to it, to find what color a pixel should have.
|
||||
// However, we want a) no areas of solid color (in front of or behind the palette), and b) we want to make use of the full palette.
|
||||
// So the rectangle needs to have exactly the right size. That size depends on the rotation.
|
||||
// This scale computation here only considers one dimension. You can think of it like the rectangle is always scaled so that
|
||||
// the left and right most points always match the left and right side of the display.
|
||||
const mathType scale = std::abs(sinTheta) + (std::abs(cosTheta) * maxYOut / maxXOut);
|
||||
// 2D simulation:
|
||||
// If we are dealing with a 1D setup, we assume that each segment represents one line on a 2-dimensional display.
|
||||
// The function is called once per segments, so we need to handle one line at a time.
|
||||
const int yFrom = isMatrix ? 0 : strip.getCurrSegmentId();
|
||||
const int yTo = isMatrix ? maxY : yFrom;
|
||||
const int yTo = isMatrix ? maxY : yFrom;
|
||||
for (int y = yFrom; y <= yTo; ++y) {
|
||||
// translate, scale, rotate
|
||||
const mathType ytCosTheta = mathType((wideMathType(cosTheta) * wideMathType(y * sInt16Scale - centerY * maxYIn))/wideMathType(maxYIn * scale));
|
||||
for (int x = 0; x < cols; ++x) {
|
||||
// translate, scale, rotate
|
||||
const mathType xtSinTheta = mathType((wideMathType(sinTheta) * wideMathType(x * sInt16Scale - centerX * maxXIn))/wideMathType(maxXIn * scale));
|
||||
// Map the pixel coordinate to an imaginary-rectangle-coordinate.
|
||||
// The y coordinate doesn't actually matter, as our imaginary rectangle is filled with the palette from left to right,
|
||||
// so all points at a given x-coordinate have the same color.
|
||||
const mathType sourceX = xtSinTheta + ytCosTheta + centerX;
|
||||
// The computation was scaled just right so that the result should always be in range [0, maxXOut], but enforce this anyway
|
||||
// to account for imprecision. Then scale it so that the range is [0, 255], which we can use with the palette.
|
||||
int colorIndex = (std::min(std::max(sourceX, mathType(0)), maxXOut * sInt16Scale) * 255) / (sInt16Scale * maxXOut);
|
||||
// inputSize determines by how much we want to scale the palette:
|
||||
// values < 128 display a fraction of a palette,
|
||||
// values > 128 display multiple palettes.
|
||||
if (inputSize <= 128) {
|
||||
colorIndex = (colorIndex * inputSize) / 128;
|
||||
} else {
|
||||
// Linear function that maps colorIndex 128=>1, 256=>9
|
||||
// Linear function that maps colorIndex 128=>1, 256=>9.
|
||||
// With this function every full palette repetition is exactly 16 configuration steps wide.
|
||||
// That allows displaying exactly 2 repetitions for example.
|
||||
colorIndex = ((inputSize - 112) * colorIndex) / 16;
|
||||
}
|
||||
// Finally, shift the palette a bit.
|
||||
const int paletteOffset = (!inputAnimateShift) ? (inputShift-128) : (((strip.now * ((inputShift >> 3) +1)) & 0xFFFF) >> 8);
|
||||
colorIndex += paletteOffset;
|
||||
const uint32_t color = SEGMENT.color_wheel((uint8_t)colorIndex);
|
||||
if (isMatrix) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user