diff --git a/fire_dual.lua b/fire_dual.lua new file mode 100644 index 0000000..de714b1 --- /dev/null +++ b/fire_dual.lua @@ -0,0 +1,159 @@ +COOLDOWN_FACTOR = 0.9998 +MAX_ENERGY_PROPAGATION = 0.3 +RM_ENERGY=0.0200 +EXPONENT=1.5 +W_EXPONENT=2.2 +OVERDRIVE=1.5 + +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 updateFire(newEnergy, energyArray) + avgEnergyPerStrip = newEnergy + + for s = 1,num_strips do + -- Add new energy in the center rows + i = idx(s, num_modules/2) + energyArray[i] = energyArray[i] + math.random() * avgEnergyPerStrip + i = idx(s, num_modules/2+1) + energyArray[i] = energyArray[i] + math.random() * avgEnergyPerStrip + + -- remove energy at the top and the bottom + i = idx(s, num_modules) + energyArray[i] = energyArray[i] * (1.0 - math.random() * MAX_ENERGY_PROPAGATION) + i = idx(s, 1) + energyArray[i] = energyArray[i] * (1.0 - math.random() * MAX_ENERGY_PROPAGATION) + + -- move energy upwards + for m_out = num_modules,num_modules/2+2,-1 do + i_out = idx(s, m_out) + i_in = idx(s, m_out - 1) + + energyMoved = energyArray[i_in] * math.random() * MAX_ENERGY_PROPAGATION + + energyArray[i_in] = energyArray[i_in] - energyMoved + energyArray[i_out] = energyArray[i_out] + energyMoved + end + + -- move energy downwards + for m_out = 1,num_modules/2-1,1 do + i_out = idx(s, m_out) + i_in = idx(s, m_out + 1) + + energyMoved = energyArray[i_in] * math.random() * MAX_ENERGY_PROPAGATION + + energyArray[i_in] = energyArray[i_in] - energyMoved + energyArray[i_out] = energyArray[i_out] + energyMoved + end + + -- globally remove energy + for m = 1,num_modules do + i = idx(s, m) + if energyArray[i] > RM_ENERGY then + energyArray[i] = energyArray[i] - RM_ENERGY + else + energyArray[i] = 0 + end + end + 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 + + updateFire((redEnergy / maxRedEnergy)^EXPONENT, fireRedEnergy) + updateFire((greenEnergy / maxGreenEnergy)^EXPONENT, fireGreenEnergy) + updateFire((blueEnergy / maxBlueEnergy)^EXPONENT, fireBlueEnergy) + updateFire((whiteEnergy / maxWhiteEnergy)^W_EXPONENT, fireWhiteEnergy) + + -- make colors more exciting + remove the first (flickering) mass + for m = 1,num_modules do + for s = 1,num_strips do + i = idx(s, m) + + rval = limit(OVERDRIVE * (fireRedEnergy[i])) + gval = limit(OVERDRIVE * (fireGreenEnergy[i])) + bval = limit(OVERDRIVE * (fireBlueEnergy[i])) + wval = limit(OVERDRIVE * (fireWhiteEnergy[i])) + + 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 diff --git a/sparkler_energycontrolled.lua b/sparkler_energycontrolled.lua index fc055c0..85c0b12 100644 --- a/sparkler_energycontrolled.lua +++ b/sparkler_energycontrolled.lua @@ -8,7 +8,7 @@ OVERDRIVE=1.5 num_modules = 1 num_strips = 1 -max_new_energy_per_strip = 2*RM_ENERGY * num_modules +max_new_energy_per_strip = 2.00*RM_ENERGY * num_modules -- warning: these must also be updated in init() max_target_energy = num_strips * num_modules @@ -69,7 +69,7 @@ function updateFire(targetEnergy, energyArray, momentum) else avgEnergyPerStrip = 0 - momentum = momentum - 2 + momentum = momentum - 1 if momentum < 0 then momentum = 0 @@ -125,6 +125,20 @@ function updateFire(targetEnergy, energyArray, momentum) return momentum end +function fractionToEnergy(fract, max) + return math.sqrt(fract) * max + + --dB = 20*math.log(fract)/math.log(10) + + --result = max * (dB + 40) / 40 + + --if result > 0 then + -- return result + --else + -- return 0 + --end +end + function periodic() local redEnergy = get_energy_in_band(0, 400); local greenEnergy = get_energy_in_band(400, 4000); @@ -151,10 +165,10 @@ function periodic() maxWhiteEnergy = whiteEnergy end - redMomentum = updateFire((redEnergy / maxRedEnergy)^EXPONENT * max_target_energy, fireRedEnergy, redMomentum) - greenMomentum = updateFire((greenEnergy / maxGreenEnergy)^EXPONENT * max_target_energy, fireGreenEnergy, greenMomentum) - blueMomentum = updateFire((blueEnergy / maxBlueEnergy)^EXPONENT * max_target_energy, fireBlueEnergy, blueMomentum) - whiteMomentum = updateFire((whiteEnergy / maxWhiteEnergy)^W_EXPONENT * max_target_energy, fireWhiteEnergy, whiteMomentum) + redMomentum = updateFire(fractionToEnergy(redEnergy / maxRedEnergy, max_target_energy), fireRedEnergy, redMomentum) + greenMomentum = updateFire(fractionToEnergy(greenEnergy / maxGreenEnergy, max_target_energy), fireGreenEnergy, greenMomentum) + blueMomentum = updateFire(fractionToEnergy(blueEnergy / maxBlueEnergy, max_target_energy), fireBlueEnergy, blueMomentum) + whiteMomentum = updateFire(fractionToEnergy((whiteEnergy / maxWhiteEnergy)^W_EXPONENT, max_target_energy), fireWhiteEnergy, whiteMomentum) --updateFire(2 * max_target_energy, fireRedEnergy) --updateFire(0 * max_target_energy, fireGreenEnergy) @@ -188,7 +202,7 @@ function init(nstrip, nmod, cmod) max_new_energy_per_strip = num_modules * RM_ENERGY * 2 base_new_energy_per_strip = num_modules * RM_ENERGY * 0.1 - max_target_energy = num_strips * num_modules + max_target_energy = 0.2 * num_strips * num_modules for i = 1,(nmod*nstrip) do red[i] = 0