imported from "final" folder
This commit is contained in:
7
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/XYPath.ino
Normal file
7
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/XYPath.ino
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "fl/sketch_macros.h"
|
||||
|
||||
#if !SKETCH_HAS_LOTS_OF_MEMORY
|
||||
#include "platforms/sketch_fake.hpp"
|
||||
#else
|
||||
#include "direct.h"
|
||||
#endif
|
||||
211
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/complex.h
Normal file
211
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/complex.h
Normal file
@@ -0,0 +1,211 @@
|
||||
|
||||
|
||||
/*
|
||||
This demo is best viewed using the FastLED compiler.
|
||||
|
||||
Windows/MacOS binaries: https://github.com/FastLED/FastLED/releases
|
||||
|
||||
Python
|
||||
|
||||
Install: pip install fastled
|
||||
Run: fastled <this sketch directory>
|
||||
This will compile and preview the sketch in the browser, and enable
|
||||
all the UI elements you see below.
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <FastLED.h>
|
||||
|
||||
#include "fl/draw_visitor.h"
|
||||
#include "fl/math_macros.h"
|
||||
#include "fl/raster.h"
|
||||
#include "fl/time_alpha.h"
|
||||
#include "fl/ui.h"
|
||||
#include "fl/xypath.h"
|
||||
#include "fx/time.h"
|
||||
|
||||
// Sketch.
|
||||
#include "src/wave.h"
|
||||
#include "src/xypaths.h"
|
||||
|
||||
#include "fl/memfill.h"
|
||||
using namespace fl;
|
||||
|
||||
#define HEIGHT 64
|
||||
#define WIDTH 64
|
||||
#define NUM_LEDS ((WIDTH) * (HEIGHT))
|
||||
#define IS_SERPINTINE true
|
||||
#define TIME_ANIMATION 1000 // ms
|
||||
|
||||
CRGB leds[NUM_LEDS];
|
||||
|
||||
XYMap xyMap(WIDTH, HEIGHT, IS_SERPINTINE);
|
||||
// XYPathPtr shape = XYPath::NewRosePath(WIDTH, HEIGHT);
|
||||
|
||||
// Speed up writing to the super sampled waveFx by writing
|
||||
// to a raster. This will allow duplicate writes to be removed.
|
||||
|
||||
WaveEffect wave_fx; // init in setup().
|
||||
fl::vector<XYPathPtr> shapes = CreateXYPaths(WIDTH, HEIGHT);
|
||||
|
||||
|
||||
XYRaster raster(WIDTH, HEIGHT);
|
||||
TimeWarp time_warp;
|
||||
|
||||
XYPathPtr getShape(int which) {
|
||||
int len = shapes.size();
|
||||
which = which % len;
|
||||
if (which < 0) {
|
||||
which += len;
|
||||
}
|
||||
return shapes[which];
|
||||
}
|
||||
|
||||
//////////////////// UI Section /////////////////////////////
|
||||
UITitle title("XYPath Demo");
|
||||
UIDescription description("Use a path on the WaveFx");
|
||||
UIButton trigger("Trigger");
|
||||
UISlider whichShape("Which Shape", 0.0f, 0.0f, shapes.size() - 1, 1.0f);
|
||||
UICheckbox useWaveFx("Use WaveFX", true);
|
||||
UISlider transition("Transition", 0.0f, 0.0f, 1.0f, 0.01f);
|
||||
|
||||
UISlider scale("Scale", 1.0f, 0.0f, 1.0f, 0.01f);
|
||||
UISlider speed("Speed", 1.0f, -20.0f, 20.0f, 0.01f);
|
||||
UISlider numberOfSteps("Number of Steps", 32.0f, 1.0f, 100.0f, 1.0f);
|
||||
UISlider maxAnimation("Max Animation", 1.0f, 5.0f, 20.0f, 1.f);
|
||||
|
||||
TimeClampedTransition shapeProgress(TIME_ANIMATION);
|
||||
|
||||
void setupUiCallbacks() {
|
||||
speed.onChanged([](float value) { time_warp.setSpeed(speed.value()); });
|
||||
maxAnimation.onChanged(
|
||||
[](float value) { shapeProgress.set_max_clamp(maxAnimation.value()); });
|
||||
|
||||
trigger.onChanged([]() {
|
||||
// shapeProgress.trigger(millis());
|
||||
FASTLED_WARN("Trigger pressed");
|
||||
});
|
||||
useWaveFx.onChanged([](bool on) {
|
||||
if (on) {
|
||||
FASTLED_WARN("WaveFX enabled");
|
||||
} else {
|
||||
FASTLED_WARN("WaveFX disabled");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
auto screenmap = xyMap.toScreenMap();
|
||||
screenmap.setDiameter(.2);
|
||||
FastLED.addLeds<NEOPIXEL, 2>(leds, NUM_LEDS).setScreenMap(screenmap);
|
||||
setupUiCallbacks();
|
||||
// Initialize wave simulation. Please don't use static constructors, keep it
|
||||
// in setup().
|
||||
trigger.click();
|
||||
wave_fx = NewWaveSimulation2D(xyMap);
|
||||
}
|
||||
|
||||
//////////////////// LOOP SECTION /////////////////////////////
|
||||
|
||||
float getAnimationTime(uint32_t now) {
|
||||
float pointf = shapeProgress.updatef(now);
|
||||
return pointf + transition.value();
|
||||
}
|
||||
|
||||
void clearLeds() { fl::memfill(leds, 0, NUM_LEDS * sizeof(CRGB)); }
|
||||
|
||||
void loop() {
|
||||
// Your code here
|
||||
clearLeds();
|
||||
const uint32_t now = millis();
|
||||
uint32_t now_warped = time_warp.update(now);
|
||||
|
||||
auto shape = getShape(whichShape.as<int>());
|
||||
shape->setScale(scale.value());
|
||||
|
||||
float curr_alpha = getAnimationTime(now_warped);
|
||||
static float s_prev_alpha = 0.0f;
|
||||
|
||||
// unconditionally apply the circle.
|
||||
if (trigger) {
|
||||
// trigger the transition
|
||||
time_warp.reset(now);
|
||||
now_warped = time_warp.update(now);
|
||||
shapeProgress.trigger(now_warped);
|
||||
FASTLED_WARN("Transition triggered on " << shape->name());
|
||||
curr_alpha = getAnimationTime(now_warped);
|
||||
s_prev_alpha = curr_alpha;
|
||||
}
|
||||
|
||||
// FASTLED_WARN("Current alpha: " << curr_alpha);
|
||||
// FASTLED_WARN("maxAnimation: " << maxAnimation.value());
|
||||
|
||||
const bool is_active =
|
||||
true || curr_alpha < maxAnimation.value() && curr_alpha > 0.0f;
|
||||
|
||||
// if (shapeProgress.isActive(now)) {
|
||||
static uint32_t frame = 0;
|
||||
frame++;
|
||||
clearLeds();
|
||||
const CRGB purple = CRGB(255, 0, 255);
|
||||
const int number_of_steps = numberOfSteps.value();
|
||||
raster.reset();
|
||||
// float factor = s_prev_alpha; // 0->1.f
|
||||
// factor = MIN(factor/4.0f, 0.05f);
|
||||
|
||||
float diff = curr_alpha - s_prev_alpha;
|
||||
diff *= 1.0f;
|
||||
float factor = MAX(s_prev_alpha - diff, 0.f);
|
||||
|
||||
for (int i = 0; i < number_of_steps; ++i) {
|
||||
float a =
|
||||
fl::map_range<float>(i, 0, number_of_steps - 1, factor, curr_alpha);
|
||||
if (a < .04) {
|
||||
// shorter tails at first.
|
||||
a = map_range<float>(a, 0.0f, .04f, 0.0f, .04f);
|
||||
}
|
||||
float diff_max_alpha = maxAnimation.value() - curr_alpha;
|
||||
if (diff_max_alpha < 0.94) {
|
||||
// shorter tails at the end.
|
||||
a = map_range<float>(a, curr_alpha, maxAnimation.value(),
|
||||
curr_alpha, maxAnimation.value());
|
||||
}
|
||||
uint8_t alpha =
|
||||
fl::map_range<float>(i, 0.0f, number_of_steps - 1, 64, 255);
|
||||
if (!is_active) {
|
||||
alpha = 0;
|
||||
}
|
||||
Tile2x2_u8 subpixel = shape->at_subpixel(a);
|
||||
subpixel.scale(alpha);
|
||||
// subpixels.push_back(subpixel);
|
||||
raster.rasterize(subpixel);
|
||||
}
|
||||
|
||||
s_prev_alpha = curr_alpha;
|
||||
|
||||
|
||||
if (useWaveFx && is_active) {
|
||||
DrawRasterToWaveSimulator draw_wave_fx(&wave_fx);
|
||||
raster.draw(xyMap, draw_wave_fx);
|
||||
} else {
|
||||
raster.draw(purple, xyMap, leds);
|
||||
}
|
||||
|
||||
int first = xyMap(1, 1);
|
||||
int last = xyMap(WIDTH - 2, HEIGHT - 2);
|
||||
|
||||
leds[first] = CRGB(255, 0, 0);
|
||||
leds[last] = CRGB(0, 255, 0);
|
||||
if (useWaveFx) {
|
||||
// fxBlend.draw(Fx::DrawContext(now, leds));
|
||||
wave_fx.draw(Fx::DrawContext(now, leds));
|
||||
}
|
||||
|
||||
EVERY_N_SECONDS(1) {
|
||||
uint32_t frame_time = millis() - now;
|
||||
FASTLED_WARN("Frame time: " << frame_time << "ms");
|
||||
}
|
||||
|
||||
FastLED.show();
|
||||
}
|
||||
70
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/direct.h
Normal file
70
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/direct.h
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
|
||||
/*
|
||||
This demo is best viewed using the FastLED compiler.
|
||||
|
||||
Windows/MacOS binaries: https://github.com/FastLED/FastLED/releases
|
||||
|
||||
Python
|
||||
|
||||
Install: pip install fastled
|
||||
Run: fastled <this sketch directory>
|
||||
This will compile and preview the sketch in the browser, and enable
|
||||
all the UI elements you see below.
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <FastLED.h>
|
||||
|
||||
#include "fl/draw_visitor.h"
|
||||
#include "fl/math_macros.h"
|
||||
#include "fl/raster.h"
|
||||
#include "fl/time_alpha.h"
|
||||
#include "fl/ui.h"
|
||||
#include "fl/xypath.h"
|
||||
#include "fx/time.h"
|
||||
#include "fl/leds.h"
|
||||
|
||||
#include "src/xypaths.h"
|
||||
|
||||
// Sketch.
|
||||
#include "src/wave.h"
|
||||
#include "src/xypaths.h"
|
||||
#include "fl/function.h"
|
||||
|
||||
|
||||
using namespace fl;
|
||||
|
||||
#define HEIGHT 64
|
||||
#define WIDTH 64
|
||||
#define NUM_LEDS ((WIDTH) * (HEIGHT))
|
||||
#define IS_SERPINTINE true
|
||||
#define TIME_ANIMATION 1000 // ms
|
||||
|
||||
LedsXY<WIDTH, HEIGHT> leds;
|
||||
XYMap xyMap(WIDTH, HEIGHT, IS_SERPINTINE);
|
||||
UITitle title("Simple control of an xy path");
|
||||
UIDescription description("This is more of a test for new features.");
|
||||
|
||||
// UIButton trigger("My Trigger");
|
||||
UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f);
|
||||
UISlider steps("Steps", 100.0f, 1.0f, 200.0f, 1.0f);
|
||||
UISlider length("Length", 1.0f, 0.0f, 1.0f, 0.01f);
|
||||
|
||||
XYPathPtr heartPath = XYPath::NewHeartPath(WIDTH, HEIGHT);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
auto screenmap = xyMap.toScreenMap();
|
||||
screenmap.setDiameter(.2);
|
||||
FastLED.addLeds<NEOPIXEL, 2>(leds, NUM_LEDS).setScreenMap(screenmap);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// leds(x,y) = CRGB(255, 0, 0);
|
||||
fl::clear(leds);
|
||||
float from = offset;
|
||||
float to = length.value() + offset.value();
|
||||
heartPath->drawColor(CRGB(255, 0, 0), from, to, &leds, steps.as_int());
|
||||
FastLED.show();
|
||||
}
|
||||
75
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/simple.h
Normal file
75
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/simple.h
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
|
||||
/*
|
||||
This demo is best viewed using the FastLED compiler.
|
||||
|
||||
Windows/MacOS binaries: https://github.com/FastLED/FastLED/releases
|
||||
|
||||
Python
|
||||
|
||||
Install: pip install fastled
|
||||
Run: fastled <this sketch directory>
|
||||
This will compile and preview the sketch in the browser, and enable
|
||||
all the UI elements you see below.
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <FastLED.h>
|
||||
|
||||
#include "fl/draw_visitor.h"
|
||||
#include "fl/math_macros.h"
|
||||
#include "fl/raster.h"
|
||||
#include "fl/time_alpha.h"
|
||||
#include "fl/ui.h"
|
||||
#include "fl/xypath.h"
|
||||
#include "fx/time.h"
|
||||
|
||||
// Sketch.
|
||||
#include "src/wave.h"
|
||||
#include "src/xypaths.h"
|
||||
#include "fl/function.h"
|
||||
|
||||
using namespace fl;
|
||||
|
||||
#define HEIGHT 64
|
||||
#define WIDTH 64
|
||||
#define NUM_LEDS ((WIDTH) * (HEIGHT))
|
||||
#define IS_SERPINTINE true
|
||||
#define TIME_ANIMATION 1000 // ms
|
||||
|
||||
CRGB leds[NUM_LEDS];
|
||||
XYMap xyMap(WIDTH, HEIGHT, IS_SERPINTINE);
|
||||
UITitle title("Simple control of an xy path");
|
||||
UIDescription description("This is more of a test for new features.");
|
||||
|
||||
// UIButton trigger("My Trigger");
|
||||
UISlider pointX("Point X", WIDTH / 2.0f, 0.0f, WIDTH - 1, 1.0f);
|
||||
UISlider pointY("Point Y", HEIGHT / 2.0f, 0.0f, HEIGHT - 1, 1.0f);
|
||||
|
||||
UIButton button("second trigger");
|
||||
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
bool triggered = false;
|
||||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
auto screenmap = xyMap.toScreenMap();
|
||||
screenmap.setDiameter(.2);
|
||||
FastLED.addLeds<NEOPIXEL, 2>(leds, NUM_LEDS).setScreenMap(screenmap);
|
||||
|
||||
}
|
||||
void loop() {
|
||||
fl::clear(leds);
|
||||
triggered = button.clicked();
|
||||
if (triggered) {
|
||||
FASTLED_WARN("Triggered");
|
||||
}
|
||||
x = pointX.as_int();
|
||||
y = pointY.as_int();
|
||||
leds[xyMap(x, y)] = CRGB(255, 0, 0);
|
||||
|
||||
FastLED.show();
|
||||
}
|
||||
65
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/src/wave.cpp
Normal file
65
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/src/wave.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
#include "wave.h"
|
||||
#include "FastLED.h"
|
||||
|
||||
DEFINE_GRADIENT_PALETTE(electricBlueFirePal){
|
||||
0, 0, 0, 0, // Black
|
||||
32, 0, 0, 70, // Dark blue
|
||||
128, 20, 57, 255, // Electric blue
|
||||
255, 255, 255, 255 // White
|
||||
};
|
||||
|
||||
DEFINE_GRADIENT_PALETTE(electricGreenFirePal){
|
||||
0, 0, 0, 0, // black
|
||||
8, 128, 64, 64, // green
|
||||
16, 255, 222, 222, // red
|
||||
64, 255, 255, 255, // white
|
||||
255, 255, 255, 255 // white
|
||||
};
|
||||
|
||||
WaveFx::Args CreateArgsLower() {
|
||||
WaveFx::Args out;
|
||||
out.factor = SuperSample::SUPER_SAMPLE_2X;
|
||||
out.half_duplex = true;
|
||||
out.auto_updates = true;
|
||||
out.speed = 0.18f;
|
||||
out.dampening = 9.0f;
|
||||
out.crgbMap = fl::make_shared<WaveCrgbGradientMap>(electricBlueFirePal);
|
||||
return out;
|
||||
}
|
||||
|
||||
WaveFx::Args CreateArgsUpper() {
|
||||
WaveFx::Args out;
|
||||
out.factor = SuperSample::SUPER_SAMPLE_2X;
|
||||
out.half_duplex = true;
|
||||
out.auto_updates = true;
|
||||
out.speed = 0.25f;
|
||||
out.dampening = 3.0f;
|
||||
out.crgbMap = fl::make_shared<WaveCrgbGradientMap>(electricGreenFirePal);
|
||||
return out;
|
||||
}
|
||||
|
||||
WaveEffect NewWaveSimulation2D(const XYMap& xymap) {
|
||||
// only apply complex xymap as the last step after compositiing.
|
||||
XYMap xy_rect =
|
||||
XYMap::constructRectangularGrid(xymap.getWidth(), xymap.getHeight());
|
||||
Blend2dPtr fxBlend =
|
||||
fl::make_shared<Blend2d>(xymap); // Final transformation goes to the blend stack.
|
||||
int width = xymap.getWidth();
|
||||
int height = xymap.getHeight();
|
||||
XYMap xyRect(width, height, false);
|
||||
WaveFx::Args args_lower = CreateArgsLower();
|
||||
WaveFx::Args args_upper = CreateArgsUpper();
|
||||
WaveFxPtr wave_fx_low = fl::make_shared<WaveFx>(xy_rect, args_lower);
|
||||
WaveFxPtr wave_fx_high = fl::make_shared<WaveFx>(xy_rect, args_upper);
|
||||
Blend2dPtr blend_stack = fl::make_shared<Blend2d>(xymap);
|
||||
blend_stack->add(wave_fx_low);
|
||||
blend_stack->add(wave_fx_high);
|
||||
WaveEffect out = {
|
||||
.wave_fx_low = wave_fx_low,
|
||||
.wave_fx_high = wave_fx_high,
|
||||
.blend_stack = blend_stack,
|
||||
};
|
||||
|
||||
return out;
|
||||
}
|
||||
34
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/src/wave.h
Normal file
34
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/src/wave.h
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fx/2d/blend.h"
|
||||
#include "fx/2d/wave.h"
|
||||
#include "fx/fx2d.h"
|
||||
#include "fl/raster.h"
|
||||
|
||||
using namespace fl;
|
||||
|
||||
struct WaveEffect {
|
||||
WaveFxPtr wave_fx_low;
|
||||
WaveFxPtr wave_fx_high;
|
||||
Blend2dPtr blend_stack;
|
||||
void draw(Fx::DrawContext context) { blend_stack->draw(context); }
|
||||
void addf(size_t x, size_t y, float value) {
|
||||
wave_fx_low->addf(x, y, value);
|
||||
wave_fx_high->addf(x, y, value);
|
||||
}
|
||||
};
|
||||
|
||||
struct DrawRasterToWaveSimulator {
|
||||
DrawRasterToWaveSimulator(WaveEffect* wave_fx) : mWaveFx(wave_fx) {}
|
||||
void draw(const vec2<int> &pt, uint32_t /*index*/, uint8_t value) {
|
||||
float valuef = value / 255.0f;
|
||||
int xx = pt.x;
|
||||
int yy = pt.y;
|
||||
mWaveFx->addf(xx, yy, valuef);
|
||||
}
|
||||
WaveEffect* mWaveFx;
|
||||
};
|
||||
|
||||
WaveEffect NewWaveSimulation2D(const XYMap& xymap);
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
|
||||
#include "fl/xypath.h"
|
||||
#include "fl/vector.h"
|
||||
#include "fl/map_range.h"
|
||||
|
||||
|
||||
#include "xypaths.h"
|
||||
|
||||
using namespace fl;
|
||||
|
||||
namespace {
|
||||
fl::shared_ptr<CatmullRomParams> make_path(int width, int height) {
|
||||
// make a triangle.
|
||||
fl::shared_ptr<CatmullRomParams> params = fl::make_shared<CatmullRomParams>();
|
||||
vector_inlined<vec2f, 5> points;
|
||||
points.push_back(vec2f(0.0f, 0.0f));
|
||||
points.push_back(vec2f(width / 3, height / 2));
|
||||
points.push_back(vec2f(width - 3, height - 1));
|
||||
points.push_back(vec2f(0.0f, height - 1));
|
||||
points.push_back(vec2f(0.0f, 0.0f));
|
||||
for (auto &p : points) {
|
||||
p.x = map_range<float, float>(p.x, 0.0f, width - 1, -1.0f, 1.0f);
|
||||
p.y = map_range<float, float>(p.y, 0.0f, height - 1, -1.0f, 1.0f);
|
||||
params->addPoint(p);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
||||
fl::vector<XYPathPtr> CreateXYPaths(int width, int height) {
|
||||
fl::vector<XYPathPtr> out;
|
||||
out.push_back(XYPath::NewCirclePath(width, height));
|
||||
out.push_back(XYPath::NewRosePath(width, height));
|
||||
out.push_back(XYPath::NewHeartPath(width, height));
|
||||
out.push_back(XYPath::NewArchimedeanSpiralPath(width, height));
|
||||
out.push_back(XYPath::NewPhyllotaxisPath(width, height));
|
||||
out.push_back(XYPath::NewGielisCurvePath(width, height));
|
||||
out.push_back(XYPath::NewCatmullRomPath(width, height, make_path(width, height)));
|
||||
return out;
|
||||
}
|
||||
10
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/src/xypaths.h
Normal file
10
.pio/libdeps/esp01_1m/FastLED/examples/XYPath/src/xypaths.h
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
#include "fl/xypath.h"
|
||||
#include "fl/vector.h"
|
||||
|
||||
using namespace fl;
|
||||
|
||||
// XYPath::NewRosePath(WIDTH, HEIGHT);
|
||||
|
||||
fl::vector<XYPathPtr> CreateXYPaths(int width, int height);
|
||||
Reference in New Issue
Block a user