Make Tile swap slow at a low Swap rate, on a curved slider
A tile has to come back to the cut it started with for the clip to loop, so every tile swapped at least twice a clip, and below that rounding left every tile still: the bottom of the slider was either frozen or busy. Swap rate is now the average per tile: below two swaps a clip only a share of the tiles swap (twice each), fewer the lower it goes, and above it each tile rounds up or down by its own draw. ParamSpec::slider() takes an optional curve: the scale runs over the slider's travel and sliderValue/sliderPosition map it onto the number as position^curve. Swap rate uses a curve of 3, so the low end gets most of the slider; the command line and project file are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,8 +4,10 @@
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <clocale>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@@ -2079,6 +2081,37 @@ int main() {
|
||||
frozenSwap.values["tileswap_rate"] = 0.0;
|
||||
check(sameBytes(frameOf(frozenSwap, 0), frameOf(frozenSwap, 5)),
|
||||
"at a rate of 0 it holds still");
|
||||
// How many pixels ever show something other than frame 0.
|
||||
auto moving = [&](const ChainStage& at) {
|
||||
const auto first = frameOf(at, 0);
|
||||
std::vector<bool> moved(static_cast<std::size_t>(80 * 48), false);
|
||||
for (int index = 1; index < 8; ++index) {
|
||||
const auto frame = frameOf(at, index);
|
||||
for (int y = 0; y < 48; ++y) {
|
||||
for (int x = 0; x < 80; ++x) {
|
||||
if (std::memcmp(frame.row(y) + x * 3, first.row(y) + x * 3, 3) != 0) {
|
||||
moved[static_cast<std::size_t>(y * 80 + x)] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::count(moved.begin(), moved.end(), true);
|
||||
};
|
||||
ChainStage slowSwap = swapStage;
|
||||
slowSwap.values["tileswap_rate"] = 0.3;
|
||||
const auto slowMoving = moving(slowSwap);
|
||||
check(slowMoving > 0 && slowMoving < moving(swapStage),
|
||||
"a rate below two swaps a clip moves only some of the tiles");
|
||||
|
||||
const auto& rate = swap->params().back();
|
||||
check(rate.onSlider && rate.curve > 1.0, "its swap rate is a curved slider");
|
||||
check(rate.sliderValue(0.0) == 0.0 && rate.sliderValue(1.0) == 5.0 &&
|
||||
rate.sliderValue(0.5) < 2.5,
|
||||
"which spans the whole range and gives the low end more travel");
|
||||
check(std::abs(rate.sliderValue(rate.sliderPosition(0.37)) - 0.37) < 1e-9 &&
|
||||
rate.sliderValue(0.123456) * 100.0 ==
|
||||
std::round(rate.sliderValue(0.123456) * 100.0),
|
||||
"a value finds its place on the slider, and a place rounds to the step");
|
||||
ChainStage scattered = swapStage;
|
||||
scattered.values["tileswap_layout"] = std::string("scatter");
|
||||
ChainStage bricks = swapStage;
|
||||
|
||||
Reference in New Issue
Block a user