From: Ben Morrow Date: Sun, 24 Nov 2013 02:03:40 +0000 (-0800) Subject: Merge branch 'master' of github.com:sugarcubes/SugarCubes X-Git-Url: https://git.piment-noir.org/?p=SugarCubes.git;a=commitdiff_plain;h=cc99cc31a31086ea874ab48c73cd6929200370ba;hp=6a4882ddc3c9219b599940168d7d83aa931cacd9 Merge branch 'master' of github.com:sugarcubes/SugarCubes --- diff --git a/JackStahl.pde b/JackStahl.pde index 862558c..4299543 100644 --- a/JackStahl.pde +++ b/JackStahl.pde @@ -10,61 +10,70 @@ class Swim extends SCPattern { // Projection stuff private final LXProjection projection; - SawLFO rotation = new SawLFO(0, TWO_PI, 19000); - SinLFO yPos = new SinLFO(-25, 25, 12323); - final BasicParameter xAngle = new BasicParameter("XANG", 0.9); - final BasicParameter yAngle = new BasicParameter("YANG", 0.3); - final BasicParameter zAngle = new BasicParameter("ZANG", 0.3); + SinLFO rotationX = new SinLFO(-PI/16, PI/8, 9000); + SinLFO rotationY = new SinLFO(-PI/8, PI/8, 7000); + SinLFO rotationZ = new SinLFO(-PI/8, PI/16, 11000); + SinLFO yPos = new SinLFO(-1, 1, 13234); + SinLFO sineHeight = new SinLFO(1, 2.5, 13234); + SawLFO phaseLFO = new SawLFO(0, 2 * PI, 15000 - 13000 * 0.5); + final BasicParameter phaseParam = new BasicParameter("Spd", 0.5); + final BasicParameter crazyParam = new BasicParameter("Crzy", 0.5); final BasicParameter hueScale = new BasicParameter("HUE", 0.3); public Swim(GLucose glucose) { super(glucose); projection = new LXProjection(model); - - addParameter(xAngle); - addParameter(yAngle); - addParameter(zAngle); addParameter(hueScale); + addParameter(crazyParam); + addParameter(phaseParam); - addModulator(rotation).trigger(); + addModulator(rotationX).trigger(); + addModulator(rotationY).trigger(); + addModulator(rotationZ).trigger(); addModulator(yPos).trigger(); + addModulator(phaseLFO).trigger(); + } + + public void onParameterChanged(LXParameter parameter) { + if (parameter == phaseParam) { + phaseLFO.setDuration(5000 - 4500 * parameter.getValuef()); + } } - int beat = 0; float prevRamp = 0; void run(double deltaMs) { - // Sync to the beat - float ramp = (float)lx.tempo.ramp(); - if (ramp < prevRamp) { - beat = (beat + 1) % 4; - } - prevRamp = ramp; - float phase = (beat+ramp) / 2.0 * 2 * PI; - - float denominator = max(xAngle.getValuef() + yAngle.getValuef() + zAngle.getValuef(), 1); + float phase = phaseLFO.getValuef(); + + float up_down_range = (model.yMax - model.yMin) / 4; + // Swim around the world + float crazy_factor = crazyParam.getValuef() / 0.2; projection.reset() - // Swim around the world - .rotate(rotation.getValuef(), xAngle.getValuef() / denominator, yAngle.getValuef() / denominator, zAngle.getValuef() / denominator) - .translateCenter(0, 50 + yPos.getValuef(), 0); + .rotate(rotationZ.getValuef() * crazy_factor, 0, 1, 0) + .rotate(rotationX.getValuef() * crazy_factor, 0, 0, 1) + .rotate(rotationY.getValuef() * crazy_factor, 0, 1, 0) + .translate(0, up_down_range * yPos.getValuef(), 0); + float model_height = model.yMax - model.yMin; float model_width = model.xMax - model.xMin; for (LXVector p : projection) { float x_percentage = (p.x - model.xMin)/model_width; - // Multiply by 1.4 to shrink the size of the sin wave to be less than the height of the cubes. - float y_in_range = 1.4 * (2*p.y - model.yMax - model.yMin) / model_height; + // Multiply by sineHeight to shrink the size of the sin wave to be less than the height of the cubes. + float y_in_range = sineHeight.getValuef() * (2*p.y - model.yMax - model.yMin) / model_height; float sin_x = sin(phase + 2 * PI * x_percentage); - // Color fade near the top of the sin wave - float v1 = sin_x > y_in_range ? (100 + 100*(y_in_range - sin_x)) : 0; + float size_of_sin_wave = 0.4; + + float v1 = (abs(y_in_range - sin_x) > size_of_sin_wave) ? 0 : abs((y_in_range - sin_x + size_of_sin_wave) / size_of_sin_wave / 2 * 100); + float hue_color = (lx.getBaseHuef() + hueScale.getValuef() * (abs(p.x-model.xMax/2.)*.3 + abs(p.y-model.yMax/2)*.9 + abs(p.z - model.zMax/2.))) % 360; - colors[p.index] = lx.hsb(hue_color, 70, v1); + colors[p.index] = lx.hsb(hue_color, 100, v1); } } } diff --git a/SugarCubes.pde b/SugarCubes.pde index 7bb9e11..389700d 100644 --- a/SugarCubes.pde +++ b/SugarCubes.pde @@ -25,8 +25,8 @@ LXPattern[] patterns(GLucose glucose) { return new LXPattern[] { - - new SineSphere(glucose), + + new SineSphere(glucose), //new CubeCurl(glucose), // Slee @@ -60,12 +60,15 @@ LXPattern[] patterns(GLucose glucose) { // Alex G // Tim + new TimMetronome(glucose), new TimPlanes(glucose), new TimPinwheels(glucose), new TimRaindrops(glucose), new TimCubes(glucose), // new TimTrace(glucose), new TimSpheres(glucose), + + // Jackie new JackieSquares(glucose), @@ -73,6 +76,9 @@ LXPattern[] patterns(GLucose glucose) { new JackieDots(glucose), + + // Vincent + new VSTowers(glucose), // Toby new GlitchPlasma(glucose), diff --git a/TimBavaro.pde b/TimBavaro.pde index 5ed805b..3fcd5b1 100644 --- a/TimBavaro.pde +++ b/TimBavaro.pde @@ -3,8 +3,9 @@ */ class TimSpheres extends SCPattern { private BasicParameter hueParameter = new BasicParameter("RAD", 1.0); + private BasicParameter periodParameter = new BasicParameter("PERIOD", 4000.0, 200.0, 10000.0); private final SawLFO lfo = new SawLFO(0, 1, 10000); - private final SinLFO sinLfo = new SinLFO(0, 1, 4000); + private final SinLFO sinLfo = new SinLFO(0, 1, periodParameter); private final float centerX, centerY, centerZ; class Sphere { @@ -18,6 +19,7 @@ class TimSpheres extends SCPattern { public TimSpheres(GLucose glucose) { super(glucose); addParameter(hueParameter); + addParameter(periodParameter); addModulator(lfo).trigger(); addModulator(sinLfo).trigger(); centerX = (model.xMax + model.xMin) / 2; @@ -828,3 +830,72 @@ class TimTrace extends SCPattern { } } } + +class TimMetronome extends SCPattern { + private BasicParameter clickyParameter = new BasicParameter("CLICK", 0, 0, 10.0); + private BasicParameter derezParameter = new BasicParameter("DREZ", 0.5, 0, 1.0); + private BasicParameter driftParameter = new BasicParameter("DRIFT", 0, 0, 1.0); + private BasicParameter fadeParameter = new BasicParameter("FADE", 0.05, 0, 0.2); + private float modelWidth; + private int beatNum; + private float prevTempoRamp; + private LXProjection projection; + private float[] values; + private float[] hues; + + TimMetronome(GLucose glucose) { + super(glucose); + addParameter(clickyParameter); + addParameter(derezParameter); + addParameter(driftParameter); + addParameter(fadeParameter); + modelWidth = model.xMax - model.xMin; + projection = new LXProjection(model); + beatNum = 0; + prevTempoRamp = 0; + values = new float[model.points.size()]; + hues = new float[model.points.size()]; + } + + public void run(double deltaMs) { + float tempoRamp = lx.tempo.rampf(); + if (tempoRamp < prevTempoRamp) { + beatNum = (beatNum + 1) % 1000; + } + prevTempoRamp = tempoRamp; + + float phase = beatNum + pow(tempoRamp, 1.0 + clickyParameter.getValuef()); + + projection.reset(); + projection.translateCenter(model.xMin, model.yMin, model.cz); + projection.rotate(phase * 0.5 * PI, 0, 0, 1); + + projection.translate(driftParameter.getValuef() * tempoRamp * modelWidth * 0.5, 0, 0); + + float derezCutoff = derezParameter.getValuef(); + + float fadeMultiplier = (1.0 - fadeParameter.getValuef()); + + float armRadius = modelWidth * 0.1; + for (LXVector p : projection) { + boolean onArm = false; + if (abs(p.x) < armRadius) { + onArm = (p.y > 0) || (sqrt(pow(p.x, 2) + pow(p.y, 2)) < armRadius); + } + if (onArm) { + values[p.index] = 1.0; + hues[p.index] = (floor(phase / 4) * 90) % 360; + } else { + values[p.index] *= fadeMultiplier; + } + + float saturation = pow(1 - values[p.index], 0.5) * 0.7 + 0.3; + float brightness = values[p.index]; + + if (random(1.0) > derezCutoff) { + colors[p.index] = lx.hsb(hues[p.index], saturation * 100, brightness * 100); + } + } + } +} + diff --git a/VincentSiao.pde b/VincentSiao.pde new file mode 100644 index 0000000..48a368e --- /dev/null +++ b/VincentSiao.pde @@ -0,0 +1,119 @@ +class VSTowers extends SCPattern { + private BasicParameter saturationParameter = new BasicParameter("SAT", 80, 0, 100); + private BasicParameter attackParameter = new BasicParameter("ATTK", 0.96, 0.1, 1.0); + private BasicParameter decayParameter = new BasicParameter("DECAY", 0.7, 0.1, 1.0); + private SawLFO hueLfo = new SawLFO(0, 360, 20000); + + private Map towerOn; + + class TowerFlash { + Tower t; + float value; + float maxVal; + float hue; + boolean hasPeaked; + + TowerFlash() { + do { + t = model.towers.get(floor(random(model.towers.size()))); + } while (towerOn.get(t)); + towerOn.put(t, true); + hue = (hueLfo.getValuef() + 50*(random(2)-1.0f)) % 360; + value = 0.0; + maxVal = random(0.4) + 0.6; + } + + boolean run(double deltaMs) { + if (!hasPeaked) { + float atk = attackParameter.getValuef(); + float atkDuration = 10000 * (1/sqrt(atk) - 1.0f); + value = value + (float)deltaMs / atkDuration; + if (value >= maxVal) { + value = maxVal; + hasPeaked = true; + } + return false; + } else { + float dec = decayParameter.getValuef(); + float decDuration = 10000 * (1/sqrt(dec) - 1.0f); + value = value - (float)deltaMs / decDuration; + return value <= 0; + } + } + } + + public VSTowers(GLucose glucose) { + super(glucose); + addParameter(saturationParameter); + addParameter(attackParameter); + addParameter(decayParameter); + addModulator(hueLfo).trigger(); + flashes = new LinkedList(); + towerOn = new HashMap(); + for (Tower t : model.towers) { + towerOn.put(t, false); + } + } + + private List flashes; + private float accDelta = 0; + + public void run(double deltaMs) { + accDelta += deltaMs; + float rate = lx.tempo.rampf(); + float msPerFlash = 5000 * (1/sqrt(rate) - 1.0f); + if (accDelta >= msPerFlash) { + accDelta -= msPerFlash; + if (flashes.size() < model.towers.size()) { + flashes.add(new TowerFlash()); + } + } + for (LXPoint p : model.points) { + if (random(1) < 0.2) { + colors[p.index] = 0; + } + } + for (TowerFlash tf : flashes) { + for (LXPoint p : tf.t.points) { + float towerHeight = model.yMin + tf.value * (model.yMax - model.yMin); + if (p.y <= towerHeight) { + colors[p.index] = lx.hsb( + (tf.hue + tf.value*50 - p.y/2) % 360, + saturationParameter.getValuef(), + tf.value*100); + } + } + if (tf.hasPeaked) { + float towerMaxHeight = model.yMin + tf.maxVal * (model.yMax - model.yMin); + Cube top = tf.t.cubes.get(tf.t.cubes.size()-1); + for (int i = tf.t.cubes.size()-1; i >= 0; --i) { + Cube c = tf.t.cubes.get(i); + float maxY = c.points.get(0).y; + for (LXPoint p : c.points) { + maxY = max(maxY, p.y); + } + if (towerMaxHeight < maxY) { + top = c; + } + } + for (LXPoint p : top.points) { + if (tf.value > 0.5) { + colors[p.index] = lx.hsb(0, 0, tf.value*100); + } else if (random(1) < 0.2) { + colors[p.index] = 0; + } + } + } + } + // Run flashes and remove completed ones + Iterator it = flashes.iterator(); + while (it.hasNext()) { + TowerFlash flash = it.next(); + if (flash.run(deltaMs)) { + towerOn.put(flash.t, false); + it.remove(); + } + } + } +} +