diff --git a/particles.lua b/particles.lua new file mode 100644 index 0000000..292f3d4 --- /dev/null +++ b/particles.lua @@ -0,0 +1,146 @@ +COOLDOWN_FACTOR = 0.9998 +MAX_ENERGY_PROPAGATION = 0.5 +EXPONENT=1.3 +W_EXPONENT=1.8 +OVERDRIVE=1 +FADE_FACTOR = 0.94 +AVG_LEDS_ACTIVATED = 0.03 + +num_modules = 1 +num_strips = 1 + +-- maximum energy values for each band +maxRedEnergy = 1 +maxGreenEnergy = 1 +maxBlueEnergy = 1 +maxWhiteEnergy = 1 + +-- array storing the flameā€™s energy for each pixel +fireRedEnergy = {} +fireGreenEnergy = {} +fireBlueEnergy = {} +fireWhiteEnergy = {} + +-- output color buffers +red = {} +green = {} +blue = {} +white = {} + +function limit(val) + if val > 1 then + return 1 + elseif val < 0 then + return 0 + else + return val + end +end + +function fade2black(energyArray) + for s = 1,num_strips do + for m = 1,num_modules do + i = idx(s, m) + + energyArray[i] = energyArray[i] * FADE_FACTOR + end + end +end + +function distributeEnergy(newEnergy, energyArray) + remainingEnergy = AVG_LEDS_ACTIVATED * newEnergy * num_modules * num_strips + + while remainingEnergy > 0 do + rndEnergy = math.random() * newEnergy * 2 + rndStrip = math.floor(math.random() * num_strips) + rndModule = math.floor(math.random() * num_modules) + + if rndEnergy > remainingEnergy then + rndEnergy = remainingEnergy + remainingEnergy = 0 + else + remainingEnergy = remainingEnergy - rndEnergy + end + + i = idx(rndStrip+1, rndModule+1) + energyArray[i] = energyArray[i] + rndEnergy + end +end + +function periodic() + local redEnergy = get_energy_in_band(0, 400); + local greenEnergy = get_energy_in_band(400, 4000); + local blueEnergy = get_energy_in_band(4000, 12000); + local whiteEnergy = get_energy_in_band(12000, 22000); + + maxRedEnergy = maxRedEnergy * COOLDOWN_FACTOR + if redEnergy > maxRedEnergy then + maxRedEnergy = redEnergy + end + + maxGreenEnergy = maxGreenEnergy * COOLDOWN_FACTOR + if greenEnergy > maxGreenEnergy then + maxGreenEnergy = greenEnergy + end + + maxBlueEnergy = maxBlueEnergy * COOLDOWN_FACTOR + if blueEnergy > maxBlueEnergy then + maxBlueEnergy = blueEnergy + end + + maxWhiteEnergy = maxWhiteEnergy * COOLDOWN_FACTOR + if whiteEnergy > maxWhiteEnergy then + maxWhiteEnergy = whiteEnergy + end + + fade2black(fireRedEnergy) + fade2black(fireGreenEnergy) + fade2black(fireBlueEnergy) + fade2black(fireWhiteEnergy) + + distributeEnergy(redEnergy / maxRedEnergy, fireRedEnergy) + distributeEnergy(greenEnergy / maxGreenEnergy, fireGreenEnergy) + distributeEnergy(blueEnergy / maxBlueEnergy, fireBlueEnergy) + distributeEnergy(whiteEnergy / maxWhiteEnergy, fireWhiteEnergy) + + -- make colors more exciting + remove the first (flickering) mass + -- TODO: update + for m = 1,num_modules do + for s = 1,num_strips do + i = idx(s, m) + + rval = limit(OVERDRIVE * fireRedEnergy[i]^EXPONENT) + gval = limit(OVERDRIVE * fireGreenEnergy[i]^EXPONENT) + bval = limit(OVERDRIVE * fireBlueEnergy[i]^EXPONENT) + wval = limit(OVERDRIVE * fireWhiteEnergy[i]^W_EXPONENT) + + red[i] = rval + green[i] = gval + blue[i] = bval + white[i] = wval + end + end + + -- return the 4 color arrays + return red, green, blue, white +end + +function init(nstrip, nmod, cmod) + num_strips = nstrip + num_modules = nmod + + for i = 1,(nmod*nstrip) do + red[i] = 0 + green[i] = 0 + blue[i] = 0 + white[i] = 0 + + fireRedEnergy[i] = 0 + fireGreenEnergy[i] = 0 + fireBlueEnergy[i] = 0 + fireWhiteEnergy[i] = 0 + end + + -- don't use fading + return 0 +end