+++ /dev/null
-import processing.core.*;
-import processing.data.*;
-import processing.event.*;
-import processing.opengl.*;
-
-import netP5.*;
-import oscP5.*;
-import processing.serial.*;
-import java.util.LinkedHashMap;
-import toxi.geom.Vec3D;
-import toxi.geom.Matrix4x4;
-
-import heronarts.lx.font.*;
-import heronarts.lx.transition.*;
-import glucose.transform.*;
-import netP5.*;
-import heronarts.lx.pattern.*;
-import glucose.pattern.*;
-import heronarts.lx.model.*;
-import toxi.geom.mesh2d.*;
-import heronarts.lx.client.*;
-import glucose.*;
-import toxi.util.datatypes.*;
-import toxi.math.waves.*;
-import heronarts.lx.kinet.*;
-import oscP5.*;
-import toxi.geom.*;
-import toxi.util.events.*;
-import heronarts.lx.modulator.*;
-import rwmidi.*;
-import glucose.transition.*;
-import glucose.effect.*;
-import glucose.model.*;
-import toxi.math.conversion.*;
-import heronarts.lx.effect.*;
-import heronarts.lx.control.*;
-import glucose.control.*;
-import toxi.math.noise.*;
-import toxi.util.*;
-import heronarts.lx.*;
-import toxi.math.*;
-import heronarts.lx.audio.*;
-
-import java.util.HashMap;
-import java.util.ArrayList;
-import java.io.File;
-import java.io.BufferedReader;
-import java.io.PrintWriter;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.IOException;
-
-public class SugarCubes extends PApplet {
-
-/**
- * +-+-+-+-+-+ +-+-+-+-+-+
- * / /| |\ \
- * / / + + \ \
- * +-+-+-+-+-+ | +-+-+-+-+ | +-+-+-+-+-+
- * | | + / \ + | |
- * + THE + / / \ \ + CUBES +
- * | |/ +-+-+-+-+-+-+-+ \| |
- * +-+-+-+-+-+ | | +-+-+-+-+-+
- * + +
- * | SUGAR |
- * + +
- * | |
- * +-+-+-+-+-+-+-+
- *
- * Welcome to the Sugar Cubes! This Processing sketch is a fun place to build
- * animations, effects, and interactions for the platform. Most of the icky
- * code guts are embedded in the GLucose library extension. If you're an
- * artist, you shouldn't need to worry about any of that.
- *
- * Below, you will find definitions of the Patterns, Effects, and Interactions.
- * If you're an artist, create a new tab in the Processing environment with
- * your name. Implement your classes there, and add them to the list below.
- */
-
-public LXPattern[] patterns(GLucose glucose) {
- return new LXPattern[] {
-
-
- // Slee
- new Cathedrals(glucose),
- new MidiMusic(glucose),
- new Pulley(glucose),
- new Swarm(glucose),
- new ViolinWave(glucose),
- new BouncyBalls(glucose),
- new SpaceTime(glucose),
- new ShiftingPlane(glucose),
- new AskewPlanes(glucose),
- new Blinders(glucose),
- new CrossSections(glucose),
- new Psychedelia(glucose),
-
- new Traktor(glucose).setEligible(false),
- new BassPod(glucose).setEligible(false),
- new CubeEQ(glucose).setEligible(false),
- new PianoKeyPattern(glucose).setEligible(false),
-
- // DanH
- new Noise(glucose),
- new Play (glucose),
- new Pong (glucose),
- new Worms(glucose),
-
- // Alex G
- new SineSphere(glucose),
-// new CubeCurl(glucose),
-
- // Shaheen
- new HelixPattern(glucose).setEligible(false),
-
- // Toby
- new GlitchPlasma(glucose),
- new FireEffect(glucose).setEligible(false),
- new StripBounce(glucose),
- new SoundRain(glucose).setEligible(false),
- new SoundSpikes(glucose).setEligible(false),
- new FaceSync(glucose),
-
- // Jack
- new Swim(glucose),
- new Balance(glucose),
-
- // Tim
- new TimPlanes(glucose),
- new TimPinwheels(glucose),
- new TimRaindrops(glucose),
- new TimCubes(glucose),
- // new TimTrace(glucose),
- new TimSpheres(glucose),
-
- // Ben
- // new Sandbox(glucose),
- new TowerParams(glucose),
- new DriveableCrossSections(glucose),
- new GranimTestPattern2(glucose),
-
- //JR
- new Gimbal(glucose),
-
- // Sam
- new JazzRainbow(glucose),
-
- // Arjun
- new TelevisionStatic(glucose),
- new AbstractPainting(glucose),
- new Spirality(glucose),
-
- // Basic test patterns for reference, not art
- new TestCubePattern(glucose),
- new TestTowerPattern(glucose),
- new TestProjectionPattern(glucose),
- new TestStripPattern(glucose),
- new TestBassMapping(glucose),
- new TestFloorMapping(glucose),
- new TestSpeakerMapping(glucose),
- new TestPerformancePattern(glucose),
- // new TestHuePattern(glucose),
- // new TestXPattern(glucose),
- // new TestYPattern(glucose),
- // new TestZPattern(glucose),
-
- };
-}
-
-public LXTransition[] transitions(GLucose glucose) {
- return new LXTransition[] {
- new DissolveTransition(lx),
- new AddTransition(glucose),
- new MultiplyTransition(glucose),
- new OverlayTransition(glucose),
- new DodgeTransition(glucose),
- new SwipeTransition(glucose),
- new FadeTransition(lx),
-// new SubtractTransition(glucose), // similar to multiply - dh
-// new BurnTransition(glucose), // similar to multiply - dh
-// new ScreenTransition(glucose), // same as add -dh
-// new SoftLightTransition(glucose), // same as overlay -dh
- };
-}
-
-// Handles to globally triggerable effects
-class Effects {
- FlashEffect flash = new FlashEffect(lx);
- BoomEffect boom = new BoomEffect(glucose);
- BlurEffect blur = new BlurEffect(glucose);
- QuantizeEffect quantize = new QuantizeEffect(glucose);
- ColorFuckerEffect colorFucker = new ColorFuckerEffect(glucose);
-
- Effects() {
- blur.enable();
- quantize.enable();
- colorFucker.enable();
- }
-}
-
-class SineSphere extends SCPattern {
- private SinLFO yrot = new SinLFO(0, TWO_PI, 2000);
- public final Projection sinespin;
- float modelrad = sqrt((model.xMax)*(model.xMax) + (model.yMax)*(model.yMax) + (model.zMax)*(model.zMax));
- Pick Sshape;
-
- class Sphery {
- float f1xcenter, f1ycenter, f1zcenter, f2xcenter , f2ycenter, f2zcenter; //second three are for an ellipse with two foci
- private SinLFO vibration;
- private SinLFO surface;
- private SinLFO vx;
- private SinLFO xbounce;
- public SinLFO ybounce;
- private SinLFO zbounce;
- float vibration_min, vibration_max, vperiod;
- public BasicParameter widthparameter;
- public BasicParameter huespread;
- public BasicParameter bouncerate;
- public BasicParameter bounceamp;
-
-
-
- public Sphery(float f1xcenter, float f1ycenter, float f1zcenter, float vibration_min, float vibration_max, float vperiod)
- {
- this.f1xcenter = f1xcenter;
- this.f1ycenter = f1ycenter;
- this.f1zcenter = f1zcenter;
- this.vibration_min = vibration_min;
- this.vibration_max = vibration_max;
- this.vperiod = vperiod;
- addParameter(bounceamp = new BasicParameter("Amp", .5f));
- addParameter(bouncerate = new BasicParameter("Rate", .5f)); //ybounce.modulateDurationBy(bouncerate);
- addParameter(widthparameter = new BasicParameter("Width", .1f));
- addParameter(huespread = new BasicParameter("Hue", .2f));
-
- addModulator( vx = new SinLFO(-4000, 10000, 100000)).trigger() ;
- //addModulator(xbounce = new SinLFO(model.xMax/3, 2*model.yMax/3, 2000)).trigger();
- addModulator(ybounce= new SinLFO(model.yMax/3, 2*model.yMax/3, 240000.f/lx.tempo.bpm())).trigger(); //ybounce.modulateDurationBy
-
- //addModulator(bounceamp); //ybounce.setMagnitude(bouncerate);
- addModulator( vibration = new SinLFO(vibration_min , vibration_max, 240000.f/lx.tempo.bpm())).trigger(); //vibration.modulateDurationBy(vx);
-
- }
- public Sphery(float f1xcenter, float f1ycenter, float f1zcenter, float f2xcenter, float f2ycenter, float f2zcenter,
- float vibration_min, float vibration_max, float vperiod)
- {
- this.f1xcenter = f1xcenter;
- this.f1ycenter = f1ycenter;
- this.f1zcenter = f1zcenter;
- this.f2xcenter = f2xcenter;
- this.f2ycenter = f2ycenter;
- this.f2zcenter = f2zcenter;
- this.vibration_min = vibration_min;
- this.vibration_max = vibration_max;
- this.vperiod = vperiod;
- //addModulator(xbounce = new SinLFO(model.xMax/3, 2*model.yMax/3, 2000)).trigger();
- addModulator(ybounce).trigger();
- addModulator( vibration = new SinLFO(vibration_min , vibration_max, lx.tempo.rampf())).trigger(); //vibration.modulateDurationBy(vx);
- addParameter(widthparameter = new BasicParameter("Width", .1f));
- addParameter(huespread = new BasicParameter("Hue", .2f));
-
-}
-
-
-
-
-
-public float distfromcirclecenter(float px, float py, float pz, float f1x, float f1y, float f1z)
-{
- return dist(px, py, pz, f1x, f1y, f1z);
- }
- //void updatespherey(deltaMs, )
- public int spheryvalue (float px, float py, float pz , float f1xc, float f1yc, float f1zc)
- {
-//switch(sShpape.cur() ) {}
- return lx.hsb(constrain(huespread.getValuef()*5*px, 0, 360) , dist(px, py, pz, f1xc, f1yc, f1zc) ,
- max(0, 100 - 100*widthparameter.getValuef()*abs(dist(px, py, pz, f1xcenter, ybounce.getValuef(), f1zcenter)
- - vibration.getValuef() ) ) );
- }
- public int ellipsevalue(float px, float py, float pz , float f1xc, float f1yc, float f1zc, float f2xc, float f2yc, float f2zc)
- {
-//switch(sShpape.cur() ) {}
- return lx.hsb(huespread.getValuef()*5*px, dist(model.xMax-px, model.yMax-py, model.zMax-pz, f1xc, f1yc, f1zc) ,
- max(0, 100 - 100*widthparameter.getValuef() *
- abs( (dist(px, py, pz, f1xc, ybounce.getValuef(), f1zc) +
- (dist(px, py , pz, f2xc, ybounce.getValuef(), f2zc) ) )/2
- - 1.2f*vibration.getValuef() ) ) ) ;
- }
-
-public void run(double deltaMs) {
- float vv = vibration.getValuef();
- float ybv = ybounce.getValuef();
-
- }
-
-}
-
-
-final Sphery[] spherys;
- SineSphere(GLucose glucose)
- {
- super(glucose);
- sinespin = new Projection(model);
- addModulator(yrot).trigger();
- //Sshape = addPick("Shape", , 1);
- spherys = new Sphery[] {
- new Sphery(model.xMax/4, model.yMax/2, model.zMax/2, modelrad/16, modelrad/8, 3000),
- new Sphery(.75f*model.xMax, model.yMax/2, model.zMax/2, modelrad/20, modelrad/10, 2000),
- new Sphery(model.xMax/2, model.yMax/2, model.zMax/2, modelrad/4, modelrad/8, 2300),
- };
-
- }
-
-// public void onParameterChanged(LXParameter parameter)
-// {
-
-
-// for (Sphery s : spherys) {
-// if (s == null) continue;
-// double bampv = s.bounceamp.getValue();
-// double brv = s.bouncerate.getValue();
-// double tempobounce = lx.tempo.bpm();
-// if (parameter == s.bounceamp)
-// {
-// s.ybounce.setRange(bampv*model.yMax/3 , bampv*2*model.yMax/3, brv);
-// }
-// else if ( parameter == s.bouncerate )
-// {
-// s.ybounce.setDuration(120000./tempobounce);
-// }
-// }
-// }
-
- public void run( double deltaMs) {
- float t = lx.tempo.rampf();
- float bpm = lx.tempo.bpmf();
- //spherys[1].run(deltaMs);
- //spherys[2].run(deltaMs);
- //spherys[3].run(deltaMs);]
- sinespin.reset(model)
-
- // Translate so the center of the car is the origin, offset by yPos
- .translateCenter(model, 0, 0, 0)
-
- // Rotate around the origin (now the center of the car) about an X-vector
- .rotate(yrot.getValuef(), 0, 1, 0);
-
-
-
- for (Point p: model.points){
- int c = 0;
- c = blendColor(c, spherys[1].spheryvalue(p.x, p.y, p.z, .75f*model.xMax, model.yMax/2, model.zMax/2), ADD);
- c = blendColor(c, spherys[0].spheryvalue(p.x, p.y, p.z, model.xMax/4, model.yMax/4, model.zMax/2), ADD);
- c = blendColor(c, spherys[2].spheryvalue(p.x, p.y, p.z, model.xMax/2, model.yMax/2, model.zMax/2),ADD);
-
- colors[p.index] = lx.hsb(lx.h(c), lx.s(c), lx.b(c));
-
- }
-
-
-
- }
- int spheremode = 0;
-
- // void keyPressed() {
- // spheremode++;
- // }
-
- // color CalcPoint(PVector Px)
- // {
- // // if (spheremode == 0 )
- //{
-
- //}
- // else if (spheremode == 1)
- // {
-
- // color c = 0;
- // c = blendColor(c, spherys[3].ellipsevalue(Px.x, Px.y, Px.z, model.xMax/4, model.yMax/4, model.zMax/4, 3*model.xMax/4, 3*model.yMax/4, 3*model.zMax/4),ADD);
- // return c;
- // }
- // return lx.hsb(0,0,0);
- // // else if(spheremode ==2)
- // { color c = 0;
- // return lx.hsb(CalcCone( (xyz by = new xyz(0,spherys[2].ybounce.getValuef(),0) ), Px, mid) );
-
- // }
-
-
- // }
-
- }
-
-class CubeCurl extends SCPattern{
-float CH, CW, diag;
-ArrayList<PVector> cubeorigin = new ArrayList<PVector>();
-ArrayList<PVector> centerlist = new ArrayList<PVector>();
-private SinLFO curl = new SinLFO(0, Cube.EDGE_HEIGHT, 5000 );
-
-private SinLFO bg = new SinLFO(180, 220, 3000);
-
-CubeCurl(GLucose glucose){
-super(glucose);
-addModulator(curl).trigger();
-addModulator(bg).trigger();
- this.CH = Cube.EDGE_HEIGHT;
- this.CW = Cube.EDGE_WIDTH;
- this.diag = sqrt(CW*CW + CW*CW);
-
-
-ArrayList<PVector> centerlistrelative = new ArrayList<PVector>();
-for (int i = 0; i < model.cubes.size(); i++){
- Cube a = model.cubes.get(i);
- cubeorigin.add(new PVector(a.x, a.y, a.z));
- centerlist.add(centerofcube(i));
-
-}
-
-}
-//there is definitely a better way of doing this!
-public PVector centerofcube(int i) {
-Cube c = model.cubes.get(i);
-
-println(" cube #: " + i + " c.x " + c.x + " c.y " + c.y + " c.z " + c.z );
-PVector cubeangle = new PVector(c.rx, c.ry, c.rz);
-//println("raw x" + cubeangle.x + "raw y" + cubeangle.y + "raw z" + cubeangle.z);
-PVector cubecenter = new PVector(c.x + CW/2, c.y + CH/2, c.z + CW/2);
-println("cubecenter unrotated: " + cubecenter.x + " " +cubecenter.y + " " +cubecenter.z );
-PVector centerrot = new PVector(cos(c.rx)*CW/2 - sin(c.rx)*CW/2, 0, cos(c.rz)*CW/2 + sin(c.rz)*CW/2);
- // nCos*(y-o.y) - nSin*(z-o.z) + o.y
-cubecenter = PVector.add(cubecenter, centerrot);
-println( " cubecenter.x " + cubecenter.x + " cubecenter.y " + cubecenter.y + " cubecenter.z " + cubecenter.z + " ");
-
-
-return cubecenter;
-}
-
-
-public void run(double deltaMs){
-for (int i =0; i < model.cubes.size(); i++) {
-Cube c = model.cubes.get(i);
-float cfloor = c.y;
-
-// if (i%3 == 0){
-
-// for (Point p : c.points ){
-// // colors[p.index]=color(0,0,0);
-// //float dif = (p.y - c.y);
-// //colors[p.index] = color( bg.getValuef() , 80 , dif < curl.getValuef() ? 80 : 0, ADD);
-// }
-// }
-
-// else if (i%3 == 1) {
-
-// for (Point p: c.points){
-// colors[p.index]=color(0,0,0);
-// float dif = (p.y - c.y);
-// // colors[p.index] =
-// // color(bg.getValuef(),
-// // map(curl.getValuef(), 0, Cube.EDGE_HEIGHT, 20, 100),
-// // 100 - 10*abs(dif - curl.getValuef()), ADD );
-// }
-// }
-// else if (i%3 == 2){
- // centerlist[i].sub(cubeorigin(i);
- for (Point p: c.points) {
- PVector pv = new PVector(p.x, p.y, p.z);
- colors[p.index] =color( constrain(4* pv.dist(centerlist.get(i)), 0, 360) , 50, 100 );
- // colors[p.index] =color(constrain(centerlist[i].x, 0, 360), constrain(centerlist[i].y, 0, 100), );
-
-
- }
-
-
- //}
-
- }
- }
- }
-
- class HueTestHSB extends SCPattern{
- BasicParameter HueT = new BasicParameter("Hue", .5f);
- BasicParameter SatT = new BasicParameter("Sat", .5f);
- BasicParameter BriT = new BasicParameter("Bright", .5f);
-
-HueTestHSB(GLucose glucose) {
- super(glucose);
- addParameter(HueT);
- addParameter(SatT);
- addParameter(BriT);
-}
- public void run(double deltaMs){
-
- for (Point p : model.points) {
- int c = 0;
- c = blendColor(c, lx.hsb(360*HueT.getValuef(), 100*SatT.getValuef(), 100*BriT.getValuef()), ADD);
- colors[p.index]= c;
- }
- int now= millis();
- if (now % 1000 <= 20)
- {
- println("Hue: " + 360*HueT.getValuef() + "Sat: " + 100*SatT.getValuef() + "Bright: " + 100*BriT.getValuef());
- }
- }
-
- }
-
-class TelevisionStatic extends SCPattern {
- BasicParameter brightParameter = new BasicParameter("BRIGHT", 1.0f);
- BasicParameter saturationParameter = new BasicParameter("SAT", 1.0f);
- BasicParameter hueParameter = new BasicParameter("HUE", 1.0f);
- SinLFO direction = new SinLFO(0, 10, 3000);
-
- public TelevisionStatic(GLucose glucose) {
- super(glucose);
- addModulator(direction).trigger();
- addParameter(brightParameter);
- addParameter(saturationParameter);
- addParameter(hueParameter);
- }
-
- public void run(double deltaMs) {
- boolean d = direction.getValuef() > 5.0f;
- for (Point p : model.points) {
- colors[p.index] = lx.hsb((lx.getBaseHuef() + random(hueParameter.getValuef() * 360))%360, random(saturationParameter.getValuef() * 100), random(brightParameter.getValuef() * 100));
- }
- }
-}
-
-class AbstractPainting extends SCPattern {
-
- PImage img;
-
- SinLFO colorMod = new SinLFO(0, 360, 5000);
- SinLFO brightMod = new SinLFO(0, model.zMax, 2000);
-
- public AbstractPainting(GLucose glucose) {
- super(glucose);
- addModulator(colorMod).trigger();
- addModulator(brightMod).trigger();
-
- img = loadImage("abstract.jpg");
- img.loadPixels();
- }
-
- public void run(double deltaMs) {
- for (Point p : model.points) {
- int c = img.get((int)((p.x / model.xMax) * img.width), img.height - (int)((p.y / model.yMax) * img.height));
- colors[p.index] = lx.hsb(hue(c) + colorMod.getValuef()%360, saturation(c), brightness(c) - ((p.z - brightMod.getValuef())/p.z));
- }
- }
-}
-
-class Spirality extends SCPattern {
- final BasicParameter r = new BasicParameter("RADIUS", 0.5f);
-
- float angle = 0;
- float rad = 0;
- int direction = 1;
-
- Spirality(GLucose glucose) {
- super(glucose);
- addParameter(r);
- for (Point p : model.points) {
- colors[p.index] = lx.hsb(0, 0, 0);
- }
- }
-
- public void run(double deltaMs) {
- angle += deltaMs * 0.007f;
- rad += deltaMs * .025f * direction;
- float x = model.xMax / 2 + cos(angle) * rad;
- float y = model.yMax / 2 + sin(angle) * rad;
- for (Point p : model.points) {
- float b = dist(x,y,p.x,p.y);
- if (b < 90) {
- colors[p.index] = blendColor(
- colors[p.index],
- lx.hsb(lx.getBaseHuef() + 25, 10, map(b, 0, 10, 100, 0)),
- ADD);
- } else {
- colors[p.index] = blendColor(
- colors[p.index],
- lx.hsb(25, 10, map(b, 0, 10, 0, 15)),
- SUBTRACT);
- }
- }
- if (rad > model.xMax / 2 || rad <= .001f) {
- direction *= -1;
- }
- }
-}
-
-
-
-
-/**
- * This is a reusable equalizer class that lets you get averaged
- * bands with dB scaling and smoothing.
- */
-public static class GraphicEQ {
-
- private final LX lx;
-
- public final BasicParameter level = new BasicParameter("LVL", 0.5f);
- public final BasicParameter range = new BasicParameter("RNGE", 0.5f);
- public final BasicParameter slope = new BasicParameter("SLOP", 0.5f);
- public final BasicParameter attack = new BasicParameter("ATK", 0.5f);
- public final BasicParameter release = new BasicParameter("REL", 0.5f);
-
- private final FFT fft;
- private final int numBands;
-
- private final LinearEnvelope[] bandVals;
-
- public final static int DEFAULT_NUM_BANDS = 16;
-
- public GraphicEQ(LX lx) {
- this(lx, DEFAULT_NUM_BANDS);
- }
-
- /**
- * Note that the number of bands is a suggestion. Due to the FFT implementation
- * the actual number may be slightly different.
- */
- public GraphicEQ(LX lx, int num) {
- this.lx = lx;
- fft = new FFT(lx.audioInput().bufferSize(), lx.audioInput().sampleRate());
- fft.window(FFT.HAMMING);
- fft.logAverages(50, num/8);
- numBands = this.fft.avgSize();
- bandVals = new LinearEnvelope[numBands];
- for (int i = 0; i < bandVals.length; ++i) {
- (bandVals[i] = new LinearEnvelope(0, 0, 500)).trigger();
- }
- }
-
- static final float logTen = log(10);
- public static float log10(float val) {
- return log(val) / logTen;
- }
-
- public float getLevel(int band) {
- return bandVals[band].getValuef();
- }
-
- public float getAverageLevel(int minBand, int numBands) {
- float avg = 0;
- for (int i = minBand; i < minBand + numBands; ++i) {
- avg += bandVals[i].getValuef();
- }
- avg /= numBands;
- return avg;
- }
-
- public void run(double deltaMs) {
- fft.forward(lx.audioInput().mix);
- float zeroDBReference = pow(10, 100*(1-level.getValuef())/20.f);
- float decibelRange = 12 + range.getValuef() * 60;
- float decibelSlope = slope.getValuef() * 60.f / numBands;
- for (int i = 0; i < numBands; ++i) {
- float raw = fft.getAvg(i);
- float decibels = 20*log10(raw / zeroDBReference);
- float positiveDecibels = decibels + decibelRange;
- positiveDecibels += i*decibelSlope;
- float value = constrain(positiveDecibels / decibelRange, 0, 1);
-
- if (value > bandVals[i].getValuef()) {
- bandVals[i].setRangeFromHereTo(value, attack.getValuef() * 20).trigger();
- }
- }
- for (LinearEnvelope band : bandVals) {
- band.run(deltaMs);
- if (!band.isRunning() && band.getValuef() > 0) {
- band.setRangeFromHereTo(0, release.getValuef() * 1600).trigger();
- }
- }
- }
-}
-
-
-class TowerParams extends SCPattern
-{
- BasicParameter hueoff = new BasicParameter("Hueoff", 0.0f);
- BasicParameter hueSpan = new BasicParameter("HueRange", 0.0f);
- BasicParameter t1 = new BasicParameter("T1", 0.0f);
- BasicParameter t2 = new BasicParameter("T2", 0.0f);
- BasicParameter t3 = new BasicParameter("T3", 0.0f);
- BasicParameter t4 = new BasicParameter("T4", 0.0f);
- BasicParameter t5 = new BasicParameter("T5", 0.0f);
- BasicParameter t6 = new BasicParameter("T6", 0.0f);
- BasicParameter t7 = new BasicParameter("T7", 0.0f);
- BasicParameter t8 = new BasicParameter("T8", 0.0f);
- BasicParameter t9 = new BasicParameter("T9", 0.0f);
- BasicParameter t10 = new BasicParameter("T10", 0.0f);
- BasicParameter t11 = new BasicParameter("T11", 0.0f);
- BasicParameter t12 = new BasicParameter("T12", 0.0f);
- BasicParameter t13 = new BasicParameter("T13", 0.0f);
- BasicParameter t14 = new BasicParameter("T14", 0.0f);
- BasicParameter t15 = new BasicParameter("T15", 0.0f);
- BasicParameter t16 = new BasicParameter("T16", 0.0f);
-
- ArrayList<BasicParameter> towerParams;
- int towerSize;
- int colorSpan;
- TowerParams(GLucose glucose) {
- super(glucose);
-
- towerParams = new ArrayList<BasicParameter>();
- addParameter(hueoff);
- addParameter(hueSpan);
- towerParams.add(t1);
- towerParams.add(t2);
- towerParams.add(t3);
- towerParams.add(t4);
- towerParams.add(t5);
- towerParams.add(t6);
- towerParams.add(t7);
- towerParams.add(t8);
- towerParams.add(t9);
- towerParams.add(t10);
- towerParams.add(t11);
- towerParams.add(t12);
- towerParams.add(t13);
- towerParams.add(t14);
- towerParams.add(t15);
- towerParams.add(t16);
- for(BasicParameter p : towerParams)
- {
- addParameter(p);
- }
- towerSize = model.towers.size();
- colorSpan = 255 / towerSize;
- }
-
- public void run(double deltaMs)
- {
- clearALL();
- Tower t;
- for(int i=0; i<towerSize ;i++)
- {
- t= model.towers.get(i);
- for(Point p : t.points)
- {
- if(p.y<towerParams.get(i).getValuef()*200)
- {
- colors[p.index]=lx.hsb(255 * hueoff.getValuef()+colorSpan * hueSpan.getValuef() * i, 255, 255);
- }
- }
- }
-
- }
-
- public void clearALL()
- {
- for(Point p : model.points)
- {
- colors[p.index] = 0;
- }
- }
-
-}
-class Sandbox extends SCPattern
-{
- int c=0;
- int prevC=0;
- int huerange=255;
- int pointrange= model.points.size();
- int striprange= model.strips.size();
- int facerange= model.faces.size();
- int cuberange = model.cubes.size();
- int towerrange = model.towers.size();
- int counter=0;
-
- Sandbox(GLucose glucose) {
- super(glucose);
- println("points "+pointrange);
- println("strips "+striprange);
- println("faces "+facerange);
- println("cubes "+cuberange);
- println("towers "+towerrange);
- }
-
- public void run(double deltaMs) {
-
-
- if(counter % 10 ==0)
- {
- doDraw(c,0);
- c = (c + 1) % towerrange;
- long col = lx.hsb(Math.round(Math.random()*255),255,255) ;
- doDraw(c,col);
- }
- counter++;
-
- }
-
- public void doDraw(int c,long col)
- {
- Tower t= model.towers.get((int) c);
- for(Point p : t.points)
- {
- colors[p.index] = (int) col;
- }
- }
-};
-
-class GranimTestPattern extends GranimPattern
-{
- GranimTestPattern(GLucose glucose)
- {
- super(glucose);
- addGraphic("myReds",new RedsGraphic(100));
- int[] dots = {0,128,0,128,0,128,0,128,0,128,0,128};
- addGraphic("myOtherColors",new ColorDotsGraphic(dots));
-
- getGraphicByName("myOtherColors").position=100;
- }
- int counter=0;
- public void run(double deltaMs)
- {
- clearALL();
- super.run(deltaMs);
-
- if(counter % 3 ==0)
- {
- Graphic reds = getGraphicByName("myReds");
- Graphic others = getGraphicByName("myOtherColors");
- reds.position = reds.position + 1 % 19000;
- others.position = others.position + 10 % 19000;
- }
- }
- public void clearALL()
- {
- for(int i = 0; i < colors.length; i++)
- {
- colors[i] = 0;
- }
- }
-
-
-}
-
-class GranimTestPattern2 extends GranimPattern
-{
- GranimTestPattern2(GLucose glucose)
- {
- super(glucose);
- /*for(int i = 0;i < 100; i++)
- {
- Graphic g = addGraphic("myReds_"+i,new RedsGraphic(Math.round(Math.random() * 100)));
-
- }*/
- Graphic g = addGraphic("myRandoms",new RandomsGranim(50));
- g.position = 200;
-
- }
- int counter=0;
- float count=0;
- public void run(double deltaMs)
- {
- clearALL();
- super.run(deltaMs);
- Graphic randomsGraphic = getGraphicByName("myRandoms");
- randomsGraphic.position = Math.round(sin(count)*1000)+5000;
- count+= 0.005f;
- }
- public void clearALL()
- {
- for(Point p : model.points)
- {
- colors[p.index] = 0;
- }
- }
-
-
-};
-
-class DriveableCrossSections extends CrossSections
-{
- BasicParameter xd;
- BasicParameter yd;
- BasicParameter zd;
- BasicParameter mode;
-
- DriveableCrossSections(GLucose glucose) {
- super(glucose);
- }
-
- public void addParams()
- {
- mode = new BasicParameter("Mode", 0.0f);
- xd = new BasicParameter("XD", 0.0f);
- yd = new BasicParameter("YD", 0.0f);
- zd = new BasicParameter("ZD", 0.0f);
- addParameter(mode);
- addParameter(xd);
- addParameter(yd);
- addParameter(zd);
-
- super.addParams();
- }
-
- public void onParameterChanged(LXParameter p) {
- if(p == mode)
- {
- if(interactive())
- {
- copyValuesToKnobs();
- }else{
- copyKnobsToValues();
- }
- }
- }
-
- public void copyValuesToKnobs()
- {
- xd.setValue(x.getValue()/200);
- yd.setValue(y.getValue()/115);
- zd.setValue(z.getValue()/100);
- }
-
- public void copyKnobsToValues()
- {
- x.setValue(xd.getValue()*200);
- y.setValue(yd.getValue()*115);
- z.setValue(zd.getValue()*100);
- }
-
- public boolean interactive()
- {
- return Math.round(mode.getValuef())>0.5f;
- }
-
- public void updateXYZVals()
- {
- if(interactive())
- {
- xv = xd.getValuef()*200;
- yv = yd.getValuef()*115;
- zv = zd.getValuef()*100;
- }else{
- super.updateXYZVals();
- copyValuesToKnobs();
- }
- }
-
-}
-//----------------------------------------------------------------------------------------------------------------------------------
-public class Pong extends DPat {
- SinLFO x,y,z,dx,dy,dz;
- float cRad; BasicParameter pSize;
- Pick pChoose;
- PVector v = new PVector(), vMir = new PVector();
-
- Pong(GLucose glucose) {
- super(glucose);
- cRad = mMax.x/10;
- addModulator(dx = new SinLFO(6000, 500, 30000 )).trigger();
- addModulator(dy = new SinLFO(3000, 500, 22472 )).trigger();
- addModulator(dz = new SinLFO(1000, 500, 18420 )).trigger();
- addModulator(x = new SinLFO(cRad, mMax.x - cRad, 0)).trigger(); x.modulateDurationBy(dx);
- addModulator(y = new SinLFO(cRad, mMax.y - cRad, 0)).trigger(); y.modulateDurationBy(dy);
- addModulator(z = new SinLFO(cRad, mMax.z - cRad, 0)).trigger(); z.modulateDurationBy(dz);
- pSize = addParam ("Size" , 0.4f );
- pChoose = addPick ("Animiation" , 2, 2, new String[] {"Pong", "Ball", "Cone"} );
- }
-
- public void StartRun(double deltaMs) { cRad = mMax.x*val(pSize)/6; }
- public int CalcPoint(PVector p) {
- v.set(x.getValuef(), y.getValuef(), z.getValuef());
- v.z=0;p.z=0;// ignore z dimension
- switch(pChoose.Cur()) {
- case 0: vMir.set(mMax); vMir.sub(p);
- return lx.hsb(lxh(),100,c1c(1 - min(v.dist(p), v.dist(vMir))*.5f/cRad)); // balls
- case 1: return lx.hsb(lxh(),100,c1c(1 - v.dist(p)*.5f/cRad)); // ball
- case 2: vMir.set(mMax.x/2,0,mMax.z/2);
- return lx.hsb(lxh(),100,c1c(1 - calcCone(p,v,vMir) * max(.02f,.45f-val(pSize)))); // spot
- }
- return lx.hsb(0,0,0);
- }
-}
-//----------------------------------------------------------------------------------------------------------------------------------
-public class NDat {
- float xz, yz, zz, hue, speed, angle, den;
- float xoff,yoff,zoff;
- float sinAngle, cosAngle;
- boolean isActive;
- NDat () { isActive=false; }
- public boolean Active() { return isActive; }
- public void set (float _hue, float _xz, float _yz, float _zz, float _den, float _speed, float _angle) {
- isActive = true;
- hue=_hue; xz=_xz; yz=_yz; zz =_zz; den=_den; speed=_speed; angle=_angle;
- xoff = random(100e3f); yoff = random(100e3f); zoff = random(100e3f);
- }
-}
-
-public class Noise extends DPat
-{
- int CurAnim, iSymm;
- int XSym=1,YSym=2,RadSym=3;
- float zTime , zTheta=0, zSin, zCos, rtime, ttime;
- BasicParameter pSpeed , pDensity, pSharp;
- Pick pChoose, pSymm;
- int _ND = 4;
- NDat N[] = new NDat[_ND];
-
- Noise(GLucose glucose) {
- super(glucose);
- pSpeed = addParam("Fast" , .55f);
- pDensity = addParam("Dens" , .5f);
- pSharp = addParam("Shrp" , 0);
- pSymm = addPick("Symmetry" , 0, 3, new String[] {"None", "X", "Y", "Radial"} );
- pChoose = addPick("Animation", 6, 7, new String[] {"Drip", "Cloud", "Rain", "Fire", "Machine", "Spark","VWave", "Wave"} );
- for (int i=0; i<_ND; i++) N[i] = new NDat();
- }
-
- public void onActive() { zTime = random(500); zTheta=0; rtime = 0; ttime = 0; }
-
- public void StartRun(double deltaMs) {
- zTime += deltaMs*(val(pSpeed)-.5f)*.002f ;
- zTheta += deltaMs*(spin()-.5f)*.01f ;
- rtime += deltaMs;
- iSymm = pSymm.Cur();
- zSin = sin(zTheta);
- zCos = cos(zTheta);
-
- if (pChoose.Cur() != CurAnim) {
- CurAnim = pChoose.Cur(); ttime = rtime;
- pSpin .reset(); zTheta = 0;
- pDensity .reset(); pSpeed .reset();
- for (int i=0; i<_ND; i++) { N[i].isActive = false; }
-
- switch(CurAnim) {
- // hue xz yz zz den mph angle
- case 0: N[0].set(0 ,75 ,75 ,150,45 ,3 ,0 ); pSharp.setValue(1 ); break; // drip
- case 1: N[0].set(0 ,100,100,200,45 ,3 ,180); pSharp.setValue(0 ); break; // clouds
- case 2: N[0].set(0 ,2 ,400,2 ,20 ,3 ,0 ); pSharp.setValue(.5f); break; // rain
- case 3: N[0].set(40 ,100,100,200,10 ,1 ,180);
- N[1].set(0 ,100,100,200,10 ,5 ,180); pSharp.setValue(0 ); break; // fire 1
- case 4: N[0].set(0 ,40 ,40 ,40 ,15 ,2.5f,180);
- N[1].set(20 ,40 ,40 ,40 ,15 ,4 ,0 );
- N[2].set(40 ,40 ,40 ,40 ,15 ,2 ,90 );
- N[3].set(60 ,40 ,40 ,40 ,15 ,3 ,-90); pSharp.setValue(.5f); break; // machine
- case 5: N[0].set(0 ,400,100,2 ,15 ,3 ,90 );
- N[1].set(20 ,400,100,2 ,15 ,2.5f,0 );
- N[2].set(40 ,100,100,2 ,15 ,2 ,180);
- N[3].set(60 ,100,100,2 ,15 ,1.5f,270); pSharp.setValue(.5f); break; // spark
- }
- }
-
- for (int i=0; i<_ND; i++) if (N[i].Active()) {
- N[i].sinAngle = sin(radians(N[i].angle));
- N[i].cosAngle = cos(radians(N[i].angle));
- }
- }
-
- public int CalcPoint(PVector p) {
- int c = 0;
- rotateZ(p, mCtr, zSin, zCos);
-
- if (CurAnim == 6 || CurAnim == 7) {
- setNorm(p);
- return lx.hsb(lxh(),100, 100 * (
- constrain(1-50*(1-val(pDensity))*abs(p.y-sin(zTime*10 + p.x*(300))*.5f - .5f),0,1) +
- (CurAnim == 7 ? constrain(1-50*(1-val(pDensity))*abs(p.x-sin(zTime*10 + p.y*(300))*.5f - .5f),0,1) : 0))
- );
- }
-
- if (iSymm == XSym && p.x > mMax.x/2) p.x = mMax.x-p.x;
- if (iSymm == YSym && p.y > mMax.y/2) p.y = mMax.y-p.y;
-
- for (int i=0;i<_ND; i++) if (N[i].Active()) {
- NDat n = N[i];
- float zx = zTime * n.speed * n.sinAngle,
- zy = zTime * n.speed * n.cosAngle;
-
- float b = (iSymm==RadSym ? noise(zTime*n.speed+n.xoff-p.dist(mCtr)/n.xz)
- : noise(p.x/n.xz+zx+n.xoff,p.y/n.yz+zy+n.yoff,p.z/n.zz+n.zoff))
- *1.8f;
-
- b += n.den/100 -.4f + val(pDensity) -1;
- c = blendColor(c,lx.hsb(lxh()+n.hue,100,c1c(b)),ADD);
- }
- return c;
- }
-}
-//----------------------------------------------------------------------------------------------------------------------------------
-public class Play extends DPat
-{
- public class rAngle {
- float prvA, dstA, c;
- float prvR, dstR, r;
- float _cos, _sin, x, y;
- public float fixAngle (float a, float b) { return a<b ?
- (abs(a-b) > abs(a+2*PI-b) ? a : a+2*PI) :
- (abs(a-b) > abs(a-2*PI-b) ? a : a-2*PI) ; }
- public float getX(float r) { return mCtr.x + _cos*r; }
- public float getY(float r) { return mCtr.y + _sin*r; }
- public void move() { c = interp(t,prvA,dstA);
- r = interp(t,prvR,dstR);
- _cos = cos(c); _sin = sin(c);
- x = getX(r); y = getY(r); }
- public void set() { prvA = dstA; dstA = random(2*PI); prvA = fixAngle(prvA, dstA);
- prvR = dstR; dstR = random(mCtr.y); }
- }
-
- BasicParameter pAmp, pRadius, pBounce;
- Pick pTimePattern, pTempoMult, pShape;
-
- ArrayList<rWave> waves = new ArrayList<rWave>(10);
-
- int nBeats = 0;
- float t,amp,rad,bnc,zTheta=0;
-
- rAngle a1 = new rAngle(), a2 = new rAngle(),
- a3 = new rAngle(), a4 = new rAngle();
- PVector cPrev = new PVector(), cRand = new PVector(),
- cMid = new PVector(), V = new PVector(),
- theta = new PVector(), tSin = new PVector(),
- tCos = new PVector(), cMidNorm = new PVector(),
- Pn = new PVector();
- float LastBeat=3, LastMeasure=3;
- int curRandTempo = 1, curRandTPat = 1;
-
- Play(GLucose glucose) {
- super(glucose);
- pRadius = addParam("Rad" , .1f );
- pBounce = addParam("Bnc" , .2f );
- pAmp = addParam("Amp" , .2f );
- pTempoMult = addPick ("TMult" , 5 , 5 , new String[] {"1x", "2x", "4x", "8x", "16x", "Rand" } );
- pTimePattern= addPick ("TPat" , 7 , 7 , new String[] {"Bounce", "Sin", "Roll", "Quant", "Accel", "Deccel", "Slide", "Rand"} );
- pShape = addPick ("Shape" , 7 , 15 , new String[] {"Line", "Tap", "V", "RandV",
- "Pyramid", "Wings", "W2", "Clock",
- "Triangle", "Quad", "Sphere", "Cone",
- "Noise", "Wave", "?", "?"} );
- }
-
- public class rWave {
- float v0, a0, x0, t,damp,a;
- boolean bDone=false;
- final float len=8;
- rWave(float _x0, float _a0, float _v0, float _damp) { x0=_x0*len; a0=_a0; v0=_v0; t=0; damp = _damp; }
- public void move(double deltaMs) {
- t += deltaMs*.001f;
- if (t>4) bDone=true;
- }
- public float val(float _x) {
- _x*=len;
- float dist = t*v0 - abs(_x-x0);
- if (dist<0) { a=1; return 0; }
- a = a0*exp(-dist*damp) * exp(-abs(_x-x0)/(.2f*len)); // * max(0,1-t/dur)
- return -a*sin(dist);
- }
- }
-
- public void onReset() { zTheta=0; super.onReset(); }
- public void onActive() {
- zTheta=0;
- while (lx.tempo.bpm() > 40) lx.tempo.setBpm(lx.tempo.bpm()/2);
- }
-
- int KeyPressed = -1;
- public boolean noteOn(Note note) {
- int row = note.getPitch(), col = note.getChannel();
- if (row == 57) {KeyPressed = col; return true; }
- return super.noteOn(note);
- }
-
- public void StartRun(double deltaMs) {
- t = lx.tempo.rampf();
- amp = pAmp .getValuef();
- rad = pRadius .getValuef();
- bnc = pBounce .getValuef();
- zTheta += deltaMs*(val(pSpin)-.5f)*.01f;
-
- theta .set(val(pRotX)*PI*2, val(pRotY)*PI*2, val(pRotZ)*PI*2 + zTheta);
- tSin .set(sin(theta.x), sin(theta.y), sin(theta.z));
- tCos .set(cos(theta.x), cos(theta.y), cos(theta.z));
-
- if (t<LastMeasure) {
- if (random(3) < 1) { curRandTempo = PApplet.parseInt(random(4)); if (curRandTempo == 3) curRandTempo = PApplet.parseInt(random(4)); }
- if (random(3) < 1) { curRandTPat = pShape.Cur() > 6 ? 2+PApplet.parseInt(random(5)) : PApplet.parseInt(random(7)); }
- } LastMeasure = t;
-
- int nTempo = pTempoMult .Cur(); if (nTempo == 5) nTempo = curRandTempo;
- int nTPat = pTimePattern.Cur(); if (nTPat == 7) nTPat = curRandTPat ;
-
- switch (nTempo) {
- case 0: t = t; break;
- case 1: t = (t*2.f )%1.f; break;
- case 2: t = (t*4.f )%1.f; break;
- case 3: t = (t*8.f )%1.f; break;
- case 4: t = (t*16.f)%1.f; break;
- }
-
- int i=0; while (i< waves.size()) {
- rWave w = waves.get(i);
- w.move(deltaMs); if (w.bDone) waves.remove(i); else i++;
- }
-
- if ((t<LastBeat && pShape.Cur()!=14) || KeyPressed>-1) {
- waves.add(new rWave(
- KeyPressed>-1 ? map(KeyPressed,0,7,0,1) : random(1), // location
- bnc*10, // bounciness
- 7, // velocity
- 2*(1-amp))); // dampiness
- KeyPressed=-1;
- if (waves.size() > 5) waves.remove(0);
- }
-
- if (t<LastBeat) {
- cPrev.set(cRand); setRand(cRand);
- a1.set(); a2.set(); a3.set(); a4.set();
- } LastBeat = t;
-
- switch (nTPat) {
- case 0: t = sin(PI*t); break; // bounce
- case 1: t = norm(sin(2*PI*(t+PI/2)),-1,1); break; // sin
- case 2: t = t; break; // roll
- case 3: t = constrain(PApplet.parseInt(t*8)/7.f,0,1); break; // quant
- case 4: t = t*t*t; break; // accel
- case 5: t = sin(PI*t*.5f); break; // deccel
- case 6: t = .5f*(1-cos(PI*t)); break; // slide
- }
-
- cMid.set (cPrev); interpolate(t,cMid,cRand);
- cMidNorm.set (cMid); setNorm(cMidNorm);
- a1.move(); a2.move(); a3.move(); a4.move();
- }
-
- public int CalcPoint(PVector Px) {
- if (theta.x != 0) rotateX(Px, mCtr, tSin.x, tCos.x);
- if (theta.y != 0) rotateY(Px, mCtr, tSin.y, tCos.y);
- if (theta.z != 0) rotateZ(Px, mCtr, tSin.z, tCos.z);
-
- Pn.set(Px); setNorm(Pn);
-
- float mp = min(Pn.x, Pn.z);
- float yt = map(t,0,1,.5f-bnc/2,.5f+bnc/2);
- float r,d;
-
- switch (pShape.Cur()) {
- case 0: V.set(Pn.x, yt , Pn.z); break; // bouncing line
- case 1: V.set(Pn.x, map(cos(PI*t * Pn.x),-1,1,0,1) , Pn.z); break; // top tap
- case 2: V.set(Pn.x, bnc*map(Pn.x<.5f?Pn.x:1-Pn.x,0,.5f ,0,t-.5f)+.5f, Pn.z); break; // V shape
- case 3: V.set(Pn.x, Pn.x < cMidNorm.x ? map(Pn.x,0,cMidNorm.x, .5f,yt) :
- map(Pn.x,cMidNorm.x,1, yt,.5f), Pn.z); break; // Random V shape
-
- case 4: V.set(Pn.x, .5f*(Pn.x < cMidNorm.x ? map(Pn.x,0,cMidNorm.x, .5f,yt) :
- map(Pn.x,cMidNorm.x,1, yt,.5f)) +
- .5f*(Pn.z < cMidNorm.z ? map(Pn.z,0,cMidNorm.z, .5f,yt) :
- map(Pn.z,cMidNorm.z,1, yt,.5f)), Pn.z); break; // Random Pyramid shape
-
- case 5: V.set(Pn.x, bnc*map((Pn.x-.5f)*(Pn.x-.5f),0,.25f,0,t-.5f)+.5f, Pn.z); break; // wings
- case 6: V.set(Pn.x, bnc*map((mp -.5f)*(mp -.5f),0,.25f,0,t-.5f)+.5f, Pn.z); break; // wings
-
- case 7: d = min(
- distToSeg(Px.x, Px.y, a1.getX(70),a1.getY(70), mCtr.x, mCtr.y),
- distToSeg(Px.x, Px.y, a2.getX(40),a2.getY(40), mCtr.x, mCtr.y));
- d = constrain(30*(rad*40-d),0,100);
- return lx.hsb(lxh(),100, d); // clock
-
- case 8: r = amp*200 * map(bnc,0,1,1,sin(PI*t));
- d = min(
- distToSeg(Px.x, Px.y, a1.getX(r),a1.getY(r), a2.getX(r),a2.getY(r)),
- distToSeg(Px.x, Px.y, a2.getX(r),a2.getY(r), a3.getX(r),a3.getY(r)),
- distToSeg(Px.x, Px.y, a3.getX(r),a3.getY(r), a1.getX(r),a1.getY(r)) // triangle
- );
- d = constrain(30*(rad*40-d),0,100);
- return lx.hsb(lxh(),100, d); // clock
-
- case 9: r = amp*200 * map(bnc,0,1,1,sin(PI*t));
- d = min(
- distToSeg(Px.x, Px.y, a1.getX(r),a1.getY(r), a2.getX(r),a2.getY(r)),
- distToSeg(Px.x, Px.y, a2.getX(r),a2.getY(r), a3.getX(r),a3.getY(r)),
- distToSeg(Px.x, Px.y, a3.getX(r),a3.getY(r), a4.getX(r),a4.getY(r)),
- distToSeg(Px.x, Px.y, a4.getX(r),a4.getY(r), a1.getX(r),a1.getY(r)) // quad
- );
- d = constrain(30*(rad*40-d),0,100);
- return lx.hsb(lxh(),100, d); // clock
-
- case 10:
- r = map(bnc,0,1,a1.r,amp*200*sin(PI*t));
- return lx.hsb(lxh(),100,c1c(.9f+2*rad - dist(Px.x,Px.y,a1.getX(r),a1.getY(r))*.03f) ); // sphere
-
- case 11:
- Px.z=mCtr.z; cMid.z=mCtr.z;
- return lx.hsb(lxh(),100,c1c(1 - calcCone(Px,cMid,mCtr) * 0.02f > .5f?1:0)); // cone
-
- case 12: return lx.hsb(lxh() + noise(Pn.x,Pn.y,Pn.z + (NoiseMove+50000)/1000.f)*200,
- 85,c1c(Pn.y < noise(Pn.x + NoiseMove/2000.f,Pn.z)*(1+amp)-amp/2.f-.1f ? 1 : 0)); // noise
-
- case 13:
- case 14: float y=0; for (rWave w : waves) y += .5f*w.val(Pn.x); // wave
- V.set(Pn.x, .7f+y, Pn.z);
- break;
-
- default: return lx.hsb(0,0,0);
- }
-
- return lx.hsb(lxh(), 100, c1c(1 - V.dist(Pn)/rad));
- }
-}
-//----------------------------------------------------------------------------------------------------------------------------------
-boolean dDebug = false;
-class dCursor {
- dVertex vCur, vNext, vDest;
- float destSpeed;
- int posStop, pos,posNext; // 0 - 65535
- int clr;
-
- dCursor() {}
-
- public boolean isDone () { return pos==posStop; }
- public boolean atDest () { return vCur.s==vDest.s ||
- xyDist(vCur.getPoint(0), vDest.getPoint(0)) < 12 ||
- xyDist(vCur.getPoint(0), vDest.getPoint(15))< 12;}
- public void setCur (dVertex _v, int _p) { p2=null; vCur=_v; pos=_p; pickNext(); }
- public void setCur (dPixel _p) { setCur(_p.v, _p.pos); }
- public void setNext (dVertex _v, int _p, int _s) { vNext = _v; posNext = _p<<12; posStop = _s<<12; }
- public void setDest (dVertex _v, float _speed) { vDest = _v; destSpeed = _speed; }
- public void onDone () { setCur(vNext, posNext); pickNext(); }
-
- float minDist;
- int nTurns;
- boolean bRandEval;
-
- public void evaluate(dVertex v, int p, int s) {
- if (v == null) return; ++nTurns;
- if (bRandEval) {
- if (random(nTurns) < 1) setNext(v,p,s); return; }
- else {
- float d = xyDist(v.getPoint(15), vDest.getPoint(0));
- if (d < minDist) { minDist=d; setNext(v,p,s); }
- if (d == minDist && random(2)<1) { minDist=d; setNext(v,p,s); }
- }
- }
-
- public void evalTurn(dTurn t) {
- if (t == null || t.pos0<<12 <= pos) return;
- evaluate(t.v , t.pos1, t.pos0);
- evaluate(t.v.opp, 16-t.pos1, t.pos0);
- }
-
- public void pickNext() {
- bRandEval = random(.05f+destSpeed) < .05f; minDist=500; nTurns=0;
- evaluate(vCur.c0, 0, 16); evaluate(vCur.c1, 0, 16);
- evaluate(vCur.c2, 0, 16); evaluate(vCur.c3, 0, 16);
- evalTurn(vCur.t0); evalTurn(vCur.t1);
- evalTurn(vCur.t2); evalTurn(vCur.t3);
- }
-
- Point p1, p2; int i2;
-
- public int draw(int nAmount, SCPattern pat) {
- int nFrom = (pos ) >> 12;
- int nMv = min(nAmount, posStop-pos);
- int nTo = min(15,(pos+nMv) >> 12);
- dVertex v = vCur;
-
- if (dDebug) { p1 = v.getPoint(nFrom); float d = (p2 == null ? 0 : pointDist(p1,p2)); if (d>5) { println("too wide! quitting: " + d); exit(); }}
- for (int i = nFrom; i <= nTo; i++) { pat.getColors()[v.ci + v.dir*i ] = clr; }
- if (v.same != null) for (int i = nFrom; i <= nTo; i++) { pat.getColors()[v.same.ci + v.same.dir*i] = clr; }
-
- if (dDebug) { p2 = v.getPoint(nTo); i2 = nTo; }
-
- pos += nMv; return nAmount - nMv;
- }
-}
-
-//----------------------------------------------------------------------------------------------------------------------------------
-class Worms extends SCPattern {
- float StripsPerSec = 10;
- float TrailTime = 3000;
- int numCursors = 50;
- ArrayList<dCursor> cur = new ArrayList<dCursor>(30);
-
- private GraphicEQ eq = null;
-
- private BasicParameter pBeat = new BasicParameter("BEAT", 0);
- private BasicParameter pSpeed = new BasicParameter("FAST", .2f);
- private BasicParameter pBlur = new BasicParameter("BLUR", .3f);
- private BasicParameter pWorms = new BasicParameter("WRMS", .3f);
- private BasicParameter pConfusion = new BasicParameter("CONF", .1f);
- private BasicParameter pEQ = new BasicParameter("EQ" , 0);
- private BasicParameter pSpawn = new BasicParameter("DIR" , 0);
- private BasicParameter pColor = new BasicParameter("CLR" , .1f);
-
- float zMidLat = 82.f;
- float nConfusion;
- private final Click moveChase = new Click(1000);
-
- PVector middle;
- public int AnimNum() { return floor(pSpawn.getValuef()*(4-.01f)); }
- public float randX() { return random(model.xMax-model.xMin)+model.xMin; }
- public float randY() { return random(model.yMax-model.yMin)+model.yMin; }
- public PVector randEdge() {
- return random(2) < 1 ? new PVector(random(2)<1 ? model.xMin:model.xMax, randY(), zMidLat) :
- new PVector(randX(), random(2)<1 ? model.yMin:model.yMax, zMidLat) ;
- }
-
- Worms(GLucose glucose) {
- super(glucose);
- addModulator(moveChase).start();
- addParameter(pBeat); addParameter(pSpeed);
- addParameter(pBlur); addParameter(pWorms);
- addParameter(pEQ); addParameter(pConfusion);
- addParameter(pSpawn); addParameter(pColor);
-
- middle = new PVector(1.5f*model.cx, 1.5f*model.cy, 71);
- if (lattice == null) lattice = new dLattice();
- for (int i=0; i<numCursors; i++) { dCursor c = new dCursor(); reset(c); cur.add(c); }
- onParameterChanged(pEQ); setNewDest();
- }
-
- public void onParameterChanged(LXParameter parameter) {
- super.onParameterChanged(parameter);
- nConfusion = 1-pConfusion.getValuef();
- for (int i=0; i<numCursors; i++) {
- if (parameter==pSpawn) reset(cur.get(i));
- cur.get(i).destSpeed = nConfusion;
- }
- }
-
- public float getClr() { return lx.getBaseHuef() + random(pColor.getValuef()*300); }
- public void reset(dCursor c) {
- switch(AnimNum()) {
- case 0: c.clr = lx.hsb(getClr(),100,100); // middle to edges
- c.setDest(lattice.getClosest(randEdge()).v, nConfusion);
- c.setCur (lattice.getClosest(middle));
- break;
-
- case 1: c.clr = lx.hsb(getClr(),100,100); // top to bottom
- float xLin = randX();
- c.setDest(lattice.getClosest(new PVector(xLin, 0 , zMidLat)).v, nConfusion);
- c.setCur (lattice.getClosest(new PVector(xLin, model.yMax, zMidLat)));
- break;
-
- case 2: c.clr = lx.hsb(getClr(),100,100); break; // chase a point around
-
- case 3: boolean bLeft = random(2)<1;
- c.clr = lx.hsb(getClr()+random(120),100,100); // sideways
- float yLin = randX();
- c.setDest(lattice.getClosest(new PVector(bLeft ? 0 : model.xMax,yLin,zMidLat)).v, nConfusion);
- c.setCur (lattice.getClosest(new PVector(bLeft ? model.xMax : 0,yLin,zMidLat)));
- break;
- }
- if (pBlur.getValuef() == 1 && random(2)<1) c.clr = lx.hsb(0,0,0);
- }
-
- public void setNewDest() {
- if (AnimNum() != 2) return;
- PVector dest = new PVector(randX(), randY(), zMidLat);
- for (int i=0; i<numCursors; i++) {
- cur.get(i).setDest(lattice.getClosest(dest).v, nConfusion);
- cur.get(i).clr = lx.hsb(getClr()+75,100,100); // chase a point around
- }
- }
-
- public void run(double deltaMs) {
- if (deltaMs > 100) return;
- if (moveChase.click()) setNewDest();
-
- float fBass=0, fTreble=0;
- if (pEQ.getValuef()>0) { // EQ
- eq.run(deltaMs);
- fBass = eq.getAverageLevel(0, 4);
- fTreble = eq.getAverageLevel(eq.numBands-7, 7);
- }
-
- if (pBlur.getValuef() < 1) { // trails
- for (int i=0,s=model.points.size(); i<s; i++) {
- int c = colors[i]; float b = lx.b(c);
- if (b>0) colors[i] = lx.hsb(lx.h(c), lx.s(c), constrain((float)(b-100*deltaMs/(pBlur.getValuef()*TrailTime)),0,100));
- }
- }
-
- int nWorms = floor(pWorms.getValuef() * numCursors *
- map(pEQ.getValuef(),0,1,1,constrain(2*fTreble,0,1)));
-
- for (int i=0; i<nWorms; i++) {
- dCursor c = cur.get(i);
- int nLeft = floor((float)deltaMs*.001f*StripsPerSec * 65536 * (5*pSpeed.getValuef()));
- nLeft *= (1 - lx.tempo.rampf()*pBeat.getValuef());
- while(nLeft > 0) {
- nLeft = c.draw(nLeft,this); if (!c.isDone()) continue;
- c.onDone(); if (c.atDest()) reset(c);
- }
- }
- }
-
-
- public void onActive() { if (eq == null) {
- eq = new GraphicEQ(lx, 16); eq.slope.setValue(0.6f);
- eq.level.setValue(0.65f); eq.range.setValue(0.35f);
- eq.release.setValue(0.4f);
- }}
-}
-//----------------------------------------------------------------------------------------------------------------------------------
-class GenericController {
- GenericController(){}
- public void RotateKnob(int type, int num, float val){
- LXParameter p = null;
- if(type==0) {
- p = glucose.patternKnobs.get(num);
- if(p!=null) { p.setValue(val); }
- }
- if(type==1) {
- p = glucose.transitionKnobs.get(num);
- if(p!=null) { p.setValue(val); }
- }
- if(type==2) {
- p = glucose.effectKnobs.get(num);
- if(p!=null) { p.setValue(val); }
- }
- }
-}
-
-class MidiController extends GenericController {
- MidiController() {
- super();
- }
-}
-//PApplet xparent; // be sure to set
-
-
-
-OscP5 listener;
-// Setup OSC
-//listener = new OscP5(this,7022);
-
-//boolean[] noteState = new boolean[16];
-//
-//void controllerChangeReceived(rwmidi.Controller cc) {
-// if (debugMode) {
-// println("CC: " + cc.toString());
-// }
-// if(cc.getCC()==1){
-// for(int i=0; i<16; i++){
-// if(noteState[i] && i<8) { LXParameter p = glucose.patternKnobs.get(i); p.setValue(cc.getValue()/127.0); }
-// else if(noteState[i] && i<12) { LXParameter p = glucose.transitionKnobs.get(i-8); p.setValue(cc.getValue()/127.0); }
-// else if(noteState[i] && i<16) { LXParameter p = glucose.effectKnobs.get(i-12); p.setValue(cc.getValue()/127.0); }
-// }
-// }
-//}
-//
-//void noteOnReceived(Note note) {
-// if (debugMode) {
-// println("Note On: " + note.toString());
-// }
-// int pitch = note.getPitch();
-// if(pitch>=36 && pitch <36+16){
-// noteState[pitch-36]=true;
-// }
-//}
-//
-//void noteOffReceived(Note note) {
-// if (debugMode) {
-// println("Note Off: " + note.toString());
-// }
-// int pitch = note.getPitch();
-// if(pitch>=36 && pitch <36+16){
-// noteState[pitch-36]=false;
-// }
-//}
-//
-//void oscEvent(OscMessage theOscMessage) {
-// println(theOscMessage);
-// LXPattern currentPattern = lx.getPattern();
-// if (currentPattern instanceof OSCPattern) {
-// ((OSCPattern)currentPattern).oscEvent(theOscMessage);
-// }
-//}
-//
-
-
-class ObjectMuckerEffect extends SCEffect {
- ObjectMuckerEffect(GLucose glucose) {
- super(glucose);
- }
- public void apply(int[] colors){
- /*for(Strip s: model.strips){
- for(int i=0; i<s.points.size(); i++){
- int index = s.points.get(i).index;
- color c = colors[index];
- colors[index] = lx.hsb((i*22.5), saturation(c), brightness(c));
- }
- }*/
- }
-}
-
-class BlendFrames extends SCEffect {
- int fcount;
- int frames[][];
- int maxfbuf;
- int blendfactor;
- BlendFrames(GLucose glucose) {
- super(glucose);
- maxfbuf = 30;
- blendfactor=30;
- fcount=0;
- frames = new int[maxfbuf][];
- for(int i=0; i<maxfbuf; i++){
- frames[i] = new int[model.points.size()];
- }
- }
- public void apply(int[] colors) {
- if(fcount<maxfbuf){
- for(int i=0; i<colors.length; i++){
- frames[(maxfbuf-1)-fcount][i]=colors[i];
- }
- fcount++;
- return;
- } else {
- for(int i=maxfbuf-1; i>0; i--){
- frames[i] = frames[i-1];
- }
- frames[0] = new int[model.points.size()];
-
- for(int i=0; i<colors.length; i++){
- int r,g,b;
- r=g=b=0;
- for(int j=0; j<blendfactor; j++){
- if(j==0) { frames[0][i] = colors[i]; }
- r += ((frames[j][i] >> 16) & 0xFF);
- g += ((frames[j][i] >> 8) & 0xFF);
- b += ((frames[j][i] >> 0) & 0xFF);
- }
- r/=blendfactor;
- g/=blendfactor;
- b/=blendfactor;
- colorMode(ARGB);
- colors[i] = (0xFF << 24) | (r << 16) | (g << 8) | b;
- colorMode(HSB);
- }
-
- }
- }
-}
-
-
-
-
-
-
-
-abstract class OSCPattern extends SCPattern {
- public OSCPattern(GLucose glucose){super(glucose);}
- public abstract void oscEvent(OscMessage msg);
-}
-
-class Ball {
- public int lastSeen;
- public float x,y;
- public Ball(){
- x=y=lastSeen=0;
- }
-}
-
-class OSC_Balls extends OSCPattern {
- Ball[] balls;
- public OSC_Balls(GLucose glucose){
- super(glucose);
- balls = new Ball[20];
- for(int i=0; i<balls.length; i++) { balls[i] = new Ball(); }
- }
- public void oscEvent(OscMessage msg){
- String pattern[] = split(msg.addrPattern(), "/");
- int ballnum = PApplet.parseInt(pattern[3]);
- balls[ballnum].lastSeen=millis();
- balls[ballnum].x = msg.get(0).floatValue();
- balls[ballnum].y = msg.get(1).floatValue();
- }
-
- public void run(double deltaMs){
- for(Point p: model.points){ colors[p.index]=0; }
- for(int i=1; i<balls.length; i++){
- if(millis() - balls[i].lastSeen < 1000) {
- for(Point p: model.points){
- int x = PApplet.parseInt(balls[i].x * 255.0f);
- int y = PApplet.parseInt(balls[i].y * 127.0f);
- if(p.x < x+4 && p.x > x-4 && p.y < y+4 && p.y > y-4) { colors[p.index] = 0xffFF0000; }
- }
- }
- }
- }
-}
-
-
-
-
-/*class ScreenScrape extends SCPattern {
- PImage pret;
- ScreenShot ss;
- public ScreenScrape(GLucose glucose) {
- super(glucose);
- System.loadLibrary("ScreenShot");
- pret = new PImage(8, 128, ARGB);
- ss = new ScreenShot();
- }
- void run(double deltaMs){
- int x=(1366/2)+516;
- int y=768-516;
- int w=8;
- int h=128;
- pret.pixels = ss.getScreenShotJNI2(x, y, w, h);
- //for(int i=0; i<px.length; i++){ pret.pixels[i] = px[i]; }
- //println(pret.get(10,10));
- for(Point p: model.points){
- colors[p.index] = pret.get((int(p.x)/8)*8, 128-int(p.y));
- }
- }
-}*/
-
-//----------------------------------------------------------------------------------------------------------------------------------
-int NumApcRows=4, NumApcCols=8;
-
-public boolean btwn (int a,int b,int c) { return a >= b && a <= c; }
-public boolean btwn (double a,double b,double c) { return a >= b && a <= c; }
-public float interp (float a, float b, float c) { return (1-a)*b + a*c; }
-public float randctr (float a) { return random(a) - a*.5f; }
-public float min (float a, float b, float c, float d) { return min(min(a,b),min(c,d)); }
-public float pointDist(Point p1, Point p2) { return dist(p1.x,p1.y,p1.z,p2.x,p2.y,p2.z); }
-public float xyDist (Point p1, Point p2) { return dist(p1.x,p1.y,p2.x,p2.y); }
-public float distToSeg(float x, float y, float x1, float y1, float x2, float y2) {
- float A = x - x1, B = y - y1, C = x2 - x1, D = y2 - y1;
- float dot = A * C + B * D, len_sq = C * C + D * D;
- float xx, yy,param = dot / len_sq;
-
- if (param < 0 || (x1 == x2 && y1 == y2)) { xx = x1; yy = y1; }
- else if (param > 1) { xx = x2; yy = y2; }
- else { xx = x1 + param * C;
- yy = y1 + param * D; }
- float dx = x - xx, dy = y - yy;
- return sqrt(dx * dx + dy * dy);
-}
-
-public class Pick {
- int NumPicks, Default ,
- CurRow , CurCol ,
- StartRow, EndRow ;
- String tag , Desc[] ;
-
- Pick (String label, int _Def, int _Num, int nStart, String d[]) {
- NumPicks = _Num; Default = _Def;
- StartRow = nStart; EndRow = StartRow + floor((NumPicks-1) / NumApcCols);
- tag = label; Desc = d;
- reset();
- }
-
- public int Cur() { return (CurRow-StartRow)*NumApcCols + CurCol; }
- public String CurDesc() { return Desc[Cur()]; }
- public void reset() { CurCol = Default % NumApcCols; CurRow = StartRow + Default / NumApcCols; }
-
- public boolean set(int r, int c) {
- if (!btwn(r,StartRow,EndRow) || !btwn(c,0,NumApcCols-1) ||
- !btwn((r-StartRow)*NumApcCols + c,0,NumPicks-1)) return false;
- CurRow=r; CurCol=c; return true;
- }
-}
-
-public class DBool {
- boolean def, b;
- String tag;
- int row, col;
- public void reset() { b = def; }
- public boolean set (int r, int c, boolean val) { if (r != row || c != col) return false; b = val; return true; }
- DBool(String _tag, boolean _def, int _row, int _col) {
- def = _def; b = _def; tag = _tag; row = _row; col = _col;
- }
-}
-//----------------------------------------------------------------------------------------------------------------------------------
-public class DPat extends SCPattern
-{
- ArrayList<Pick> picks = new ArrayList<Pick> ();
- ArrayList<DBool> bools = new ArrayList<DBool> ();
-
- PVector mMax, mCtr, mHalf;
-
- MidiOutput APCOut;
- int nMaxRow = 53;
- float LastJog = -1;
- float[] xWaveNz, yWaveNz;
- int nPoint , nPoints;
- PVector xyzJog = new PVector(), modmin;
-
- float NoiseMove = random(10000);
- BasicParameter pSpark, pWave, pRotX, pRotY, pRotZ, pSpin, pTransX, pTransY;
- DBool pXsym, pYsym, pRsym, pXdup, pXtrip, pJog, pGrey;
-
- public float lxh () { return lx.getBaseHuef(); }
- public int c1c (float a) { return round(100*constrain(a,0,1)); }
- public float interpWv(float i, float[] vals) { return interp(i-floor(i), vals[floor(i)], vals[ceil(i)]); }
- public void setNorm (PVector vec) { vec.set(vec.x/mMax.x, vec.y/mMax.y, vec.z/mMax.z); }
- public void setRand (PVector vec) { vec.set(random(mMax.x), random(mMax.y), random(mMax.z)); }
- public void setVec (PVector vec, Point p) { vec.set(p.x, p.y, p.z); }
- public void interpolate(float i, PVector a, PVector b) { a.set(interp(i,a.x,b.x), interp(i,a.y,b.y), interp(i,a.z,b.z)); }
- public void StartRun(double deltaMs) { }
- public float val (BasicParameter p) { return p.getValuef(); }
- public int CalcPoint(PVector p) { return lx.hsb(0,0,0); }
- public int blend3(int c1, int c2, int c3) { return blendColor(c1,blendColor(c2,c3,ADD),ADD); }
-
- public void rotateZ (PVector p, PVector o, float nSin, float nCos) { p.set( nCos*(p.x-o.x) - nSin*(p.y-o.y) + o.x , nSin*(p.x-o.x) + nCos*(p.y-o.y) + o.y,p.z); }
- public void rotateX (PVector p, PVector o, float nSin, float nCos) { p.set(p.x,nCos*(p.y-o.y) - nSin*(p.z-o.z) + o.y , nSin*(p.y-o.y) + nCos*(p.z-o.z) + o.z ); }
- public void rotateY (PVector p, PVector o, float nSin, float nCos) { p.set( nSin*(p.z-o.z) + nCos*(p.x-o.x) + o.x,p.y, nCos*(p.z-o.z) - nSin*(p.x-o.x) + o.z ); }
-
- public BasicParameter addParam(String label, double value) { BasicParameter p = new BasicParameter(label, value); addParameter(p); return p; }
-
- PVector vT1 = new PVector(), vT2 = new PVector();
- public float calcCone (PVector v1, PVector v2, PVector c) { vT1.set(v1); vT2.set(v2); vT1.sub(c); vT2.sub(c);
- return degrees(PVector.angleBetween(vT1,vT2)); }
-
- public Pick addPick(String name, int def, int _max, String[] desc) {
- Pick P = new Pick(name, def, _max+1, nMaxRow, desc);
- nMaxRow = P.EndRow + 1;
- picks.add(P);
- return P;
- }
-
- public boolean noteOff(Note note) {
- int row = note.getPitch(), col = note.getChannel();
- for (int i=0; i<bools.size(); i++) if (bools.get(i).set(row, col, false)) { presetManager.dirty(this); return true; }
- updateLights(); return false;
- }
-
- public boolean noteOn(Note note) {
- int row = note.getPitch(), col = note.getChannel();
- for (int i=0; i<picks.size(); i++) if (picks.get(i).set(row, col)) { presetManager.dirty(this); return true; }
- for (int i=0; i<bools.size(); i++) if (bools.get(i).set(row, col, true)) { presetManager.dirty(this); return true; }
- println("row: " + row + " col: " + col); return false;
- }
-
- public void onInactive() { uiDebugText.setText(""); }
- public void onReset() {
- for (int i=0; i<bools .size(); i++) bools.get(i).reset();
- for (int i=0; i<picks .size(); i++) picks.get(i).reset();
- presetManager.dirty(this);
- updateLights();
- }
-
- DPat(GLucose glucose) {
- super(glucose);
-
- pSpark = addParam("Sprk", 0);
- pWave = addParam("Wave", 0);
- pTransX = addParam("TrnX", .5f);
- pTransY = addParam("TrnY", .5f);
- pRotX = addParam("RotX", .5f);
- pRotY = addParam("RotY", .5f);
- pRotZ = addParam("RotZ", .5f);
- pSpin = addParam("Spin", .5f);
-
- nPoints = model.points.size();
- pXsym = new DBool("X-SYM", false, 48, 0); bools.add(pXsym );
- pYsym = new DBool("Y-SYM", false, 48, 1); bools.add(pYsym );
- pRsym = new DBool("R-SYM", false, 48, 2); bools.add(pRsym );
- pXdup = new DBool("X-DUP", false, 48, 3); bools.add(pXdup );
- pJog = new DBool("JOG" , false, 48, 4); bools.add(pJog );
- pGrey = new DBool("GREY" , false, 48, 5); bools.add(pGrey );
-
- modmin = new PVector(model.xMin, model.yMin, model.zMin);
- mMax = new PVector(model.xMax, model.yMax, model.zMax); mMax.sub(modmin);
- mCtr = new PVector(); mCtr.set(mMax); mCtr.mult(.5f);
- mHalf = new PVector(.5f,.5f,.5f);
- xWaveNz = new float[ceil(mMax.y)+1];
- yWaveNz = new float[ceil(mMax.x)+1];
-
- //println (model.xMin + " " + model.yMin + " " + model.zMin);
- //println (model.xMax + " " + model.yMax + " " + model.zMax);
- //for (MidiOutputDevice o: RWMidi.getOutputDevices()) { if (o.toString().contains("APC")) { APCOut = o.createOutput(); break;}}
- }
-
- public float spin() {
- float raw = val(pSpin);
- if (raw <= 0.45f) {
- return raw + 0.05f;
- } else if (raw >= 0.55f) {
- return raw - 0.05f;
- }
- return 0.5f;
- }
-
- public void setAPCOutput(MidiOutput output) {
- APCOut = output;
- }
-
- public void updateLights() { if (APCOut == null) return;
- for (int i = 0; i < NumApcRows; ++i)
- for (int j = 0; j < 8; ++j) APCOut.sendNoteOn(j, 53+i, 0);
- for (int i=0; i<picks .size(); i++) APCOut.sendNoteOn(picks.get(i).CurCol, picks.get(i).CurRow, 3);
- for (int i=0; i<bools .size(); i++) if (bools.get(i).b) APCOut.sendNoteOn (bools.get(i).col, bools.get(i).row, 1);
- else APCOut.sendNoteOff (bools.get(i).col, bools.get(i).row, 0);
- }
-
- public void run(double deltaMs)
- {
- if (deltaMs > 100) return;
-
- if (this == midiEngine.getFocusedDeck().getActivePattern()) {
- String Text1="", Text2="";
- for (int i=0; i<bools.size(); i++) if (bools.get(i).b) Text1 += " " + bools.get(i).tag + " ";
- for (int i=0; i<picks.size(); i++) Text1 += picks.get(i).tag + ": " + picks.get(i).CurDesc() + " ";
- uiDebugText.setText(Text1, Text2);
- }
-
- NoiseMove += deltaMs; NoiseMove = NoiseMove % 1e7f;
- StartRun (deltaMs);
- PVector P = new PVector(), tP = new PVector(), pSave = new PVector();
- PVector pTrans = new PVector(val(pTransX)*200-100, val(pTransY)*100-50,0);
- nPoint = 0;
-
- if (pJog.b) {
- float tRamp = (lx.tempo.rampf() % .25f);
- if (tRamp < LastJog) xyzJog.set(randctr(mMax.x*.2f), randctr(mMax.y*.2f), randctr(mMax.z*.2f));
- LastJog = tRamp;
- }
-
- // precalculate this stuff
- float wvAmp = val(pWave), sprk = val(pSpark);
- if (wvAmp > 0) {
- for (int i=0; i<ceil(mMax.x)+1; i++)
- yWaveNz[i] = wvAmp * (noise(i/(mMax.x*.3f)-(2e3f+NoiseMove)/1500.f) - .5f) * (mMax.y/2.f);
-
- for (int i=0; i<ceil(mMax.y)+1; i++)
- xWaveNz[i] = wvAmp * (noise(i/(mMax.y*.3f)-(1e3f+NoiseMove)/1500.f) - .5f) * (mMax.x/2.f);
- }
-
- for (Point p : model.points) { nPoint++;
- setVec(P,p);
- P.sub(modmin);
- P.sub(pTrans);
- if (sprk > 0) {P.y += sprk*randctr(50); P.x += sprk*randctr(50); P.z += sprk*randctr(50); }
- if (wvAmp > 0) P.y += interpWv(p.x-modmin.x, yWaveNz);
- if (wvAmp > 0) P.x += interpWv(p.y-modmin.y, xWaveNz);
- if (pJog.b) P.add(xyzJog);
-
-
- int cNew, cOld = colors[p.index];
- { tP.set(P); cNew = CalcPoint(tP); }
- if (pXsym.b) { tP.set(mMax.x-P.x,P.y,P.z); cNew = blendColor(cNew, CalcPoint(tP), ADD); }
- if (pYsym.b) { tP.set(P.x,mMax.y-P.y,P.z); cNew = blendColor(cNew, CalcPoint(tP), ADD); }
- if (pRsym.b) { tP.set(mMax.x-P.x,mMax.y-P.y,mMax.z-P.z); cNew = blendColor(cNew, CalcPoint(tP), ADD); }
- if (pXdup.b) { tP.set((P.x+mMax.x*.5f)%mMax.x,P.y,P.z); cNew = blendColor(cNew, CalcPoint(tP), ADD); }
- if (pGrey.b) { cNew = lx.hsb(0, 0, lx.b(cNew)); }
- colors[p.index] = cNew;
- }
- }
-}
-//----------------------------------------------------------------------------------------------------------------------------------
-class dTurn {
- dVertex v;
- int pos0, pos1;
- dTurn(int _pos0, dVertex _v, int _pos1) { v = _v; pos0 = _pos0; pos1 = _pos1; }
-}
-
-class dVertex {
- dVertex c0, c1, c2, c3, // connections on the cube
- opp, same; // opp - same strip, opp direction
- // same - same strut, diff strip, dir
- dTurn t0, t1, t2, t3;
- Strip s;
- int dir, ci; // dir -- 1 or -1.
- // ci -- color index
-
- dVertex(Strip _s, Point _p) { s = _s; ci = _p.index; }
- public Point getPoint(int i) { return s.points.get(dir>0 ? i : 15-i); }
- public void setOpp(dVertex _opp) { opp = _opp; dir = (ci < opp.ci ? 1 : -1); }
-}
-//----------------------------------------------------------------------------------------------------------------------------------
-class dPixel { dVertex v; int pos; dPixel(dVertex _v, int _pos) { v=_v; pos=_pos; } }
-class dLattice {
- public void addTurn (dVertex v0, int pos0, dVertex v1, int pos1) { dTurn t = new dTurn(pos0, v1, pos1);
- if (v0.t0 == null) { v0.t0=t; return; }
- if (v0.t1 == null) { v0.t1=t; return; }
- if (v0.t2 == null) { v0.t2=t; return; }
- if (v0.t3 == null) { v0.t3=t; return; }
- }
- public float dist2 (Strip s1, int pos1, Strip s2, int pos2) { return pointDist(s1.points.get(pos1), s2.points.get(pos2)); }
- public float pd2 (Point p1, float x, float y, float z) { return dist(p1.x,p1.y,p1.z,x,y,z); }
- public boolean sameSame (Strip s1, Strip s2) { return max(dist2(s1, 0, s2, 0), dist2(s1,15, s2,15)) < 5 ; } // same strut, same direction
- public boolean sameOpp (Strip s1, Strip s2) { return max(dist2(s1, 0, s2,15), dist2(s1,15, s2,0 )) < 5 ; } // same strut, opp direction
- public boolean sameBar (Strip s1, Strip s2) { return sameSame(s1,s2) || sameOpp(s1,s2); } // 2 strips on same strut
-
-
- public void addJoint (dVertex v1, dVertex v2) {
- // should probably replace parallel but further with the new one
- if (v1.c0 != null && sameBar(v2.s, v1.c0.s)) return;
- if (v1.c1 != null && sameBar(v2.s, v1.c1.s)) return;
- if (v1.c2 != null && sameBar(v2.s, v1.c2.s)) return;
- if (v1.c3 != null && sameBar(v2.s, v1.c3.s)) return;
-
- if (v1.c0 == null) v1.c0 = v2;
- else if (v1.c1 == null) v1.c1 = v2;
- else if (v1.c2 == null) v1.c2 = v2;
- else if (v1.c3 == null) v1.c3 = v2;
- }
-
- public dVertex v0(Strip s) { return (dVertex)s.obj1; }
- public dVertex v1(Strip s) { return (dVertex)s.obj2; }
-
- public dPixel getClosest(PVector p) {
- dVertex v = null; int pos=0; float d = 500;
-
- for (Strip s : glucose.model.strips) {
- float nd = pd2(s.points.get(0),p.x,p.y,p.z); if (nd < d) { v=v0(s); d=nd; pos=0; }
- if (nd > 30) continue;
- for (int k=0; k<=15; k++) {
- nd = pd2(s.points.get(k),p.x,p.y,p.z); if (nd < d) { v =v0(s); d=nd; pos=k; }
- }
- }
- return random(2) < 1 ? new dPixel(v,pos) : new dPixel(v.opp,15-pos);
- }
-
- dLattice() {
- lattice=this;
-
- for (Strip s : glucose.model.strips) {
- dVertex vrtx0 = new dVertex(s,s.points.get(0 )); s.obj1=vrtx0;
- dVertex vrtx1 = new dVertex(s,s.points.get(15)); s.obj2=vrtx1;
- vrtx0.setOpp(vrtx1); vrtx1.setOpp(vrtx0);
- }
-
- for (Strip s1 : glucose.model.strips) { for (Strip s2 : glucose.model.strips) {
- if (s1.points.get(0).index < s2.points.get(0).index) continue;
- int c=0;
- if (sameSame(s1,s2)) { v0(s1).same = v0(s2); v1(s1).same = v1(s2);
- v0(s2).same = v0(s1); v1(s2).same = v1(s1); continue; } // parallel
- if (sameOpp (s1,s2)) { v0(s1).same = v1(s2); v1(s1).same = v0(s2);
- v0(s2).same = v1(s1); v1(s2).same = v0(s1); continue; } // parallel
- if (dist2(s1, 0, s2, 0) < 5) { c++; addJoint(v1(s1), v0(s2)); addJoint(v1(s2), v0(s1)); }
- if (dist2(s1, 0, s2,15) < 5) { c++; addJoint(v1(s1), v1(s2)); addJoint(v0(s2), v0(s1)); }
- if (dist2(s1,15, s2, 0) < 5) { c++; addJoint(v0(s1), v0(s2)); addJoint(v1(s2), v1(s1)); }
- if (dist2(s1,15, s2,15) < 5) { c++; addJoint(v0(s1), v1(s2)); addJoint(v0(s2), v1(s1)); }
- if (c>0) continue;
-
- // Are they touching at all?
- int pos1=0, pos2=0; float d = 100;
-
- while (pos1 < 15 || pos2 < 15) {
- float oldD = d;
- if (pos1<15) { float d2 = dist2(s1, pos1+1, s2, pos2+0); if (d2 < d) { d=d2; pos1++; } }
- if (pos2<15) { float d2 = dist2(s1, pos1+0, s2, pos2+1); if (d2 < d) { d=d2; pos2++; } }
- if (d > 50 || oldD == d) break ;
- }
-
- if (d>5) continue;
- addTurn(v0(s1), pos1, v0(s2), pos2); addTurn(v1(s1), 15-pos1, v0(s2), pos2);
- addTurn(v0(s2), pos2, v0(s1), pos1); addTurn(v1(s2), 15-pos2, v0(s1), pos1);
- }}
- }
-}
-
-dLattice lattice;
-//----------------------------------------------------------------------------------------------------------------------------------
-
-class Graphic
-{
- public boolean changed = false;
- public int position = 0;
- public ArrayList<Integer> graphicBuffer;
- Graphic()
- {
- graphicBuffer = new ArrayList<Integer>();
- }
- public int width()
- {
- return graphicBuffer.size();
- }
-
-
-};
-class Granim extends Graphic
-{
- HashMap<String,Graphic> displayList;
-
- Granim()
- {
- displayList = new HashMap<String,Graphic>();
- }
- public Graphic addGraphic(String name, Graphic g)
- {
- while(width()< g.position+1)
- {
- graphicBuffer.add(lx.hsb(0,0,0));
- }
- drawAll();
- displayList.put(name , g);
- changed =true;
- return g;
- }
-
- public Graphic getGraphicByName(String name)
- {
- return displayList.get(name);
- }
-
- public void update()
- {
-
- for(Graphic g : displayList.values())
- {
- if(g instanceof Granim)
- {
- ((Granim) g).update();
-
- }
- changed = changed || g.changed;
- if(changed)
- {
- while(width()< g.position + g.width())
- {
- graphicBuffer.add(lx.hsb(0,0,0));
- }
- if(g.changed)
- {
- drawOne(g);
- g.changed =false;
- }
- }
- }
- changed = false;
-
- }
- public void drawOne(Graphic g)
- {
- graphicBuffer.addAll(g.position,g.graphicBuffer);
- }
- public void drawAll()
- {
- }
-};
-class GranimPattern extends SCPattern
-{
- HashMap<String,Graphic> displayList;
-
- GranimPattern(GLucose glucose)
- {
- super(glucose);
- displayList = new HashMap<String,Graphic>();
- }
-
- public Graphic addGraphic(String name, Graphic g)
- {
- displayList.put(name,g);
- return g;
- }
-
- public Graphic getGraphicByName(String name)
- {
- return displayList.get(name);
- }
-
- public void run(double deltaMs)
- {
- drawToPointList();
- }
- private Integer[] gbuffer;
- public void drawToPointList()
- {
- for(Graphic g : displayList.values())
- {
- if(g instanceof Granim)
- {
- ((Granim) g).update();
- }
- List<Point> drawList = model.points.subList(Math.min(g.position,colors.length-1), Math.min(g.position + g.width(),colors.length-1));
- //println("drawlistsize "+drawList.size());
-
- gbuffer = g.graphicBuffer.toArray(new Integer[0]);
-
- for (int i=0; i < drawList.size(); i++)
- {
- colors[drawList.get(i).index] = gbuffer[i];
- }
- g.changed = false;
- }
- }
-
-};
-
-class RedsGraphic extends Graphic
-{
- RedsGraphic()
- {
- super();
- drawit(10);
- }
- RedsGraphic(int len)
- {
- super();
- drawit(len);
-
- }
- public void drawit(int len)
- {
- for(int i = 0; i < len ;i++)
- {
- graphicBuffer.add(lx.hsb(0,255,255));
- }
- }
-};
-
-class RedsGranim extends Granim
-{
- RedsGranim()
- {
- super();
- addGraphic("myreds", new RedsGraphic(10));
- }
- RedsGranim(int len)
- {
- super();
- addGraphic("myreds", new RedsGraphic(len));
- }
- public float count = 0.0f;
- public void update()
- {
- Graphic g=getGraphicByName("myreds");
- g.position = Math.round(sin(count)*20)+100;
- count+= 0.1f;
- if(count>Math.PI*2)
- {
- count=0;
- }
- super.update();
- }
-
-};
-
-class RandomsGranim extends Granim
-{
- private int _len =0 ;
- RandomsGranim()
- {
- super();
- _len =100;
- addGraphic("myrandoms", makeGraphic(_len));
- }
- RandomsGranim(int len)
- {
- super();
- _len=len;
- addGraphic("myrandoms", makeGraphic(len));
- }
- int colorLid=0;
- public Graphic makeGraphic(int len)
- {
-
- int[] colors= new int[len];
- for(int i =0;i<len;i++)
- {
- colors[i]=(int) Math.round(Math.random()*80)+colorLid;
-
- }
- colorLid+=4;
- return new ColorDotsGraphic(colors);
- }
- private int count =1;
- private int instanceCount =0;
- public void update()
- {
-
- if(instanceCount<90 && count % 20==0)
- {
- instanceCount++;
- Graphic h=addGraphic("myrandoms_"+instanceCount, makeGraphic(_len));
- h.position = instanceCount*(_len+100);
- //println("one more " + instanceCount+" at "+h.position);
- count=0;
- changed = true;
- }
- count++;
- super.update();
- }
-
-};
-
-
-class ColorDotsGraphic extends Graphic
-{
- ColorDotsGraphic(int[] colorSequence)
- {
- super();
- for (int colorVal : colorSequence)
- {
- graphicBuffer.add(lx.hsb(colorVal, 255, 255));
- }
- changed = true;
- }
-};
-int BLACK = 0xff000000;
-
-class Gimbal extends SCPattern {
-
- private final boolean DEBUG_MANUAL_ABG = false;
- private final int MAXIMUM_BEATS_PER_REVOLUTION = 100;
-
- private boolean first_run = true;
- private final Projection projection;
- private final BasicParameter beatsPerRevolutionParam = new BasicParameter("SLOW", 20.f/MAXIMUM_BEATS_PER_REVOLUTION);
- private final BasicParameter hueDeltaParam = new BasicParameter("HUED", 60.f/360);
- private final BasicParameter fadeFromCoreParam = new BasicParameter("FADE", 1);
- private final BasicParameter girthParam = new BasicParameter("GRTH", .18f);
- private final BasicParameter ringExtendParam = new BasicParameter("XTND", 1);
- private final BasicParameter relativeSpeedParam = new BasicParameter("RLSP", .83f);
- private final BasicParameter sizeParam = new BasicParameter("SIZE", .9f);
-
- private final BasicParameter aP = new BasicParameter("a", 0);
- private final BasicParameter bP = new BasicParameter("b", 0);
- private final BasicParameter gP = new BasicParameter("g", 0);
-
- Gimbal(GLucose glucose) {
- super(glucose);
- projection = new Projection(model);
- addParameter(beatsPerRevolutionParam);
- addParameter(hueDeltaParam);
- addParameter(fadeFromCoreParam);
- addParameter(girthParam);
- addParameter(ringExtendParam);
- addParameter(relativeSpeedParam);
- addParameter(sizeParam);
-
- if (DEBUG_MANUAL_ABG) {
- addParameter(aP);
- addParameter(bP);
- addParameter(gP);
- }
- }
-
- float a = 0, b = 0, g = 0;
-
- public void run(double deltaMs) {
-
- if (DEBUG_MANUAL_ABG) {
- a = aP.getValuef() * (2 * PI);
- b = bP.getValuef() * (2 * PI);
- g = gP.getValuef() * (2 * PI);
- } else {
- float relativeSpeed = relativeSpeedParam.getValuef();
- float time = millis() / 1000.f;
-
- int beatsPerRevolution = (int) (beatsPerRevolutionParam.getValuef() * MAXIMUM_BEATS_PER_REVOLUTION) + 1;
- float radiansPerMs = 2 * PI // radians / revolution
- / beatsPerRevolution // beats / revolution
- * lx.tempo.bpmf() // BPM beats / min
- / 60 // sec / min
- / 1000; // ms / sec
-
- a += deltaMs * radiansPerMs * pow(relativeSpeed, 0);
- b += deltaMs * radiansPerMs * pow(relativeSpeed, 1);
- g += deltaMs * radiansPerMs * pow(relativeSpeed, 2);
- a %= 2 * PI;
- b %= 2 * PI;
- g %= 2 * PI;
- }
-
- float hue = lx.getBaseHuef();
- float hue_delta = hueDeltaParam.getValuef() * 360;
-
- float radius1 = model.xMax / 2 * sizeParam.getValuef();
- float radius2 = ((model.xMax + model.yMax) / 2) / 2 * sizeParam.getValuef();
- float radius3 = model.yMax / 2 * sizeParam.getValuef();
- float girth = model.xMax * girthParam.getValuef();
- Ring ring1 = new Ring((hue + hue_delta * 0) % 360, radius1, girth);
- Ring ring2 = new Ring((hue + hue_delta * 1) % 360, radius2, girth);
- Ring ring3 = new Ring((hue + hue_delta * 2) % 360, radius3, girth);
-
- projection.reset(model)
- // Translate so the center of the car is the origin
- .translateCenter(model, 0, 0, 0);
-
- for (Coord c : projection) {
- //if (first_run) println(c.x + "," + c.y + "," + c.z);
-
- rotate3d(c, a, 0, 0);
- rotate3d(c, PI/4, PI/4, PI/4);
- int color1 = ring1.colorFor(c);
-
- rotate3d(c, 0, b, 0);
- int color2 = ring2.colorFor(c);
-
- rotate3d(c, 0, 0, g);
- int color3 = ring3.colorFor(c);
-
- colors[c.index] = specialBlend(color1, color2, color3);
- }
-
- first_run = false;
- }
-
- class Ring {
-
- float hue;
- float radius, girth;
-
- public Ring(float hue, float radius, float girth) {
- this.hue = hue;
- this.radius = radius;
- this.girth = girth;
- }
-
- public int colorFor(Coord c) {
- float theta = atan2(c.y, c.x);
- float nearest_circle_x = cos(theta) * radius;
- float nearest_circle_y = sin(theta) * radius;
- float nearest_circle_z = 0;
-
- float distance_to_circle
- = sqrt(pow(nearest_circle_x - c.x, 2)
- + pow(nearest_circle_y - c.y, 2)
- + pow(nearest_circle_z - c.z * ringExtendParam.getValuef(), 2));
-
- float xy_distance = sqrt(c.x*c.x + c.y*c.y);
- return lx.hsb(this.hue, 100, (1 - distance_to_circle / girth * fadeFromCoreParam.getValuef()) * 100);
- }
-
- }
-
-}
-
-
-
-
-
-
-class Zebra extends SCPattern {
-
- private final Projection projection;
- SinLFO angleM = new SinLFO(0, PI * 2, 30000);
-
-/*
- SinLFO x, y, z, dx, dy, dz;
- float cRad;
- _P size;
- */
-
- Zebra(GLucose glucose) {
- super(glucose);
- projection = new Projection(model);
-
- addModulator(angleM).trigger();
- }
-
- public int colorFor(Coord c) {
- float hue = lx.getBaseHuef();
-
-
-
-
-/* SLIDE ALONG
- c.x = c.x + millis() / 100.f;
- */
-
-
-
- int stripe_count = 12;
- float stripe_width = model.xMax / (float)stripe_count;
- if (Math.floor((c.x) / stripe_width) % 2 == 0) {
- return lx.hsb(hue, 100, 100);
- } else {
- return lx.hsb((hue + 90) % 360, 100, 100);
- }
-
-
- /* OCTANTS
-
- if ((isPositiveBit(c.x) + isPositiveBit(c.y) + isPositiveBit(c.z)) % 2 == 0) {
- return lx.hsb(lx.getBaseHuef(), 100, 100);
- } else {
- return lx.hsb(0, 0, 0);
- }
- */
- }
-
- public int isPositiveBit(float f) {
- return f > 0 ? 1 : 0;
- }
-
- public void run(double deltaMs) {
- float a = (millis() / 1000.f) % (2 * PI);
- float b = (millis() / 1200.f) % (2 * PI);
- float g = (millis() / 1600.f) % (2 * PI);
-
- projection.reset(model)
- // Translate so the center of the car is the origin
- .translateCenter(model, 0, 0, 0);
-
- for (Coord c : projection) {
-// rotate3d(c, a, b, g);
- colors[c.index] = colorFor(c);
- }
-
- first_run = false;
- }
-
-
- // Utility!
- boolean first_run = true;
- private void log(String s) {
- if (first_run) {
- println(s);
- }
- }
-
-
-}
-
-public void rotate3d(Coord c, float a /* roll */, float b /* pitch */, float g /* yaw */) {
- float cosa = cos(a);
- float cosb = cos(b);
- float cosg = cos(g);
- float sina = sin(a);
- float sinb = sin(b);
- float sing = sin(g);
-
- float a1 = cosa*cosb;
- float a2 = cosa*sinb*sing - sina*cosg;
- float a3 = cosa*sinb*cosg + sina*sing;
- float b1 = sina*cosb;
- float b2 = sina*sinb*sing + cosa*cosg;
- float b3 = sina*sinb*cosg - cosa*sing;
- float c1 = -sinb;
- float c2 = cosb*sing;
- float c3 = cosb*cosg;
-
- float[] cArray = { c.x, c.y, c.z };
- c.x = dotProduct(new float[] {a1, a2, a3}, cArray);
- c.y = dotProduct(new float[] {b1, b2, b3}, cArray);
- c.z = dotProduct(new float[] {c1, c2, c3}, cArray);
-}
-
-public float dotProduct(float[] a, float[] b) {
- float ret = 0;
- for (int i = 0 ; i < a.length; ++i) {
- ret += a[i] * b[i];
- }
- return ret;
-}
-
-public int specialBlend(int c1, int c2, int c3) {
- float h1 = hue(c1);
- float h2 = hue(c2);
- float h3 = hue(c3);
-
- // force h1 < h2 < h3
- while (h2 < h1) {
- h2 += 360;
- }
- while (h3 < h2) {
- h3 += 360;
- }
-
- float s1 = saturation(c1);
- float s2 = saturation(c2);
- float s3 = saturation(c3);
-
- float b1 = brightness(c1);
- float b2 = brightness(c2);
- float b3 = brightness(c3);
- float relative_b1 = b1 / (b1 + b2 + b3);
- float relative_b2 = b2 / (b1 + b2 + b3);
- float relative_b3 = b3 / (b1 + b2 + b3);
-
- return lx.hsb(
- (h1 * relative_b1 + h2 * relative_b1 + h3 * relative_b3) % 360,
- s1 * relative_b1 + s2 * relative_b2 + s3 * relative_b3,
- max(max(b1, b2), b3)
- );
-}
-
-/**
- * A Projection of sin wave in 3d space.
- * It sort of looks like an animal swiming around in water.
- * Angle sliders are sort of a work in progress that allow yo to change the crazy ways it moves around.
- * Hue slider allows you to control how different the colors are along the wave.
- *
- * This code copied heavily from Tim and Slee.
- */
-class Swim extends SCPattern {
-
- // Projection stuff
- private final Projection projection;
- SawLFO rotation = new SawLFO(0, TWO_PI, 19000);
- SinLFO yPos = new SinLFO(-25, 25, 12323);
- final BasicParameter xAngle = new BasicParameter("XANG", 0.9f);
- final BasicParameter yAngle = new BasicParameter("YANG", 0.3f);
- final BasicParameter zAngle = new BasicParameter("ZANG", 0.3f);
-
- final BasicParameter hueScale = new BasicParameter("HUE", 0.3f);
-
- public Swim(GLucose glucose) {
- super(glucose);
- projection = new Projection(model);
-
- addParameter(xAngle);
- addParameter(yAngle);
- addParameter(zAngle);
- addParameter(hueScale);
-
- addModulator(rotation).trigger();
- addModulator(yPos).trigger();
- }
-
-
- int beat = 0;
- float prevRamp = 0;
- public 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.0f * 2 * PI;
-
- float denominator = max(xAngle.getValuef() + yAngle.getValuef() + zAngle.getValuef(), 1);
-
- projection.reset(model)
- // Swim around the world
- .rotate(rotation.getValuef(), xAngle.getValuef() / denominator, yAngle.getValuef() / denominator, zAngle.getValuef() / denominator)
- .translateCenter(model, 0, 50 + yPos.getValuef(), 0);
-
- float model_height = model.yMax - model.yMin;
- float model_width = model.xMax - model.xMin;
- for (Coord 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.4f * (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 hue_color = (lx.getBaseHuef() + hueScale.getValuef() * (abs(p.x-model.xMax/2.f)*.3f + abs(p.y-model.yMax/2)*.9f + abs(p.z - model.zMax/2.f))) % 360;
- colors[p.index] = lx.hsb(hue_color, 70, v1);
- }
- }
-}
-
-/**
- * The idea here is to do another sin wave pattern, but with less rotation and more of a breathing / heartbeat affect with spheres above / below the wave.
- * This is not done.
- */
-class Balance extends SCPattern {
-
- final BasicParameter hueScale = new BasicParameter("Hue", 0.4f);
-
- class Sphere {
- float x, y, z;
- }
-
-
- // Projection stuff
- private final Projection projection;
-
- SinLFO sphere1Z = new SinLFO(0, 0, 15323);
- SinLFO sphere2Z = new SinLFO(0, 0, 8323);
- SinLFO rotationX = new SinLFO(-PI/32, PI/32, 9000);
- SinLFO rotationY = new SinLFO(-PI/16, PI/16, 7000);
- SinLFO rotationZ = new SinLFO(-PI/16, PI/16, 11000);
- SawLFO phaseLFO = new SawLFO(0, 2 * PI, 5000 - 4500 * 0.5f);
- final BasicParameter phaseParam = new BasicParameter("Spd", 0.5f);
- final BasicParameter crazyParam = new BasicParameter("Crzy", 0.2f);
-
-
- private final Sphere[] spheres;
- private final float centerX, centerY, centerZ, modelHeight, modelWidth, modelDepth;
- SinLFO heightMod = new SinLFO(0.8f, 1.9f, 17298);
-
- public Balance(GLucose glucose) {
- super(glucose);
-
- projection = new Projection(model);
-
- addParameter(hueScale);
- addParameter(phaseParam);
- addParameter(crazyParam);
-
- spheres = new Sphere[2];
- centerX = (model.xMax + model.xMin) / 2;
- centerY = (model.yMax + model.yMin) / 2;
- centerZ = (model.zMax + model.zMin) / 2;
- modelHeight = model.yMax - model.yMin;
- modelWidth = model.xMax - model.xMin;
- modelDepth = model.zMax - model.zMin;
-
- spheres[0] = new Sphere();
- spheres[0].x = 1*modelWidth/2 + model.xMin;
- spheres[0].y = centerY + 20;
- spheres[0].z = centerZ;
-
- spheres[1] = new Sphere();
- spheres[1].x = model.xMin;
- spheres[1].y = centerY - 20;
- spheres[1].z = centerZ;
-
- addModulator(rotationX).trigger();
- addModulator(rotationY).trigger();
- addModulator(rotationZ).trigger();
-
-
- addModulator(sphere1Z).trigger();
- addModulator(sphere2Z).trigger();
- addModulator(phaseLFO).trigger();
-
- addModulator(heightMod).trigger();
- }
-
- public void onParameterChanged(LXParameter parameter) {
- if (parameter == phaseParam) {
- phaseLFO.setDuration(5000 - 4500 * parameter.getValuef());
- }
- }
-
- int beat = 0;
- float prevRamp = 0;
- public 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 = phaseLFO.getValuef();
-
- float crazy_factor = crazyParam.getValuef() / 0.2f;
- projection.reset(model)
- .rotate(rotationZ.getValuef() * crazy_factor, 0, 1, 0)
- .rotate(rotationX.getValuef() * crazy_factor, 0, 0, 1)
- .rotate(rotationY.getValuef() * crazy_factor, 0, 1, 0);
-
- for (Coord p : projection) {
- float x_percentage = (p.x - model.xMin)/modelWidth;
-
- float y_in_range = heightMod.getValuef() * (2*p.y - model.yMax - model.yMin) / modelHeight;
- float sin_x = sin(PI / 2 + phase + 2 * PI * x_percentage);
-
- // Color fade near the top of the sin wave
- float v1 = max(0, 100 * (1 - 4*abs(sin_x - y_in_range)));
-
- float hue_color = (lx.getBaseHuef() + hueScale.getValuef() * (abs(p.x-model.xMax/2.f) + abs(p.y-model.yMax/2)*.2f + abs(p.z - model.zMax/2.f)*.5f)) % 360;
- int c = lx.hsb(hue_color, 80, v1);
-
- // Now draw the spheres
- for (Sphere s : spheres) {
- float phase_x = (s.x - phase / (2 * PI) * modelWidth) % modelWidth;
- float x_dist = LXUtils.wrapdistf(p.x, phase_x, modelWidth);
-
- float sphere_z = (s == spheres[0]) ? (s.z + sphere1Z.getValuef()) : (s.z - sphere2Z.getValuef());
-
-
- float d = sqrt(pow(x_dist, 2) + pow(p.y - s.y, 2) + pow(p.z - sphere_z, 2));
-
- float distance_from_beat = (beat % 2 == 1) ? 1 - ramp : ramp;
-
- min(ramp, 1-ramp);
-
- float r = 40 - pow(distance_from_beat, 0.75f) * 20;
-
- float distance_value = max(0, 1 - max(0, d - r) / 10);
- float beat_value = 1.0f;
-
- float value = min(beat_value, distance_value);
-
- float sphere_color = (lx.getBaseHuef() - (1 - hueScale.getValuef()) * d/r * 45) % 360;
-
- c = blendColor(c, lx.hsb((sphere_color + 270) % 360, 60, min(1, value) * 100), ADD);
- }
- colors[p.index] = c;
- }
- }
-}
-class Cathedrals extends SCPattern {
-
- private final BasicParameter xpos = new BasicParameter("XPOS", 0.5f);
- private final BasicParameter wid = new BasicParameter("WID", 0.5f);
- private final BasicParameter arms = new BasicParameter("ARMS", 0.5f);
- private final BasicParameter sat = new BasicParameter("SAT", 0.5f);
- private GraphicEQ eq;
-
- Cathedrals(GLucose glucose) {
- super(glucose);
- addParameter(xpos);
- addParameter(wid);
- addParameter(arms);
- addParameter(sat);
- }
-
- protected void onActive() {
- if (eq == null) {
- eq = new GraphicEQ(lx, 16);
- eq.slope.setValue(0.7f);
- eq.range.setValue(0.4f);
- eq.attack.setValue(0.4f);
- eq.release.setValue(0.4f);
- addParameter(eq.level);
- addParameter(eq.range);
- addParameter(eq.attack);
- addParameter(eq.release);
- addParameter(eq.slope);
- }
- }
-
-
- public void run(double deltaMs) {
- eq.run(deltaMs);
- float bassLevel = eq.getAverageLevel(0, 4);
- float trebleLevel = eq.getAverageLevel(8, 6);
-
- float falloff = 100 / (2 + 14*wid.getValuef());
- float cx = model.xMin + (model.xMax-model.xMin) * xpos.getValuef();
- float barm = 12 + 60*arms.getValuef()*max(0, 2*(bassLevel-0.1f));
- float tarm = 12 + 60*arms.getValuef()*max(0, 2*(trebleLevel-0.1f));
-
- float arm = 0;
- float middle = 0;
-
- float sf = 100.f / (70 - 69.9f*sat.getValuef());
-
- for (Point p : model.points) {
- float d = MAX_FLOAT;
- if (p.y > model.cy) {
- arm = tarm;
- middle = model.yMax * 3/5.f;
- } else {
- arm = barm;
- middle = model.yMax * 1/5.f;
- }
- if (abs(p.x - cx) < arm) {
- d = min(abs(p.x - cx), abs(p.y - middle));
- }
- colors[p.index] = color(
- (lx.getBaseHuef() + .2f*abs(p.y - model.cy)) % 360,
- min(100, sf*dist(abs(p.x - cx), p.y, arm, middle)),
- max(0, 120 - d*falloff));
- }
- }
-}
-
-class MidiMusic extends SCPattern {
-
- private final Stack<LXLayer> newLayers = new Stack<LXLayer>();
-
- private final Map<Integer, LightUp> lightMap = new HashMap<Integer, LightUp>();
- private final List<LightUp> lights = new ArrayList<LightUp>();
- private final BasicParameter lightSize = new BasicParameter("SIZE", 0.5f);
-
- private final List<Sweep> sweeps = new ArrayList<Sweep>();
-
- private final LinearEnvelope sparkle = new LinearEnvelope(0, 1, 500);
- private boolean sparkleDirection = true;
- private float sparkleBright = 100;
-
- private final BasicParameter wave = new BasicParameter("WAVE", 0);
-
- MidiMusic(GLucose glucose) {
- super(glucose);
- addParameter(lightSize);
- addParameter(wave);
- addModulator(sparkle).setValue(1);
- }
-
- public void onReset() {
- for (LightUp light : lights) {
- light.noteOff(null);
- }
- }
-
- class Sweep extends LXLayer {
-
- final LinearEnvelope position = new LinearEnvelope(0, 1, 1000);
- float bright = 100;
- float falloff = 10;
-
- Sweep() {
- addModulator(position);
- }
-
- public void run(double deltaMs, int[] colors) {
- if (!position.isRunning()) {
- return;
- }
- float posf = position.getValuef();
- for (Point p : model.points) {
- colors[p.index] = blendColor(colors[p.index], color(
- (lx.getBaseHuef() + .2f*abs(p.x - model.cx) + .2f*abs(p.y - model.cy)) % 360,
- 100,
- max(0, bright - posf*100 - falloff*abs(p.y - posf*model.yMax))
- ), ADD);
- }
- }
- }
-
- class LightUp extends LXLayer {
-
- private final LinearEnvelope brt = new LinearEnvelope(0, 0, 0);
- private final Accelerator yPos = new Accelerator(0, 0, 0);
- private float xPos;
-
- LightUp() {
- addModulator(brt);
- addModulator(yPos);
- }
-
- public boolean isAvailable() {
- return brt.getValuef() <= 0;
- }
-
- public void noteOn(Note note) {
- xPos = lerp(0, model.xMax, constrain(0.5f + (note.getPitch() - 60) / 28.f, 0, 1));
- yPos.setValue(lerp(20, model.yMax*.72f, note.getVelocity() / 127.f)).stop();
- brt.setRangeFromHereTo(lerp(40, 100, note.getVelocity() / 127.f), 20).start();
- }
-
- public void noteOff(Note note) {
- yPos.setVelocity(0).setAcceleration(-380).start();
- brt.setRangeFromHereTo(0, 1000).start();
- }
-
- public void run(double deltaMs, int[] colors) {
- float bVal = brt.getValuef();
- if (bVal <= 0) {
- return;
- }
- float yVal = yPos.getValuef();
- for (Point p : model.points) {
- float falloff = 6 - 5*lightSize.getValuef();
- float b = max(0, bVal - falloff*dist(p.x, p.y, xPos, yVal));
- if (b > 0) {
- colors[p.index] = blendColor(colors[p.index], lx.hsb(
- (lx.getBaseHuef() + .2f*abs(p.x - model.cx) + .2f*abs(p.y - model.cy)) % 360,
- 100,
- b
- ), ADD);
- }
- }
- }
- }
-
- private LightUp getLight() {
- for (LightUp light : lights) {
- if (light.isAvailable()) {
- return light;
- }
- }
- LightUp newLight = new LightUp();
- lights.add(newLight);
- synchronized(newLayers) {
- newLayers.push(newLight);
- }
- return newLight;
- }
-
- private Sweep getSweep() {
- for (Sweep s : sweeps) {
- if (!s.position.isRunning()) {
- return s;
- }
- }
- Sweep newSweep = new Sweep();
- sweeps.add(newSweep);
- synchronized(newLayers) {
- newLayers.push(newSweep);
- }
- return newSweep;
- }
-
- public synchronized boolean noteOn(Note note) {
- if (note.getChannel() == 0) {
- LightUp light = getLight();
- lightMap.put(note.getPitch(), light);
- light.noteOn(note);
- } else if (note.getChannel() == 1) {
- } else if (note.getChannel() == 9) {
- if (note.getVelocity() > 0) {
- switch (note.getPitch()) {
- case 36:
- Sweep s = getSweep();
- s.bright = 50 + note.getVelocity() / 127.f * 50;
- s.falloff = 20 - note.getVelocity() / 127.f * 17;
- s.position.trigger();
- break;
- case 37:
- sparkleBright = note.getVelocity() / 127.f * 100;
- sparkleDirection = true;
- sparkle.trigger();
- break;
- case 38:
- sparkleBright = note.getVelocity() / 127.f * 100;
- sparkleDirection = false;
- sparkle.trigger();
- break;
- case 39:
- effects.boom.trigger();
- break;
- case 40:
- effects.flash.trigger();
- break;
- }
- }
- }
- return true;
- }
-
- public synchronized boolean noteOff(Note note) {
- if (note.getChannel() == 0) {
- LightUp light = lightMap.get(note.getPitch());
- if (light != null) {
- light.noteOff(note);
- }
- }
- return true;
- }
-
- final float[] wval = new float[16];
- float wavoff = 0;
-
- public synchronized void run(double deltaMs) {
- wavoff += deltaMs * .001f;
- for (int i = 0; i < wval.length; ++i) {
- wval[i] = model.cy + 0.2f * model.yMax/2.f * sin(wavoff + i / 1.9f);
- }
- float sparklePos = (sparkleDirection ? sparkle.getValuef() : (1 - sparkle.getValuef())) * (Cube.POINTS_PER_STRIP)/2.f;
- float maxBright = sparkleBright * (1 - sparkle.getValuef());
- for (Strip s : model.strips) {
- int i = 0;
- for (Point p : s.points) {
- int wavi = (int) constrain(p.x / model.xMax * wval.length, 0, wval.length-1);
- float wavb = max(0, wave.getValuef()*100.f - 8.f*abs(p.y - wval[wavi]));
- colors[p.index] = color(
- (lx.getBaseHuef() + .2f*abs(p.x - model.cx) + .2f*abs(p.y - model.cy)) % 360,
- 100,
- constrain(wavb + max(0, maxBright - 40.f*abs(sparklePos - abs(i - (Cube.POINTS_PER_STRIP-1)/2.f))), 0, 100)
- );
- ++i;
- }
- }
-
- if (!newLayers.isEmpty()) {
- synchronized(newLayers) {
- while (!newLayers.isEmpty()) {
- addLayer(newLayers.pop());
- }
- }
- }
- }
-}
-
-class Pulley extends SCPattern {
-
- final int NUM_DIVISIONS = 16;
- private final Accelerator[] gravity = new Accelerator[NUM_DIVISIONS];
- private final Click[] delays = new Click[NUM_DIVISIONS];
-
- private final Click reset = new Click(9000);
- private boolean isRising = false;
-
- private BasicParameter sz = new BasicParameter("SIZE", 0.5f);
- private BasicParameter beatAmount = new BasicParameter("BEAT", 0);
-
- Pulley(GLucose glucose) {
- super(glucose);
- for (int i = 0; i < NUM_DIVISIONS; ++i) {
- addModulator(gravity[i] = new Accelerator(0, 0, 0));
- addModulator(delays[i] = new Click(0));
- }
- addModulator(reset).start();
- addParameter(sz);
- addParameter(beatAmount);
- trigger();
-
- }
-
- private void trigger() {
- isRising = !isRising;
- int i = 0;
- for (Accelerator g : gravity) {
- if (isRising) {
- g.setSpeed(random(20, 33), 0).start();
- } else {
- g.setVelocity(0).setAcceleration(-420);
- delays[i].setDuration(random(0, 500)).trigger();
- }
- ++i;
- }
- }
-
- public void run(double deltaMs) {
- if (reset.click()) {
- trigger();
- }
-
- if (isRising) {
- // Fucking A, had to comment this all out because of that bizarre
- // Processing bug where some simple loop takes an absurd amount of
- // time, must be some pre-processor bug
-// for (Accelerator g : gravity) {
-// if (g.getValuef() > model.yMax) {
-// g.stop();
-// } else if (g.getValuef() > model.yMax*.55) {
-// if (g.getVelocityf() > 10) {
-// g.setAcceleration(-16);
-// } else {
-// g.setAcceleration(0);
-// }
-// }
-// }
- } else {
- int j = 0;
- for (Click d : delays) {
- if (d.click()) {
- gravity[j].start();
- d.stop();
- }
- ++j;
- }
- for (Accelerator g : gravity) {
- if (g.getValuef() < 0) {
- g.setValue(-g.getValuef());
- g.setVelocity(-g.getVelocityf() * random(0.74f, 0.84f));
- }
- }
- }
-
- // A little silliness to test the grid API
- if (midiEngine != null && midiEngine.getFocusedPattern() == this) {
- for (int i = 0; i < 5; ++i) {
- for (int j = 0; j < 8; ++j) {
- int gi = (int) constrain(j * NUM_DIVISIONS / 8, 0, NUM_DIVISIONS-1);
- float b = 1 - 4.f*abs((6-i)/6.f - gravity[gi].getValuef() / model.yMax);
- midiEngine.grid.setState(i, j, (b < 0) ? 0 : 3);
- }
- }
- }
-
- float fPos = 1 - lx.tempo.rampf();
- if (fPos < .2f) {
- fPos = .2f + 4 * (.2f - fPos);
- }
- float falloff = 100.f / (3 + sz.getValuef() * 36 + fPos * beatAmount.getValuef()*48);
- for (Point p : model.points) {
- int gi = (int) constrain((p.x - model.xMin) * NUM_DIVISIONS / (model.xMax - model.xMin), 0, NUM_DIVISIONS-1);
- colors[p.index] = lx.hsb(
- (lx.getBaseHuef() + abs(p.x - model.cx)*.8f + p.y*.4f) % 360,
- constrain(130 - p.y*.8f, 0, 100),
- max(0, 100 - abs(p.y - gravity[gi].getValuef())*falloff)
- );
- }
- }
-}
-
-class ViolinWave extends SCPattern {
-
- BasicParameter level = new BasicParameter("LVL", 0.45f);
- BasicParameter range = new BasicParameter("RNG", 0.5f);
- BasicParameter edge = new BasicParameter("EDG", 0.5f);
- BasicParameter release = new BasicParameter("RLS", 0.5f);
- BasicParameter speed = new BasicParameter("SPD", 0.5f);
- BasicParameter amp = new BasicParameter("AMP", 0.25f);
- BasicParameter period = new BasicParameter("WAVE", 0.5f);
- BasicParameter pSize = new BasicParameter("PSIZE", 0.5f);
- BasicParameter pSpeed = new BasicParameter("PSPD", 0.5f);
- BasicParameter pDensity = new BasicParameter("PDENS", 0.25f);
-
- LinearEnvelope dbValue = new LinearEnvelope(0, 0, 10);
-
- ViolinWave(GLucose glucose) {
- super(glucose);
- addParameter(level);
- addParameter(edge);
- addParameter(range);
- addParameter(release);
- addParameter(speed);
- addParameter(amp);
- addParameter(period);
- addParameter(pSize);
- addParameter(pSpeed);
- addParameter(pDensity);
-
- addModulator(dbValue);
- }
-
- final List<Particle> particles = new ArrayList<Particle>();
-
- class Particle {
-
- LinearEnvelope x = new LinearEnvelope(0, 0, 0);
- LinearEnvelope y = new LinearEnvelope(0, 0, 0);
-
- Particle() {
- addModulator(x);
- addModulator(y);
- }
-
- public Particle trigger(boolean direction) {
- float xInit = random(model.xMin, model.xMax);
- float time = 3000 - 2500*pSpeed.getValuef();
- x.setRange(xInit, xInit + random(-40, 40), time).trigger();
- y.setRange(model.cy + 10, direction ? model.yMax + 50 : model.yMin - 50, time).trigger();
- return this;
- }
-
- public boolean isActive() {
- return x.isRunning() || y.isRunning();
- }
-
- public void run(double deltaMs) {
- if (!isActive()) {
- return;
- }
-
- float pFalloff = (30 - 27*pSize.getValuef());
- for (Point p : model.points) {
- float b = 100 - pFalloff * (abs(p.x - x.getValuef()) + abs(p.y - y.getValuef()));
- if (b > 0) {
- colors[p.index] = blendColor(colors[p.index], lx.hsb(
- lx.getBaseHuef(), 20, b
- ), ADD);
- }
- }
- }
- }
-
- float[] centers = new float[30];
- double accum = 0;
- boolean rising = true;
-
- public void fireParticle(boolean direction) {
- boolean gotOne = false;
- for (Particle p : particles) {
- if (!p.isActive()) {
- p.trigger(direction);
- return;
- }
- }
- particles.add(new Particle().trigger(direction));
- }
-
- public void run(double deltaMs) {
- accum += deltaMs / (1000.f - 900.f*speed.getValuef());
- for (int i = 0; i < centers.length; ++i) {
- centers[i] = model.cy + 30*amp.getValuef()*sin((float) (accum + (i-centers.length/2.f)/(1.f + 9.f*period.getValuef())));
- }
-
- float zeroDBReference = pow(10, (50 - 190*level.getValuef())/20.f);
- float dB = 20*GraphicEQ.log10(lx.audioInput().mix.level() / zeroDBReference);
- if (dB > dbValue.getValuef()) {
- rising = true;
- dbValue.setRangeFromHereTo(dB, 10).trigger();
- } else {
- if (rising) {
- for (int j = 0; j < pDensity.getValuef()*3; ++j) {
- fireParticle(true);
- fireParticle(false);
- }
- }
- rising = false;
- dbValue.setRangeFromHereTo(max(dB, -96), 50 + 1000*release.getValuef()).trigger();
- }
- float edg = 1 + edge.getValuef() * 40;
- float rng = (78 - 64 * range.getValuef()) / (model.yMax - model.cy);
- float val = max(2, dbValue.getValuef());
-
- for (Point p : model.points) {
- int ci = (int) lerp(0, centers.length-1, (p.x - model.xMin) / (model.xMax - model.xMin));
- float rFactor = 1.0f - 0.9f * abs(p.x - model.cx) / (model.xMax - model.cx);
- colors[p.index] = lx.hsb(
- (lx.getBaseHuef() + abs(p.x - model.cx)) % 360,
- min(100, 20 + 8*abs(p.y - centers[ci])),
- constrain(edg*(val*rFactor - rng * abs(p.y-centers[ci])), 0, 100)
- );
- }
-
- for (Particle p : particles) {
- p.run(deltaMs);
- }
- }
-}
-
-class BouncyBalls extends SCPattern {
-
- static final int NUM_BALLS = 6;
-
- class BouncyBall {
-
- Accelerator yPos;
- TriangleLFO xPos = new TriangleLFO(0, model.xMax, random(8000, 19000));
- float zPos;
-
- BouncyBall(int i) {
- addModulator(xPos.setBasis(random(0, TWO_PI)).start());
- addModulator(yPos = new Accelerator(0, 0, 0));
- zPos = lerp(model.zMin, model.zMax, (i+2.f) / (NUM_BALLS + 4.f));
- }
-
- public void bounce(float midiVel) {
- float v = 100 + 8*midiVel;
- yPos.setSpeed(v, getAccel(v, 60 / lx.tempo.bpmf())).start();
- }
-
- public float getAccel(float v, float oneBeat) {
- return -2*v / oneBeat;
- }
-
- public void run(double deltaMs) {
- float flrLevel = flr.getValuef() * model.xMax/2.f;
- if (yPos.getValuef() < flrLevel) {
- if (yPos.getVelocity() < -50) {
- yPos.setValue(2*flrLevel-yPos.getValuef());
- float v = -yPos.getVelocityf() * bounce.getValuef();
- yPos.setSpeed(v, getAccel(v, 60 / lx.tempo.bpmf()));
- } else {
- yPos.setValue(flrLevel).stop();
- }
- }
- float falloff = 130.f / (12 + blobSize.getValuef() * 36);
- float xv = xPos.getValuef();
- float yv = yPos.getValuef();
-
- for (Point p : model.points) {
- float d = sqrt((p.x-xv)*(p.x-xv) + (p.y-yv)*(p.y-yv) + .1f*(p.z-zPos)*(p.z-zPos));
- float b = constrain(130 - falloff*d, 0, 100);
- if (b > 0) {
- colors[p.index] = blendColor(colors[p.index], lx.hsb(
- (lx.getBaseHuef() + p.y*.5f + abs(model.cx - p.x) * .5f) % 360,
- max(0, 100 - .45f*(p.y - flrLevel)),
- b
- ), ADD);
- }
- }
- }
- }
-
- final BouncyBall[] balls = new BouncyBall[NUM_BALLS];
-
- final BasicParameter bounce = new BasicParameter("BNC", .8f);
- final BasicParameter flr = new BasicParameter("FLR", 0);
- final BasicParameter blobSize = new BasicParameter("SIZE", 0.5f);
-
- BouncyBalls(GLucose glucose) {
- super(glucose);
- for (int i = 0; i < balls.length; ++i) {
- balls[i] = new BouncyBall(i);
- }
- addParameter(bounce);
- addParameter(flr);
- addParameter(blobSize);
- }
-
- public void run(double deltaMs) {
- setColors(0xff000000);
- for (BouncyBall b : balls) {
- b.run(deltaMs);
- }
- }
-
- public boolean noteOn(Note note) {
- int pitch = (note.getPitch() + note.getChannel()) % NUM_BALLS;
- balls[pitch].bounce(note.getVelocity());
- return true;
- }
-}
-
-class SpaceTime extends SCPattern {
-
- SinLFO pos = new SinLFO(0, 1, 3000);
- SinLFO rate = new SinLFO(1000, 9000, 13000);
- SinLFO falloff = new SinLFO(10, 70, 5000);
- float angle = 0;
-
- BasicParameter rateParameter = new BasicParameter("RATE", 0.5f);
- BasicParameter sizeParameter = new BasicParameter("SIZE", 0.5f);
-
-
- public SpaceTime(GLucose glucose) {
- super(glucose);
-
- addModulator(pos).trigger();
- addModulator(rate).trigger();
- addModulator(falloff).trigger();
- pos.modulateDurationBy(rate);
- addParameter(rateParameter);
- addParameter(sizeParameter);
- }
-
- public void onParameterChanged(LXParameter parameter) {
- if (parameter == rateParameter) {
- rate.stop().setValue(9000 - 8000*parameter.getValuef());
- } else if (parameter == sizeParameter) {
- falloff.stop().setValue(70 - 60*parameter.getValuef());
- }
- }
-
- public void run(double deltaMs) {
- angle += deltaMs * 0.0007f;
- float sVal1 = model.strips.size() * (0.5f + 0.5f*sin(angle));
- float sVal2 = model.strips.size() * (0.5f + 0.5f*cos(angle));
-
- float pVal = pos.getValuef();
- float fVal = falloff.getValuef();
-
- int s = 0;
- for (Strip strip : model.strips) {
- int i = 0;
- for (Point p : strip.points) {
- colors[p.index] = lx.hsb(
- (lx.getBaseHuef() + 360 - p.x*.2f + p.y * .3f) % 360,
- constrain(.4f * min(abs(s - sVal1), abs(s - sVal2)), 20, 100),
- max(0, 100 - fVal*abs(i - pVal*(strip.metrics.numPoints - 1)))
- );
- ++i;
- }
- ++s;
- }
- }
-}
-
-class Swarm extends SCPattern {
-
- SawLFO offset = new SawLFO(0, 1, 1000);
- SinLFO rate = new SinLFO(350, 1200, 63000);
- SinLFO falloff = new SinLFO(15, 50, 17000);
- SinLFO fX = new SinLFO(0, model.xMax, 19000);
- SinLFO fY = new SinLFO(0, model.yMax, 11000);
- SinLFO hOffX = new SinLFO(0, model.xMax, 13000);
-
- public Swarm(GLucose glucose) {
- super(glucose);
-
- addModulator(offset).trigger();
- addModulator(rate).trigger();
- addModulator(falloff).trigger();
- addModulator(fX).trigger();
- addModulator(fY).trigger();
- addModulator(hOffX).trigger();
- offset.modulateDurationBy(rate);
- }
-
- public float modDist(float v1, float v2, float mod) {
- v1 = v1 % mod;
- v2 = v2 % mod;
- if (v2 > v1) {
- return min(v2-v1, v1+mod-v2);
- }
- else {
- return min(v1-v2, v2+mod-v1);
- }
- }
-
- public void run(double deltaMs) {
- float s = 0;
- for (Strip strip : model.strips ) {
- int i = 0;
- for (Point p : strip.points) {
- float fV = max(-1, 1 - dist(p.x/2.f, p.y, fX.getValuef()/2.f, fY.getValuef()) / 64.f);
- colors[p.index] = lx.hsb(
- (lx.getBaseHuef() + 0.3f * abs(p.x - hOffX.getValuef())) % 360,
- constrain(80 + 40 * fV, 0, 100),
- constrain(100 - (30 - fV * falloff.getValuef()) * modDist(i + (s*63)%61, offset.getValuef() * strip.metrics.numPoints, strip.metrics.numPoints), 0, 100)
- );
- ++i;
- }
- ++s;
- }
- }
-}
-
-class SwipeTransition extends SCTransition {
-
- final BasicParameter bleed = new BasicParameter("WIDTH", 0.5f);
-
- SwipeTransition(GLucose glucose) {
- super(glucose);
- setDuration(5000);
- addParameter(bleed);
- }
-
- public void computeBlend(int[] c1, int[] c2, double progress) {
- float bleedf = 10 + bleed.getValuef() * 200.f;
- float xPos = (float) (-bleedf + progress * (model.xMax + bleedf));
- for (Point p : model.points) {
- float d = (p.x - xPos) / bleedf;
- if (d < 0) {
- colors[p.index] = c2[p.index];
- } else if (d > 1) {
- colors[p.index] = c1[p.index];
- } else {
- colors[p.index] = lerpColor(c2[p.index], c1[p.index], d, RGB);
- }
- }
- }
-}
-
-abstract class BlendTransition extends SCTransition {
-
- final int blendType;
-
- BlendTransition(GLucose glucose, int blendType) {
- super(glucose);
- this.blendType = blendType;
- }
-
- public void computeBlend(int[] c1, int[] c2, double progress) {
- if (progress < 0.5f) {
- for (int i = 0; i < c1.length; ++i) {
- colors[i] = lerpColor(
- c1[i],
- blendColor(c1[i], c2[i], blendType),
- (float) (2.f*progress),
- RGB);
- }
- } else {
- for (int i = 0; i < c1.length; ++i) {
- colors[i] = lerpColor(
- c2[i],
- blendColor(c1[i], c2[i], blendType),
- (float) (2.f*(1.f - progress)),
- RGB);
- }
- }
- }
-}
-
-class MultiplyTransition extends BlendTransition {
- MultiplyTransition(GLucose glucose) {
- super(glucose, MULTIPLY);
- }
-}
-
-class ScreenTransition extends BlendTransition {
- ScreenTransition(GLucose glucose) {
- super(glucose, SCREEN);
- }
-}
-
-class BurnTransition extends BlendTransition {
- BurnTransition(GLucose glucose) {
- super(glucose, BURN);
- }
-}
-
-class DodgeTransition extends BlendTransition {
- DodgeTransition(GLucose glucose) {
- super(glucose, DODGE);
- }
-}
-
-class OverlayTransition extends BlendTransition {
- OverlayTransition(GLucose glucose) {
- super(glucose, OVERLAY);
- }
-}
-
-class AddTransition extends BlendTransition {
- AddTransition(GLucose glucose) {
- super(glucose, ADD);
- }
-}
-
-class SubtractTransition extends BlendTransition {
- SubtractTransition(GLucose glucose) {
- super(glucose, SUBTRACT);
- }
-}
-
-class SoftLightTransition extends BlendTransition {
- SoftLightTransition(GLucose glucose) {
- super(glucose, SOFT_LIGHT);
- }
-}
-
-class BassPod extends SCPattern {
-
- private GraphicEQ eq = null;
-
- private final BasicParameter clr = new BasicParameter("CLR", 0.5f);
-
- public BassPod(GLucose glucose) {
- super(glucose);
- addParameter(clr);
- }
-
- protected void onActive() {
- if (eq == null) {
- eq = new GraphicEQ(lx, 16);
- eq.range.setValue(0.4f);
- eq.level.setValue(0.4f);
- eq.slope.setValue(0.6f);
- addParameter(eq.level);
- addParameter(eq.range);
- addParameter(eq.attack);
- addParameter(eq.release);
- addParameter(eq.slope);
- }
- }
-
- public void run(double deltaMs) {
- eq.run(deltaMs);
-
- float bassLevel = eq.getAverageLevel(0, 5);
-
- float satBase = bassLevel*480*clr.getValuef();
-
- for (Point p : model.points) {
- int avgIndex = (int) constrain(1 + abs(p.x-model.cx)/(model.cx)*(eq.numBands-5), 0, eq.numBands-5);
- float value = 0;
- for (int i = avgIndex; i < avgIndex + 5; ++i) {
- value += eq.getLevel(i);
- }
- value /= 5.f;
-
- float b = constrain(8 * (value*model.yMax - abs(p.y-model.yMax/2.f)), 0, 100);
- colors[p.index] = lx.hsb(
- (lx.getBaseHuef() + abs(p.y - model.cy) + abs(p.x - model.cx)) % 360,
- constrain(satBase - .6f*dist(p.x, p.y, model.cx, model.cy), 0, 100),
- b
- );
- }
- }
-}
-
-
-class CubeEQ extends SCPattern {
-
- private GraphicEQ eq = null;
-
- private final BasicParameter edge = new BasicParameter("EDGE", 0.5f);
- private final BasicParameter clr = new BasicParameter("CLR", 0.5f);
- private final BasicParameter blockiness = new BasicParameter("BLK", 0.5f);
-
- public CubeEQ(GLucose glucose) {
- super(glucose);
- }
-
- protected void onActive() {
- if (eq == null) {
- eq = new GraphicEQ(lx, 16);
- addParameter(eq.level);
- addParameter(eq.range);
- addParameter(eq.attack);
- addParameter(eq.release);
- addParameter(eq.slope);
- addParameter(edge);
- addParameter(clr);
- addParameter(blockiness);
- }
- }
-
- public void run(double deltaMs) {
- eq.run(deltaMs);
-
- float edgeConst = 2 + 30*edge.getValuef();
- float clrConst = 1.1f + clr.getValuef();
-
- for (Point p : model.points) {
- float avgIndex = constrain(2 + p.x / model.xMax * (eq.numBands-4), 0, eq.numBands-4);
- int avgFloor = (int) avgIndex;
-
- float leftVal = eq.getLevel(avgFloor);
- float rightVal = eq.getLevel(avgFloor+1);
- float smoothValue = lerp(leftVal, rightVal, avgIndex-avgFloor);
-
- float chunkyValue = (
- eq.getLevel(avgFloor/4*4) +
- eq.getLevel(avgFloor/4*4 + 1) +
- eq.getLevel(avgFloor/4*4 + 2) +
- eq.getLevel(avgFloor/4*4 + 3)
- ) / 4.f;
-
- float value = lerp(smoothValue, chunkyValue, blockiness.getValuef());
-
- float b = constrain(edgeConst * (value*model.yMax - p.y), 0, 100);
- colors[p.index] = lx.hsb(
- (480 + lx.getBaseHuef() - min(clrConst*p.y, 120)) % 360,
- 100,
- b
- );
- }
- }
-}
-
-class BoomEffect extends SCEffect {
-
- final BasicParameter falloff = new BasicParameter("WIDTH", 0.5f);
- final BasicParameter speed = new BasicParameter("SPD", 0.5f);
- final BasicParameter bright = new BasicParameter("BRT", 1.0f);
- final BasicParameter sat = new BasicParameter("SAT", 0.2f);
- List<Layer> layers = new ArrayList<Layer>();
- final float maxr = sqrt(model.xMax*model.xMax + model.yMax*model.yMax + model.zMax*model.zMax) + 10;
-
- class Layer {
- LinearEnvelope boom = new LinearEnvelope(-40, 500, 1300);
-
- Layer() {
- addModulator(boom);
- trigger();
- }
-
- public void trigger() {
- float falloffv = falloffv();
- boom.setRange(-100 / falloffv, maxr + 100/falloffv, 4000 - speed.getValuef() * 3300);
- boom.trigger();
- }
-
- public void apply(int[] colors) {
- float brightv = 100 * bright.getValuef();
- float falloffv = falloffv();
- float satv = sat.getValuef() * 100;
- float huev = lx.getBaseHuef();
- for (Point p : model.points) {
- colors[p.index] = blendColor(
- colors[p.index],
- lx.hsb(huev, satv, constrain(brightv - falloffv*abs(boom.getValuef() - dist(p.x, 2*p.y, 3*p.z, model.xMax/2, model.yMax, model.zMax*1.5f)), 0, 100)),
- ADD);
- }
- }
- }
-
- BoomEffect(GLucose glucose) {
- super(glucose, true);
- addParameter(falloff);
- addParameter(speed);
- addParameter(bright);
- addParameter(sat);
- }
-
- public void onEnable() {
- for (Layer l : layers) {
- if (!l.boom.isRunning()) {
- l.trigger();
- return;
- }
- }
- layers.add(new Layer());
- }
-
- private float falloffv() {
- return 20 - 19 * falloff.getValuef();
- }
-
- public void onTrigger() {
- onEnable();
- }
-
- public void apply(int[] colors) {
- for (Layer l : layers) {
- if (l.boom.isRunning()) {
- l.apply(colors);
- }
- }
- }
-}
-
-public class PianoKeyPattern extends SCPattern {
-
- final LinearEnvelope[] cubeBrt;
- final SinLFO base[];
- final BasicParameter attack = new BasicParameter("ATK", 0.1f);
- final BasicParameter release = new BasicParameter("REL", 0.5f);
- final BasicParameter level = new BasicParameter("AMB", 0.6f);
-
- PianoKeyPattern(GLucose glucose) {
- super(glucose);
-
- addParameter(attack);
- addParameter(release);
- addParameter(level);
- cubeBrt = new LinearEnvelope[model.cubes.size() / 4];
- for (int i = 0; i < cubeBrt.length; ++i) {
- addModulator(cubeBrt[i] = new LinearEnvelope(0, 0, 100));
- }
- base = new SinLFO[model.cubes.size() / 12];
- for (int i = 0; i < base.length; ++i) {
- addModulator(base[i] = new SinLFO(0, 1, 7000 + 1000*i)).trigger();
- }
- }
-
- private float getAttackTime() {
- return 15 + attack.getValuef()*attack.getValuef() * 2000;
- }
-
- private float getReleaseTime() {
- return 15 + release.getValuef() * 3000;
- }
-
- private LinearEnvelope getEnvelope(int index) {
- return cubeBrt[index % cubeBrt.length];
- }
-
- private SinLFO getBase(int index) {
- return base[index % base.length];
- }
-
- public boolean noteOn(Note note) {
- LinearEnvelope env = getEnvelope(note.getPitch());
- env.setEndVal(min(1, env.getValuef() + (note.getVelocity() / 127.f)), getAttackTime()).start();
- return true;
- }
-
- public boolean noteOff(Note note) {
- getEnvelope(note.getPitch()).setEndVal(0, getReleaseTime()).start();
- return true;
- }
-
- public void run(double deltaMs) {
- int i = 0;
- float huef = lx.getBaseHuef();
- float levelf = level.getValuef();
- for (Cube c : model.cubes) {
- float v = max(getBase(i).getValuef() * levelf/4.f, getEnvelope(i++).getValuef());
- setColor(c, lx.hsb(
- (huef + 20*v + abs(c.cx-model.xMax/2.f)*.3f + c.cy) % 360,
- min(100, 120*v),
- 100*v
- ));
- }
- }
-}
-
-class CrossSections extends SCPattern {
-
- final SinLFO x = new SinLFO(0, model.xMax, 5000);
- final SinLFO y = new SinLFO(0, model.yMax, 6000);
- final SinLFO z = new SinLFO(0, model.zMax, 7000);
-
- final BasicParameter xw = new BasicParameter("XWID", 0.3f);
- final BasicParameter yw = new BasicParameter("YWID", 0.3f);
- final BasicParameter zw = new BasicParameter("ZWID", 0.3f);
- final BasicParameter xr = new BasicParameter("XRAT", 0.7f);
- final BasicParameter yr = new BasicParameter("YRAT", 0.6f);
- final BasicParameter zr = new BasicParameter("ZRAT", 0.5f);
- final BasicParameter xl = new BasicParameter("XLEV", 1);
- final BasicParameter yl = new BasicParameter("YLEV", 1);
- final BasicParameter zl = new BasicParameter("ZLEV", 0.5f);
-
-
- CrossSections(GLucose glucose) {
- super(glucose);
- addModulator(x).trigger();
- addModulator(y).trigger();
- addModulator(z).trigger();
- addParams();
- }
-
- protected void addParams() {
- addParameter(xr);
- addParameter(yr);
- addParameter(zr);
- addParameter(xw);
- addParameter(xl);
- addParameter(yl);
- addParameter(zl);
- addParameter(yw);
- addParameter(zw);
- }
-
- public void onParameterChanged(LXParameter p) {
- if (p == xr) {
- x.setDuration(10000 - 8800*p.getValuef());
- } else if (p == yr) {
- y.setDuration(10000 - 9000*p.getValuef());
- } else if (p == zr) {
- z.setDuration(10000 - 9000*p.getValuef());
- }
- }
-
- float xv, yv, zv;
-
- protected void updateXYZVals() {
- xv = x.getValuef();
- yv = y.getValuef();
- zv = z.getValuef();
- }
-
- public void run(double deltaMs) {
- updateXYZVals();
-
- float xlv = 100*xl.getValuef();
- float ylv = 100*yl.getValuef();
- float zlv = 100*zl.getValuef();
-
- float xwv = 100.f / (10 + 40*xw.getValuef());
- float ywv = 100.f / (10 + 40*yw.getValuef());
- float zwv = 100.f / (10 + 40*zw.getValuef());
-
- for (Point p : model.points) {
- int c = 0;
- c = blendColor(c, lx.hsb(
- (lx.getBaseHuef() + p.x/10 + p.y/3) % 360,
- constrain(140 - 1.1f*abs(p.x - model.xMax/2.f), 0, 100),
- max(0, xlv - xwv*abs(p.x - xv))
- ), ADD);
- c = blendColor(c, lx.hsb(
- (lx.getBaseHuef() + 80 + p.y/10) % 360,
- constrain(140 - 2.2f*abs(p.y - model.yMax/2.f), 0, 100),
- max(0, ylv - ywv*abs(p.y - yv))
- ), ADD);
- c = blendColor(c, lx.hsb(
- (lx.getBaseHuef() + 160 + p.z / 10 + p.y/2) % 360,
- constrain(140 - 2.2f*abs(p.z - model.zMax/2.f), 0, 100),
- max(0, zlv - zwv*abs(p.z - zv))
- ), ADD);
- colors[p.index] = c;
- }
- }
-}
-
-class Blinders extends SCPattern {
-
- final SinLFO[] m;
- final TriangleLFO r;
- final SinLFO s;
- final TriangleLFO hs;
-
- public Blinders(GLucose glucose) {
- super(glucose);
- m = new SinLFO[12];
- for (int i = 0; i < m.length; ++i) {
- addModulator(m[i] = new SinLFO(0.5f, 120, (120000.f / (3+i)))).trigger();
- }
- addModulator(r = new TriangleLFO(9000, 15000, 29000)).trigger();
- addModulator(s = new SinLFO(-20, 275, 11000)).trigger();
- addModulator(hs = new TriangleLFO(0.1f, 0.5f, 15000)).trigger();
- s.modulateDurationBy(r);
- }
-
- public void run(double deltaMs) {
- float hv = lx.getBaseHuef();
- int si = 0;
- for (Strip strip : model.strips) {
- int i = 0;
- float mv = m[si % m.length].getValuef();
- for (Point p : strip.points) {
- colors[p.index] = lx.hsb(
- (hv + p.z + p.y*hs.getValuef()) % 360,
- min(100, abs(p.x - s.getValuef())/2.f),
- max(0, 100 - mv/2.f - mv * abs(i - (strip.metrics.length-1)/2.f))
- );
- ++i;
- }
- ++si;
- }
- }
-}
-
-class Psychedelia extends SCPattern {
-
- final int NUM = 3;
- SinLFO m = new SinLFO(-0.5f, NUM-0.5f, 9000);
- SinLFO s = new SinLFO(-20, 147, 11000);
- TriangleLFO h = new TriangleLFO(0, 240, 19000);
- SinLFO c = new SinLFO(-.2f, .8f, 31000);
-
- Psychedelia(GLucose glucose) {
- super(glucose);
- addModulator(m).trigger();
- addModulator(s).trigger();
- addModulator(h).trigger();
- addModulator(c).trigger();
- }
-
- public void run(double deltaMs) {
- float huev = h.getValuef();
- float cv = c.getValuef();
- float sv = s.getValuef();
- float mv = m.getValuef();
- int i = 0;
- for (Strip strip : model.strips) {
- for (Point p : strip.points) {
- colors[p.index] = lx.hsb(
- (huev + i*constrain(cv, 0, 2) + p.z/2.f + p.x/4.f) % 360,
- min(100, abs(p.y-sv)),
- max(0, 100 - 50*abs((i%NUM) - mv))
- );
- }
- ++i;
- }
- }
-}
-
-class AskewPlanes extends SCPattern {
-
- class Plane {
- private final SinLFO a;
- private final SinLFO b;
- private final SinLFO c;
- float av = 1;
- float bv = 1;
- float cv = 1;
- float denom = 0.1f;
-
- Plane(int i) {
- addModulator(a = new SinLFO(-1, 1, 4000 + 1029*i)).trigger();
- addModulator(b = new SinLFO(-1, 1, 11000 - 1104*i)).trigger();
- addModulator(c = new SinLFO(-50, 50, 4000 + 1000*i * ((i % 2 == 0) ? 1 : -1))).trigger();
- }
-
- public void run(double deltaMs) {
- av = a.getValuef();
- bv = b.getValuef();
- cv = c.getValuef();
- denom = sqrt(av*av + bv*bv);
- }
- }
-
- final Plane[] planes;
- final int NUM_PLANES = 3;
-
- AskewPlanes(GLucose glucose) {
- super(glucose);
- planes = new Plane[NUM_PLANES];
- for (int i = 0; i < planes.length; ++i) {
- planes[i] = new Plane(i);
- }
- }
-
- public void run(double deltaMs) {
- float huev = lx.getBaseHuef();
-
- // This is super fucking bizarre. But if this is a for loop, the framerate
- // tanks to like 30FPS, instead of 60. Call them manually and it works fine.
- // Doesn't make ANY sense... there must be some weird side effect going on
- // with the Processing internals perhaps?
-// for (Plane plane : planes) {
-// plane.run(deltaMs);
-// }
- planes[0].run(deltaMs);
- planes[1].run(deltaMs);
- planes[2].run(deltaMs);
-
- for (Point p : model.points) {
- float d = MAX_FLOAT;
- for (Plane plane : planes) {
- if (plane.denom != 0) {
- d = min(d, abs(plane.av*(p.x-model.cx) + plane.bv*(p.y-model.cy) + plane.cv) / plane.denom);
- }
- }
- colors[p.index] = lx.hsb(
- (huev + abs(p.x-model.cx)*.3f + p.y*.8f) % 360,
- max(0, 100 - .8f*abs(p.x - model.cx)),
- constrain(140 - 10.f*d, 0, 100)
- );
- }
- }
-}
-
-class ShiftingPlane extends SCPattern {
-
- final SinLFO a = new SinLFO(-.2f, .2f, 5300);
- final SinLFO b = new SinLFO(1, -1, 13300);
- final SinLFO c = new SinLFO(-1.4f, 1.4f, 5700);
- final SinLFO d = new SinLFO(-10, 10, 9500);
-
- ShiftingPlane(GLucose glucose) {
- super(glucose);
- addModulator(a).trigger();
- addModulator(b).trigger();
- addModulator(c).trigger();
- addModulator(d).trigger();
- }
-
- public void run(double deltaMs) {
- float hv = lx.getBaseHuef();
- float av = a.getValuef();
- float bv = b.getValuef();
- float cv = c.getValuef();
- float dv = d.getValuef();
- float denom = sqrt(av*av + bv*bv + cv*cv);
- for (Point p : model.points) {
- float d = abs(av*(p.x-model.cx) + bv*(p.y-model.cy) + cv*(p.z-model.cz) + dv) / denom;
- colors[p.index] = lx.hsb(
- (hv + abs(p.x-model.cx)*.6f + abs(p.y-model.cy)*.9f + abs(p.z - model.cz)) % 360,
- constrain(110 - d*6, 0, 100),
- constrain(130 - 7*d, 0, 100)
- );
- }
- }
-}
-
-class Traktor extends SCPattern {
-
- final int FRAME_WIDTH = 60;
-
- final BasicParameter speed = new BasicParameter("SPD", 0.5f);
-
- private float[] bass = new float[FRAME_WIDTH];
- private float[] treble = new float[FRAME_WIDTH];
-
- private int index = 0;
- private GraphicEQ eq = null;
-
- public Traktor(GLucose glucose) {
- super(glucose);
- for (int i = 0; i < FRAME_WIDTH; ++i) {
- bass[i] = 0;
- treble[i] = 0;
- }
- addParameter(speed);
- }
-
- public void onActive() {
- if (eq == null) {
- eq = new GraphicEQ(lx, 16);
- eq.slope.setValue(0.6f);
- eq.level.setValue(0.65f);
- eq.range.setValue(0.35f);
- eq.release.setValue(0.4f);
- addParameter(eq.level);
- addParameter(eq.range);
- addParameter(eq.attack);
- addParameter(eq.release);
- addParameter(eq.slope);
- }
- }
-
- int counter = 0;
-
- public void run(double deltaMs) {
- eq.run(deltaMs);
-
- int stepThresh = (int) (40 - 39*speed.getValuef());
- counter += deltaMs;
- if (counter < stepThresh) {
- return;
- }
- counter = counter % stepThresh;
-
- index = (index + 1) % FRAME_WIDTH;
-
- float rawBass = eq.getAverageLevel(0, 4);
- float rawTreble = eq.getAverageLevel(eq.numBands-7, 7);
-
- bass[index] = rawBass * rawBass * rawBass * rawBass;
- treble[index] = rawTreble * rawTreble;
-
- for (Point p : model.points) {
- int i = (int) constrain((model.xMax - p.x) / model.xMax * FRAME_WIDTH, 0, FRAME_WIDTH-1);
- int pos = (index + FRAME_WIDTH - i) % FRAME_WIDTH;
-
- colors[p.index] = lx.hsb(
- (360 + lx.getBaseHuef() + .8f*abs(p.x-model.cx)) % 360,
- 100,
- constrain(9 * (bass[pos]*model.cy - abs(p.y - model.cy + 5)), 0, 100)
- );
- colors[p.index] = blendColor(colors[p.index], lx.hsb(
- (400 + lx.getBaseHuef() + .5f*abs(p.x-model.cx)) % 360,
- 60,
- constrain(5 * (treble[pos]*.6f*model.cy - abs(p.y - model.cy)), 0, 100)
-
- ), ADD);
- }
- }
-}
-
-class ColorFuckerEffect extends SCEffect {
-
- final BasicParameter level = new BasicParameter("BRT", 1);
- final BasicParameter desat = new BasicParameter("DSAT", 0);
- final BasicParameter hueShift = new BasicParameter("HSHFT", 0);
- final BasicParameter sharp = new BasicParameter("SHARP", 0);
- final BasicParameter soft = new BasicParameter("SOFT", 0);
- final BasicParameter mono = new BasicParameter("MONO", 0);
- final BasicParameter invert = new BasicParameter("INVERT", 0);
-
-
- float[] hsb = new float[3];
-
- ColorFuckerEffect(GLucose glucose) {
- super(glucose);
- addParameter(level);
- addParameter(desat);
- addParameter(sharp);
- addParameter(hueShift);
- addParameter(soft);
- addParameter(mono);
- addParameter(invert);
- }
-
- public void apply(int[] colors) {
- if (!enabled) {
- return;
- }
- float bMod = level.getValuef();
- float sMod = 1 - desat.getValuef();
- float hMod = hueShift.getValuef();
- float fSharp = 1/(1.0001f-sharp.getValuef());
- float fSoft = soft.getValuef();
- boolean mon = mono.getValuef() > 0.5f;
- boolean ivt = invert.getValuef() > 0.5f;
- if (bMod < 1 || sMod < 1 || hMod > 0 || fSharp > 0 || ivt || mon || fSoft > 0) {
- for (int i = 0; i < colors.length; ++i) {
- lx.RGBtoHSB(colors[i], hsb);
- if (mon) {
- hsb[0] = lx.getBaseHuef() / 360.f;
- }
- if (ivt) {
- hsb[2] = 1 - hsb[2];
- }
- if (fSharp > 0) {
- hsb[2] = hsb[2] < .5f ? pow(hsb[2],fSharp) : 1-pow(1-hsb[2],fSharp);
- }
- if (fSoft > 0) {
- if (hsb[2] > 0.5f) {
- hsb[2] = lerp(hsb[2], 0.5f + 2 * (hsb[2]-0.5f)*(hsb[2]-0.5f), fSoft);
- } else {
- hsb[2] = lerp(hsb[2], 0.5f * sqrt(2*hsb[2]), fSoft);
- }
- }
- colors[i] = lx.hsb(
- (360.f * hsb[0] + hMod*360.f) % 360,
- 100.f * hsb[1] * sMod,
- 100.f * hsb[2] * bMod
- );
- }
- }
- }
-}
-
-class QuantizeEffect extends SCEffect {
-
- int[] quantizedFrame;
- float lastQuant;
- final BasicParameter amount = new BasicParameter("AMT", 0);
-
- QuantizeEffect(GLucose glucose) {
- super(glucose);
- quantizedFrame = new int[glucose.lx.total];
- lastQuant = 0;
- }
-
- public void apply(int[] colors) {
- float fQuant = amount.getValuef();
- if (fQuant > 0) {
- float tRamp = (lx.tempo.rampf() % (1.f/pow(2,floor((1-fQuant) * 4))));
- float f = lastQuant;
- lastQuant = tRamp;
- if (tRamp > f) {
- for (int i = 0; i < colors.length; ++i) {
- colors[i] = quantizedFrame[i];
- }
- return;
- }
- }
- for (int i = 0; i < colors.length; ++i) {
- quantizedFrame[i] = colors[i];
- }
- }
-}
-
-class BlurEffect extends SCEffect {
-
- final LXParameter amount = new BasicParameter("AMT", 0);
- final int[] frame;
- final LinearEnvelope env = new LinearEnvelope(0, 1, 100);
-
- BlurEffect(GLucose glucose) {
- super(glucose);
- addParameter(amount);
- addModulator(env);
- frame = new int[lx.total];
- for (int i = 0; i < frame.length; ++i) {
- frame[i] = 0xff000000;
- }
- }
-
- public void onEnable() {
- env.setRangeFromHereTo(1, 400).start();
- for (int i = 0; i < frame.length; ++i) {
- frame[i] = 0xff000000;
- }
- }
-
- public void onDisable() {
- env.setRangeFromHereTo(0, 1000).start();
- }
-
- public void apply(int[] colors) {
- float amt = env.getValuef() * amount.getValuef();
- if (amt > 0) {
- amt = (1 - amt);
- amt = 1 - (amt*amt*amt);
- for (int i = 0; i < colors.length; ++i) {
- // frame[i] = colors[i] = blendColor(colors[i], lerpColor(#000000, frame[i], amt, RGB), SCREEN);
- frame[i] = colors[i] = lerpColor(colors[i], blendColor(colors[i], frame[i], SCREEN), amt, RGB);
- }
- }
-
- }
-}
-abstract class SamPattern extends SCPattern {
- public SamPattern(GLucose glucose) {
- super(glucose);
- setEligible(false);
- }
-}
-
-class JazzRainbow extends SamPattern {
- public JazzRainbow(GLucose glucose) {
- super(glucose);
- }
-
-
- public void run(double deltaMs) {
- // Access the core master hue via this method call
- float hv = lx.getBaseHuef();
- for (int i = 0; i < colors.length*5; i=i+27) {
- float a = hv%250;
- if (i%2 == 0) {
- for (int b = 0; b < 70; b++) {
- colors[(i+b)%colors.length] = lx.hsb(a+i%250, 100, b*a%100);
- }
- }
- }
- }
-}
-
-
-
-class HelixPattern extends SCPattern {
-
- // Stores a line in point + vector form
- private class Line {
- private final PVector origin;
- private final PVector vector;
-
- Line(PVector pt, PVector v) {
- origin = pt;
- vector = v.get();
- vector.normalize();
- }
-
- public PVector getPoint() {
- return origin;
- }
-
- public PVector getVector() {
- return vector;
- }
-
- public PVector getPointAt(final float t) {
- return PVector.add(origin, PVector.mult(vector, t));
- }
-
- public boolean isColinear(final PVector pt) {
- PVector projected = projectPoint(pt);
- return projected.x==pt.x && projected.y==pt.y && projected.z==pt.z;
- }
-
- public float getTValue(final PVector pt) {
- PVector subtraction = PVector.sub(pt, origin);
- return subtraction.dot(vector);
- }
-
- public PVector projectPoint(final PVector pt) {
- return getPointAt(getTValue(pt));
- }
-
- public PVector rotatePoint(final PVector p, final float t) {
- final PVector o = origin;
- final PVector v = vector;
-
- final float cost = cos(t);
- final float sint = sin(t);
-
- float x = (o.x*(v.y*v.y + v.z*v.z) - v.x*(o.y*v.y + o.z*v.z - v.x*p.x - v.y*p.y - v.z*p.z))*(1 - cost) + p.x*cost + (-o.z*v.y + o.y*v.z - v.z*p.y + v.y*p.z)*sint;
- float y = (o.y*(v.x*v.x + v.z*v.z) - v.y*(o.x*v.x + o.z*v.z - v.x*p.x - v.y*p.y - v.z*p.z))*(1 - cost) + p.y*cost + (o.z*v.x - o.x*v.z + v.z*p.x - v.x*p.z)*sint;
- float z = (o.z*(v.x*v.x + v.y*v.y) - v.z*(o.x*v.x + o.y*v.y - v.x*p.x - v.y*p.y - v.z*p.z))*(1 - cost) + p.z*cost + (-o.y*v.x + o.x*v.y - v.y*p.x + v.x*p.y)*sint;
- return new PVector(x, y, z);
- }
- }
-
- private class Helix {
- private final Line axis;
- private final float period; // period of coil
- private final float rotationPeriod; // animation period
- private final float radius; // radius of coil
- private final float girth; // girth of coil
- private final PVector referencePoint;
- private float phase;
- private PVector phaseNormal;
-
- Helix(Line axis, float period, float radius, float girth, float phase, float rotationPeriod) {
- this.axis = axis;
- this.period = period;
- this.radius = radius;
- this.girth = girth;
- this.phase = phase;
- this.rotationPeriod = rotationPeriod;
-
- // Generate a normal that will rotate to
- // produce the helical shape.
- PVector pt = new PVector(0, 1, 0);
- if (this.axis.isColinear(pt)) {
- pt = new PVector(0, 0, 1);
- if (this.axis.isColinear(pt)) {
- pt = new PVector(0, 1, 1);
- }
- }
-
- this.referencePoint = pt;
-
- // The normal is calculated by the cross product of the axis
- // and a random point that is not colinear with it.
- phaseNormal = axis.getVector().cross(referencePoint);
- phaseNormal.normalize();
- phaseNormal.mult(radius);
- }
-
- public Line getAxis() {
- return axis;
- }
-
- public PVector getPhaseNormal() {
- return phaseNormal;
- }
-
- public float getPhase() {
- return phase;
- }
-
- public void step(double deltaMs) {
- // Rotate
- if (rotationPeriod != 0) {
- this.phase = (phase + ((float)deltaMs / (float)rotationPeriod) * TWO_PI);
- }
- }
-
- public PVector pointOnToroidalAxis(float t) {
- PVector p = axis.getPointAt(t);
- PVector middle = PVector.add(p, phaseNormal);
- return axis.rotatePoint(middle, (t / period) * TWO_PI + phase);
- }
-
- private float myDist(PVector p1, PVector p2) {
- final float x = p2.x-p1.x;
- final float y = p2.y-p1.y;
- final float z = p2.z-p1.z;
- return sqrt(x*x + y*y + z*z);
- }
-
- public int colorOfPoint(final PVector p) {
- final float t = axis.getTValue(p);
- final PVector axisPoint = axis.getPointAt(t);
-
- // For performance reasons, cut out points that are outside of
- // the tube where the toroidal coil lives.
- if (abs(myDist(p, axisPoint) - radius) > girth*.5f) {
- return lx.hsb(0,0,0);
- }
-
- // Find the appropriate point for the current rotation
- // of the helix.
- PVector toroidPoint = axisPoint;
- toroidPoint.add(phaseNormal);
- toroidPoint = axis.rotatePoint(toroidPoint, (t / period) * TWO_PI + phase);
-
- // The rotated point represents the middle of the girth of
- // the helix. Figure out if the current point is inside that
- // region.
- float d = myDist(p, toroidPoint);
-
- // Soften edges by fading brightness.
- float b = constrain(100*(1 - ((d-.5f*girth)/(girth*.5f))), 0, 100);
- return lx.hsb((lx.getBaseHuef() + (360*(phase / TWO_PI)))%360, 80, b);
- }
- }
-
- private class BasePairInfo {
- Line line;
- float colorPhase1;
- float colorPhase2;
-
- BasePairInfo(Line line, float colorPhase1, float colorPhase2) {
- this.line = line;
- this.colorPhase1 = colorPhase1;
- this.colorPhase2 = colorPhase2;
- }
- }
-
- private final Helix h1;
- private final Helix h2;
- private final BasePairInfo[] basePairs;
-
- private final BasicParameter helix1On = new BasicParameter("H1ON", 1);
- private final BasicParameter helix2On = new BasicParameter("H2ON", 1);
- private final BasicParameter basePairsOn = new BasicParameter("BPON", 1);
-
- private static final float helixCoilPeriod = 100;
- private static final float helixCoilRadius = 50;
- private static final float helixCoilGirth = 30;
- private static final float helixCoilRotationPeriod = 5000;
-
- private static final float spokePeriod = 40;
- private static final float spokeGirth = 20;
- private static final float spokePhase = 10;
- private static final float spokeRadius = helixCoilRadius - helixCoilGirth*.5f;
-
- private static final float tMin = -200;
- private static final float tMax = 200;
-
- public HelixPattern(GLucose glucose) {
- super(glucose);
-
- addParameter(helix1On);
- addParameter(helix2On);
- addParameter(basePairsOn);
-
- PVector origin = new PVector(100, 50, 55);
- PVector axis = new PVector(1,0,0);
-
- h1 = new Helix(
- new Line(origin, axis),
- helixCoilPeriod,
- helixCoilRadius,
- helixCoilGirth,
- 0,
- helixCoilRotationPeriod);
- h2 = new Helix(
- new Line(origin, axis),
- helixCoilPeriod,
- helixCoilRadius,
- helixCoilGirth,
- PI,
- helixCoilRotationPeriod);
-
- basePairs = new BasePairInfo[(int)floor((tMax - tMin)/spokePeriod)];
- }
-
- private void calculateSpokes() {
- float colorPhase = PI/6;
- for (float t = tMin + spokePhase; t < tMax; t += spokePeriod) {
- int spokeIndex = (int)floor((t - tMin)/spokePeriod);
- PVector h1point = h1.pointOnToroidalAxis(t);
- PVector spokeCenter = h1.getAxis().getPointAt(t);
- PVector spokeVector = PVector.sub(h1point, spokeCenter);
- Line spokeLine = new Line(spokeCenter, spokeVector);
- basePairs[spokeIndex] = new BasePairInfo(spokeLine, colorPhase * spokeIndex, colorPhase * (spokeIndex + 1));
- }
- }
-
- private int calculateSpokeColor(final PVector pt) {
- // Find the closest spoke's t-value and calculate its
- // axis. Until everything animates in the model reference
- // frame, this has to be calculated at every step because
- // the helices rotate.
- Line axis = h1.getAxis();
- float t = axis.getTValue(pt) + spokePhase;
- int spokeIndex = (int)floor((t - tMin + spokePeriod/2) / spokePeriod);
- if (spokeIndex < 0 || spokeIndex >= basePairs.length) {
- return lx.hsb(0,0,0);
- }
- BasePairInfo basePair = basePairs[spokeIndex];
- Line spokeLine = basePair.line;
- PVector pointOnSpoke = spokeLine.projectPoint(pt);
- float d = PVector.dist(pt, pointOnSpoke);
- float b = (PVector.dist(pointOnSpoke, spokeLine.getPoint()) < spokeRadius) ? constrain(100*(1 - ((d-.5f*spokeGirth)/(spokeGirth*.5f))), 0, 100) : 0.f;
- float phase = spokeLine.getTValue(pointOnSpoke) < 0 ? basePair.colorPhase1 : basePair.colorPhase2;
- return lx.hsb((lx.getBaseHuef() + (360*(phase / TWO_PI)))%360, 80.f, b);
- }
-
- public void run(double deltaMs) {
- boolean h1on = helix1On.getValue() > 0.5f;
- boolean h2on = helix2On.getValue() > 0.5f;
- boolean spokesOn = (float)basePairsOn.getValue() > 0.5f;
-
- h1.step(deltaMs);
- h2.step(deltaMs);
- calculateSpokes();
-
- for (Point p : model.points) {
- PVector pt = new PVector(p.x,p.y,p.z);
- int h1c = h1.colorOfPoint(pt);
- int h2c = h2.colorOfPoint(pt);
- int spokeColor = calculateSpokeColor(pt);
-
- if (!h1on) {
- h1c = lx.hsb(0,0,0);
- }
-
- if (!h2on) {
- h2c = lx.hsb(0,0,0);
- }
-
- if (!spokesOn) {
- spokeColor = lx.hsb(0,0,0);
- }
-
- // The helices are positioned to not overlap. If that changes,
- // a better blending formula is probably needed.
- colors[p.index] = blendColor(blendColor(h1c, h2c, ADD), spokeColor, ADD);
- }
- }
-}
-
-class BlankPattern extends SCPattern {
- BlankPattern(GLucose glucose) {
- super(glucose);
- }
-
- public void run(double deltaMs) {
- setColors(0xff000000);
- }
-}
-
-abstract class TestPattern extends SCPattern {
- public TestPattern(GLucose glucose) {
- super(glucose);
- setEligible(false);
- }
-}
-
-class TestSpeakerMapping extends TestPattern {
- TestSpeakerMapping(GLucose glucose) {
- super(glucose);
- }
-
- public void run(double deltaMs) {
- int h = 0;
- for (Speaker speaker : model.speakers) {
- for (Strip strip : speaker.strips) {
- float b = 100;
- for (Point p : strip.points) {
- colors[p.index] = lx.hsb(h % 360, 100, b);
- b = max(0, b - 10);
- }
- h += 70;
- }
- }
- }
-
-}
-
-class TestBassMapping extends TestPattern {
- TestBassMapping(GLucose glucose) {
- super(glucose);
- }
-
- public void run(double deltaMs) {
- int[] strips = { 2, 1, 0, 3, 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6 };
- int h = 0;
- for (int si : strips) {
- float b = 100;
- for (Point p : model.bassBox.strips.get(si).points) {
- colors[p.index] = lx.hsb(h % 360, 100, b);
- b = max(0, b - 10);
- }
- h += 70;
- }
- }
-}
-
-class TestFloorMapping extends TestPattern {
- TestFloorMapping(GLucose glucose) {
- super(glucose);
- }
-
- public void run(double deltaMs) {
- int[] strutIndices = {6, 5, 4, 3, 2, 1, 0, 7};
- int h = 0;
- for (int si : strutIndices) {
- float b = 100;
- for (Point p : model.bassBox.struts.get(si).points) {
- colors[p.index] = lx.hsb(h % 360, 100, b);
- b = max(0, b - 10);
- }
- h += 50;
- }
- int[] floorIndices = {0, 1, 2, 3};
- h = 0;
- for (int fi : floorIndices) {
- float b = 100;
- for (Point p : model.boothFloor.strips.get(fi).points) {
- colors[p.index] = lx.hsb(h, 100, b);
- b = max(0, b - 3);
- }
- h += 90;
- }
- }
-}
-
-class TestPerformancePattern extends TestPattern {
-
- final BasicParameter ops = new BasicParameter("OPS", 0);
- final BasicParameter iter = new BasicParameter("ITER", 0);
-
- TestPerformancePattern(GLucose glucose) {
- super(glucose);
- addParameter(ops);
- addParameter(iter);
- }
-
- public void run(double deltaMs) {
- float x = 1;
- for (int j = 0; j < ops.getValuef() * 400000; ++j) {
- x *= random(0, 1);
- }
-
- if (iter.getValuef() < 0.25f) {
- for (Point p : model.points) {
- colors[p.index] = lx.hsb(
- (p.x*.1f + p.y*.1f) % 360,
- 100,
- 100
- );
- }
- } else if (iter.getValuef() < 0.5f) {
- for (int i = 0; i < colors.length; ++i) {
- colors[i] = lx.hsb(
- (90 + model.px[i]*.1f + model.py[i]*.1f) % 360,
- 100,
- 100
- );
- }
- } else if (iter.getValuef() < 0.75f) {
- for (int i = 0; i < colors.length; ++i) {
- colors[i] = lx.hsb(
- (180 + model.p[3*i]*.1f + model.p[3*i+1]*.1f) % 360,
- 100,
- 100
- );
- }
- } else {
- for (int i = 0; i < colors.length; ++i) {
- colors[i] = lx.hsb(
- (270 + model.x(i)*.1f + model.y(i)*.1f) % 360,
- 100,
- 100
- );
- }
- }
- }
-}
-
-class TestStripPattern extends TestPattern {
-
- SinLFO d = new SinLFO(4, 40, 4000);
-
- public TestStripPattern(GLucose glucose) {
- super(glucose);
- addModulator(d).trigger();
- }
-
- public void run(double deltaMs) {
- for (Strip s : model.strips) {
- for (Point p : s.points) {
- colors[p.index] = lx.hsb(
- lx.getBaseHuef(),
- 100,
- max(0, 100 - d.getValuef()*dist(p.x, p.y, s.cx, s.cy))
- );
- }
- }
- }
-}
-
-/**
- * Simplest demonstration of using the rotating master hue.
- * All pixels are full-on the same color.
- */
-class TestHuePattern extends TestPattern {
- public TestHuePattern(GLucose glucose) {
- super(glucose);
- }
-
- public void run(double deltaMs) {
- // Access the core master hue via this method call
- float hv = lx.getBaseHuef();
- for (int i = 0; i < colors.length; ++i) {
- colors[i] = lx.hsb(hv, 100, 100);
- }
- }
-}
-
-/**
- * Test of a wave moving across the X axis.
- */
-class TestXPattern extends TestPattern {
- private final SinLFO xPos = new SinLFO(0, model.xMax, 4000);
- public TestXPattern(GLucose glucose) {
- super(glucose);
- addModulator(xPos).trigger();
- }
- public void run(double deltaMs) {
- float hv = lx.getBaseHuef();
- for (Point p : model.points) {
- // This is a common technique for modulating brightness.
- // You can use abs() to determine the distance between two
- // values. The further away this point is from an exact
- // point, the more we decrease its brightness
- float bv = max(0, 100 - abs(p.x - xPos.getValuef()));
- colors[p.index] = lx.hsb(hv, 100, bv);
- }
- }
-}
-
-/**
- * Test of a wave on the Y axis.
- */
-class TestYPattern extends TestPattern {
- private final SinLFO yPos = new SinLFO(0, model.yMax, 4000);
- public TestYPattern(GLucose glucose) {
- super(glucose);
- addModulator(yPos).trigger();
- }
- public void run(double deltaMs) {
- float hv = lx.getBaseHuef();
- for (Point p : model.points) {
- float bv = max(0, 100 - abs(p.y - yPos.getValuef()));
- colors[p.index] = lx.hsb(hv, 100, bv);
- }
- }
-}
-
-/**
- * Test of a wave on the Z axis.
- */
-class TestZPattern extends TestPattern {
- private final SinLFO zPos = new SinLFO(0, model.zMax, 4000);
- public TestZPattern(GLucose glucose) {
- super(glucose);
- addModulator(zPos).trigger();
- }
- public void run(double deltaMs) {
- float hv = lx.getBaseHuef();
- for (Point p : model.points) {
- float bv = max(0, 100 - abs(p.z - zPos.getValuef()));
- colors[p.index] = lx.hsb(hv, 100, bv);
- }
- }
-}
-
-/**
- * This shows how to iterate over towers, enumerated in the model.
- */
-class TestTowerPattern extends TestPattern {
- private final SawLFO towerIndex = new SawLFO(0, model.towers.size(), 1000*model.towers.size());
-
- public TestTowerPattern(GLucose glucose) {
- super(glucose);
- addModulator(towerIndex).trigger();
- }
-
- public void run(double deltaMs) {
- int ti = 0;
- for (Tower t : model.towers) {
- for (Point p : t.points) {
- colors[p.index] = lx.hsb(
- lx.getBaseHuef(),
- 100,
- max(0, 100 - 80*LXUtils.wrapdistf(ti, towerIndex.getValuef(), model.towers.size()))
- );
- }
- ++ti;
- }
- }
-
-}
-
-/**
- * This is a demonstration of how to use the projection library. A projection
- * creates a mutation of the coordinates of all the points in the model, creating
- * virtual x,y,z coordinates. In effect, this is like virtually rotating the entire
- * art car. However, since in reality the car does not move, the result is that
- * it appears that the object we are drawing on the car is actually moving.
- *
- * Keep in mind that what we are creating a projection of is the view coordinates.
- * Depending on your intuition, some operations may feel backwards. For instance,
- * if you translate the view to the right, it will make it seem that the object
- * you are drawing has moved to the left. If you scale the view up 2x, objects
- * drawn with the same absolute values will seem to be half the size.
- *
- * If this feels counterintuitive at first, don't worry. Just remember that you
- * are moving the pixels, not the structure. We're dealing with a finite set
- * of sparse, non-uniformly spaced pixels. Mutating the structure would move
- * things to a space where there are no pixels in 99% of the cases.
- */
-class TestProjectionPattern extends TestPattern {
-
- private final Projection projection;
- private final SawLFO angle = new SawLFO(0, TWO_PI, 9000);
- private final SinLFO yPos = new SinLFO(-20, 40, 5000);
-
- public TestProjectionPattern(GLucose glucose) {
- super(glucose);
- projection = new Projection(model);
- addModulator(angle).trigger();
- addModulator(yPos).trigger();
- }
-
- public void run(double deltaMs) {
- // For the same reasons described above, it may logically feel to you that
- // some of these operations are in reverse order. Again, just keep in mind that
- // the car itself is what's moving, not the object
- projection.reset(model)
-
- // Translate so the center of the car is the origin, offset by yPos
- .translateCenter(model, 0, yPos.getValuef(), 0)
-
- // Rotate around the origin (now the center of the car) about an X-vector
- .rotate(angle.getValuef(), 1, 0, 0)
-
- // Scale up the Y axis (objects will look smaller in that access)
- .scale(1, 1.5f, 1);
-
- float hv = lx.getBaseHuef();
- for (Coord c : projection) {
- float d = sqrt(c.x*c.x + c.y*c.y + c.z*c.z); // distance from origin
- // d = abs(d-60) + max(0, abs(c.z) - 20); // life saver / ring thing
- d = max(0, abs(c.y) - 10 + .1f*abs(c.z) + .02f*abs(c.x)); // plane / spear thing
- colors[c.index] = lx.hsb(
- (hv + .6f*abs(c.x) + abs(c.z)) % 360,
- 100,
- constrain(140 - 40*d, 0, 100)
- );
- }
- }
-}
-
-class TestCubePattern extends TestPattern {
-
- private SawLFO index = new SawLFO(0, Cube.POINTS_PER_CUBE, Cube.POINTS_PER_CUBE*60);
-
- TestCubePattern(GLucose glucose) {
- super(glucose);
- addModulator(index).start();
- }
-
- public void run(double deltaMs) {
- for (Cube c : model.cubes) {
- int i = 0;
- for (Point p : c.points) {
- colors[p.index] = lx.hsb(
- lx.getBaseHuef(),
- 100,
- max(0, 100 - 80.f*abs(i - index.getValuef()))
- );
- ++i;
- }
- }
- }
-}
-
-class MappingTool extends TestPattern {
-
- private int cubeIndex = 0;
- private int stripIndex = 0;
- private int channelIndex = 0;
-
- public final int MAPPING_MODE_ALL = 0;
- public final int MAPPING_MODE_CHANNEL = 1;
- public final int MAPPING_MODE_SINGLE_CUBE = 2;
- public int mappingMode = MAPPING_MODE_ALL;
-
- public final int CUBE_MODE_ALL = 0;
- public final int CUBE_MODE_SINGLE_STRIP = 1;
- public final int CUBE_MODE_STRIP_PATTERN = 2;
- public int cubeMode = CUBE_MODE_ALL;
-
- public boolean channelModeRed = true;
- public boolean channelModeGreen = false;
- public boolean channelModeBlue = false;
-
- private final int numChannels;
-
- private final PandaMapping[] pandaMappings;
- private PandaMapping activePanda;
- private ChannelMapping activeChannel;
-
- MappingTool(GLucose glucose, PandaMapping[] pandaMappings) {
- super(glucose);
- this.pandaMappings = pandaMappings;
- numChannels = pandaMappings.length * PandaMapping.CHANNELS_PER_BOARD;
- setChannel();
- }
-
- public int numChannels() {
- return numChannels;
- }
-
- private void setChannel() {
- activePanda = pandaMappings[channelIndex / PandaMapping.CHANNELS_PER_BOARD];
- activeChannel = activePanda.channelList[channelIndex % PandaMapping.CHANNELS_PER_BOARD];
- }
-
- private int indexOfCubeInChannel(Cube c) {
- if (activeChannel.mode == ChannelMapping.MODE_CUBES) {
- int i = 1;
- for (int index : activeChannel.objectIndices) {
- if ((index >= 0) && (c == model.getCubeByRawIndex(index))) {
- return i;
- }
- ++i;
- }
- }
- return 0;
- }
-
- private void printInfo() {
- println("Cube:" + cubeIndex + " Strip:" + (stripIndex+1));
- }
-
- public void cube(int delta) {
- int len = model.cubes.size();
- cubeIndex = (len + cubeIndex + delta) % len;
- printInfo();
- }
-
- public void strip(int delta) {
- int len = Cube.STRIPS_PER_CUBE;
- stripIndex = (len + stripIndex + delta) % len;
- printInfo();
- }
-
- public void run(double deltaMs) {
- int off = 0xff000000;
- int c = off;
- int r = 0xffFF0000;
- int g = 0xff00FF00;
- int b = 0xff0000FF;
- if (channelModeRed) c |= r;
- if (channelModeGreen) c |= g;
- if (channelModeBlue) c |= b;
-
- int ci = 0;
- for (Cube cube : model.cubes) {
- boolean cubeOn = false;
- int indexOfCubeInChannel = indexOfCubeInChannel(cube);
- switch (mappingMode) {
- case MAPPING_MODE_ALL: cubeOn = true; break;
- case MAPPING_MODE_SINGLE_CUBE: cubeOn = (cubeIndex == ci); break;
- case MAPPING_MODE_CHANNEL: cubeOn = (indexOfCubeInChannel > 0); break;
- }
- if (cubeOn) {
- if (mappingMode == MAPPING_MODE_CHANNEL) {
- int cc = off;
- switch (indexOfCubeInChannel) {
- case 1: cc = r; break;
- case 2: cc = r|g; break;
- case 3: cc = g; break;
- case 4: cc = b; break;
- case 5: cc = r|b; break;
- }
- setColor(cube, cc);
- } else if (cubeMode == CUBE_MODE_STRIP_PATTERN) {
- int si = 0;
- int sc = off;
- for (Strip strip : cube.strips) {
- int faceI = si / Face.STRIPS_PER_FACE;
- switch (faceI) {
- case 0: sc = r; break;
- case 1: sc = g; break;
- case 2: sc = b; break;
- case 3: sc = r|g|b; break;
- }
- if (si % Face.STRIPS_PER_FACE == 2) {
- sc = r|g;
- }
- setColor(strip, sc);
- ++si;
- }
- } else if (cubeMode == CUBE_MODE_SINGLE_STRIP) {
- setColor(cube, off);
- setColor(cube.strips.get(stripIndex), c);
- } else {
- setColor(cube, c);
- }
- } else {
- setColor(cube, off);
- }
- ++ci;
- }
- }
-
- public void setCube(int index) {
- cubeIndex = index % model.cubes.size();
- }
-
- public void incCube() {
- cubeIndex = (cubeIndex + 1) % model.cubes.size();
- }
-
- public void decCube() {
- --cubeIndex;
- if (cubeIndex < 0) {
- cubeIndex += model.cubes.size();
- }
- }
-
- public void setChannel(int index) {
- channelIndex = index % numChannels;
- setChannel();
- }
-
- public void incChannel() {
- channelIndex = (channelIndex + 1) % numChannels;
- setChannel();
- }
-
- public void decChannel() {
- channelIndex = (channelIndex + numChannels - 1) % numChannels;
- setChannel();
- }
-
- public void setStrip(int index) {
- stripIndex = index % Cube.STRIPS_PER_CUBE;
- }
-
- public void incStrip() {
- stripIndex = (stripIndex + 1) % Cube.STRIPS_PER_CUBE;
- }
-
- public void decStrip() {
- stripIndex = (stripIndex + Cube.STRIPS_PER_CUBE - 1) % Cube.STRIPS_PER_CUBE;
- }
-
- public void keyPressed(UIMapping uiMapping) {
- switch (keyCode) {
- case UP: if (mappingMode == MAPPING_MODE_CHANNEL) incChannel(); else incCube(); break;
- case DOWN: if (mappingMode == MAPPING_MODE_CHANNEL) decChannel(); else decCube(); break;
- case LEFT: decStrip(); break;
- case RIGHT: incStrip(); break;
- }
- switch (key) {
- case 'r': channelModeRed = !channelModeRed; break;
- case 'g': channelModeGreen = !channelModeGreen; break;
- case 'b': channelModeBlue = !channelModeBlue; break;
- }
- uiMapping.setChannelID(channelIndex+1);
- uiMapping.setCubeID(cubeIndex+1);
- uiMapping.setStripID(stripIndex+1);
- uiMapping.redraw();
- }
-
-}
-/**
- * Not very flushed out, but kind of fun nonetheless.
- */
-class TimSpheres extends SCPattern {
- private BasicParameter hueParameter = new BasicParameter("RAD", 1.0f);
- private final SawLFO lfo = new SawLFO(0, 1, 10000);
- private final SinLFO sinLfo = new SinLFO(0, 1, 4000);
- private final float centerX, centerY, centerZ;
-
- class Sphere {
- float x, y, z;
- float radius;
- float hue;
- }
-
- private final Sphere[] spheres;
-
- public TimSpheres(GLucose glucose) {
- super(glucose);
- addParameter(hueParameter);
- addModulator(lfo).trigger();
- addModulator(sinLfo).trigger();
- centerX = (model.xMax + model.xMin) / 2;
- centerY = (model.yMax + model.yMin) / 2;
- centerZ = (model.zMax + model.zMin) / 2;
-
- spheres = new Sphere[2];
-
- spheres[0] = new Sphere();
- spheres[0].x = model.xMin;
- spheres[0].y = centerY;
- spheres[0].z = centerZ;
- spheres[0].hue = 0;
- spheres[0].radius = 50;
-
- spheres[1] = new Sphere();
- spheres[1].x = model.xMax;
- spheres[1].y = centerY;
- spheres[1].z = centerZ;
- spheres[1].hue = 0.33f;
- spheres[1].radius = 50;
- }
-
- public void run(double deltaMs) {
- // Access the core master hue via this method call
- float hv = hueParameter.getValuef();
- float lfoValue = lfo.getValuef();
- float sinLfoValue = sinLfo.getValuef();
-
- spheres[0].x = model.xMin + sinLfoValue * model.xMax;
- spheres[1].x = model.xMax - sinLfoValue * model.xMax;
-
- spheres[0].radius = 100 * hueParameter.getValuef();
- spheres[1].radius = 100 * hueParameter.getValuef();
-
- for (Point p : model.points) {
- float value = 0;
-
- int c = lx.hsb(0, 0, 0);
- for (Sphere s : spheres) {
- float d = sqrt(pow(p.x - s.x, 2) + pow(p.y - s.y, 2) + pow(p.z - s.z, 2));
- float r = (s.radius); // * (sinLfoValue + 0.5));
- value = max(0, 1 - max(0, d - r) / 10);
-
- c = blendColor(c, lx.hsb(((s.hue + lfoValue) % 1) * 360, 100, min(1, value) * 100), ADD);
- }
-
- colors[p.index] = c;
- }
- }
-}
-
-class Vector2 {
- float x, y;
-
- Vector2() {
- this(0, 0);
- }
-
- Vector2(float x, float y) {
- this.x = x;
- this.y = y;
- }
-
- public float distanceTo(float x, float y) {
- return sqrt(pow(x - this.x, 2) + pow(y - this.y, 2));
- }
-
- public float distanceTo(Vector2 v) {
- return distanceTo(v.x, v.y);
- }
-
- public Vector2 plus(float x, float y) {
- return new Vector2(this.x + x, this.y + y);
- }
-
- public Vector2 plus(Vector2 v) {
- return plus(v.x, v.y);
- }
-
- public Vector2 minus(Vector2 v) {
- return plus(-1 * v.x, -1 * v.y);
- }
-}
-
-class Vector3 {
- float x, y, z;
-
- Vector3() {
- this(0, 0, 0);
- }
-
- Vector3(float x, float y, float z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- public float distanceTo(float x, float y, float z) {
- return sqrt(pow(x - this.x, 2) + pow(y - this.y, 2) + pow(z - this.z, 2));
- }
-
- public float distanceTo(Vector3 v) {
- return distanceTo(v.x, v.y, v.z);
- }
-
- public float distanceTo(Point p) {
- return distanceTo(p.x, p.y, p.z);
- }
-
- public void add(Vector3 other, float multiplier) {
- this.add(other.x * multiplier, other.y * multiplier, other.z * multiplier);
- }
-
- public void add(float x, float y, float z) {
- this.x += x;
- this.y += y;
- this.z += z;
- }
-
- public void divide(float factor) {
- this.x /= factor;
- this.y /= factor;
- this.z /= factor;
- }
-}
-
-class Rotation {
- private float a, b, c, d, e, f, g, h, i;
-
- Rotation(float yaw, float pitch, float roll) {
- float cosYaw = cos(yaw);
- float sinYaw = sin(yaw);
- float cosPitch = cos(pitch);
- float sinPitch = sin(pitch);
- float cosRoll = cos(roll);
- float sinRoll = sin(roll);
-
- a = cosYaw * cosPitch;
- b = cosYaw * sinPitch * sinRoll - sinYaw * cosRoll;
- c = cosYaw * sinPitch * cosRoll + sinYaw * sinRoll;
- d = sinYaw * cosPitch;
- e = sinYaw * sinPitch * sinRoll + cosYaw * cosRoll;
- f = sinYaw * sinPitch * cosRoll - cosYaw * sinRoll;
- g = -1 * sinPitch;
- h = cosPitch * sinRoll;
- i = cosPitch * cosRoll;
- }
-
- public Vector3 rotated(Vector3 v) {
- return new Vector3(
- rotatedX(v),
- rotatedY(v),
- rotatedZ(v));
-
- }
-
- public float rotatedX(Vector3 v) {
- return a * v.x + b * v.y + c * v.z;
- }
-
- public float rotatedY(Vector3 v) {
- return d * v.x + e * v.y + f * v.z;
- }
-
- public float rotatedZ(Vector3 v) {
- return g * v.x + h * v.y + i * v.z;
- }
-}
-
-/**
- * Very literal rain effect. Not that great as-is but some tweaking could make it nice.
- * A couple ideas:
- * - changing hue and direction of "rain" could make a nice fire effect
- * - knobs to change frequency and size of rain drops
- * - sync somehow to tempo but maybe less frequently than every beat?
- */
-class TimRaindrops extends SCPattern {
- public Vector3 randomVector3() {
- return new Vector3(
- random(model.xMax - model.xMin) + model.xMin,
- random(model.yMax - model.yMin) + model.yMin,
- random(model.zMax - model.zMin) + model.zMin);
- }
-
- class Raindrop {
- Vector3 p;
- Vector3 v;
- float radius;
- float hue;
-
- Raindrop() {
- this.radius = 30;
- this.p = new Vector3(
- random(model.xMax - model.xMin) + model.xMin,
- model.yMax + this.radius,
- random(model.zMax - model.zMin) + model.zMin);
- float velMagnitude = 120;
- this.v = new Vector3(
- 0,
- -3 * model.yMax,
- 0);
- this.hue = random(40) + 200;
- }
-
- // returns TRUE when this should die
- public boolean age(double ms) {
- p.add(v, (float) (ms / 1000.0f));
- return this.p.y < (0 - this.radius);
- }
- }
-
- private float leftoverMs = 0;
- private float msPerRaindrop = 40;
- private List<Raindrop> raindrops;
-
- public TimRaindrops(GLucose glucose) {
- super(glucose);
- raindrops = new LinkedList<Raindrop>();
- }
-
- public void run(double deltaMs) {
- leftoverMs += deltaMs;
- while (leftoverMs > msPerRaindrop) {
- leftoverMs -= msPerRaindrop;
- raindrops.add(new Raindrop());
- }
-
- for (Point p : model.points) {
- int c =
- blendColor(
- lx.hsb(210, 20, (float)Math.max(0, 1 - Math.pow((model.yMax - p.y) / 10, 2)) * 50),
- lx.hsb(220, 60, (float)Math.max(0, 1 - Math.pow((p.y - model.yMin) / 10, 2)) * 100),
- ADD);
- for (Raindrop raindrop : raindrops) {
- if (p.x >= (raindrop.p.x - raindrop.radius) && p.x <= (raindrop.p.x + raindrop.radius) &&
- p.y >= (raindrop.p.y - raindrop.radius) && p.y <= (raindrop.p.y + raindrop.radius)) {
- float d = raindrop.p.distanceTo(p) / raindrop.radius;
- // float value = (float)Math.max(0, 1 - Math.pow(Math.min(0, d - raindrop.radius) / 5, 2));
- if (d < 1) {
- c = blendColor(c, lx.hsb(raindrop.hue, 80, (float)Math.pow(1 - d, 0.01f) * 100), ADD);
- }
- }
- }
- colors[p.index] = c;
- }
-
- Iterator<Raindrop> i = raindrops.iterator();
- while (i.hasNext()) {
- Raindrop raindrop = i.next();
- boolean dead = raindrop.age(deltaMs);
- if (dead) {
- i.remove();
- }
- }
- }
-}
-
-
-class TimCubes extends SCPattern {
- private BasicParameter rateParameter = new BasicParameter("RATE", 0.125f);
- private BasicParameter attackParameter = new BasicParameter("ATTK", 0.5f);
- private BasicParameter decayParameter = new BasicParameter("DECAY", 0.5f);
- private BasicParameter hueParameter = new BasicParameter("HUE", 0.5f);
- private BasicParameter hueVarianceParameter = new BasicParameter("H.V.", 0.25f);
- private BasicParameter saturationParameter = new BasicParameter("SAT", 0.5f);
-
- class CubeFlash {
- Cube c;
- float value;
- float hue;
- boolean hasPeaked;
-
- CubeFlash() {
- c = model.cubes.get(floor(random(model.cubes.size())));
- hue = random(1);
- boolean infiniteAttack = (attackParameter.getValuef() > 0.999f);
- hasPeaked = infiniteAttack;
- value = (infiniteAttack ? 1 : 0);
- }
-
- // returns TRUE if this should die
- public boolean age(double ms) {
- if (!hasPeaked) {
- value = value + (float) (ms / 1000.0f * ((attackParameter.getValuef() + 0.01f) * 5));
- if (value >= 1.0f) {
- value = 1.0f;
- hasPeaked = true;
- }
- return false;
- } else {
- value = value - (float) (ms / 1000.0f * ((decayParameter.getValuef() + 0.01f) * 10));
- return value <= 0;
- }
- }
- }
-
- private float leftoverMs = 0;
- private List<CubeFlash> flashes;
-
- public TimCubes(GLucose glucose) {
- super(glucose);
- addParameter(rateParameter);
- addParameter(attackParameter);
- addParameter(decayParameter);
- addParameter(hueParameter);
- addParameter(hueVarianceParameter);
- addParameter(saturationParameter);
- flashes = new LinkedList<CubeFlash>();
- }
-
- public void run(double deltaMs) {
- leftoverMs += deltaMs;
- float msPerFlash = 1000 / ((rateParameter.getValuef() + .01f) * 100);
- while (leftoverMs > msPerFlash) {
- leftoverMs -= msPerFlash;
- flashes.add(new CubeFlash());
- }
-
- for (Point p : model.points) {
- colors[p.index] = 0;
- }
-
- for (CubeFlash flash : flashes) {
- float hue = (hueParameter.getValuef() + (hueVarianceParameter.getValuef() * flash.hue)) % 1.0f;
- int c = lx.hsb(hue * 360, saturationParameter.getValuef() * 100, (flash.value) * 100);
- for (Point p : flash.c.points) {
- colors[p.index] = c;
- }
- }
-
- Iterator<CubeFlash> i = flashes.iterator();
- while (i.hasNext()) {
- CubeFlash flash = i.next();
- boolean dead = flash.age(deltaMs);
- if (dead) {
- i.remove();
- }
- }
- }
-}
-
-/**
- * This one is the best but you need to play with all the knobs. It's synced to
- * the tempo, with the WSpd knob letting you pick 4 discrete multipliers for
- * the tempo.
- *
- * Basically it's just 3 planes all rotating to the beat, but also rotated relative
- * to one another. The intersection of the planes and the cubes over time makes
- * for a nice abstract effect.
- */
-class TimPlanes extends SCPattern {
- private BasicParameter wobbleParameter = new BasicParameter("Wob", 0.166f);
- private BasicParameter wobbleSpreadParameter = new BasicParameter("WSpr", 0.25f);
- private BasicParameter wobbleSpeedParameter = new BasicParameter("WSpd", 0.375f);
- private BasicParameter wobbleOffsetParameter = new BasicParameter("WOff", 0);
- private BasicParameter derezParameter = new BasicParameter("Drez", 0.5f);
- private BasicParameter thicknessParameter = new BasicParameter("Thick", 0.4f);
- private BasicParameter ySpreadParameter = new BasicParameter("ySpr", 0.2f);
- private BasicParameter hueParameter = new BasicParameter("Hue", 0.75f);
- private BasicParameter hueSpreadParameter = new BasicParameter("HSpr", 0.68f);
-
- final float centerX, centerY, centerZ;
- float phase;
-
- class Plane {
- Vector3 center;
- Rotation rotation;
- float hue;
-
- Plane(Vector3 center, Rotation rotation, float hue) {
- this.center = center;
- this.rotation = rotation;
- this.hue = hue;
- }
- }
-
- TimPlanes(GLucose glucose) {
- super(glucose);
- centerX = (model.xMin + model.xMax) / 2;
- centerY = (model.yMin + model.yMax) / 2;
- centerZ = (model.zMin + model.zMax) / 2;
- phase = 0;
- addParameter(wobbleParameter);
- addParameter(wobbleSpreadParameter);
- addParameter(wobbleSpeedParameter);
-// addParameter(wobbleOffsetParameter);
- addParameter(derezParameter);
- addParameter(thicknessParameter);
- addParameter(ySpreadParameter);
- addParameter(hueParameter);
- addParameter(hueSpreadParameter);
- }
-
- int beat = 0;
- float prevRamp = 0;
- float[] wobbleSpeeds = { 1.0f/8, 1.0f/4, 1.0f/2, 1.0f };
-
- public void run(double deltaMs) {
- float ramp = (float)lx.tempo.ramp();
- if (ramp < prevRamp) {
- beat = (beat + 1) % 32;
- }
- prevRamp = ramp;
-
- float wobbleSpeed = wobbleSpeeds[floor(wobbleSpeedParameter.getValuef() * wobbleSpeeds.length * 0.9999f)];
-
- phase = (((beat + ramp) * wobbleSpeed + wobbleOffsetParameter.getValuef()) % 1) * 2 * PI;
-
- float ySpread = ySpreadParameter.getValuef() * 50;
- float wobble = wobbleParameter.getValuef() * PI;
- float wobbleSpread = wobbleSpreadParameter.getValuef() * PI;
- float hue = hueParameter.getValuef() * 360;
- float hueSpread = (hueSpreadParameter.getValuef() - 0.5f) * 360;
-
- float saturation = 10 + 60.0f * pow(ramp, 0.25f);
-
- float derez = derezParameter.getValuef();
-
- Plane[] planes = {
- new Plane(
- new Vector3(centerX, centerY + ySpread, centerZ),
- new Rotation(wobble - wobbleSpread, phase, 0),
- (hue + 360 - hueSpread) % 360),
- new Plane(
- new Vector3(centerX, centerY, centerZ),
- new Rotation(wobble, phase, 0),
- hue),
- new Plane(
- new Vector3(centerX, centerY - ySpread, centerZ),
- new Rotation(wobble + wobbleSpread, phase, 0),
- (hue + 360 + hueSpread) % 360)
- };
-
- float thickness = (thicknessParameter.getValuef() * 25 + 1);
-
- Vector3 normalizedPoint = new Vector3();
-
- for (Point p : model.points) {
- if (random(1.0f) < derez) {
- continue;
- }
-
- int c = 0;
-
- for (Plane plane : planes) {
- normalizedPoint.x = p.x - plane.center.x;
- normalizedPoint.y = p.y - plane.center.y;
- normalizedPoint.z = p.z - plane.center.z;
-
- float v = plane.rotation.rotatedY(normalizedPoint);
- float d = abs(v);
-
- final int planeColor;
- if (d <= thickness) {
- planeColor = lx.hsb(plane.hue, saturation, 100);
- } else if (d <= thickness * 2) {
- float value = 1 - ((d - thickness) / thickness);
- planeColor = lx.hsb(plane.hue, saturation, value * 100);
- } else {
- planeColor = 0;
- }
-
- if (planeColor != 0) {
- if (c == 0) {
- c = planeColor;
- } else {
- c = blendColor(c, planeColor, ADD);
- }
- }
- }
-
- colors[p.index] = c;
- }
- }
-}
-
-/**
- * Two spinning wheels, basically XORed together, with a color palette that should
- * be pretty easy to switch around. Timed to the beat; also introduces "clickiness"
- * which makes the movement non-linear throughout a given beat, giving it a nice
- * dance feel. I'm not 100% sure that it's actually going to look like it's _on_
- * the beat, but that should be easy enough to adjust.
- *
- * It's particularly nice to turn down the clickiness and turn up derez during
- * slow/beatless parts of the music and then revert them at the drop :) But maybe
- * I shouldn't be listening to so much shitty dubstep while making these...
- */
-class TimPinwheels extends SCPattern {
- private BasicParameter horizSpreadParameter = new BasicParameter("HSpr", 0.75f);
- private BasicParameter vertSpreadParameter = new BasicParameter("VSpr", 0.5f);
- private BasicParameter vertOffsetParameter = new BasicParameter("VOff", 1.0f);
- private BasicParameter zSlopeParameter = new BasicParameter("ZSlp", 0.6f);
- private BasicParameter sharpnessParameter = new BasicParameter("Shrp", 0.25f);
- private BasicParameter derezParameter = new BasicParameter("Drez", 0.25f);
- private BasicParameter clickinessParameter = new BasicParameter("Clic", 0.5f);
- private BasicParameter hueParameter = new BasicParameter("Hue", 0.667f);
- private BasicParameter hueSpreadParameter = new BasicParameter("HSpd", 0.667f);
-
- float phase = 0;
- private final int NUM_BLADES = 12;
-
- class Pinwheel {
- Vector2 center;
- int numBlades;
- float realPhase;
- float phase;
- float speed;
-
- Pinwheel(float xCenter, float yCenter, int numBlades, float speed) {
- this.center = new Vector2(xCenter, yCenter);
- this.numBlades = numBlades;
- this.speed = speed;
- }
-
- public void age(float numBeats) {
- int numSteps = numBlades;
-
- realPhase = (realPhase + numBeats / numSteps) % 2.0f;
-
- float phaseStep = floor(realPhase * numSteps);
- float phaseRamp = (realPhase * numSteps) % 1.0f;
- phase = (phaseStep + pow(phaseRamp, (clickinessParameter.getValuef() * 10) + 1)) / (numSteps * 2);
-// phase = (phase + deltaMs / 1000.0 * speed) % 1.0;
- }
-
- public boolean isOnBlade(float x, float y) {
- x = x - center.x;
- y = y - center.y;
-
- float normalizedAngle = (atan2(x, y) / (2 * PI) + 1 + phase) % 1;
- float v = (normalizedAngle * 4 * numBlades);
- int blade_num = floor((v + 2) / 4);
- return (blade_num % 2) == 0;
- }
- }
-
- private final List<Pinwheel> pinwheels;
- private final float[] values;
-
- TimPinwheels(GLucose glucose) {
- super(glucose);
-
- addParameter(horizSpreadParameter);
-// addParameter(vertSpreadParameter);
- addParameter(vertOffsetParameter);
- addParameter(zSlopeParameter);
- addParameter(sharpnessParameter);
- addParameter(derezParameter);
- addParameter(clickinessParameter);
- addParameter(hueParameter);
- addParameter(hueSpreadParameter);
-
- pinwheels = new ArrayList();
- pinwheels.add(new Pinwheel(0, 0, NUM_BLADES, 0.1f));
- pinwheels.add(new Pinwheel(0, 0, NUM_BLADES, -0.1f));
-
- this.updateHorizSpread();
- this.updateVertPositions();
-
- values = new float[model.points.size()];
- }
-
- public void onParameterChanged(LXParameter parameter) {
- if (parameter == horizSpreadParameter) {
- updateHorizSpread();
- } else if (parameter == vertSpreadParameter || parameter == vertOffsetParameter) {
- updateVertPositions();
- }
- }
-
- private void updateHorizSpread() {
- float xDist = model.xMax - model.xMin;
- float xCenter = (model.xMin + model.xMax) / 2;
-
- float spread = horizSpreadParameter.getValuef() - 0.5f;
- pinwheels.get(0).center.x = xCenter - xDist * spread;
- pinwheels.get(1).center.x = xCenter + xDist * spread;
- }
-
- private void updateVertPositions() {
- float yDist = model.yMax - model.yMin;
- float yCenter = model.yMin + yDist * vertOffsetParameter.getValuef();
-
- float spread = vertSpreadParameter.getValuef() - 0.5f;
- pinwheels.get(0).center.y = yCenter - yDist * spread;
- pinwheels.get(1).center.y = yCenter + yDist * spread;
- }
-
- private float prevRamp = 0;
-
- public void run(double deltaMs) {
- float ramp = lx.tempo.rampf();
- float numBeats = (1 + ramp - prevRamp) % 1;
- prevRamp = ramp;
-
- float hue = hueParameter.getValuef() * 360;
- // 0 -> -180
- // 0.5 -> 0
- // 1 -> 180
- float hueSpread = (hueSpreadParameter.getValuef() - 0.5f) * 360;
-
- float fadeAmount = (float) (deltaMs / 1000.0f) * pow(sharpnessParameter.getValuef() * 10, 1);
-
- for (Pinwheel pw : pinwheels) {
- pw.age(numBeats);
- }
-
- float derez = derezParameter.getValuef();
-
- float zSlope = (zSlopeParameter.getValuef() - 0.5f) * 2;
-
- int i = -1;
- for (Point p : model.points) {
- ++i;
-
- int value = 0;
- for (Pinwheel pw : pinwheels) {
- value += (pw.isOnBlade(p.x, p.y - p.z * zSlope) ? 1 : 0);
- }
- if (value == 1) {
- values[i] = 1;
-// colors[p.index] = lx.hsb(120, 0, 100);
- } else {
- values[i] = max(0, values[i] - fadeAmount);
- //color c = colors[p.index];
- //colors[p.index] = lx.hsb(max(0, lx.h(c) - 10), min(100, lx.s(c) + 10), lx.b(c) - 5 );
- }
-
- if (random(1.0f) >= derez) {
- float v = values[i];
- colors[p.index] = lx.hsb((360 + hue + pow(v, 2) * hueSpread) % 360, 30 + pow(1 - v, 0.25f) * 60, v * 100);
- }
- }
- }
-}
-
-/**
- * This tries to figure out neighboring pixels from one cube to another to
- * let you have a bunch of moving points tracing all over the structure.
- * Adds a couple seconds of startup time to do the calculation, and in the
- * end just comes out looking a lot like a screensaver. Probably not worth
- * it but there may be useful code here.
- */
-class TimTrace extends SCPattern {
- private Map<Point, List<Point>> pointToNeighbors;
- private Map<Point, Strip> pointToStrip;
- // private final Map<Strip, List<Strip>> stripToNearbyStrips;
-
- int extraMs;
-
- class MovingPoint {
- Point currentPoint;
- float hue;
- private Strip currentStrip;
- private int currentStripIndex;
- private int direction; // +1 or -1
-
- MovingPoint(Point p) {
- this.setPointOnNewStrip(p);
- hue = random(360);
- }
-
- private void setPointOnNewStrip(Point p) {
- this.currentPoint = p;
- this.currentStrip = pointToStrip.get(p);
- for (int i = 0; i < this.currentStrip.points.size(); ++i) {
- if (this.currentStrip.points.get(i) == p) {
- this.currentStripIndex = i;
- break;
- }
- }
- if (this.currentStripIndex == 0) {
- // we are at the beginning of the strip; go forwards
- this.direction = 1;
- } else if (this.currentStripIndex == this.currentStrip.points.size()) {
- // we are at the end of the strip; go backwards
- this.direction = -1;
- } else {
- // we are in the middle of a strip; randomly go one way or another
- this.direction = ((random(1.0f) < 0.5f) ? -1 : 1);
- }
- }
-
- public void step() {
- List<Point> neighborsOnOtherStrips = pointToNeighbors.get(this.currentPoint);
-
- Point nextPointOnCurrentStrip = null;
- this.currentStripIndex += this.direction;
- if (this.currentStripIndex >= 0 && this.currentStripIndex < this.currentStrip.points.size()) {
- nextPointOnCurrentStrip = this.currentStrip.points.get(this.currentStripIndex);
- }
-
- // pick which option to take; if we can keep going on the current strip then
- // add that as another option
- int option = floor(random(neighborsOnOtherStrips.size() + (nextPointOnCurrentStrip == null ? 0 : 100)));
-
- if (option < neighborsOnOtherStrips.size()) {
- this.setPointOnNewStrip(neighborsOnOtherStrips.get(option));
- } else {
- this.currentPoint = nextPointOnCurrentStrip;
- }
- }
- }
-
- List<MovingPoint> movingPoints;
-
- TimTrace(GLucose glucose) {
- super(glucose);
-
- extraMs = 0;
-
- pointToNeighbors = this.buildPointToNeighborsMap();
- pointToStrip = this.buildPointToStripMap();
-
- int numMovingPoints = 1000;
- movingPoints = new ArrayList();
- for (int i = 0; i < numMovingPoints; ++i) {
- movingPoints.add(new MovingPoint(model.points.get(floor(random(model.points.size())))));
- }
-
- }
-
- private Map<Strip, List<Strip>> buildStripToNearbyStripsMap() {
- Map<Strip, Vector3> stripToCenter = new HashMap();
- for (Strip s : model.strips) {
- Vector3 v = new Vector3();
- for (Point p : s.points) {
- v.add(p.x, p.y, p.z);
- }
- v.divide(s.points.size());
- stripToCenter.put(s, v);
- }
-
- Map<Strip, List<Strip>> stripToNeighbors = new HashMap();
- for (Strip s : model.strips) {
- List<Strip> neighbors = new ArrayList();
- Vector3 sCenter = stripToCenter.get(s);
- for (Strip potentialNeighbor : model.strips) {
- if (s != potentialNeighbor) {
- float distance = sCenter.distanceTo(stripToCenter.get(potentialNeighbor));
- if (distance < 25) {
- neighbors.add(potentialNeighbor);
- }
- }
- }
- stripToNeighbors.put(s, neighbors);
- }
-
- return stripToNeighbors;
- }
-
- private Map<Point, List<Point>> buildPointToNeighborsMap() {
- Map<Point, List<Point>> m = new HashMap();
- Map<Strip, List<Strip>> stripToNearbyStrips = this.buildStripToNearbyStripsMap();
-
- for (Strip s : model.strips) {
- List<Strip> nearbyStrips = stripToNearbyStrips.get(s);
-
- for (Point p : s.points) {
- Vector3 v = new Vector3(p.x, p.y, p.z);
-
- List<Point> neighbors = new ArrayList();
-
- for (Strip nearbyStrip : nearbyStrips) {
- Point closestPoint = null;
- float closestPointDistance = 100000;
-
- for (Point nsp : nearbyStrip.points) {
- float distance = v.distanceTo(nsp.x, nsp.y, nsp.z);
- if (closestPoint == null || distance < closestPointDistance) {
- closestPoint = nsp;
- closestPointDistance = distance;
- }
- }
-
- if (closestPointDistance < 15) {
- neighbors.add(closestPoint);
- }
- }
-
- m.put(p, neighbors);
- }
- }
-
- return m;
- }
-
- private Map<Point, Strip> buildPointToStripMap() {
- Map<Point, Strip> m = new HashMap();
- for (Strip s : model.strips) {
- for (Point p : s.points) {
- m.put(p, s);
- }
- }
- return m;
- }
-
- public void run(double deltaMs) {
- for (Point p : model.points) {
- int c = colors[p.index];
- colors[p.index] = lx.hsb(lx.h(c), lx.s(c), lx.b(c) - 3);
- }
-
- for (MovingPoint mp : movingPoints) {
- mp.step();
- colors[mp.currentPoint.index] = blendColor(colors[mp.currentPoint.index], lx.hsb(mp.hue, 10, 100), ADD);
- }
- }
-}
-class GlitchPlasma extends SCPattern {
- private int pos = 0;
- private float satu = 100;
- private float speed = 1;
- private float glitch = 0;
- BasicParameter saturationParameter = new BasicParameter("SATU", 1.0f);
- BasicParameter speedParameter = new BasicParameter("SPEED", 0.1f);
- BasicParameter glitchParameter = new BasicParameter("GLITCH", 0.0f);
-
- public GlitchPlasma(GLucose glucose) {
- super(glucose);
- addParameter(saturationParameter);
- addParameter(speedParameter);
- addParameter(glitchParameter);
- }
- public void onParameterChanged(LXParameter parameter) {
- if (parameter == saturationParameter) {
- satu = 100*parameter.getValuef();
- } else if (parameter == speedParameter) {
- speed = 8*parameter.getValuef();
- } else if (parameter == glitchParameter) {
- glitch = parameter.getValuef();
- }
- }
-
- public void run(double deltaMs) {
- for (Point p : model.points) {
- float hv = sin(dist(p.x + pos, p.y, 128.0f, 128.0f) / 8.0f)
- + sin(dist(p.x, p.y, 64.0f, 64.0f) / 8.0f)
- + sin(dist(p.x, p.y + pos / 7, 192.0f, 64.0f) / 7.0f)
- + sin(dist(p.x, p.z + pos, 192.0f, 100.0f) / 8.0f);
- float bv = 100;
- colors[p.index] = lx.hsb((hv+2)*50, satu, bv);
- }
- if (random(1.0f)<glitch/20) {
- pos=pos-PApplet.parseInt(random(10,30));
- }
- pos+=speed;
- if (pos >= MAX_INT-1) pos=0;
- }
-}
-
-// This is very much a work in progress. Trying to get a flame effect.
-class FireEffect extends SCPattern {
- private float[][] intensity;
- private float hotspot;
- private float decay = 0.3f;
- private int xm;
- private int ym;
- BasicParameter decayParameter = new BasicParameter("DECAY", 0.3f);
-
- public FireEffect(GLucose glucose) {
- super(glucose);
- xm = PApplet.parseInt(model.xMax);
- ym = PApplet.parseInt(model.yMax);
-
- intensity = new float[xm][ym];
- addParameter(decayParameter);
- }
- public void onParameterChanged(LXParameter parameter) {
- if (parameter == decayParameter) {
- decay = parameter.getValuef();
- }
- }
- private int flameColor(float level) {
- if (level<=0) return lx.hsb(0,0,0);
- float br=min(100,sqrt(level)*15);
- return lx.hsb(level/1.7f,100,br);
- }
- public void run(double deltaMs) {
- for (int x=10;x<xm-10;x++) {
- if (x%50>45 || x%50<5) {
- intensity[x][ym-1] = random(30,100);
- } else {
- intensity[x][ym-1] = random(0,50);
- }
- }
- for (int x=1;x<xm-1;x++) {
- for (int y=0;y<ym-1;y++) {
- intensity[x][y] = (intensity[x-1][y+1]+intensity[x][y+1]+intensity[x+1][y+1])/3-decay;
- }
- }
-
- for (Point p : model.points) {
- int x = max(0,(PApplet.parseInt(p.x)+PApplet.parseInt(p.z))%xm);
- int y = constrain(ym-PApplet.parseInt(p.y),0,ym-1);
- colors[p.index] = flameColor(intensity[x][y]);
- }
- }
-}
-
-class StripBounce extends SCPattern {
- private final int numOsc = 30;
- SinLFO[] fX = new SinLFO[numOsc]; //new SinLFO(0, model.xMax, 5000);
- SinLFO[] fY = new SinLFO[numOsc]; //new SinLFO(0, model.yMax, 4000);
- SinLFO[] fZ = new SinLFO[numOsc]; //new SinLFO(0, model.yMax, 3000);
- SinLFO[] sat = new SinLFO[numOsc];
- float[] colorOffset = new float[numOsc];
-
- public StripBounce(GLucose glucose) {
- super(glucose);
- for (int i=0;i<numOsc;i++) {
- fX[i] = new SinLFO(0, model.xMax, random(2000,20000));
- fY[i] = new SinLFO(0, model.yMax, random(2000,20000));
- fZ[i] = new SinLFO(0, model.zMax, random(2000,20000));
- sat[i] = new SinLFO(60, 100, random(2000,50000));
- addModulator(fX[i]).trigger();
- addModulator(fY[i]).trigger();
- addModulator(fZ[i]).trigger();
- colorOffset[i]=random(0,256);
- }
- }
-
- public void run(double deltaMs) {
- float[] bright = new float[model.points.size()];
- for (Strip strip : model.strips) {
- for (int i=0;i<numOsc;i++) {
- float avgdist=0.0f;
- avgdist = dist(strip.points.get(8).x,strip.points.get(8).y,strip.points.get(8).z,fX[i].getValuef(),fY[i].getValuef(),fZ[i].getValuef());
- boolean on = avgdist<30;
- float hv = (lx.getBaseHuef()+colorOffset[i])%360;
- float br = max(0,100-avgdist*4);
- for (Point p : strip.points) {
- if (on && br>bright[p.index]) {
- colors[p.index] = lx.hsb(hv,sat[i].getValuef(),br);
- bright[p.index] = br;
- }
- }
- }
- }
- }
-}
-
-class SoundRain extends SCPattern {
-
- private FFT fft = null;
- private LinearEnvelope[] bandVals = null;
- private float[] lightVals = null;
- private int avgSize;
- private float gain = 25;
- SawLFO pos = new SawLFO(0, 9, 8000);
- SinLFO col1 = new SinLFO(0, model.xMax, 5000);
- BasicParameter gainParameter = new BasicParameter("GAIN", 0.5f);
-
- public SoundRain(GLucose glucose) {
- super(glucose);
- addModulator(pos).trigger();
- addModulator(col1).trigger();
- addParameter(gainParameter);
- }
-
- public void onParameterChanged(LXParameter parameter) {
- if (parameter == gainParameter) {
- gain = 50*parameter.getValuef();
- }
- }
- protected void onActive() {
- if (this.fft == null) {
- this.fft = new FFT(lx.audioInput().bufferSize(), lx.audioInput().sampleRate());
- this.fft.window(FFT.HAMMING);
- this.fft.logAverages(40, 1);
- this.avgSize = this.fft.avgSize();
- this.bandVals = new LinearEnvelope[this.avgSize];
- for (int i = 0; i < this.bandVals.length; ++i) {
- this.addModulator(this.bandVals[i] = (new LinearEnvelope(0, 0, 700+i*4))).trigger();
- }
- lightVals = new float[avgSize];
- }
- }
-
- public void run(double deltaMs) {
- this.fft.forward(this.lx.audioInput().mix);
- for (int i = 0; i < avgSize; ++i) {
- float value = this.fft.getAvg(i);
- this.bandVals[i].setEndVal(value,40).trigger();
- float lv = min(value*gain,100);
- if (lv>lightVals[i]) {
- lightVals[i]=min(lightVals[i]+15,lv,100);
- } else {
- lightVals[i]=max(lv,lightVals[i]-5,0);
- }
- }
- for (Cube c : model.cubes) {
- for (int j=0; j<c.strips.size(); j++) {
- Strip s = c.strips.get(j);
- if (j%4!=0 && j%4!=2) {
- for (Point p : s.points) {
- int seq = PApplet.parseInt(p.y*avgSize/model.yMax+pos.getValuef()+sin(p.x+p.z)*2)%avgSize;
- seq=min(abs(seq-(avgSize/2)),avgSize-1);
- colors[p.index] = lx.hsb(200,max(0,100-abs(p.x-col1.getValuef())/2),lightVals[seq]);
- }
- }
- }
- }
- }
-}
-
-class FaceSync extends SCPattern {
- SinLFO xosc = new SinLFO(-10, 10, 3000);
- SinLFO zosc = new SinLFO(-10, 10, 3000);
- SinLFO col1 = new SinLFO(0, model.xMax, 5000);
- SinLFO col2 = new SinLFO(0, model.xMax, 4000);
-
- public FaceSync(GLucose glucose) {
- super(glucose);
- addModulator(xosc).trigger();
- addModulator(zosc).trigger();
- zosc.setValue(0);
- addModulator(col1).trigger();
- addModulator(col2).trigger();
- col2.setValue(model.xMax);
- }
-
- public void run(double deltaMs) {
- int i=0;
- for (Strip s : model.strips) {
- i++;
- for (Point p : s.points) {
- float dx, dz;
- if (i%32 < 16) {
- dx = p.x - (s.cx+xosc.getValuef());
- dz = p.z - (s.cz+zosc.getValuef());
- } else {
- dx = p.x - (s.cx+zosc.getValuef());
- dz = p.z - (s.cz+xosc.getValuef());
- }
- //println(dx);
- float a1=max(0,100-abs(p.x-col1.getValuef()));
- float a2=max(0,100-abs(p.x-col2.getValuef()));
- float sat = max(a1,a2);
- float h = (359*a1+200*a2) / (a1+a2);
- colors[p.index] = lx.hsb(h,sat,100-abs(dx*5)-abs(dz*5));
- }
- }
- }
-}
-
-class SoundSpikes extends SCPattern {
- private FFT fft = null;
- private LinearEnvelope[] bandVals = null;
- private float[] lightVals = null;
- private int avgSize;
- private float gain = 25;
- BasicParameter gainParameter = new BasicParameter("GAIN", 0.5f);
- SawLFO pos = new SawLFO(0, model.xMax, 8000);
-
- public SoundSpikes(GLucose glucose) {
- super(glucose);
- addParameter(gainParameter);
- addModulator(pos).trigger();
- }
-
- public void onParameterChanged(LXParameter parameter) {
- if (parameter == gainParameter) {
- gain = 50*parameter.getValuef();
- }
- }
- protected void onActive() {
- if (this.fft == null) {
- this.fft = new FFT(lx.audioInput().bufferSize(), lx.audioInput().sampleRate());
- this.fft.window(FFT.HAMMING);
- this.fft.logAverages(40, 1);
- this.avgSize = this.fft.avgSize();
- this.bandVals = new LinearEnvelope[this.avgSize];
- for (int i = 0; i < this.bandVals.length; ++i) {
- this.addModulator(this.bandVals[i] = (new LinearEnvelope(0, 0, 700+i*4))).trigger();
- }
- lightVals = new float[avgSize];
- }
- }
-
- public void run(double deltaMs) {
- this.fft.forward(this.lx.audioInput().mix);
- for (int i = 0; i < avgSize; ++i) {
- float value = this.fft.getAvg(i);
- this.bandVals[i].setEndVal(value,40).trigger();
- float lv = min(value*gain,model.yMax+10);
- if (lv>lightVals[i]) {
- lightVals[i]=min(lightVals[i]+30,lv,model.yMax+10);
- } else {
- lightVals[i]=max(lv,lightVals[i]-10,0);
- }
- }
- int i = 0;
- for (Cube c : model.cubes) {
- for (int j=0; j<c.strips.size(); j++) {
- Strip s = c.strips.get(j);
- if (j%4!=0 && j%4!=2) {
- for (Point p : s.points) {
- float dis = (abs(p.x-model.xMax/2)+pos.getValuef())%model.xMax/2;
- int seq = PApplet.parseInt((dis*avgSize*2)/model.xMax);
- if (seq>avgSize) seq=avgSize-seq;
- seq=constrain(seq,0,avgSize-1);
- float br=max(0, lightVals[seq]-p.y);
- colors[p.index] = lx.hsb((dis*avgSize*65)/model.xMax,90,br);
- }
- }
- }
- }
- }
-}
-
- static public void main(String[] passedArgs) {
- String[] appletArgs = new String[] { "SugarCubes" };
- if (passedArgs != null) {
- PApplet.main(concat(appletArgs, passedArgs));
- } else {
- PApplet.main(appletArgs);
- }
- }
-}