Adding 2 ball track modes

With and without collisions
This commit is contained in:
pjhatch 2020-07-12 08:33:48 -05:00
parent 341d9d1697
commit a20358b61b
3 changed files with 28 additions and 16 deletions

View File

@ -2528,13 +2528,6 @@ 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
*/ */
@ -2594,7 +2587,15 @@ uint16_t WS2812FX::mode_bouncing_balls(void) {
/* /*
* bouncing balls on a track track Effect modified from Air Cookie's bouncing balls * bouncing balls on a track track Effect modified from Air Cookie's bouncing balls
*/ */
uint16_t WS2812FX::mode_balltrack(void) { // 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;
uint16_t WS2812FX::ball_track(bool collide) {
//allocate segment data //allocate segment data
uint16_t maxNumBalls = 16; uint16_t maxNumBalls = 16;
uint16_t dataSize = sizeof(ballt) * maxNumBalls; uint16_t dataSize = sizeof(ballt) * maxNumBalls;
@ -2641,8 +2642,7 @@ uint16_t WS2812FX::mode_balltrack(void) {
balls[i].height=thisHeight; balls[i].height=thisHeight;
} }
// check for collisions // check for collisions
bool docol=true; if(collide){
if(docol){
for(uint8_t j= i+1; j < numBalls; j++){ for(uint8_t j= i+1; j < numBalls; j++){
if(balls[j].velocity != balls[i].velocity) { if(balls[j].velocity != balls[i].velocity) {
// tcollided + balls[j].lastBounceUpdate is acutal time of collision (this keeps precision with long to float conversions) // tcollided + balls[j].lastBounceUpdate is acutal time of collision (this keeps precision with long to float conversions)
@ -2650,14 +2650,14 @@ uint16_t WS2812FX::mode_balltrack(void) {
balls[i].velocity*float(balls[j].lastBounceUpdate-balls[i].lastBounceUpdate))/ balls[i].velocity*float(balls[j].lastBounceUpdate-balls[i].lastBounceUpdate))/
(balls[j].velocity-balls[i].velocity); (balls[j].velocity-balls[i].velocity);
if( (tcollided>2)&&(tcollided<float(time-balls[j].lastBounceUpdate))){ // 2ms minimum to avoid duplicate bounces if( (tcollided>2)&&(tcollided<float(time-balls[j].lastBounceUpdate))){ // 2ms minimum to avoid duplicate bounces
balls[i].height=balls[i].height + balls[i].velocity*(tcollided+float(balls[j].lastBounceUpdate-balls[i].lastBounceUpdate))/cfac; balls[i].height=balls[i].height + balls[i].velocity*(tcollided+float(balls[j].lastBounceUpdate-balls[i].lastBounceUpdate))/cfac;
balls[j].height=balls[i].height; balls[j].height=balls[i].height;
balls[i].lastBounceUpdate=(unsigned long)(tcollided+.5)+balls[j].lastBounceUpdate; balls[i].lastBounceUpdate=(unsigned long)(tcollided+.5)+balls[j].lastBounceUpdate;
balls[j].lastBounceUpdate=balls[i].lastBounceUpdate; balls[j].lastBounceUpdate=balls[i].lastBounceUpdate;
float vtmp=balls[i].velocity; float vtmp=balls[i].velocity;
balls[i].velocity=((balls[i].mass-balls[j].mass)*vtmp + 2.*balls[j].mass*balls[j].velocity)/(balls[i].mass+balls[j].mass); balls[i].velocity=((balls[i].mass-balls[j].mass)*vtmp + 2.*balls[j].mass*balls[j].velocity)/(balls[i].mass+balls[j].mass);
balls[j].velocity=((balls[j].mass-balls[i].mass)*balls[j].velocity + 2.*balls[i].mass*vtmp) /(balls[i].mass+balls[j].mass); balls[j].velocity=((balls[j].mass-balls[i].mass)*balls[j].velocity + 2.*balls[i].mass*vtmp) /(balls[i].mass+balls[j].mass);
//balls[i].height=balls[i].height + balls[i].velocity*(time-balls[i].lastBounceUpdate)/cfac; //balls[i].height=balls[i].height + balls[i].velocity*(time-balls[i].lastBounceUpdate)/cfac;
thisHeight= balls[i].height + balls[i].velocity*(time-balls[i].lastBounceUpdate)/cfac; thisHeight= balls[i].height + balls[i].velocity*(time-balls[i].lastBounceUpdate)/cfac;
} }
@ -2683,6 +2683,13 @@ uint16_t WS2812FX::mode_balltrack(void) {
return FRAMETIME; return FRAMETIME;
} }
uint16_t WS2812FX::mode_balltrack(void) {
return ball_track(false);
}
uint16_t WS2812FX::mode_balltrack_collide(void) {
return ball_track(true);
}
/* /*
* Sinelon stolen from FASTLED examples * Sinelon stolen from FASTLED examples

View File

@ -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 113 #define MODE_COUNT 114
#define FX_MODE_STATIC 0 #define FX_MODE_STATIC 0
#define FX_MODE_BLINK 1 #define FX_MODE_BLINK 1
@ -213,6 +213,7 @@
#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 #define FX_MODE_BALLTRACK 112
#define FX_MODE_BALLTRACK_COLLIDE 113
class WS2812FX { class WS2812FX {
typedef uint16_t (WS2812FX::*mode_ptr)(void); typedef uint16_t (WS2812FX::*mode_ptr)(void);
@ -413,6 +414,7 @@ class WS2812FX {
_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; _mode[FX_MODE_BALLTRACK] = &WS2812FX::mode_balltrack;
_mode[FX_MODE_BALLTRACK_COLLIDE] = &WS2812FX::mode_balltrack_collide;
_brightness = DEFAULT_BRIGHTNESS; _brightness = DEFAULT_BRIGHTNESS;
currentPalette = CRGBPalette16(CRGB::Black); currentPalette = CRGBPalette16(CRGB::Black);
targetPalette = CloudColors_p; targetPalette = CloudColors_p;
@ -608,7 +610,8 @@ class WS2812FX {
mode_phased_noise(void), mode_phased_noise(void),
mode_flow(void), mode_flow(void),
mode_chunchun(void), mode_chunchun(void),
mode_balltrack(void); mode_balltrack(void),
mode_balltrack_collide(void);
private: private:
NeoPixelWrapper *bus; NeoPixelWrapper *bus;
@ -656,7 +659,8 @@ class WS2812FX {
tricolor_chase(uint32_t, uint32_t), tricolor_chase(uint32_t, uint32_t),
twinklefox_base(bool), twinklefox_base(bool),
spots_base(uint16_t), spots_base(uint16_t),
phased_base(uint8_t); phased_base(uint8_t),
ball_track(bool collide);
CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat); CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat);
CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff); CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff);
@ -696,7 +700,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","Ball Track" "Flow","Chunchun","Ball Track","Ball Track Collide"
])====="; ])=====";

View File

@ -1,3 +1,4 @@
/* /*
* WLED Arduino IDE compatibility file. * WLED Arduino IDE compatibility file.
* *