Added Ball Track V1
In this version the balls bounce of the edges and do not interact with one another.
This commit is contained in:
parent
10a1275a52
commit
04d17e4839
@ -2528,7 +2528,13 @@ typedef struct Ball {
|
|||||||
float impactVelocity;
|
float impactVelocity;
|
||||||
float height;
|
float height;
|
||||||
} ball;
|
} ball;
|
||||||
|
// modified for balltrack mode
|
||||||
|
typedef struct Ballt {
|
||||||
|
unsigned long lastBounceUpdate;
|
||||||
|
float mass; // could fix this to be = 1. if memory is an issue
|
||||||
|
float velocity;
|
||||||
|
float height;
|
||||||
|
} ballt;
|
||||||
/*
|
/*
|
||||||
* Bouncing Balls Effect
|
* Bouncing Balls Effect
|
||||||
*/
|
*/
|
||||||
@ -2540,7 +2546,7 @@ uint16_t WS2812FX::mode_bouncing_balls(void) {
|
|||||||
|
|
||||||
Ball* balls = reinterpret_cast<Ball*>(SEGENV.data);
|
Ball* balls = reinterpret_cast<Ball*>(SEGENV.data);
|
||||||
|
|
||||||
// number of balls based on intensity setting to max of 7 (cycles colors)
|
// number of balls based on intensity setting to max of 16 (cycles colors)
|
||||||
// non-chosen color is a random color
|
// non-chosen color is a random color
|
||||||
uint8_t numBalls = int(((SEGMENT.intensity * (maxNumBalls - 0.8f)) / 255) + 1);
|
uint8_t numBalls = int(((SEGMENT.intensity * (maxNumBalls - 0.8f)) / 255) + 1);
|
||||||
|
|
||||||
@ -2585,6 +2591,70 @@ uint16_t WS2812FX::mode_bouncing_balls(void) {
|
|||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* bouncing balls on a track track Effect modified from Air Cookie's bouncing balls
|
||||||
|
*/
|
||||||
|
uint16_t WS2812FX::mode_balltrack(void) {
|
||||||
|
//allocate segment data
|
||||||
|
uint16_t maxNumBalls = 16;
|
||||||
|
uint16_t dataSize = sizeof(ballt) * maxNumBalls;
|
||||||
|
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||||
|
|
||||||
|
Ballt* balls = reinterpret_cast<Ballt*>(SEGENV.data);
|
||||||
|
|
||||||
|
// number of balls based on intensity setting to max of 16 (cycles colors)
|
||||||
|
// non-chosen color is a random color
|
||||||
|
uint8_t numBalls = int(((SEGMENT.intensity * (maxNumBalls - 0.8f)) / 255) + 1);
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long time = millis();
|
||||||
|
|
||||||
|
if (SEGENV.call == 0) {
|
||||||
|
for (uint8_t i = 0; i < maxNumBalls; i++) {
|
||||||
|
balls[i].lastBounceUpdate = time;
|
||||||
|
balls[i].velocity = 0;
|
||||||
|
while(abs(balls[i].velocity)<.5){
|
||||||
|
balls[i].velocity=10.*(-.5-float(random16(0, 10000)) / 10000.0); // from -5. to 5. note that sqt(2*9.8)= 4.4 max speed in bouncing ball mode
|
||||||
|
}
|
||||||
|
balls[i].height=(float(random16(0, 10000)) / 10000.0); // from 0. to 1.
|
||||||
|
balls[i].mass=(float(random16(5000, 10000)) / 10000.0); // from .5 to 1.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasCol2 = SEGCOLOR(2);
|
||||||
|
fill(hasCol2 ? BLACK : SEGCOLOR(1));
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < numBalls; i++) {
|
||||||
|
if(abs(balls[i].velocity)<.5) { // then I am guessing we have a new ball
|
||||||
|
balls[i].lastBounceUpdate = time;
|
||||||
|
balls[i].velocity = 0;
|
||||||
|
while(abs(balls[i].velocity)<.5){
|
||||||
|
balls[i].velocity=10.*(-.5-float(random16(0, 10000)) / 10000.0); // from -5. to 5. note that sqt(2*9.8)= 4.4 max speed in bouncing ball mode
|
||||||
|
}
|
||||||
|
balls[i].height=(float(random16(0, 10000)) / 10000.0); // from 0. to 1.
|
||||||
|
balls[i].mass=(float(random16(5000, 10000)) / 10000.0); // from .5 to 1.
|
||||||
|
}
|
||||||
|
|
||||||
|
float timeSinceLastUpdate = (time - balls[i].lastBounceUpdate)/((255-SEGMENT.speed)*8/256 +1); //uses Air Cookie conversion
|
||||||
|
balls[i].height += balls[i].velocity * timeSinceLastUpdate/1000/10;
|
||||||
|
|
||||||
|
if (balls[i].height < 0. && balls[i].velocity<0) balls[i].velocity=-balls[i].velocity; //reverse velocity
|
||||||
|
if (balls[i].height > 1. && balls[i].velocity>0) balls[i].velocity=-balls[i].velocity; // reverse velocity
|
||||||
|
balls[i].lastBounceUpdate = time;
|
||||||
|
|
||||||
|
uint32_t color = SEGCOLOR(0);
|
||||||
|
if (SEGMENT.palette) {
|
||||||
|
color = color_wheel(i*(256/MAX(numBalls, 8)));
|
||||||
|
} else if (hasCol2) {
|
||||||
|
color = SEGCOLOR(i % NUM_COLORS);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t pos = round(balls[i].height * (SEGLEN - 1));
|
||||||
|
setPixelColor(pos, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
11
wled00/FX.h
11
wled00/FX.h
@ -98,7 +98,7 @@
|
|||||||
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
||||||
#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED )
|
#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED )
|
||||||
|
|
||||||
#define MODE_COUNT 112
|
#define MODE_COUNT 113
|
||||||
|
|
||||||
#define FX_MODE_STATIC 0
|
#define FX_MODE_STATIC 0
|
||||||
#define FX_MODE_BLINK 1
|
#define FX_MODE_BLINK 1
|
||||||
@ -212,7 +212,7 @@
|
|||||||
#define FX_MODE_PHASEDNOISE 109
|
#define FX_MODE_PHASEDNOISE 109
|
||||||
#define FX_MODE_FLOW 110
|
#define FX_MODE_FLOW 110
|
||||||
#define FX_MODE_CHUNCHUN 111
|
#define FX_MODE_CHUNCHUN 111
|
||||||
|
#define FX_MODE_BALLTRACK 112
|
||||||
class WS2812FX {
|
class WS2812FX {
|
||||||
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
||||||
|
|
||||||
@ -412,7 +412,7 @@ class WS2812FX {
|
|||||||
_mode[FX_MODE_PHASEDNOISE] = &WS2812FX::mode_phased_noise;
|
_mode[FX_MODE_PHASEDNOISE] = &WS2812FX::mode_phased_noise;
|
||||||
_mode[FX_MODE_FLOW] = &WS2812FX::mode_flow;
|
_mode[FX_MODE_FLOW] = &WS2812FX::mode_flow;
|
||||||
_mode[FX_MODE_CHUNCHUN] = &WS2812FX::mode_chunchun;
|
_mode[FX_MODE_CHUNCHUN] = &WS2812FX::mode_chunchun;
|
||||||
|
_mode[FX_MODE_BALLTRACK] = &WS2812FX::mode_balltrack;
|
||||||
_brightness = DEFAULT_BRIGHTNESS;
|
_brightness = DEFAULT_BRIGHTNESS;
|
||||||
currentPalette = CRGBPalette16(CRGB::Black);
|
currentPalette = CRGBPalette16(CRGB::Black);
|
||||||
targetPalette = CloudColors_p;
|
targetPalette = CloudColors_p;
|
||||||
@ -607,7 +607,8 @@ class WS2812FX {
|
|||||||
mode_sinewave(void),
|
mode_sinewave(void),
|
||||||
mode_phased_noise(void),
|
mode_phased_noise(void),
|
||||||
mode_flow(void),
|
mode_flow(void),
|
||||||
mode_chunchun(void);
|
mode_chunchun(void),
|
||||||
|
mode_balltrack(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoPixelWrapper *bus;
|
NeoPixelWrapper *bus;
|
||||||
@ -695,7 +696,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([
|
|||||||
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
|
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
|
||||||
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow",
|
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow",
|
||||||
"Heartbeat","Pacifica","Candle Multi", "Solid Glitter","Sunrise","Phased","Twinkleup","Noise Pal", "Sine","Phased Noise",
|
"Heartbeat","Pacifica","Candle Multi", "Solid Glitter","Sunrise","Phased","Twinkleup","Noise Pal", "Sine","Phased Noise",
|
||||||
"Flow","Chunchun"
|
"Flow","Chunchun","Ball Track"
|
||||||
])=====";
|
])=====";
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user