Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
751 changes: 423 additions & 328 deletions plugins/RGBMatrixAnimations/matrix/anim/RGBMatrixRenderer.cpp

Large diffs are not rendered by default.

86 changes: 64 additions & 22 deletions plugins/RGBMatrixAnimations/matrix/scenes/ParticleScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,68 @@ ParticleScene::ParticleScene()
: Scene(),
prevTime(0),
lastFpsLog(0),
frameCount(0),
matrix(nullptr) {
frameCount(0)
{
}

void ParticleScene::initialize(int width, int height) {
void ParticleScene::initialize(int width, int height)
{
Scene::initialize(width, height);
matrix = nullptr;
renderer.reset();
animation.reset();
}

bool ParticleScene::render(rgb_matrix::FrameCanvas *canvas) {
if (matrix != canvas || !renderer.has_value() || !animation.has_value()) {
matrix = canvas;
renderer = std::make_shared<ParticleMatrixRenderer>(matrix_width, matrix_height, matrix);
animation = std::unique_ptr<GravityParticles, void(*)(GravityParticles *)>(
new GravityParticles(renderer.value(), shake->get(), bounce->get()),
[](GravityParticles *a) {
bool ParticleScene::render(rgb_matrix::FrameCanvas* canvas)
{
if (renderer.has_value())
{
renderer.value()->setCanvas(canvas);
}

if (!renderer.has_value() || !animation.has_value())
{
spdlog::trace("Init particle scenes");
auto local_renderer = std::make_shared<ParticleMatrixRenderer>(matrix_width, matrix_height, canvas);
auto local_animation = std::shared_ptr<GravityParticles>(
new GravityParticles(local_renderer, shake->get(), bounce->get()),
[](GravityParticles* a)
{
delete a;
}
);
initializeParticles();

renderer = local_renderer;
animation = local_animation;

initializeParticles(local_renderer, local_animation);
}

animation->get()->runCycle();
auto current_renderer = renderer.value();
auto current_animation = animation.value();

if (!current_renderer || !current_animation)
{
spdlog::warn("Particle scene renderer or animation was unexpectedly null, reinitializing on next frame.");
renderer.reset();
animation.reset();
return true;
}

preRender(current_renderer, current_animation);
current_animation->runCycle();

uint8_t MAX_FPS = 1000 / delay_ms->get();
uint32_t t;
while ((t = micros() - prevTime) < (100000L / MAX_FPS)) {
while ((t = micros() - prevTime) < (100000L / MAX_FPS))
{
}

frameCount++;
uint64_t now = micros();

if (now - lastFpsLog >= 1000000) {
spdlog::trace("FPS: {:.2f}", (float) frameCount * 1000000.0f / (now - lastFpsLog));
if (now - lastFpsLog >= 1000000)
{
spdlog::trace("FPS: {:.2f}", (float)frameCount * 1000000.0f / (now - lastFpsLog));
frameCount = 0;
lastFpsLog = now;
}
Expand All @@ -52,13 +78,15 @@ bool ParticleScene::render(rgb_matrix::FrameCanvas *canvas) {
return true;
}

uint64_t ParticleScene::micros() {
uint64_t ParticleScene::micros()
{
uint64_t us = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::
now().time_since_epoch()).count();
return us;
}

void ParticleScene::register_properties() {
void ParticleScene::register_properties()
{
add_property(numParticles);
add_property(velocity);
add_property(accel);
Expand All @@ -67,12 +95,26 @@ void ParticleScene::register_properties() {
add_property(delay_ms);
}

void ParticleScene::after_render_stop() {
if (this->animation.has_value()) {
this->animation->get()->clearParticles();
void ParticleScene::after_render_stop()
{
if (animation.has_value() && renderer.value())
{
this->particle_on_render_stop(renderer.value(), animation.value());
}

if (animation.has_value())
{
animation.value()->clearParticles();
}

if (renderer.has_value())
{
renderer.value()->clearImage();
}

animation.reset();
renderer.reset();
matrix = nullptr;
prevTime = 0;
lastFpsLog = 0;
frameCount = 0;
}
27 changes: 22 additions & 5 deletions plugins/RGBMatrixAnimations/matrix/scenes/ParticleScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ namespace Scenes {
: RGBMatrixRenderer(width, height), canvas_(canvas) {
}

void setCanvas(rgb_matrix::Canvas *canvas) {
if (canvas_ == canvas) {
return;
}

canvas_ = canvas;
updateDisplay();
}

void setPixel(uint16_t x, uint16_t y, RGB_color colour) override {
if (canvas_) {
canvas_->SetPixel(x, gridHeight - y - 1, colour.r, colour.g, colour.b);
Expand All @@ -36,11 +45,12 @@ namespace Scenes {
};

class ParticleScene : public Scene {
protected:
rgb_matrix::Canvas *matrix;
private:
std::optional<std::shared_ptr<ParticleMatrixRenderer> > renderer;
std::optional<std::unique_ptr<GravityParticles, void(*)(GravityParticles *)> > animation;
std::optional<std::shared_ptr<GravityParticles> > animation;

void after_render_stop() override;
protected:
PropertyPointer<int> numParticles = MAKE_PROPERTY("numParticles", int, 40);
PropertyPointer<int16_t> velocity = MAKE_PROPERTY("velocity", int16_t, 6000);
PropertyPointer<int> accel = MAKE_PROPERTY("acceleration", int, 1);
Expand All @@ -59,7 +69,11 @@ namespace Scenes {
return renderer ? renderer->get()->random_int16(a, b) : a + rand() % (b - a);
}

virtual void initializeParticles() = 0;
virtual void initializeParticles(std::shared_ptr<ParticleMatrixRenderer> renderer, std::shared_ptr<GravityParticles> animation) = 0;
virtual void preRender(std::shared_ptr<ParticleMatrixRenderer> renderer, std::shared_ptr<GravityParticles> animation)
{

}

public:
explicit ParticleScene();
Expand All @@ -72,6 +86,9 @@ namespace Scenes {

void initialize(int width, int height) override;

void after_render_stop() override;
virtual void particle_on_render_stop(std::shared_ptr<ParticleMatrixRenderer> renderer, std::shared_ptr<GravityParticles> animation)
{

}
};
}
50 changes: 28 additions & 22 deletions plugins/RGBMatrixAnimations/matrix/scenes/RainScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@ void RainScene::initialize(int width, int height) {
totalCols = matrix_width / 1.4;
}

void RainScene::initializeParticles() {
animation->get()->setAcceleration(0, -accel->get());
void RainScene::initializeParticles(std::shared_ptr<ParticleMatrixRenderer> renderer, std::shared_ptr<GravityParticles> animation) {
animation->setAcceleration(0, -accel->get());
initializeColumns();
createColorPalette();
createColorPalette(renderer);
}

void RainScene::initializeColumns() {
delete[] cols;
delete[] vels;
delete[] lengths;

cols = new uint16_t[totalCols];
vels = new uint16_t[totalCols];
lengths = new uint8_t[totalCols];
Expand All @@ -49,7 +53,7 @@ void RainScene::initializeColumns() {
}
}

void RainScene::createColorPalette() {
void RainScene::createColorPalette(std::shared_ptr<ParticleMatrixRenderer> renderer) {
uint16_t brightness = 255;
uint8_t red = 0, green = 255, blue = 0;
uint8_t shadeSize = 8;
Expand All @@ -62,7 +66,7 @@ void RainScene::createColorPalette() {
brightness = random_int16(50, 255);
red = uint16_t(brightness * i / 255);
green = brightness;
colID = renderer->get()->getColourId(RGB_color(red, green, blue));
colID = renderer->getColourId(RGB_color(red, green, blue));
}
}
for (uint16_t i = 0; i <= 255; i++) {
Expand All @@ -71,7 +75,7 @@ void RainScene::createColorPalette() {
brightness = random_int16(50, 255);
red = brightness;
green = uint16_t(brightness * (255 - i) / 255);
colID = renderer->get()->getColourId(RGB_color(red, green, blue));
colID = renderer->getColourId(RGB_color(red, green, blue));
}
}
for (uint16_t i = 0; i <= 255; i++) {
Expand All @@ -80,7 +84,7 @@ void RainScene::createColorPalette() {
brightness = random_int16(50, 255);
red = brightness;
blue = uint16_t(brightness * i / 255);
colID = renderer->get()->getColourId(RGB_color(red, green, blue));
colID = renderer->getColourId(RGB_color(red, green, blue));
}
}
for (uint16_t i = 0; i <= 255; i++) {
Expand All @@ -89,7 +93,7 @@ void RainScene::createColorPalette() {
brightness = random_int16(50, 255);
red = uint16_t(brightness * (255 - i) / 255);
blue = brightness;
colID = renderer->get()->getColourId(RGB_color(red, green, blue));
colID = renderer->getColourId(RGB_color(red, green, blue));
}
}
for (uint16_t i = 0; i <= 255; i++) {
Expand All @@ -98,7 +102,7 @@ void RainScene::createColorPalette() {
brightness = random_int16(50, 255);
green = uint16_t(brightness * i / 255);
blue = brightness;
colID = renderer->get()->getColourId(RGB_color(red, green, blue));
colID = renderer->getColourId(RGB_color(red, green, blue));
}
}
for (uint16_t i = 0; i <= 255; i++) {
Expand All @@ -107,27 +111,31 @@ void RainScene::createColorPalette() {
brightness = random_int16(50, 255);
green = brightness;
blue = uint16_t(brightness * (255 - i) / 255);
colID = renderer->get()->getColourId(RGB_color(red, green, blue));
colID = renderer->getColourId(RGB_color(red, green, blue));
}
}

// ...additional color transitions...
totalColors = renderer->get()->getColourId(RGB_color(0, 255, 0)) - 1;
totalColors = renderer->getColourId(RGB_color(0, 255, 0)) - 1;
}

bool RainScene::render(rgb_matrix::FrameCanvas *canvas) {
addNewParticles();
removeOldParticles();

// Call parent class render which handles animation and FPS
return ParticleScene::render(canvas);
}

void RainScene::addNewParticles() {
auto ren = renderer->get();
void RainScene::preRender(std::shared_ptr<ParticleMatrixRenderer> renderer, std::shared_ptr<GravityParticles> animation)
{
if (!renderer || !animation || !cols || !vels || !lengths) {
return;
}

addNewParticles(renderer, animation);
removeOldParticles(animation);
}

void RainScene::addNewParticles(std::shared_ptr<ParticleMatrixRenderer> ren, std::shared_ptr<GravityParticles> animation) {
const uint16_t stepSize = 1;
if (animation->get()->getParticleCount() >= numParticles->get()) return;
if (animation->getParticleCount() >= numParticles->get()) return;
float v = velocity->get();

counter++;
Expand Down Expand Up @@ -155,15 +163,13 @@ void RainScene::addNewParticles() {
if (currentColorId >= totalColors) currentColorId = 1;
}
RGB_color color = ren->getColor(currentColorId);
animation->get()->addParticle(cols[i], ren->getGridHeight() - 1, color, 0, -vels[i]);
animation->addParticle(cols[i], ren->getGridHeight() - 1, color, 0, -vels[i]);
lengths[i]--;
}
}
}

void RainScene::removeOldParticles() {
auto anim = animation->get();

void RainScene::removeOldParticles(std::shared_ptr<GravityParticles> anim) {
uint16_t removeNum = std::min((uint16_t) (numParticles->get() - 1), (uint16_t) matrix_width);
if (anim->getParticleCount() > removeNum) {
for (uint16_t i = 0; i < removeNum; i++) {
Expand Down
14 changes: 6 additions & 8 deletions plugins/RGBMatrixAnimations/matrix/scenes/RainScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ namespace Scenes {
uint32_t counter;


void initializeParticles() override;
void initializeParticles(std::shared_ptr<ParticleMatrixRenderer> renderer, std::shared_ptr<GravityParticles> animation) override;

void initializeColumns();

void createColorPalette();
void createColorPalette(std::shared_ptr<ParticleMatrixRenderer> renderer);

void addNewParticles();
void addNewParticles(std::shared_ptr<ParticleMatrixRenderer> renderer, std::shared_ptr<GravityParticles> animation);

void removeOldParticles();
void removeOldParticles(std::shared_ptr<GravityParticles> animation);
protected:
void preRender(std::shared_ptr<ParticleMatrixRenderer> renderer, std::shared_ptr<GravityParticles> animation) override;

public:
explicit RainScene();
Expand All @@ -38,10 +40,6 @@ namespace Scenes {
void initialize(int width, int height) override; // Add override here instead
[[nodiscard]] string get_name() const override;

void after_render_stop() override {
}


tmillis_t get_default_duration() override {
return 20000;
}
Expand Down
Loading
Loading