From: Ben Morrow Date: Mon, 3 Mar 2014 06:02:04 +0000 (-0800) Subject: redo with new anti-GLucose X-Git-Url: https://git.piment-noir.org/?p=SugarCubes.git;a=commitdiff_plain;h=7d60f6f6ea82fd5c9794524ce11d40e7d6c00bf7;hp=cc9e8c8be45767207e09c434bad100b0156877e6 redo with new anti-GLucose --- diff --git a/AlexGreen.pde b/AlexGreen.pde index 3e164d8..5a35b3e 100644 --- a/AlexGreen.pde +++ b/AlexGreen.pde @@ -1,3 +1,4 @@ + class SineSphere extends APat { float modelrad = sqrt((model.xMax)*(model.xMax) + (model.yMax)*(model.yMax) + (model.zMax)*(model.zMax)); private BasicParameter yrotspeed = new BasicParameter("yspeed", 3000, 1, 10000); @@ -11,15 +12,15 @@ class SineSphere extends APat { public BasicParameter widthparameter= new BasicParameter("Width", 20, 1, 60); public BasicParameter vibration_magnitude = new BasicParameter("Vmag", 20, 2, modelrad/2); public BasicParameter scale = new BasicParameter("Scale", 1, .1, 5); - private int pitch = 0; - private int channel = 0; - private int velocity = 0; - private int cur = 0; - public final LXProjection sinespin; + private int pitch = 0; + private int channel = 0; + private int velocity = 0; + private int cur = 0; + public final LXProjection sinespin; public final LXProjection sinespin2; public final LXProjection sinespin3; - Pick Galaxy, STime; + Pick Galaxy, STime; public BasicParameter rotationx = new BasicParameter("rotx", 0, 0, 1 ); public BasicParameter rotationy = new BasicParameter("roty", 1, 0, 1); @@ -29,8 +30,8 @@ class SineSphere extends APat { class Sphery { float f1xcenter, f1ycenter, f1zcenter, f2xcenter , f2ycenter, f2zcenter; //second three are for an ellipse with two foci - private SinLFO vibration; - private SinLFO surfacewave; + private SinLFO vibration; + private SinLFO surfacewave; private SinLFO xbounce; public SinLFO ybounce; @@ -43,22 +44,22 @@ class SineSphere extends APat { public BasicParameter vibrationrate; public final PVector circlecenter; - public Sphery(float f1xcenter, float f1ycenter, float f1zcenter, float radius, float vibration_magnitude , float vperiod) + public Sphery(float f1xcenter, float f1ycenter, float f1zcenter, float radius, float vibration_magnitude , float vperiod) { this.f1xcenter = f1xcenter; this.f1ycenter = f1ycenter; this.f1zcenter = f1zcenter; - this.radius = radius; + this.radius = radius; this.circlecenter= new PVector(f1xcenter,f1ycenter,f1zcenter); this.vibration_magnitude = vibration_magnitude; this.vperiod = vperiod; //addParameter(bounceamp = new BasicParameter("Amp", .5)); - //addParameter(bouncerate = new BasicParameter("Rate", .5)); //ybounce.modulateDurationBy(bouncerate); + //addParameter(bouncerate = new BasicParameter("Rate", .5)); //ybounce.modulateDurationBy(bouncerate); //addParameter(vibrationrate = new BasicParameter("vibration", 1000, 10000)); //addParameter(widthparameter = new BasicParameter("Width", .2)); - //addModulator(xbounce = new SinLFO(model.xMax/3, 2*model.yMax/3, 2000)).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)).trigger(); //bounce.modulateDurationBy //addModulator(bounceamp); //ybounce.setMagnitude(bouncerate); @@ -67,44 +68,44 @@ class SineSphere extends APat { } - // public Sphery(float f1xcenter, float f1ycenter, float f1zcenter, float vibration_magnitude, float vperiod) + // public Sphery(float f1xcenter, float f1ycenter, float f1zcenter, float vibration_magnitude, float vperiod) // { - // this.f1xcenter = f1xcenter; - // this.f1ycenter = f1ycenter; - // this.f1zcenter = f1zcenter; - // this.vibration_magnitude = vibration_magnitude; + // this.f1xcenter = f1xcenter; + // this.f1ycenter = f1ycenter; + // this.f1zcenter = f1zcenter; + // this.vibration_magnitude = vibration_magnitude; // this.vperiod = vperiod; - // addModulator(ybounce= new SinLFO(model.yMax/3, 2*model.yMax/3, 240000)).trigger(); //bounce.modulateDurationBy - // addModulator( vibration = new SinLFO( modelrad/10 - vibration_magnitude , modelrad/10 + vibration_magnitude, vperiod)).trigger(); //vibration.setPeriod(240000/lx.tempo.bpm()); + // addModulator(ybounce= new SinLFO(model.yMax/3, 2*model.yMax/3, 240000)).trigger(); //bounce.modulateDurationBy + // addModulator( vibration = new SinLFO( modelrad/10 - vibration_magnitude , modelrad/10 + vibration_magnitude, vperiod)).trigger(); //vibration.setPeriod(240000/lx.tempo.bpm()); // } //for an ellipse -// public Sphery(float f1xcenter, float f1ycenter, float f1zcenter, float f2xcenter, float f2ycenter, float f2zcenter, -// float vibration_min, float vibration_max, float vperiod) +// 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", .1)); -// //addParameter(huespread = new BasicParameter("bonk", .2)); +// { +// 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", .1)); +// //addParameter(huespread = new BasicParameter("bonk", .2)); // } -public int c1c (float a) { return round(100*constrain(a,0,1)); } +public int c1c (float a) { return round(100*constrain(a,0,1)); } void setVibrationPeriod(double period){ -// to-do: make this conditional upon time signature +// to-do: make this conditional upon time signature this.vibration.setPeriod(period); } @@ -116,33 +117,33 @@ this.vibration.setRange(-mag,mag); } -float distfromcirclecenter(float px, float py, float pz, float f1x, float f1y, float f1z) +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, ) float quadrant(PVector q) { - float qtheta = atan2( (q.x-f1xcenter) , (q.z - f1zcenter) ); - float qphi = acos( (q.z-f1zcenter)/(PVector.dist(q,circlecenter)) ); + float qtheta = atan2( (q.x-f1xcenter) , (q.z - f1zcenter) ); + float qphi = acos( (q.z-f1zcenter)/(PVector.dist(q,circlecenter)) ); return map(qtheta, -PI/2, PI/2, 200-huespread.getValuef(), 240+huespread.getValuef()); //if (q.x > f1xcenter ) {return 140 ;} - //else {return 250;} + //else {return 250;} } // float noisesat(PVector q) { - // return noise() + // return noise() // } color spheryvalue (PVector p) { - circlecenter.set(this.f1xcenter, this.f1ycenter, this.f1zcenter); + circlecenter.set(this.f1xcenter, this.f1ycenter, this.f1zcenter); -//switch(sShpape.cur() ) {} +//switch(sShpape.cur() ) {} float b = max(0, 100 - widthparameter.getValuef()*abs(p.dist(circlecenter) - vibration.getValuef()) ); @@ -156,49 +157,49 @@ float distfromcirclecenter(float px, float py, float pz, float f1x, float f1y, f // constrain(100*noise(quadrant(p)), 0, 100), 100, b - ); + ); } color 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) , +//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.2*vibration.getValuef() ) ) ) ; + abs( (dist(px, py, pz, f1xc, ybounce.getValuef(), f1zc) + + (dist(px, py , pz, f2xc, ybounce.getValuef(), f2zc) ) )/2 + - 1.2*vibration.getValuef() ) ) ) ; } -} +} boolean noteOn(Note note) { int row = note.getPitch(), col = note.getChannel(); - // if (row == 57) {KeyPressed = col; return true; } + // if (row == 57) {KeyPressed = col; return true; } return super.noteOn(note); } -// public boolean noteOn(Note note) { -// pitch= note.getPitch(); +// public boolean noteOn(Note note) { +// pitch= note.getPitch(); // velocity=note.getVelocity(); // channel=note.getChannel(); // return true; // } // public boolean gridPressed(int row, int col) { -// pitch = row; channel = col; -// cur = NumApcCols*(pitch-53)+col; -// //setState(row, col, 0 ? 1 : 0); +// pitch = row; channel = col; +// cur = NumApcCols*(pitch-53)+col; +// //setState(row, col, 0 ? 1 : 0); // return true; // } //public grid final Sphery[] spherys; - SineSphere(GLucose glucose) + SineSphere(LX lx) { - super(glucose); - println("modelrad " + modelrad); + super(lx); + println("modelrad " + modelrad); sinespin = new LXProjection(model); sinespin2 = new LXProjection(model); sinespin3= new LXProjection(model); @@ -214,7 +215,7 @@ final Sphery[] spherys; addParameter(vibration_magnitude); addParameter(scale); addModulator(yrot).trigger(); - addModulator(yrot2).trigger(); + addModulator(yrot2).trigger(); addModulator(yrot3).trigger(); //Galaxy = addPick("Galaxy", 1, 3, new String[] {"home", "vertical","single","aquarium"}); STime =addPick("Time", 1, 4, new String[]{"half", "triplet", "beat", "2x", "3x" }); @@ -222,47 +223,36 @@ final Sphery[] spherys; spherys = new Sphery[] { new Sphery(model.xMax/4, model.yMax/2, model.zMax/2, modelrad/12, modelrad/25, 3000), new Sphery(.75*model.xMax, model.yMax/2, model.zMax/2, modelrad/14, modelrad/28, 2000), - new Sphery(model.cx, model.cy, model.cz, modelrad/5, modelrad/15, 2300), + new Sphery(model.cx, model.cy, model.cz, modelrad/5, modelrad/15, 2300), new Sphery(.7*model.xMax, .65*model.yMax, .5*model.zMax, modelrad/11, modelrad/25, 3500), new Sphery(.75*model.xMax, .8*model.yMax, .7*model.zMax, modelrad/12, modelrad/30, 2000) - - - - - // new Sphery(model.xMax/4, model.yMax/2, model.zMax/2, modelrad/16, modelrad/8, 3000), - // new Sphery(.75*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), - - // new Sphery(.7*model.xMax, .65*model.yMax, .5*model.zMax, modelrad/14, modelrad/7, 3500), - // new Sphery(.75*model.xMax, .8*model.yMax, .7*model.zMax, 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); -// } -// } -// } +// 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 t = lx.tempo.rampf(); float bpm = lx.tempo.bpmf(); float scalevalue = scale.getValuef(); int spherytime= STime.Cur(); @@ -270,28 +260,26 @@ final Sphery[] spherys; switch (spherytime) { - case 0: t = map(.5*t ,0,.5, 0,1); bpm = .5*bpm; break; + case 0: t = map(.5*t ,0,.5, 0,1); bpm = .5*bpm; break; - case 1: t = t; bpm = bpm; break; + case 1: t = t; bpm = bpm; break; - case 2: t = map(2*t,0,2,0,1); bpm = 2*bpm; break; + case 2: t = map(2*t,0,2,0,1); bpm = 2*bpm; break; - default: t= t; bpm = bpm; + default: t= t; bpm = bpm; } //switch(sphery.colorscheme) for ( Sphery s: spherys){ - - //s.vibration.setBasis(t); s.setVibrationPeriod(vibrationrate.getValuef()); - // s.setVibrationMagnitude(vibration_magnitude.getValuef()); + // s.setVibrationMagnitude(vibration_magnitude.getValuef()); } sinespin.reset() - // Translate so the center of the car is the origin, offset + // Translate so the center of the car is the origin, offset .center() .scale(scalevalue, scalevalue, scalevalue) // Rotate around the origin (now the center of the car) about an y-vector @@ -324,21 +312,21 @@ final Sphery[] spherys; .translate(model.cx,model.cy,model.cz); for (LXVector p: sinespin2) - { color c = 0; + { color c = 0; // PVector P = new PVector(p.x, p.y, p.z); P.set(p.x, p.y, p.z); c = blendIfColor(c, spherys[3].spheryvalue(P),ADD); colors[p.index] = blendIfColor(colors[p.index], c , ADD); - } + } sinespin3.reset() .center() .scale(scalevalue,scalevalue,scalevalue) .rotate(yrot3.getValuef(),-1 + rotationx.getValuef(), rotationy.getValuef(), rotationz.getValuef()) .translate(model.cx, model.cy, model.cz); for (LXVector p: sinespin3) - { color c = 0; + { color c = 0; // PVector P = new PVector(p.x, p.y, p.z); P.set(p.x, p.y, p.z); c = blendIfColor(c, spherys[4].spheryvalue(P),ADD); @@ -363,116 +351,116 @@ final Sphery[] spherys; } - // 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; + // 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) + // // else if(spheremode ==2) // { color c = 0; - // return lx.hsb(CalcCone( (xyz by = new xyz(0,spherys[2].ybounce.getValuef(),0) ), Px, mid) ); + // return lx.hsb(CalcCone( (xyz by = new xyz(0,spherys[2].ybounce.getValuef(),0) ), Px, mid) ); // } - // } + // } } /*This just takes all of Dan Horwitz's code that I want to inherit and leaves the rest behind. - A work in progress. */ +A work in progress. */ public class APat extends SCPattern { - ArrayList picks = new ArrayList (); - ArrayList bools = new ArrayList (); - - 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; - - float lxh () { return lx.getBaseHuef(); } - int c1c (float a) { return round(100*constrain(a,0,1)); } - float interpWv(float i, float[] vals) { return interp(i-floor(i), vals[floor(i)], vals[ceil(i)]); } - void setNorm (PVector vec) { vec.set(vec.x/mMax.x, vec.y/mMax.y, vec.z/mMax.z); } - void setRand (PVector vec) { vec.set(random(mMax.x), random(mMax.y), random(mMax.z)); } - void setVec (PVector vec, LXPoint p) { vec.set(p.x, p.y, p.z); } - 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)); } - //void StartRun(double deltaMs) { } - float val (BasicParameter p) { return p.getValuef(); } - //color CalcPoint(PVector p) { return lx.hsb(0,0,0); } - color blend3(color c1, color c2, color c3) { return blendColor(c1,blendColor(c2,c3,ADD),ADD); } - - 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); } - 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 ); } - 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 ); } - - BasicParameter addParam(String label, double value) { BasicParameter p = new BasicParameter(label, value); addParameter(p); return p; } - - PVector vT1 = new PVector(), vT2 = new PVector(); - float calcCone (PVector v1, PVector v2, PVector c) { vT1.set(v1); vT2.set(v2); vT1.sub(c); vT2.sub(c); + ArrayList picks = new ArrayList (); + ArrayList bools = new ArrayList (); + + 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; + + float lxh () { return lx.getBaseHuef(); } + int c1c (float a) { return round(100*constrain(a,0,1)); } + float interpWv(float i, float[] vals) { return interp(i-floor(i), vals[floor(i)], vals[ceil(i)]); } + void setNorm (PVector vec) { vec.set(vec.x/mMax.x, vec.y/mMax.y, vec.z/mMax.z); } + void setRand (PVector vec) { vec.set(random(mMax.x), random(mMax.y), random(mMax.z)); } + void setVec (PVector vec, LXPoint p) { vec.set(p.x, p.y, p.z); } + 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)); } + void StartRun(double deltaMs) { } + float val (BasicParameter p) { return p.getValuef(); } + color CalcPoint(PVector p) { return lx.hsb(0,0,0); } + color blend3(color c1, color c2, color c3) { return blendColor(c1,blendColor(c2,c3,ADD),ADD); } + + 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); } + 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 ); } + 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 ); } + + BasicParameter addParam(String label, double value) { BasicParameter p = new BasicParameter(label, value); addParameter(p); return p; } + + PVector vT1 = new PVector(), vT2 = new PVector(); + 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)); } - Pick addPick(String name, int def, int _max, String[] desc) { - Pick P = new Pick(name, def, _max+1, nMaxRow, desc); - nMaxRow = P.EndRow + 1; + 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; } - boolean noteOff(Note note) { + boolean noteOff(Note note) { int row = note.getPitch(), col = note.getChannel(); for (int i=0; i 0) { + for (int i=0; i 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); + + + color 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*.5)%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; + } } } @@ -517,12 +545,12 @@ class CubeCurl extends SCPattern{ float CH, CW, diag; ArrayList cubeorigin = new ArrayList(); ArrayList centerlist = new ArrayList(); -private SinLFO curl = new SinLFO(0, Cube.EDGE_HEIGHT, 5000 ); +private SinLFO curl = new SinLFO(0, Cube.EDGE_HEIGHT, 5000 ); private SinLFO bg = new SinLFO(180, 220, 3000); -CubeCurl(GLucose glucose){ -super(glucose); +CubeCurl(LX lx){ +super(lx); addModulator(curl).trigger(); addModulator(bg).trigger(); this.CH = Cube.EDGE_HEIGHT; @@ -536,11 +564,11 @@ for (int i = 0; i < model.cubes.size(); i++){ cubeorigin.add(new PVector(a.x, a.y, a.z)); centerlist.add(new PVector(a.cx, a.cy, a.cz) ); -} +} } //there is definitely a better way of doing this! -PVector centerofcube(int i) { +PVector centerofcube(int i) { Cube c = model.cubes.get(i); PVector cubecenter = new PVector(c.cx, c.cy, c.cz); @@ -549,36 +577,36 @@ return cubecenter; void run(double deltaMs){ -for (int i =0; i < model.cubes.size(); i++) { +for (int i =0; i < model.cubes.size(); i++) { Cube c = model.cubes.get(i); float cfloor = c.y; - + // if (i%3 == 0){ // for (LXPoint 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); -// } -// } +// // 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 (LXPoint 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 ); -// } -// } +// for (LXPoint 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 (LXPoint 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), ); + 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), ); } @@ -589,14 +617,130 @@ float cfloor = c.y; } } } + JGraphAdapterDemo graph1; + + +// class SpinningCube extends SCPattern{ +// LXProjection spin1, spin2, spin3; +// SawLFO + +//} + + + + + +class PixelGraph implements EdgeFactory { + +dPixel p0; dPixel p1; dVertex v0; + +public dVertex createEdge(dPixel p0, dPixel p1) { + + return v0; + +} + + +} + + class GraphTest extends SCPattern { + JGraphAdapterDemo graph1; + +GraphTest( LX lx) {super(lx); JGraphAdapterDemo graph1 = new JGraphAdapterDemo();} + + void run(double deltaMs){ + } +} + +class SpinningCube extends SCPattern{ + + LXProjection spin1, spin2, spin3; + SawLFO spinx, spiny, spinz; + SinLFO spinx1, spiny1, spinz1, cubesize; + BasicParameter xoff = new BasicParameter("xoff", 10, 0, 100); + BasicParameter toff = new BasicParameter("toff", 10,0,1000); + BasicParameter huev = new BasicParameter("hue", 200, 0, 360); + BasicParameter density = new BasicParameter("density", 0, 0, 1); + BasicParameter Vsize = new BasicParameter("size", model.xMax/3,0, model.xMax); + VirtualCube V1, V2, V3; + PVector P = new PVector(); + float noisetime=0.; + class VirtualCube { + float x,y,z,d; + PVector center; + + VirtualCube(float x, float y, float z, float d) { + this.x=x; + this.y= y; + this.z=z; + this.d=d; + this.center=new PVector(x,y,z); + } + + color getcolor(LXVector q) { + if ( q.x > this.x + d/2 || q.x < this.x - d/2 || q.y > this.y + d/2 || q.y < this.y - d/2 || q.z > this.z + d/2 || q.z < this.z - d/2 ) + {return 0;} + else { + return lx.hsb(huev.getValuef()*noise(xoff.getValuef()*.001*noisetime ) , constrain(100*noise(xoff.getValuef()*.001*q.x*noisetime), 0, 100), max(100*(noise(xoff.getValuef()*.001*q.x*noisetime)-density.getValuef()), 0) ); + } + } + void setcenter(float x, float y, float z) {this.x=x; this.y = y; this.z=z; } + void setsize(float din){ this.d=din ; } + + } + +SpinningCube(LX lx) { + super(lx); + addParameter(xoff); + addParameter(toff); + addParameter(Vsize); + addParameter(huev); + addParameter(density); + //addModulator() + V1 = new VirtualCube(model.cx, model.cy, model.cz, model.xMax/2); + spinx= new SawLFO(0, TWO_PI, 8000); + spin1 = new LXProjection(model); + +} + + +void run(double deltaMs) { + + noisetime+= deltaMs*.0001*toff.getValuef(); + +spin1.reset() +.center() +//.scale () +.rotate(spinx.getValuef(),0, 1, 0) +.translate(model.cx, model.cy, model.cz); + +for (LXVector p: spin1) { + P.set(p.x, p.y, p.z); + + colors[p.index] = V1.getcolor(p); + +} + +V1.setsize(Vsize.getValuef()); + + +}; + + +} + + + + + class HueTestHSB extends SCPattern{ BasicParameter HueT = new BasicParameter("Hue", .5); BasicParameter SatT = new BasicParameter("Sat", .5); BasicParameter BriT = new BasicParameter("Bright", .5); -HueTestHSB(GLucose glucose) { - super(glucose); +HueTestHSB(LX lx) { + super(lx); addParameter(HueT); addParameter(SatT); addParameter(BriT); @@ -611,7 +755,7 @@ HueTestHSB(GLucose glucose) { int now= millis(); if (now % 1000 <= 20) { - println("Hue: " + 360*HueT.getValuef() + "Sat: " + 100*SatT.getValuef() + "Bright: " + 100*BriT.getValuef()); + println("Hue: " + 360*HueT.getValuef() + "Sat: " + 100*SatT.getValuef() + "Bright: " + 100*BriT.getValuef()); } } diff --git a/AlexGreen.pde.orig b/AlexGreen.pde.orig deleted file mode 100644 index 9d657e9..0000000 --- a/AlexGreen.pde.orig +++ /dev/null @@ -1,446 +0,0 @@ -class SineSphere extends SCPattern { -<<<<<<< HEAD - private SawLFO yrot = new SawLFO(0, TWO_PI, 3000); - private SawLFO yrot2 = new SawLFO(0, -TWO_PI, 8000); - public BasicParameter huespread = new BasicParameter("Hue", 0, 180); - public BasicParameter widthparameter= new BasicParameter("Width", .2); - private int pitch = 0; - private int channel = 0; - private int velocity = 0; - public final Projection sinespin; - public final Projection sinespin2; - - //to-do: how to sync all hues across sphery's via one basicparameter - //public BasicParameter huespread = new BasicParameter("HueSpread", 180, 360); - public BasicParameter rotationx = new BasicParameter("rotx", 0, 0, 1 ); - public BasicParameter rotationy = new BasicParameter("roty", 1, 0, 1); - public BasicParameter rotationz = new BasicParameter("rotz", 0, 0, 1); - -======= - private SinLFO yrot = new SinLFO(0, TWO_PI, 2000); - public final LXProjection sinespin; ->>>>>>> b8bb27489db7dc687bf150576e9d9439f1fa17a6 - float modelrad = sqrt((model.xMax)*(model.xMax) + (model.yMax)*(model.yMax) + (model.zMax)*(model.zMax)); - Pick Sshape; - public final PVector P = new PVector(); - - 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 huespread; - public BasicParameter bouncerate; - public BasicParameter bounceamp; - public BasicParameter vibrationrate; - public final PVector circlecenter = new PVector(); - - 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", .5)); - //addParameter(bouncerate = new BasicParameter("Rate", .5)); //ybounce.modulateDurationBy(bouncerate); - //addParameter(vibrationrate = new BasicParameter("vibration", 1000, 10000)); - //addParameter(widthparameter = new BasicParameter("Width", .2)); - - - addModulator( vx = new SinLFO(500, 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./lx.tempo.bpm())).trigger(); //bounce.modulateDurationBy - - //addModulator(bounceamp); //ybounce.setMagnitude(bouncerate); - addModulator( vibration = new SinLFO(vibration_min , vibration_max, 10000)).trigger(); //vibration.setPeriod(240000/lx.tempo.bpm()); - - } - - //for an ellipse -// 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", .1)); -// //addParameter(huespread = new BasicParameter("bonk", .2)); - -// } - - - -void setVibrationPeriod(double period){ -// to-do: make this conditional upon time signature - -vibration.setPeriod(period); - -} - - -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, ) - - float quadrant(PVector q) { - float qtheta = atan2( (q.x-f1xcenter) , (q.z - f1zcenter) ); - - - return map(qtheta, -PI/2, PI/2, 160-huespread.getValuef(), 240 +huespread.getValuef()); - //if (q.x > f1xcenter ) {return 140 ;} - //else {return 250;} - } - color spheryvalue (PVector p, float f1xcenter, float f1ycenter, float f1zcenter) { - circlecenter.set(f1xcenter, f1ycenter, f1zcenter); - - -//switch(sShpape.cur() ) {} - - float b = max(0, 100 - 100*widthparameter.getValuef()*abs(p.dist(circlecenter) - - vibration.getValuef() ) ); - - if (b <= 0) { - return 0; - } - - return lx.hsb( - constrain(quadrant(p), 0, 360), - 80, - b - ); - } - color 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.2*vibration.getValuef() ) ) ) ; - } - -void run(double deltaMs) { - float vv = vibration.getValuef(); - float ybv = ybounce.getValuef(); - - } - -} - -// public boolean gridPressed(int row, int co){ -// midiengine.grid.setState(); - -// return true; - -// } - -public boolean noteOn(Note note) { -pitch= note.getPitch(); -velocity=note.getVelocity(); -channel=note.getChannel(); -return true; -} - -final Sphery[] spherys; - - SineSphere(GLucose glucose) - { - super(glucose); -<<<<<<< HEAD - sinespin = new Projection(model); - sinespin2 = new Projection(model); - addParameter(huespread); - addParameter(rotationx); - addParameter(rotationy); - addParameter(rotationz); -======= - sinespin = new LXProjection(model); ->>>>>>> b8bb27489db7dc687bf150576e9d9439f1fa17a6 - addModulator(yrot).trigger(); - addModulator(yrot2).trigger(); - - //addParameter(huespread); - //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(.75*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), - - new Sphery(.3*model.xMax, .4*model.yMax, .6*model.zMax, modelrad/16, modelrad/8, 4000), - new Sphery(.75*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); -// } -// } -// } - -<<<<<<< HEAD - public void run( double deltaMs) { - double t = lx.tempo.ramp(); - double bpm = lx.tempo.bpm(); - spherys[0].run(deltaMs); - spherys[1].run(deltaMs); - spherys[2].run(deltaMs); - spherys[3].run(deltaMs); - - - switch (pitch) - { - case 53: t = .5*t; bpm = .5*bpm; break; -======= - 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() - - // Translate so the center of the car is the origin, offset by yPos - .center() ->>>>>>> b8bb27489db7dc687bf150576e9d9439f1fa17a6 - - case 54: t = t; bpm = bpm; break; - - case 55: t = 2*t; bpm = 2*bpm; break; - - default: t= t; bpm = bpm; - -<<<<<<< HEAD -======= - for (LXPoint p : model.points){ - color c = 0; - c = blendColor(c, spherys[1].spheryvalue(p.x, p.y, p.z, .75*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); ->>>>>>> b8bb27489db7dc687bf150576e9d9439f1fa17a6 - - } - - for ( Sphery s: spherys){ - s.setVibrationPeriod(480000/bpm); - s.vibration.setBasis(t); - } - sinespin.reset(model) - - - // Translate so the center of the car is the origin, offset - .translateCenter(model, 0, 0, 0) - // .scale(1.3,1.3,1.3) - // Rotate around the origin (now the center of the car) about an y-vector - .rotate(yrot.getValuef(), rotationx.getValuef(), rotationy.getValuef() , rotationz.getValuef()) - .translate(model.cx, model.cy, model.cz); - - - - - - for (Coord p: sinespin) - // for (Point p: model.points) - { - P.set(p.x, p.y, p.z); - // PVector P = new PVector(p.x, p.y, p.z); - color c = #000000; - c = blendIfColor(c, spherys[1].spheryvalue(P, .75*model.xMax, model.yMax/2, model.zMax/2), ADD); - c = blendIfColor(c, spherys[0].spheryvalue(P, model.xMax/4, model.yMax/4, model.zMax/2), ADD); - c = blendIfColor(c, spherys[2].spheryvalue(P, model.xMax/2, model.yMax/2, model.zMax/2),ADD); - - - colors[p.index] = c; - - - } - sinespin2.reset(model). - translateCenter(model,0,0,0). - rotate(yrot2.getValuef(), 0, 1, 0). - translate(model.cx,model.cy,model.cz); - - for (Coord p: sinespin2) - { color c = 0; - // PVector P = new PVector(p.x, p.y, p.z); - P.set(p.x, p.y, p.z); - c = blendIfColor(c, spherys[3].spheryvalue(P, .3*model.xMax, .7*model.yMax, .6*model.zMax),ADD); - - colors[p.index] = blendIfColor(colors[p.index], c , ADD); - - } - - - - } - - color blendIfColor(color c1, color c2, int mode) { - if (c2 != 0) { - return blendColor(c1, c2, mode); - } - return c1; - } - - - // 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 cubeorigin = new ArrayList(); -ArrayList centerlist = new ArrayList(); -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 centerlistrelative = new ArrayList(); -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(new PVector(a.cx, a.cy, a.cz) ); - -} - -} -//there is definitely a better way of doing this! -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 angle: " + c.rx + "raw y angle: " + c.ry + "raw z angle: " + c.rz); -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, cubecenter.y, cos(c.rz)*CW/2 + sin(c.rz)*CW/2); - // nCos*(y-o.y) - nSin*(z-o.z) + o.y -cubecenter = PVector.add(new PVector(c.x, c.y, c.z), centerrot); -println( " cubecenter.x " + cubecenter.x + " cubecenter.y " + cubecenter.y + " cubecenter.z " + cubecenter.z + " "); - - -return cubecenter; -} - - -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 (LXPoint 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 (LXPoint 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 (LXPoint 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", .5); - BasicParameter SatT = new BasicParameter("Sat", .5); - BasicParameter BriT = new BasicParameter("Bright", .5); - -HueTestHSB(GLucose glucose) { - super(glucose); - addParameter(HueT); - addParameter(SatT); - addParameter(BriT); -} - void run(double deltaMs){ - - for (LXPoint p : model.points) { - color 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()); - } - } - - } diff --git a/AntonK.pde b/AntonK.pde index 33f4f5d..5b286f1 100644 --- a/AntonK.pde +++ b/AntonK.pde @@ -122,9 +122,9 @@ class AKPong extends SCPattern return true; } - public AKPong(GLucose glucose) + public AKPong(LX lx) { - super(glucose); + super(lx); addParameter(speed); addParameter(leftKnob); addParameter(rightKnob); @@ -171,9 +171,9 @@ class AKPong extends SCPattern class AKInvader extends SCPattern { private final SawLFO h = new SawLFO(0, 1, 5000); - public AKInvader(GLucose glucose) + public AKInvader(LX lx) { - super(glucose); + super(lx); addModulator(h).trigger(); } @@ -320,9 +320,9 @@ class AKTetris extends SCPattern } } - public AKTetris(GLucose glucose) + public AKTetris(LX lx) { - super(glucose); + super(lx); } public boolean noteOn(Note note) @@ -373,9 +373,9 @@ class AKMatrix extends SCPattern } } - public AKMatrix(GLucose glucose) + public AKMatrix(LX lx) { - super(glucose); + super(lx); // for (Tower t : model.towers) { Tower t = model.towers.get(0); @@ -416,9 +416,9 @@ class AKEgg extends SCPattern private final float Y = model.yMax / 2; private final float Z = model.zMax / 2; - public AKEgg(GLucose glucose) + public AKEgg(LX lx) { - super(glucose); + super(lx); addModulator(xRadius).trigger(); addModulator(yRadius).trigger(); addModulator(zRadius).trigger(); @@ -447,9 +447,9 @@ class AKCubes extends SCPattern private Cube cube; private int sec; - public AKCubes(GLucose glucose) + public AKCubes(LX lx) { - super(glucose); + super(lx); cube = model.cubes.get((int) random(model.cubes.size())); sec = 0; } @@ -474,9 +474,9 @@ class AKCubes extends SCPattern class AKSpiral extends SCPattern { private int ms; - public AKSpiral(GLucose glucose) + public AKSpiral(LX lx) { - super(glucose); + super(lx); ms = 0; } @@ -538,9 +538,9 @@ class AKSpace extends SCPattern } } - public AKSpace(GLucose glucose) + public AKSpace(LX lx) { - super(glucose); + super(lx); stars = new LinkedList(); for (int i = 0; i < 50; ++i) stars.add(new Star()); diff --git a/ArjunBanker.pde b/ArjunBanker.pde index 4709bdc..e4f1ec9 100644 --- a/ArjunBanker.pde +++ b/ArjunBanker.pde @@ -5,8 +5,8 @@ class TelevisionStatic extends SCPattern { BasicParameter hueParameter = new BasicParameter("HUE", 1.0); SinLFO direction = new SinLFO(0, 10, 3000); - public TelevisionStatic(GLucose glucose) { - super(glucose); + public TelevisionStatic(LX lx) { + super(lx); addModulator(direction).trigger(); addParameter(brightParameter); addParameter(saturationParameter); @@ -28,8 +28,8 @@ class AbstractPainting extends SCPattern { SinLFO colorMod = new SinLFO(0, 360, 5000); SinLFO brightMod = new SinLFO(0, model.zMax, 2000); - public AbstractPainting(GLucose glucose) { - super(glucose); + public AbstractPainting(LX lx) { + super(lx); addModulator(colorMod).trigger(); addModulator(brightMod).trigger(); @@ -52,8 +52,8 @@ class Spirality extends SCPattern { float rad = 0; int direction = 1; - Spirality(GLucose glucose) { - super(glucose); + Spirality(LX lx) { + super(lx); addParameter(r); for (LXPoint p : model.points) { colors[p.index] = lx.hsb(0, 0, 0); diff --git a/BenMorrow.pde b/BenMorrow.pde index f88e208..081da53 100644 --- a/BenMorrow.pde +++ b/BenMorrow.pde @@ -9,8 +9,8 @@ class XYZPixel extends SCPattern float ym2 = model.yMin+cubeWidth; float zm2 = model.zMin+cubeWidth; - XYZPixel(GLucose glucose) { - super(glucose); + XYZPixel(LX lx) { + super(lx); //myP = new LXPoint(20,20,20); } @@ -50,8 +50,8 @@ class MultipleCubes extends SCPattern float minIS; - MultipleCubes(GLucose glucose) { - super(glucose); + MultipleCubes(LX lx) { + super(lx); minIS = 200; } @@ -130,8 +130,8 @@ class TowerParams extends SCPattern ArrayList towerParams; int towerSize; int colorSpan; - TowerParams(GLucose glucose) { - super(glucose); + TowerParams(LX lx) { + super(lx); towerParams = new ArrayList(); addParameter(hueoff); @@ -199,8 +199,8 @@ class Sandbox extends SCPattern int towerrange = model.towers.size(); int counter=0; - Sandbox(GLucose glucose) { - super(glucose); + Sandbox(LX lx) { + super(lx); println("points "+pointrange); println("strips "+striprange); println("faces "+facerange); @@ -234,9 +234,9 @@ class Sandbox extends SCPattern class GranimTestPattern extends GranimPattern { - GranimTestPattern(GLucose glucose) + GranimTestPattern(LX lx) { - super(glucose); + super(lx); addGraphic("myReds",new RedsGraphic(100)); int[] dots = {0,128,0,128,0,128,0,128,0,128,0,128}; addGraphic("myOtherColors",new ColorDotsGraphic(dots)); @@ -270,9 +270,9 @@ class GranimTestPattern extends GranimPattern class GranimTestPattern2 extends GranimPattern { - GranimTestPattern2(GLucose glucose) + GranimTestPattern2(LX lx) { - super(glucose); + super(lx); /*for(int i = 0;i < 100; i++) { Graphic g = addGraphic("myReds_"+i,new RedsGraphic(Math.round(Math.random() * 100))); @@ -310,8 +310,8 @@ class DriveableCrossSections extends CrossSections BasicParameter zd; BasicParameter mode; - DriveableCrossSections(GLucose glucose) { - super(glucose); + DriveableCrossSections(LX lx) { + super(lx); } public void addParams() diff --git a/DanHorwitz.pde b/DanHorwitz.pde index ab23fa5..cdec36b 100644 --- a/DanHorwitz.pde +++ b/DanHorwitz.pde @@ -5,8 +5,8 @@ public class Pong extends DPat { Pick pChoose; PVector v = new PVector(), vMir = new PVector(); - Pong(GLucose glucose) { - super(glucose); + Pong(LX lx) { + super(lx); cRad = mMax.x/10; addModulator(dx = new SinLFO(6000, 500, 30000 )).trigger(); addModulator(dy = new SinLFO(3000, 500, 22472 )).trigger(); @@ -57,8 +57,8 @@ public class Noise extends DPat int _ND = 4; NDat N[] = new NDat[_ND]; - Noise(GLucose glucose) { - super(glucose); + Noise(LX lx) { + super(lx); pSpeed = addParam("Fast" , .55); pDensity = addParam("Dens" , .5); pSharp = addParam("Shrp" , 0); @@ -175,8 +175,8 @@ public class Play extends DPat float LastBeat=3, LastMeasure=3; int curRandTempo = 1, curRandTPat = 1; - Play(GLucose glucose) { - super(glucose); + Play(LX lx) { + super(lx); pRadius = addParam("Rad" , .1 ); pBounce = addParam("Bnc" , .2 ); pAmp = addParam("Amp" , .2 ); @@ -452,8 +452,8 @@ class Worms extends SCPattern { new PVector(randX(), random(2)<1 ? model.yMin:model.yMax, zMidLat) ; } - Worms(GLucose glucose) { - super(glucose); + Worms(LX lx) { + super(lx); addModulator(moveChase).start(); addParameter(pBeat); addParameter(pSpeed); addParameter(pBlur); addParameter(pWorms); diff --git a/DanKaminsky.pde b/DanKaminsky.pde index 8e236a2..cf77504 100644 --- a/DanKaminsky.pde +++ b/DanKaminsky.pde @@ -1,215 +1,211 @@ -class GenericController { - GenericController(){} - public void RotateKnob(int type, int num, float val){ - LXParameter p = null; - if(type==0) { - p = glucose.getPattern().getParameters().get(num); - if(p!=null) { p.setValue(val); } - } - if(type==1) { - p = glucose.getSelectedTransition().getParameters().get(num); - if(p!=null) { p.setValue(val); } - } - if(type==2) { - p = glucose.getSelectedEffect().getParameters().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.getPattern().getParameters().get(i); p.setValue(cc.getValue()/127.0); } -// else if(noteState[i] && i<12) { LXParameter p = glucose.getSelectedTransition().getParameters().get(i-8); p.setValue(cc.getValue()/127.0); } -// else if(noteState[i] && i<16) { LXParameter p = glucose.getSelectedEffect().getParameters().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; i0; i--){ - frames[i] = frames[i-1]; - } - frames[0] = new int[model.points.size()]; +// class GenericController { +// GenericController(){} +// public void RotateKnob(int type, int num, float val){ +// LXParameter p = null; +// if(type==0) { +// p = getPattern().getParameters().get(num); +// if(p!=null) { p.setValue(val); } +// } +// if(type==1) { +// p = lx.engine.getDeck(RIGHT_DECK).getFaderTransition().getParameters().get(num); +// if(p!=null) { p.setValue(val); } +// } +// if(type==2) { +// p = getSelectedEffect().getParameters().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.getPattern().getParameters().get(i); p.setValue(cc.getValue()/127.0); } +// // else if(noteState[i] && i<12) { LXParameter p = glucose.getSelectedTransition().getParameters().get(i-8); p.setValue(cc.getValue()/127.0); } +// // else if(noteState[i] && i<16) { LXParameter p = glucose.getSelectedEffect().getParameters().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 LXEffect { +// ObjectMuckerEffect(LX lx) { +// super(lx); +// } +// public void apply(int[] colors){ +// /*for(Strip s: model.strips){ +// for(int i=0; i0; i--){ +// frames[i] = frames[i-1]; +// } +// frames[0] = new int[model.points.size()]; - for(int i=0; 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); - } +// for(int i=0; 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); +// } - } - } -} - - -import netP5.*; -import oscP5.*; - - - -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 x-4 && p.y < y+4 && p.y > y-4) { colors[p.index] = #FF0000; } - } - } - } - } -} - -import processing.serial.*; - - -/*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 x-4 && p.y < y+4 && p.y > y-4) { colors[p.index] = #FF0000; } +// } +// } +// } +// } +// } + +// import processing.serial.*; + + +// /*class ScreenScrape extends SCPattern { +// PImage pret; +// ScreenShot ss; +// public ScreenScrape(LX lx) { +// super(lx); +// 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 30) continue; for (int k=0; k<=15; k++) { @@ -300,13 +300,13 @@ class dLattice { dLattice() { lattice=this; - for (Strip s : glucose.model.strips) { + for (Strip s : 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) { + for (Strip s1 : model.strips) { for (Strip s2 : 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); diff --git a/DebugUI.pde b/DebugUI.pde deleted file mode 100644 index a36f688..0000000 --- a/DebugUI.pde +++ /dev/null @@ -1,283 +0,0 @@ -/** - * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND - * - * //\\ //\\ //\\ //\\ - * ///\\\ ///\\\ ///\\\ ///\\\ - * \\\/// \\\/// \\\/// \\\/// - * \\// \\// \\// \\// - * - * EXPERTS ONLY!! EXPERTS ONLY!! - * - * Overlay UI that indicates pattern control, etc. This will be moved - * into the Processing library once it is stabilized and need not be - * regularly modified. - */ - -class DebugUI { - - final ChannelMapping[] channelList; - final int debugX = 5; - final int debugY = 5; - final int debugXSpacing = 28; - final int debugYSpacing = 21; - final int[][] debugState; - final int[] indexState; - - final int CUBE_STATE_UNUSED = 0; - final int CUBE_STATE_USED = 1; - final int CUBE_STATE_DUPLICATED = 2; - - final int DEBUG_STATE_ANIM = 0; - final int DEBUG_STATE_WHITE = 1; - final int DEBUG_STATE_OFF = 2; - final int DEBUG_STATE_UNUSED = 3; - - DebugUI(PandaMapping[] pandaMappings) { - int totalChannels = pandaMappings.length * PandaMapping.CHANNELS_PER_BOARD; - debugState = new int[totalChannels+1][ChannelMapping.CUBES_PER_CHANNEL+1]; - indexState = new int[glucose.model.cubes.size()+1]; - - channelList = new ChannelMapping[totalChannels]; - int channelIndex = 0; - for (PandaMapping pm : pandaMappings) { - for (ChannelMapping channel : pm.channelList) { - channelList[channelIndex++] = channel; - } - } - for (int i = 0; i < debugState.length; ++i) { - for (int j = 0; j < debugState[i].length; ++j) { - debugState[i][j] = DEBUG_STATE_ANIM; - } - } - - for (int rawIndex = 0; rawIndex < glucose.model.cubes.size()+1; ++rawIndex) { - indexState[rawIndex] = CUBE_STATE_UNUSED; - } - for (ChannelMapping channel : channelList) { - for (int rawCubeIndex : channel.objectIndices) { - if (rawCubeIndex > 0) - ++indexState[rawCubeIndex]; - } - } - } - - void draw() { - noStroke(); - int xBase = debugX; - int yPos = debugY; - - textSize(10); - - fill(#000000); - rect(0, 0, debugX + 5*debugXSpacing, height); - - int channelNum = 0; - for (ChannelMapping channel : channelList) { - int xPos = xBase; - drawNumBox(xPos, yPos, channelNum+1, debugState[channelNum][0]); - xPos += debugXSpacing; - - switch (channel.mode) { - case ChannelMapping.MODE_CUBES: - int stateIndex = 0; - boolean first = true; - for (int rawCubeIndex : channel.objectIndices) { - if (rawCubeIndex < 0) { - break; - } - if (first) { - first = false; - } else { - stroke(#999999); - line(xPos - 12, yPos + 8, xPos, yPos + 8); - } - drawNumBox(xPos, yPos, rawCubeIndex, debugState[channelNum][stateIndex+1], indexState[rawCubeIndex]); - ++stateIndex; - xPos += debugXSpacing; - } - break; - case ChannelMapping.MODE_BASS: - drawNumBox(xPos, yPos, "B", debugState[channelNum][1]); - break; - case ChannelMapping.MODE_SPEAKER: - drawNumBox(xPos, yPos, "S" + channel.objectIndices[0], debugState[channelNum][1]); - break; - case ChannelMapping.MODE_STRUTS_AND_FLOOR: - drawNumBox(xPos, yPos, "F", debugState[channelNum][1]); - break; - case ChannelMapping.MODE_NULL: - break; - default: - throw new RuntimeException("Unhandled channel mapping mode: " + channel.mode); - } - - yPos += debugYSpacing; - ++channelNum; - } - drawNumBox(xBase, yPos, "A", debugState[channelNum][0]); - yPos += debugYSpacing * 2; - - noFill(); - fill(#CCCCCC); - text("Unused Cubes", xBase, yPos + 12); - yPos += debugYSpacing; - - int xIndex = 0; - for (int rawIndex = 1; rawIndex <= glucose.model.cubes.size(); ++rawIndex) { - if (indexState[rawIndex] == CUBE_STATE_UNUSED) { - drawNumBox(xBase + (xIndex * debugXSpacing), yPos, rawIndex, DEBUG_STATE_UNUSED); - ++xIndex; - if (xIndex > 4) { - xIndex = 0; - yPos += debugYSpacing + 2; - } - } - } - } - - - void drawNumBox(int xPos, int yPos, int label, int state) { - drawNumBox(xPos, yPos, "" + label, state); - } - - void drawNumBox(int xPos, int yPos, String label, int state) { - drawNumBox(xPos, yPos, "" + label, state, CUBE_STATE_USED); - } - - void drawNumBox(int xPos, int yPos, int label, int state, int cubeState) { - drawNumBox(xPos, yPos, "" + label, state, cubeState); - } - - void drawNumBox(int xPos, int yPos, String label, int state, int cubeState) { - noFill(); - color textColor = #cccccc; - switch (state) { - case DEBUG_STATE_ANIM: - noStroke(); - fill(#880000); - rect(xPos, yPos, 16, 8); - fill(#000088); - rect(xPos, yPos+8, 16, 8); - noFill(); - stroke(textColor); - break; - case DEBUG_STATE_WHITE: - stroke(textColor); - fill(#e9e9e9); - textColor = #333333; - break; - case DEBUG_STATE_OFF: - stroke(textColor); - break; - case DEBUG_STATE_UNUSED: - stroke(textColor); - fill(#880000); - break; - } - - if (cubeState >= CUBE_STATE_DUPLICATED) { - stroke(textColor = #FF0000); - } - - rect(xPos, yPos, 16, 16); - noStroke(); - fill(textColor); - text(label, xPos + 2, yPos + 12); - } - - void maskColors(color[] colors) { - color white = #FFFFFF; - color off = #000000; - int channelIndex = 0; - int state; - for (ChannelMapping channel : channelList) { - switch (channel.mode) { - case ChannelMapping.MODE_CUBES: - int cubeIndex = 1; - for (int rawCubeIndex : channel.objectIndices) { - if (rawCubeIndex >= 0) { - state = debugState[channelIndex][cubeIndex]; - if (state != DEBUG_STATE_ANIM) { - color debugColor = (state == DEBUG_STATE_WHITE) ? white : off; - Cube cube = glucose.model.getCubeByRawIndex(rawCubeIndex); - for (LXPoint p : cube.points) { - colors[p.index] = debugColor; - } - } - } - ++cubeIndex; - } - break; - - case ChannelMapping.MODE_BASS: - state = debugState[channelIndex][1]; - if (state != DEBUG_STATE_ANIM) { - color debugColor = (state == DEBUG_STATE_WHITE) ? white : off; - for (Strip s : glucose.model.bassBox.boxStrips) { - for (LXPoint p : s.points) { - colors[p.index] = debugColor; - } - } - } - break; - - case ChannelMapping.MODE_STRUTS_AND_FLOOR: - state = debugState[channelIndex][1]; - if (state != DEBUG_STATE_ANIM) { - color debugColor = (state == DEBUG_STATE_WHITE) ? white : off; - for (LXPoint p : glucose.model.boothFloor.points) { - colors[p.index] = debugColor; - } - for (Strip s : glucose.model.bassBox.struts) { - for (LXPoint p : s.points) { - colors[p.index] = debugColor; - } - } - } - break; - - case ChannelMapping.MODE_SPEAKER: - state = debugState[channelIndex][1]; - if (state != DEBUG_STATE_ANIM) { - color debugColor = (state == DEBUG_STATE_WHITE) ? white : off; - for (LXPoint p : glucose.model.speakers.get(channel.objectIndices[0]).points) { - colors[p.index] = debugColor; - } - } - break; - - case ChannelMapping.MODE_NULL: - break; - - default: - throw new RuntimeException("Unhandled channel mapping mode: " + channel.mode); - } - ++channelIndex; - } - } - - boolean mousePressed() { - int dx = (mouseX - debugX) / debugXSpacing; - int dy = (mouseY - debugY) / debugYSpacing; - if ((dy < 0) || (dy >= debugState.length)) { - return false; - } - if ((dx < 0) || (dx >= debugState[dy].length)) { - return false; - } - int newState = debugState[dy][dx] = (debugState[dy][dx] + 1) % 3; - if (dy == debugState.length-1) { - for (int[] states : debugState) { - for (int i = 0; i < states.length; ++i) { - states[i] = newState; - } - } - } else if (dx == 0) { - for (int i = 0; i < debugState[dy].length; ++i) { - debugState[dy][i] = newState; - } - } - return true; - } -} - diff --git a/GranimPattern.pde b/GranimPattern.pde index da4c78f..83a70be 100644 --- a/GranimPattern.pde +++ b/GranimPattern.pde @@ -79,9 +79,9 @@ class GranimPattern extends SCPattern { HashMap displayList; - GranimPattern(GLucose glucose) + GranimPattern(LX lx) { - super(glucose); + super(lx); displayList = new HashMap(); } diff --git a/Grizzly.pde b/Grizzly.pde new file mode 100644 index 0000000..5f46b96 --- /dev/null +++ b/Grizzly.pde @@ -0,0 +1,158 @@ +/** + * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND + * + * //\\ //\\ //\\ //\\ + * ///\\\ ///\\\ ///\\\ ///\\\ + * \\\/// \\\/// \\\/// \\\/// + * \\// \\// \\// \\//H + * + * EXPERTS ONLY!! EXPERTS ONLY!! + * + * If you are an artist, you may ignore this file! It contains + * the code to drive grizzly board outputs. + */ +import java.net.*; +GrizzlyOutput[] buildGrizzlies() throws SocketException, UnknownHostException { + return new GrizzlyOutput[] { + new GrizzlyOutput(lx, "192.168.88.100", 6, 5, 6, 7, 7, 8, 1, 2, 4, 3, 11, 10, 9, 9, 12, 13), + new GrizzlyOutput(lx, "192.168.88.101", 25, 23, 24, 43, 45, 44, 1, 1, 1, 1, 1, 41, 42, 21, 20, 22), + new GrizzlyOutput(lx, "192.168.88.104", 26, 28, 27, 19, 18, 17, 1, 1, 18, 19, 15, 16, 14, 29, 30, 31), + new GrizzlyOutput(lx, "192.168.88.105", 1, 1, 1, 39, 38, 40, 34, 35, 33, 32, 37, 37, 1, 1, 1, 1), + }; +} + +/** + * Grizzly Output, sends packets to one grizzly board with a fixed IP and a number + * of channels. + */ +class GrizzlyOutput extends LXDatagramOutput { + + public final String ipAddress; + + private int frameNumber = 0; + + public GrizzlyOutput(LX lx, String ipAddress, int ... cubeIndices) throws UnknownHostException, SocketException { + super(lx); + this.ipAddress = ipAddress; + int channelNum = 0; + for (int rawCubeIndex : cubeIndices) { + if (rawCubeIndex > 0) { + Cube cube = model.getCubeByRawIndex(rawCubeIndex); + addDatagram(new GrizzlyDatagram(this, channelNum, cube).setAddress(ipAddress)); + } + ++channelNum; + } + this.enabled.setValue(false); + } + + protected void beforeSend(int[] colors) { + ++frameNumber; + } + + public int getFrameNumber() { + return this.frameNumber; + } +} + +/** + * Datagram to a Grizzlyboard. A simple fixed OSC packet. + */ +static class GrizzlyDatagram extends LXDatagram { + + private static byte[] oscString(String s) { + int len = s.length(); + int padding = (4 - ((len + 1) % 4)) % 4; + byte[] bytes = new byte[len + 1 + padding]; + System.arraycopy(s.getBytes(), 0, bytes, 0, len); + for (int i = len; i < bytes.length; ++i) { + bytes[i] = 0; + } + return bytes; + } + + private static int oscIntCopy(int i, byte[] buffer, int pos) { + buffer[pos] = (byte) ((i >> 24) & 0xff); + buffer[pos + 1] = (byte) ((i >> 16) & 0xff); + buffer[pos + 2] = (byte) ((i >> 8) & 0xff); + buffer[pos + 3] = (byte) (i & 0xff); + return 4; + } + + private final static int[] STRIP_ORDERING = new int[] { 9, 8, 11, 5, 4, 7, 6, 10, 14, 2, 1, 0, 3, 13, 12, 15 }; + + private static int[] cubePointIndices(Cube cube) { + int[] pointIndices = new int[Cube.POINTS_PER_CUBE - 2]; + int pi = 0; + for (int stripIndex : STRIP_ORDERING) { + Strip strip = cube.strips.get(stripIndex); + int stripLen = ((stripIndex == 9) || (stripIndex == 15)) ? 15 : 16; + for (int i = stripLen-1; i >= 0; --i) { + pointIndices[pi++] = strip.points.get(i).index; + } + } + return pointIndices; + } + + private final static byte[] OSC_ADDRESS = oscString("/shady/pointbuffer"); + private final static byte[] OSC_TYPETAG = oscString(",iiiiibi"); + + private final static int HEADER_LENGTH = OSC_ADDRESS.length + OSC_TYPETAG.length + 24; + private final static int FOOTER_LENGTH = 4; + + private final static int OSC_PORT = 779; + + private GrizzlyOutput output; + + private int[] pointIndices; + + private final int frameNumberPos; + + private final int dataPos; + + public GrizzlyDatagram(GrizzlyOutput output, int channelNum, Cube cube) { + this(output, channelNum, cubePointIndices(cube)); + } + + public GrizzlyDatagram(GrizzlyOutput output, int channelNum, int[] pointIndices) { + super(HEADER_LENGTH + 4*pointIndices.length + FOOTER_LENGTH); + setPort(OSC_PORT); + + this.output = output; + this.pointIndices = pointIndices; + int dataLength = 4*pointIndices.length; + + int pos = 0; + + // OSC address + System.arraycopy(OSC_ADDRESS, 0, this.buffer, pos, OSC_ADDRESS.length); + pos += OSC_ADDRESS.length; + + // OSC typetag + System.arraycopy(OSC_TYPETAG, 0, this.buffer, pos, OSC_TYPETAG.length); + pos += OSC_TYPETAG.length; + this.frameNumberPos = pos; + pos += oscIntCopy(0, this.buffer, pos); // placeholder for frame number + pos += oscIntCopy(0xDEADBEEF, this.buffer, pos); + pos += oscIntCopy(channelNum, this.buffer, pos); + pos += oscIntCopy(0xFEEDBEEF, this.buffer, pos); + pos += oscIntCopy(dataLength, this.buffer, pos); + pos += oscIntCopy(dataLength, this.buffer, pos); + this.dataPos = pos; + + // end header + oscIntCopy(0xBEFFFFEB, this.buffer, this.buffer.length - 4); + } + + void onSend(int[] colors) { + oscIntCopy(this.output.getFrameNumber(), this.buffer, frameNumberPos); + int dataIndex = this.dataPos; + for (int index : this.pointIndices) { + color c = (index >= 0) ? colors[index] : 0; + this.buffer[dataIndex] = (byte) 0; // unused, alpha + this.buffer[dataIndex + 1] = (byte) ((c >> 16) & 0xff); // r + this.buffer[dataIndex + 2] = (byte) ((c >> 8) & 0xff); // g + this.buffer[dataIndex + 3] = (byte) (c & 0xff); // b + dataIndex += 4; + } + } +} diff --git a/Internals.pde b/Internals.pde index a1b8baf..b593f3e 100644 --- a/Internals.pde +++ b/Internals.pde @@ -13,48 +13,56 @@ * for general animation work. */ -import glucose.*; -import glucose.model.*; import heronarts.lx.*; import heronarts.lx.effect.*; +import heronarts.lx.model.*; import heronarts.lx.modulator.*; import heronarts.lx.parameter.*; import heronarts.lx.pattern.*; import heronarts.lx.transform.*; import heronarts.lx.transition.*; +import heronarts.lx.ui.*; +import heronarts.lx.ui.component.*; +import heronarts.lx.ui.control.*; import ddf.minim.*; import ddf.minim.analysis.*; import processing.opengl.*; import rwmidi.*; import java.lang.reflect.*; -import javax.media.opengl.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; -final int VIEWPORT_WIDTH = 900; -final int VIEWPORT_HEIGHT = 700; +static final int VIEWPORT_WIDTH = 900; +static final int VIEWPORT_HEIGHT = 700; + +static final int LEFT_DECK = 0; +static final int RIGHT_DECK = 1; // The trailer is measured from the outside of the black metal (but not including the higher welded part on the front) -final float TRAILER_WIDTH = 240; -final float TRAILER_DEPTH = 97; -final float TRAILER_HEIGHT = 33; +static final float TRAILER_WIDTH = 192; +static final float TRAILER_DEPTH = 192; +static final float TRAILER_HEIGHT = 33; int targetFramerate = 60; int startMillis, lastMillis; // Core engine variables -GLucose glucose; LX lx; +Model model; LXPattern[] patterns; +LXTransition[] transitions; Effects effects; +LXEffect[] effectsArr; +DiscreteParameter selectedEffect; MappingTool mappingTool; -PandaDriver[] pandaBoards; +GrizzlyOutput[] grizzlies; PresetManager presetManager; MidiEngine midiEngine; // Display configuration mode boolean mappingMode = false; boolean debugMode = false; -DebugUI debugUI; -boolean uiOn = true; boolean simulationOn = true; boolean diagnosticsOn = false; LXPattern restoreToPattern = null; @@ -62,7 +70,6 @@ PImage logo; float[] hsb = new float[3]; // Handles to UI objects -UIContext[] overlays; UIPatternDeck uiPatternA; UICrossfader uiCrossfader; UIMidi uiMidi; @@ -70,30 +77,27 @@ UIMapping uiMapping; UIDebugText uiDebugText; UISpeed uiSpeed; -// Camera variables -float eyeR, eyeA, eyeX, eyeY, eyeZ, midX, midY, midZ; - /** * Engine construction and initialization. */ -LXTransition _transition(GLucose glucose) { - return new DissolveTransition(glucose.lx).setDuration(1000); +LXTransition _transition(LX lx) { + return new DissolveTransition(lx).setDuration(1000); } -LXPattern[] _leftPatterns(GLucose glucose) { - LXPattern[] patterns = patterns(glucose); +LXPattern[] _leftPatterns(LX lx) { + LXPattern[] patterns = patterns(lx); for (LXPattern p : patterns) { - p.setTransition(_transition(glucose)); + p.setTransition(_transition(lx)); } return patterns; } -LXPattern[] _rightPatterns(GLucose glucose) { - LXPattern[] patterns = _leftPatterns(glucose); +LXPattern[] _rightPatterns(LX lx) { + LXPattern[] patterns = _leftPatterns(lx); LXPattern[] rightPatterns = new LXPattern[patterns.length+1]; int i = 0; - rightPatterns[i++] = new BlankPattern(glucose).setTransition(_transition(glucose)); + rightPatterns[i++] = new BlankPattern(lx).setTransition(_transition(lx)); for (LXPattern p : patterns) { rightPatterns[i++] = p; } @@ -111,7 +115,11 @@ LXEffect[] _effectsArray(Effects effects) { } catch (IllegalAccessException iax) {} } return effectList.toArray(new LXEffect[]{}); -} +} + +LXEffect getSelectedEffect() { + return effectsArr[selectedEffect.getValuei()]; +} void logTime(String evt) { int now = millis(); @@ -129,20 +137,29 @@ void setup() { // hint(ENABLE_OPENGL_4X_SMOOTH); // no discernable improvement? logTime("Created viewport"); - // Create the GLucose engine to run the cubes - glucose = new GLucose(this, buildModel()); - lx = glucose.lx; + // Create the model + model = buildModel(); + logTime("Built Model"); + + // LX engine + lx = new LX(this, model); lx.enableKeyboardTempo(); - logTime("Built GLucose engine"); + logTime("Built LX engine"); // Set the patterns LXEngine engine = lx.engine; - engine.setPatterns(patterns = _leftPatterns(glucose)); - engine.addDeck(_rightPatterns(glucose)); + engine.setPatterns(patterns = _leftPatterns(lx)); + engine.addDeck(_rightPatterns(lx)); logTime("Built patterns"); - glucose.setTransitions(transitions(glucose)); + + // Transitions + transitions = transitions(lx); + lx.engine.getDeck(RIGHT_DECK).setFaderTransition(transitions[0]); logTime("Built transitions"); - glucose.lx.addEffects(_effectsArray(effects = new Effects())); + + // Effects + lx.addEffects(effectsArr = _effectsArray(effects = new Effects())); + selectedEffect = new DiscreteParameter("EFFECT", effectsArr.length); logTime("Built effects"); // Preset manager @@ -154,93 +171,160 @@ void setup() { logTime("Setup MIDI devices"); // Build output driver - PandaMapping[] pandaMappings = buildPandaList(); - pandaBoards = new PandaDriver[pandaMappings.length]; - int pbi = 0; - for (PandaMapping pm : pandaMappings) { - pandaBoards[pbi++] = new PandaDriver(pm.ip, glucose.model, pm); + grizzlies = new GrizzlyOutput[]{}; + try { + grizzlies = buildGrizzlies(); + for (LXOutput output : grizzlies) { + lx.addOutput(output); + } + } catch (Exception x) { + x.printStackTrace(); } - mappingTool = new MappingTool(glucose, pandaMappings); - logTime("Built PandaDriver"); + logTime("Built Grizzly Outputs"); + // Mapping tool + mappingTool = new MappingTool(lx); + logTime("Built Mapping Tool"); + // Build overlay UI - debugUI = new DebugUI(pandaMappings); - overlays = new UIContext[] { - uiPatternA = new UIPatternDeck(lx.engine.getDeck(GLucose.LEFT_DECK), "PATTERN A", 4, 4, 140, 324), + UILayer[] layers = new UILayer[] { + // Camera layer + new UICameraLayer(lx.ui) + .setCenter(model.cx, model.cy, model.cz) + .setRadius(290).addComponent(new UICubesLayer()), + + // Left controls + uiPatternA = new UIPatternDeck(lx.ui, lx.engine.getDeck(LEFT_DECK), "PATTERN A", 4, 4, 140, 324), new UIBlendMode(4, 332, 140, 86), new UIEffects(4, 422, 140, 144), new UITempo(4, 570, 140, 50), uiSpeed = new UISpeed(4, 624, 140, 50), - new UIPatternDeck(lx.engine.getDeck(GLucose.RIGHT_DECK), "PATTERN B", width-144, 4, 140, 324), + // Right controls + new UIPatternDeck(lx.ui, lx.engine.getDeck(RIGHT_DECK), "PATTERN B", width-144, 4, 140, 324), uiMidi = new UIMidi(midiEngine, width-144, 332, 140, 158), - new UIOutput(width-144, 494, 140, 106), + new UIOutput(grizzlies, width-144, 494, 140, 106), + // Crossfader uiCrossfader = new UICrossfader(width/2-90, height-90, 180, 86), + // Overlays uiDebugText = new UIDebugText(148, height-138, width-304, 44), - uiMapping = new UIMapping(mappingTool, 4, 4, 140, 324), + uiMapping = new UIMapping(mappingTool, 4, 4, 140, 324) }; - uiMapping.setVisible(false); - logTime("Built overlay UI"); + uiMapping.setVisible(false); + for (UILayer layer : layers) { + lx.ui.addLayer(layer); + } + logTime("Built UI"); // Load logo image logo = loadImage("data/logo.png"); - - // Setup camera - midX = TRAILER_WIDTH/2.; - midY = glucose.model.yMax/2; - midZ = TRAILER_DEPTH/2.; - eyeR = -290; - eyeA = .15; - eyeY = midY + 70; - eyeX = midX + eyeR*sin(eyeA); - eyeZ = midZ + eyeR*cos(eyeA); - - // Add mouse scrolling event support - addMouseWheelListener(new java.awt.event.MouseWheelListener() { - public void mouseWheelMoved(java.awt.event.MouseWheelEvent mwe) { - mouseWheel(mwe.getWheelRotation()); - }}); - + logTime("Loaded logo image"); + println("Total setup: " + (millis() - startMillis) + "ms"); - println("Hit the 'p' key to toggle Panda Board output"); + println("Hit the 'o' key to toggle live output"); } +public SCPattern getPattern() { + return (SCPattern) lx.getPattern(); +} + +/** + * Subclass of LXPattern specific to sugar cubes. These patterns + * get access to the state and geometry, and have some + * little helpers for interacting with the model. + */ +public static abstract class SCPattern extends LXPattern { + + protected SCPattern(LX lx) { + super(lx); + } + + /** + * Reset this pattern to its default state. + */ + public final void reset() { + for (LXParameter parameter : getParameters()) { + parameter.reset(); + } + onReset(); + } + + /** + * Subclasses may override to add additional reset functionality. + */ + protected /*abstract*/ void onReset() {} + + /** + * Invoked by the engine when a grid controller button press occurs + * + * @param row Row index on the gird + * @param col Column index on the grid + * @return True if the event was consumed, false otherwise + */ + public boolean gridPressed(int row, int col) { + return false; + } + + /** + * Invoked by the engine when a grid controller button release occurs + * + * @param row Row index on the gird + * @param col Column index on the grid + * @return True if the event was consumed, false otherwise + */ + public boolean gridReleased(int row, int col) { + return false; + } + + /** + * Invoked by engine when this pattern is focused an a midi note is received. + * + * @param note + * @return True if the pattern has consumed this note, false if the top-level + * may handle it + */ + public boolean noteOn(rwmidi.Note note) { + return false; + } + + /** + * Invoked by engine when this pattern is focused an a midi note off is received. + * + * @param note + * @return True if the pattern has consumed this note, false if the top-level + * may handle it + */ + public boolean noteOff(rwmidi.Note note) { + return false; + } + + /** + * Invoked by engine when this pattern is focused an a controller is received + * + * @param note + * @return True if the pattern has consumed this controller, false if the top-level + * may handle it + */ + public boolean controllerChange(rwmidi.Controller controller) { + return false; + } +} + +long simulationNanos = 0; + /** * Core render loop and drawing functionality. */ void draw() { long drawStart = System.nanoTime(); - // Draws the simulation and the 2D UI overlay + // Set background background(40); - - color[] simulationColors; - color[] sendColors; - simulationColors = sendColors = glucose.getColors(); - String displayMode = uiCrossfader.getDisplayMode(); - if (displayMode == "A") { - simulationColors = lx.engine.getDeck(GLucose.LEFT_DECK).getColors(); - } else if (displayMode == "B") { - simulationColors = lx.engine.getDeck(GLucose.RIGHT_DECK).getColors(); - } - if (debugMode) { - debugUI.maskColors(simulationColors); - debugUI.maskColors(sendColors); - } - - long simulationStart = System.nanoTime(); - if (simulationOn) { - drawSimulation(simulationColors); - } - long simulationNanos = System.nanoTime() - simulationStart; - - // 2D Overlay UI - long uiStart = System.nanoTime(); - drawUI(); - long uiNanos = System.nanoTime() - uiStart; + // Send colors + color[] sendColors = lx.getColors(); long gammaStart = System.nanoTime(); // Gamma correction here. Apply a cubic to the brightness // for better representation of dynamic range @@ -250,21 +334,20 @@ void draw() { sendColors[i] = lx.hsb(360.*hsb[0], 100.*hsb[1], 100.*(b*b*b)); } long gammaNanos = System.nanoTime() - gammaStart; - - long sendStart = System.nanoTime(); - for (PandaDriver p : pandaBoards) { - p.send(sendColors); - } - long sendNanos = System.nanoTime() - sendStart; - + + // Always draw FPS meter + drawFPS(); + + // TODO(mcslee): fix long drawNanos = System.nanoTime() - drawStart; - + long uiNanos = 0; + if (diagnosticsOn) { - drawDiagnostics(drawNanos, simulationNanos, uiNanos, gammaNanos, sendNanos); - } + drawDiagnostics(drawNanos, simulationNanos, uiNanos, gammaNanos); + } } -void drawDiagnostics(long drawNanos, long simulationNanos, long uiNanos, long gammaNanos, long sendNanos) { +void drawDiagnostics(long drawNanos, long simulationNanos, long uiNanos, long gammaNanos) { float ws = 4 / 1000000.; int thirtyfps = 1000000000 / 30; int sixtyfps = 1000000000 / 60; @@ -277,7 +360,7 @@ void drawDiagnostics(long drawNanos, long simulationNanos, long uiNanos, long ga noStroke(); int xp = x; float hv = 0; - for (long val : new long[] {lx.timer.drawNanos, simulationNanos, uiNanos, gammaNanos, sendNanos }) { + for (long val : new long[] {lx.timer.drawNanos, simulationNanos, uiNanos, gammaNanos, lx.timer.outputNanos }) { fill(lx.hsb(hv % 360, 100, 80)); rect(xp, y, val * ws, h-1); hv += 140; @@ -321,190 +404,12 @@ void drawDiagnostics(long drawNanos, long simulationNanos, long uiNanos, long ga } } -void drawSimulation(color[] simulationColors) { - camera( - eyeX, eyeY, eyeZ, - midX, midY, midZ, - 0, -1, 0 - ); - - translate(0, 40, 0); - - noStroke(); - fill(#141414); - drawBox(0, -TRAILER_HEIGHT, 0, 0, 0, 0, TRAILER_WIDTH, TRAILER_HEIGHT, TRAILER_DEPTH, TRAILER_HEIGHT/2.); - fill(#070707); - stroke(#222222); - beginShape(); - vertex(0, 0, 0); - vertex(TRAILER_WIDTH, 0, 0); - vertex(TRAILER_WIDTH, 0, TRAILER_DEPTH); - vertex(0, 0, TRAILER_DEPTH); - endShape(); - - // Draw the logo on the front of platform - pushMatrix(); - translate(0, 0, -1); - float s = .07; - scale(s, -s, s); - image(logo, TRAILER_WIDTH/2/s-logo.width/2, TRAILER_HEIGHT/2/s-logo.height/2-2/s); - popMatrix(); - - noStroke(); - if (glucose.model.bassBox.exists) { - drawBassBox(glucose.model.bassBox, false); - } - for (Speaker speaker : glucose.model.speakers) { - drawSpeaker(speaker); - } - for (Cube c : glucose.model.cubes) { - drawCube(c); - } - - noFill(); - strokeWeight(2); - beginShape(POINTS); - for (LXPoint p : glucose.model.points) { - stroke(simulationColors[p.index]); - vertex(p.x, p.y, p.z); - } - endShape(); -} - -void drawBassBox(BassBox b, boolean hasSub) { - - float in = .15; - - if (hasSub) { - noStroke(); - fill(#191919); - pushMatrix(); - translate(b.x + BassBox.EDGE_WIDTH/2., b.y + BassBox.EDGE_HEIGHT/2, b.z + BassBox.EDGE_DEPTH/2.); - box(BassBox.EDGE_WIDTH-20*in, BassBox.EDGE_HEIGHT-20*in, BassBox.EDGE_DEPTH-20*in); - popMatrix(); - } - - noStroke(); - fill(#393939); - drawBox(b.x+in, b.y+in, b.z+in, 0, 0, 0, BassBox.EDGE_WIDTH-in*2, BassBox.EDGE_HEIGHT-in*2, BassBox.EDGE_DEPTH-in*2, Cube.CHANNEL_WIDTH-in); - - pushMatrix(); - translate(b.x+(Cube.CHANNEL_WIDTH-in)/2., b.y + BassBox.EDGE_HEIGHT-in, b.z + BassBox.EDGE_DEPTH/2.); - float lastOffset = 0; - for (float offset : BoothFloor.STRIP_OFFSETS) { - translate(offset - lastOffset, 0, 0); - box(Cube.CHANNEL_WIDTH-in, 0, BassBox.EDGE_DEPTH - 2*in); - lastOffset = offset; - } - popMatrix(); - - pushMatrix(); - translate(b.x + (Cube.CHANNEL_WIDTH-in)/2., b.y + BassBox.EDGE_HEIGHT/2., b.z + in); - for (int j = 0; j < 2; ++j) { - pushMatrix(); - for (int i = 0; i < BassBox.NUM_FRONT_STRUTS; ++i) { - translate(BassBox.FRONT_STRUT_SPACING, 0, 0); - box(Cube.CHANNEL_WIDTH-in, BassBox.EDGE_HEIGHT - in*2, 0); - } - popMatrix(); - translate(0, 0, BassBox.EDGE_DEPTH - 2*in); - } - popMatrix(); - - pushMatrix(); - translate(b.x + in, b.y + BassBox.EDGE_HEIGHT/2., b.z + BassBox.SIDE_STRUT_SPACING + (Cube.CHANNEL_WIDTH-in)/2.); - box(0, BassBox.EDGE_HEIGHT - in*2, Cube.CHANNEL_WIDTH-in); - translate(BassBox.EDGE_WIDTH-2*in, 0, 0); - box(0, BassBox.EDGE_HEIGHT - in*2, Cube.CHANNEL_WIDTH-in); - popMatrix(); - -} - -void drawCube(Cube c) { - float in = .15; - noStroke(); - fill(#393939); - drawBox(c.x+in, c.y+in, c.z+in, c.rx, c.ry, c.rz, Cube.EDGE_WIDTH-in*2, Cube.EDGE_HEIGHT-in*2, Cube.EDGE_WIDTH-in*2, Cube.CHANNEL_WIDTH-in); -} - -void drawSpeaker(Speaker s) { - float in = .15; - - noStroke(); - fill(#191919); - pushMatrix(); - translate(s.x, s.y, s.z); - rotate(s.ry / 180. * PI, 0, -1, 0); - translate(Speaker.EDGE_WIDTH/2., Speaker.EDGE_HEIGHT/2., Speaker.EDGE_DEPTH/2.); - box(Speaker.EDGE_WIDTH-20*in, Speaker.EDGE_HEIGHT-20*in, Speaker.EDGE_DEPTH-20*in); - translate(0, Speaker.EDGE_HEIGHT/2. + Speaker.EDGE_HEIGHT*.8/2, 0); - - fill(#222222); - box(Speaker.EDGE_WIDTH*.6, Speaker.EDGE_HEIGHT*.8, Speaker.EDGE_DEPTH*.75); - popMatrix(); - - noStroke(); - fill(#393939); - drawBox(s.x+in, s.y+in, s.z+in, 0, s.ry, 0, Speaker.EDGE_WIDTH-in*2, Speaker.EDGE_HEIGHT-in*2, Speaker.EDGE_DEPTH-in*2, Cube.CHANNEL_WIDTH-in); -} - -void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) { - pushMatrix(); - translate(x, y, z); - rotate(rx / 180. * PI, -1, 0, 0); - rotate(ry / 180. * PI, 0, -1, 0); - rotate(rz / 180. * PI, 0, 0, -1); - for (int i = 0; i < 4; ++i) { - float wid = (i % 2 == 0) ? xd : zd; - - beginShape(); - vertex(0, 0); - vertex(wid, 0); - vertex(wid, yd); - vertex(wid - sw, yd); - vertex(wid - sw, sw); - vertex(0, sw); - endShape(); - beginShape(); - vertex(0, sw); - vertex(0, yd); - vertex(wid - sw, yd); - vertex(wid - sw, yd - sw); - vertex(sw, yd - sw); - vertex(sw, sw); - endShape(); - - translate(wid, 0, 0); - rotate(HALF_PI, 0, -1, 0); - } - popMatrix(); -} - - - -void drawUI() { - camera(); - PGraphicsOpenGL gl = (PGraphicsOpenGL) g; - - //gl.glClear(javax.media.opengl.GL.GL_DEPTH_BUFFER_BIT); - //((PGraphicsOpenGL)g).endGL(); - strokeWeight(1); - - if (uiOn) { - for (UIContext context : overlays) { - context.draw(); - } - } - +void drawFPS() { // Always draw FPS meter fill(#555555); textSize(9); textAlign(LEFT, BASELINE); text("FPS: " + ((int) (frameRate*10)) / 10. + " / " + targetFramerate + " (-/+)", 4, height-4); - - if (debugMode) { - debugUI.draw(); - } } @@ -593,9 +498,10 @@ void keyPressed() { lx.engine.setThreaded(!lx.engine.isThreaded()); } break; + case 'o': case 'p': - for (PandaDriver p : pandaBoards) { - p.toggle(); + for (LXOutput output : grizzlies) { + output.enabled.toggle(); } break; case 'q': @@ -608,64 +514,6 @@ void keyPressed() { simulationOn = !simulationOn; } break; - case 'u': - if (!midiEngine.isQwertyEnabled()) { - uiOn = !uiOn; - } - break; - } -} - -/** - * Top-level mouse event handling - */ -int mx, my; -void mousePressed() { - boolean debugged = false; - if (debugMode) { - debugged = debugUI.mousePressed(); } - if (!debugged) { - for (UIContext context : overlays) { - context.mousePressed(mouseX, mouseY); - } - } - mx = mouseX; - my = mouseY; } -void mouseDragged() { - boolean dragged = false; - for (UIContext context : overlays) { - dragged |= context.mouseDragged(mouseX, mouseY); - } - if (!dragged) { - int dx = mouseX - mx; - int dy = mouseY - my; - mx = mouseX; - my = mouseY; - eyeA += dx*.003; - eyeX = midX + eyeR*sin(eyeA); - eyeZ = midZ + eyeR*cos(eyeA); - eyeY += dy; - } -} - -void mouseReleased() { - for (UIContext context : overlays) { - context.mouseReleased(mouseX, mouseY); - } -} - -void mouseWheel(int delta) { - boolean wheeled = false; - for (UIContext context : overlays) { - wheeled |= context.mouseWheel(mouseX, mouseY, delta); - } - - if (!wheeled) { - eyeR = constrain(eyeR - delta, -500, -80); - eyeX = midX + eyeR*sin(eyeA); - eyeZ = midZ + eyeR*cos(eyeA); - } -} diff --git a/JR.pde b/JR.pde index b1d8a43..07ddf38 100644 --- a/JR.pde +++ b/JR.pde @@ -23,8 +23,8 @@ class Gimbal extends SCPattern { private final BasicParameter bP = new BasicParameter("b", 0); private final BasicParameter gP = new BasicParameter("g", 0); - Gimbal(GLucose glucose) { - super(glucose); + Gimbal(LX lx) { + super(lx); projection = new LXProjection(model); addParameter(beatsPerRevolutionParam); addParameter(hueDeltaParam); @@ -207,8 +207,8 @@ class Zebra extends SCPattern { _P size; */ - Zebra(GLucose glucose) { - super(glucose); + Zebra(LX lx) { + super(lx); projection = new LXProjection(model); addModulator(angleM).trigger(); diff --git a/JackStahl.pde b/JackStahl.pde index 4299543..3b69815 100644 --- a/JackStahl.pde +++ b/JackStahl.pde @@ -21,8 +21,8 @@ class Swim extends SCPattern { final BasicParameter hueScale = new BasicParameter("HUE", 0.3); - public Swim(GLucose glucose) { - super(glucose); + public Swim(LX lx) { + super(lx); projection = new LXProjection(model); addParameter(hueScale); addParameter(crazyParam); @@ -108,8 +108,8 @@ class Balance extends SCPattern { private final float centerX, centerY, centerZ, modelHeight, modelWidth, modelDepth; SinLFO heightMod = new SinLFO(0.8, 1.9, 17298); - public Balance(GLucose glucose) { - super(glucose); + public Balance(LX lx) { + super(lx); projection = new LXProjection(model); diff --git a/JackieBavaro.pde b/JackieBavaro.pde index dc5922f..fe18092 100644 --- a/JackieBavaro.pde +++ b/JackieBavaro.pde @@ -43,8 +43,8 @@ class JackieSquares extends SCPattern { private List flashes; private int faceNum = 0; - public JackieSquares(GLucose glucose) { - super(glucose); + public JackieSquares(LX lx) { + super(lx); addParameter(rateParameter); addParameter(attackParameter); addParameter(decayParameter); @@ -132,8 +132,8 @@ class JackieLines extends SCPattern { private List flashes; private int stripNum = 0; - public JackieLines(GLucose glucose) { - super(glucose); + public JackieLines(LX lx) { + super(lx); addParameter(rateParameter); addParameter(attackParameter); addParameter(decayParameter); @@ -222,8 +222,8 @@ class JackieDots extends SCPattern { private List flashes; private int pointNum = 0; - public JackieDots(GLucose glucose) { - super(glucose); + public JackieDots(LX lx) { + super(lx); addParameter(rateParameter); addParameter(attackParameter); addParameter(decayParameter); diff --git a/L8onWallace.pde b/L8onWallace.pde index fc4bac0..a819016 100644 --- a/L8onWallace.pde +++ b/L8onWallace.pde @@ -42,8 +42,8 @@ class L8onLife extends SCPattern { // Hold the new lives private List new_lives; - public L8onLife(GLucose glucose) { - super(glucose); + public L8onLife(LX lx) { + super(lx); //Print debug info about the cubes. //outputCubeInfo(); @@ -310,8 +310,8 @@ class L8onAutomata extends SCPattern { // Hold the new lives private List new_states; - public L8onAutomata(GLucose glucose) { - super(glucose); + public L8onAutomata(LX lx) { + super(lx); //Print debug info about the cubes. //outputCubeInfo(); @@ -552,8 +552,8 @@ class L8onStripLife extends SCPattern { // Hold the new lives private List new_lives; - public L8onStripLife(GLucose glucose) { - super(glucose); + public L8onStripLife(LX lx) { + super(lx); //Print debug info about the strips. //outputStripInfo(); diff --git a/MIDI.pde b/MIDI.pde index 2716494..5a198f0 100644 --- a/MIDI.pde +++ b/MIDI.pde @@ -115,7 +115,7 @@ public interface SCMidiInputListener { public void onEnabled(SCMidiInput controller, boolean enabled); } -public abstract class SCMidiInput extends AbstractScrollItem { +public abstract class SCMidiInput extends UIScrollList.AbstractItem { protected boolean enabled = false; private final String name; @@ -445,7 +445,7 @@ public class APC40MidiInput extends GenericDeviceMidiInput { // Crossfader case 15: - lx.engine.getDeck(GLucose.RIGHT_DECK).getFader().setNormalized(value); + lx.engine.getDeck(RIGHT_DECK).getFader().setNormalized(value); return true; // Cue level @@ -478,7 +478,8 @@ public class APC40MidiInput extends GenericDeviceMidiInput { if (number >= 20 && number <= 23) { int effectIndex = number - 20; - List parameters = glucose.getSelectedEffect().getParameters(); + // TODO(mclsee): fix selected effect + List parameters = getSelectedEffect().getParameters(); if (effectIndex < parameters.size()) { setNormalized(parameters.get(effectIndex), value); return true; @@ -537,7 +538,7 @@ public class APC40MidiInput extends GenericDeviceMidiInput { case 91: // play if (shiftOn) { - midiEngine.setFocusedDeck(GLucose.LEFT_DECK); + midiEngine.setFocusedDeck(LEFT_DECK); } else { uiCrossfader.setDisplayMode("A"); } @@ -549,7 +550,7 @@ public class APC40MidiInput extends GenericDeviceMidiInput { case 93: // rec if (shiftOn) { - midiEngine.setFocusedDeck(GLucose.RIGHT_DECK); + midiEngine.setFocusedDeck(RIGHT_DECK); } else { uiCrossfader.setDisplayMode("B"); } @@ -557,7 +558,7 @@ public class APC40MidiInput extends GenericDeviceMidiInput { case 94: // up bank if (shiftOn) { - glucose.incrementSelectedEffectBy(-1); + selectedEffect.setValue(selectedEffect.getValuei() - 1); } else { getTargetDeck().goPrev(); } @@ -565,7 +566,7 @@ public class APC40MidiInput extends GenericDeviceMidiInput { case 95: // down bank if (shiftOn) { - glucose.incrementSelectedEffectBy(1); + selectedEffect.setValue(selectedEffect.getValuei() + 1); } else { getTargetDeck().goNext(); } @@ -588,7 +589,7 @@ public class APC40MidiInput extends GenericDeviceMidiInput { return true; case 62: // Detail View / red 5 - releaseEffect = glucose.getSelectedEffect(); + releaseEffect = getSelectedEffect(); if (releaseEffect.isMomentary()) { releaseEffect.enable(); } else { @@ -597,7 +598,7 @@ public class APC40MidiInput extends GenericDeviceMidiInput { return true; case 63: // rec quantize / red 6 - glucose.getSelectedEffect().disable(); + getSelectedEffect().disable(); return true; } @@ -689,11 +690,11 @@ class KorgNanoKontrolMidiInput extends GenericDeviceMidiInput { switch (number) { case 58: // Left track - midiEngine.setFocusedDeck(GLucose.LEFT_DECK); + midiEngine.setFocusedDeck(LEFT_DECK); return true; case 59: // Right track - midiEngine.setFocusedDeck(GLucose.RIGHT_DECK); + midiEngine.setFocusedDeck(RIGHT_DECK); return true; case 43: // Left chevron @@ -737,8 +738,8 @@ class APC40MidiOutput implements LXParameterListener, GridOutput { } }); } - glucose.addEffectListener(new GLucose.EffectListener() { - public void effectSelected(LXEffect effect) { + selectedEffect.addListener(new LXParameterListener() { + public void onParameterChanged(LXParameter parameter) { resetEffectParameters(); } }); @@ -842,7 +843,7 @@ class APC40MidiOutput implements LXParameterListener, GridOutput { } private void resetEffectParameters() { - LXEffect newEffect = glucose.getSelectedEffect(); + LXEffect newEffect = getSelectedEffect(); if (newEffect == focusedEffect) { return; } diff --git a/Mappings.pde b/Mappings.pde index d1c51b2..8798fb5 100644 --- a/Mappings.pde +++ b/Mappings.pde @@ -13,447 +13,58 @@ * when physical changes or tuning is being done to the structure. */ -import java.util.Arrays; +static final float SPACING = 27; +static final float RISER = 13.5; +static final float FLOOR = 0; -final int MaxCubeHeight = 6; -final int NumBackTowers = 16; +/** + * Definitions of tower positions. This is all that should need + * to be modified. Distances are measured from the left-most cube. + * The first value is the offset moving NE (towards back-right). + * The second value is the offset moving NW (negative comes forward-right). + */ +static final float[][] TOWER_CONFIG = new float[][] { + new float[] { 0, 0, RISER, 4 }, + new float[] { 25, -10, RISER, 4 }, + new float[] { 50, -22.5, FLOOR, 5 }, + new float[] { 17.25, -35.5, FLOOR, 6 }, + new float[] { 43.25, -51.5, RISER, 6 }, + new float[] { 69.25, -56, FLOOR, 6 }, + new float[] { 12.75, -62.5, RISER, 4 }, + new float[] { 38.75, -78.5, FLOOR, 5 }, + new float[] { 65.75, -83, RISER, 5 }, + +}; public Model buildModel() { - // Shorthand helpers for specifying wiring more quickly - final Cube.Wiring WFL = Cube.Wiring.FRONT_LEFT; - final Cube.Wiring WFR = Cube.Wiring.FRONT_RIGHT; - final Cube.Wiring WRL = Cube.Wiring.REAR_LEFT; - final Cube.Wiring WRR = Cube.Wiring.REAR_RIGHT; - - // Utility value if you need the height of a cube shorthand - final float CH = Cube.EDGE_HEIGHT; - final float CW = Cube.EDGE_WIDTH ; - - // Positions for the bass box - final float BBY = BassBox.EDGE_HEIGHT + BoothFloor.PLEXI_WIDTH; - final float BBX = 56; - final float BBZ = 2; - - // The model is represented as an array of towers. The cubes in the tower - // are represenented relatively. Each tower has an x, y, z reference position, - // which is typically the base cube's bottom left corner. - // - // Following that is an array of floats. A 2-d array contains an x-offset - // and a z-offset from the previous reference position. Typically the first cube - // will just be {0, 0}. Each successive cube uses the position of the previous - // cube as its reference. - // - // A 3-d array contains an x-offset, a z-offset, and a rotation about the - // y-axis. - // - // The cubes automatically increment their y-position by Cube.EDGE_HEIGHT. - - // To-Do: (Mark Slee, Alex Green, or Ben Morrow): The Cube # is determined by the order in this list. - // "raw object index" is serialized by running through towermapping and then individual cube mapping below. - // We can do better than this. The raw object index should be obvious from the code-- looking through the - // rendered simulation and counting through cubes in mapping mode is grossly inefficient. - - TowerMapping[] towerCubes = new TowerMapping[] {}; - - // Single cubes can be constructed directly here if you need them - Cube[] singleCubes = new Cube[] { - // new Cube(15, int( Cube.EDGE_HEIGHT), 39, 0, 10, 0, WRL), // Back left channel behind speaker - //new Cube(x, y, z, rx, ry, rz, wiring), - //new Cube(0,0,0,0,225,0, WRR), - }; - - // The bass box! - // BassBox bassBox = BassBox.unlitBassBox(BBX, 0, BBZ); // frame exists, no lights - BassBox bassBox = BassBox.noBassBox(); // no bass box at all - // BassBox bassBox = new BassBox(BBX, 0, BBZ); // bass box with lights - - // The speakers! - List speakers = Arrays.asList(new Speaker[] { - // Each speaker parameter is x, y, z, rotation, the left speaker comes first - // new Speaker(TRAILER_WIDTH - Speaker.EDGE_WIDTH + 8, 6, 3, -15) - }); - - - //////////////////////////////////////////////////////////////////////// - // dan's proposed lattice - ArrayList scubes = new ArrayList(); - //if (NumBackTowers != 25) exit(); - for (int i=0; i dcubes = new ArrayList(); - // for (int i=1; i<6; i++) { - // if (i>1) dcubes.add(new Cube(-6+CW*4/3*i , 0, 0, 0, 0, 0, WRR)); - // dcubes.add(new Cube(-6+CW*4/3*i+CW*2/3., CH*.5, 0, 0, 0, 0, WRR)); - // } - -float current_x_position = 0; -// scubes.add(new StaggeredTower(//tower 1 -// current_x_position, // x -// 15 , // y -// 0 , // z -// 45, 6, new Cube.Wiring[] { WFL, WRR, WFL, WRR, WFL, WRR}) ); -// current_x_position += 25.25; -// scubes.add(new StaggeredTower(// tower 2 -// current_x_position, // x -// 0 , // y -// -10.5 , // z -// 45, 6, new Cube.Wiring[] { WFR, WFL, WRR, WRR, WFL, WRR}) ); -// current_x_position += 25.25; -// scubes.add(new StaggeredTower(//tower 3 -// current_x_position, // x -// 15 , // y -// 0, // z -// 45, 6, new Cube.Wiring[] { WRR, WFL, WRR, WRR, WFL, WRR}) ); -// current_x_position += 25.25; -// scubes.add(new StaggeredTower(//tower 4 -// current_x_position, // x -// 0, // y -// -10.5 , // z -// 45, 6, new Cube.Wiring[] { WFL, WRR, WFL, WRR, WFL, WRR}) ); -// current_x_position += 28; -// scubes.add(new StaggeredTower(//tower 5 -// current_x_position, // x -// 15 , // y -// -4.5 , // z -// 45, 6, new Cube.Wiring[] { WRR, WFL, WRR, WFL, WRR, WFL}) ); -// current_x_position += 28; -// scubes.add(new StaggeredTower(//tower 6 -// current_x_position, // x -// 0 , // y -// -10.5, // z -// 45, 6, new Cube.Wiring[] { WFL, WRR, WFL, WRR, WFL, WRR}) ); -// current_x_position += 25.25; -// scubes.add(new StaggeredTower(// tower 7 -// current_x_position, // x -// 15 , // y -// 0, // z -// 45, 6, new Cube.Wiring[] { WRR, WFL, WRR, WFL, WRR, WFL}) ); -// current_x_position += 25.25; -// scubes.add(new StaggeredTower(//tower 8 -// current_x_position, // x -// 0 , // y -// -10.5 , // z -// 45, 6, new Cube.Wiring[] { WFL, WRR, WFL, WRR, WFL, WRR}) ); -// current_x_position += 25.25; -// scubes.add(new StaggeredTower(//tower 9 -// current_x_position, // x -// 15 , // y -// 0, // z -// 45, 6, new Cube.Wiring[] { WFL, WRR, WFL, WRR, WFL, WRR}) ); -// current_x_position += 25.25; - -// //TOWERS ON DANCE FLOOR -// scubes.add(new StaggeredTower(//tower 10 -// 83.75+39+43-124.5, // x -// 0, // y -// -47.5-43, // z -// 45, 4, new Cube.Wiring[]{ WRR, WFL, WFL, WRR}) ); -// scubes.add(new StaggeredTower(//tower 11 -// 83.75, // x -// 0, // y -// -47.5, // z -// 45, 4, new Cube.Wiring[]{ WFL, WRR, WRR, WFL}) ); -// scubes.add(new StaggeredTower(//tower 12 -// 83.75+39, // x -// 0, // y -// -47.5, // z -// 45, 4, new Cube.Wiring[]{ WRR, WFL, WFL, WRR}) ); -// scubes.add(new StaggeredTower(//tower 13 -// 83.75+39+43, // x -// 0, // y -// -47.5-43, // z -// 45, 4, new Cube.Wiring[]{ WFL, WRR, WFL, WRR}) ); - -// scubes.add(new StaggeredTower(// Single cube on top of tower 4 -// 42, // x -// 112 , // y -// 72, // z -// -10, 1, new Cube.Wiring[]{ WRL}) ); - - - - - - - - ////////////////////////////////////////////////////////////////////// - // BENEATH HERE SHOULD NOT REQUIRE ANY MODIFICATION!!!! // - ////////////////////////////////////////////////////////////////////// - - // These guts just convert the shorthand mappings into usable objects - ArrayList towerList = new ArrayList(); - ArrayList tower; + List towers = new ArrayList(); Cube[] cubes = new Cube[200]; - int cubeIndex = 1; - float px, pz, ny; - for (TowerMapping tm : towerCubes) { - px = tm.x; - ny = tm.y; - pz = tm.z; - tower = new ArrayList(); - for (CubeMapping cm : tm.cubeMappings) { - tower.add(cubes[cubeIndex++] = new Cube(px = px + cm.dx, ny, pz = pz + cm.dz, 0, cm.ry, 0, cm.wiring)); - ny += Cube.EDGE_HEIGHT; + int cubeIndex = 1; + + float rt2 = sqrt(2); + float x, y, z, xd, zd, num; + for (float[] tc : TOWER_CONFIG) { + x = -tc[1]; + z = tc[0]; + y = tc[2]; + num = tc[3]; + if (z < x) { + zd = -(x-z)/rt2; + xd = z*rt2 - zd; + } else { + zd = (z-x)/rt2; + xd = z*rt2 - zd; } - towerList.add(new Tower(tower)); - } - - - for (Cube cube : singleCubes) { - cubes[cubeIndex++] = cube; - } - for (Cube cube : dcubes) { - cubes[cubeIndex++] = cube; - } - for (StaggeredTower st : scubes) { - tower = new ArrayList(); - for (int i=0; i < st.n; i++) { - Cube.Wiring w = (i < st.wiring.length) ? st.wiring[i] : WRR; - tower.add(cubes[cubeIndex++] = new Cube(st.x, st.y + CH* 4/3.*i, st.z, 0, st.r, 0, w)); - } - towerList.add(new Tower(tower)); - } - - return new Model(towerList, cubes, bassBox, speakers); -} - -/** - * This function maps the panda boards. We have an array of them, each has - * an IP address and a list of channels. - */ -public PandaMapping[] buildPandaList() { - final int LEFT_SPEAKER = 0; - final int RIGHT_SPEAKER = 1; - - // 8 channels map to: 3, 4, 7, 8, 13, 14, 15, 16. - return new PandaMapping[] { - new PandaMapping( - "10.200.1.28", new ChannelMapping[] { - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 37, 38, 39 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 43, 44, 45 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 46, 47, 48 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // new front thing - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // new back thing - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 13, 14, 15 }), // new back thing - }), - new PandaMapping( - "10.200.1.29", new ChannelMapping[] { - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 19, 20, 21 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1, 2, 3 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 4, 5, 6 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 7, 8, 9 }), - - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 10, 11, 12 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 16, 17, 18 }), -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 34, 35, 36}), -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 19, 20, 21}), -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 22, 23, 24}), -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 25, 26, 27}), -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 28, 29, 30}), -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 31, 32, 33}), -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), - }), - new PandaMapping( - "10.200.1.30", new ChannelMapping[] { - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 40, 41, 42 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 22, 23, 24 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 25, 26, 27 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 28, 29, 30 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 31, 32, 33 }), - new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 34, 35, 36 }), -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1,1}), // 30 J3 * -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1,1}), // 30 J4 //ORIG * -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 37, 38, 39}), // 30 J7 * -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 40, 41, 42}), // 30 J8 * -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 43, 44, 45}), // 30 J13 (not working) -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 46, 47, 48}), // 30 J14 (unplugged) -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 49, 50, 51}), // 30 J15 (unplugged) -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 52, 53, 54}), // 30 J16 - }), -// new PandaMapping( -// "10.200.1.31", new ChannelMapping[] { -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 65, 66}), // J3 -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1}), // J4 -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 55, 56}), // 30 J7 -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 57, 58}), // J8 -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 59, 60}), // J13 -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 61, 62}), // 30 J14 -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 63, 64}), // J15 -// new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1}), // J16 -// }), - - // new PandaMapping( - // "10.200.1.32", new ChannelMapping[] { - // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // J3 - // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // J4 - // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 67, 68}), // 30 J7 - // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 69, 70}), // J8 - // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // J13 - // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // 30 J14 - // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // J15 - // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // J16 - // }), - }; -} - -class TowerMapping { - public final float x, y, z; - public final CubeMapping[] cubeMappings; - - TowerMapping(float x, float y, float z, CubeMapping[] cubeMappings) { - this.x = x; - this.y = y; - this.z = z; - this.cubeMappings = cubeMappings; - } -} - -class CubeMapping { - public final float dx, dz, ry; - public final Cube.Wiring wiring; - - CubeMapping(float dx, float dz, Cube.Wiring wiring) { - this(dx, dz, 0., wiring); - } - CubeMapping(float dx, float dz, float ry) { - this(dz, dz, ry, Cube.Wiring.FRONT_LEFT); - } - - CubeMapping(float dx, float dz, float ry, Cube.Wiring wiring) { - this.dx = dx; - this.dz = dz; - this.ry = ry; - this.wiring = wiring; - } -} - -class StaggeredTower { - public final float x, y, z, r; - public final int n; - public final Cube.Wiring[] wiring; - StaggeredTower(float _x, float _y, float _z, float _r, int _n) { this(_x, _y, _z, _r, _n, new Cube.Wiring[]{}); } - StaggeredTower(float _x, float _y, float _z, float _r, int _n, Cube.Wiring[] _wiring) { x=_x; y=_y; z=_z; r=_r; n=_n; wiring=_wiring;} -} - -/** - * Each panda board has an IP address and a fixed number of channels. The channels - * each have a fixed number of pixels on them. Whether or not that many physical - * pixels are connected to the channel, we still send it that much data. - */ -class PandaMapping { - - // How many channels are on the panda board - public final static int CHANNELS_PER_BOARD = 8; - - // How many total pixels on the whole board - public final static int PIXELS_PER_BOARD = ChannelMapping.PIXELS_PER_CHANNEL * CHANNELS_PER_BOARD; - - final String ip; - final ChannelMapping[] channelList = new ChannelMapping[CHANNELS_PER_BOARD]; - - PandaMapping(String ip, ChannelMapping[] rawChannelList) { - this.ip = ip; - - // Ensure our array is the right length and has all valid items in it - for (int i = 0; i < channelList.length; ++i) { - channelList[i] = (i < rawChannelList.length) ? rawChannelList[i] : new ChannelMapping(); - if (channelList[i] == null) { - channelList[i] = new ChannelMapping(); - } + List tower = new ArrayList(); + for (int n = 0; n < num; ++n) { + Cube cube = new Cube(xd + 24, y, zd + 84, 0, -45, 0); + tower.add(cube); + cubes[cubeIndex++] = cube; + y += SPACING; } + towers.add(new Tower(tower)); } -} - -/** - * Each channel on a pandaboard can be mapped in a number of modes. The typical is - * to a series of connected cubes, but we also have special mappings for the bass box, - * the speaker enclosures, and the DJ booth floor. - * - * This class is just the mapping meta-data. It sanitizes the input to make sure - * that the cubes and objects being referenced actually exist in the model. - * - * The logic for how to encode the pixels is contained in the PandaDriver. - */ -class ChannelMapping { - - // How many cubes per channel xc_PB is configured for - public final static int CUBES_PER_CHANNEL = 4; - // How many total pixels on each channel - public final static int PIXELS_PER_CHANNEL = Cube.POINTS_PER_CUBE * CUBES_PER_CHANNEL; - - public static final int MODE_NULL = 0; - public static final int MODE_CUBES = 1; - public static final int MODE_BASS = 2; - public static final int MODE_SPEAKER = 3; - public static final int MODE_STRUTS_AND_FLOOR = 4; - public static final int MODE_INVALID = 5; - - public static final int NO_OBJECT = -1; - - final int mode; - final int[] objectIndices = new int[CUBES_PER_CHANNEL]; - - ChannelMapping() { - this(MODE_NULL); - } - - ChannelMapping(int mode) { - this(mode, new int[]{}); - } - - ChannelMapping(int mode, int rawObjectIndex) { - this(mode, new int[]{ rawObjectIndex }); - } - - ChannelMapping(int mode, int[] rawObjectIndices) { - if (mode < 0 || mode >= MODE_INVALID) { - throw new RuntimeException("Invalid channel mapping mode: " + mode); - } - if (mode == MODE_SPEAKER) { - if (rawObjectIndices.length != 1) { - throw new RuntimeException("Speaker channel mapping mode must specify one speaker index"); - } - int speakerIndex = rawObjectIndices[0]; - if (speakerIndex < 0 || speakerIndex >= glucose.model.speakers.size()) { - throw new RuntimeException("Invalid speaker channel mapping: " + speakerIndex); - } - } else if ((mode == MODE_STRUTS_AND_FLOOR) || (mode == MODE_BASS) || (mode == MODE_NULL)) { - if (rawObjectIndices.length > 0) { - throw new RuntimeException("Bass/floor/null mappings cannot specify object indices"); - } - } else if (mode == MODE_CUBES) { - for (int rawCubeIndex : rawObjectIndices) { - if (glucose.model.getCubeByRawIndex(rawCubeIndex) == null) { - throw new RuntimeException("Non-existing cube specified in cube mapping: " + rawCubeIndex); - } - } - } - - this.mode = mode; - for (int i = 0; i < objectIndices.length; ++i) { - objectIndices[i] = (i < rawObjectIndices.length) ? rawObjectIndices[i] : NO_OBJECT; - } - } + return new Model(towers, cubes); } diff --git a/MarkSlee.pde b/MarkSlee.pde index 0976d57..fea4a43 100644 --- a/MarkSlee.pde +++ b/MarkSlee.pde @@ -7,15 +7,15 @@ class Cathedrals extends SCPattern { private final BasicParameter sat = new BasicParameter("SAT", 0.5); private GraphicEQ eq; - Cathedrals(GLucose glucose) { - super(glucose); + Cathedrals(LX lx) { + super(lx); addParameter(xpos); addParameter(wid); addParameter(arms); addParameter(sat); } - protected void onActive() { + void onActive() { if (eq == null) { eq = new GraphicEQ(lx, 16); eq.slope.setValue(0.7); @@ -82,8 +82,8 @@ class MidiMusic extends SCPattern { private final BasicParameter wave = new BasicParameter("WAVE", 0); - MidiMusic(GLucose glucose) { - super(glucose); + MidiMusic(LX lx) { + super(lx); addParameter(lightSize); addParameter(wave); addModulator(sparkle).setValue(1); @@ -287,8 +287,8 @@ class Pulley extends SCPattern { private BasicParameter sz = new BasicParameter("SIZE", 0.5); private BasicParameter beatAmount = new BasicParameter("BEAT", 0); - Pulley(GLucose glucose) { - super(glucose); + Pulley(LX lx) { + super(lx); for (int i = 0; i < NUM_DIVISIONS; ++i) { addModulator(gravity[i] = new Accelerator(0, 0, 0)); addModulator(delays[i] = new Click(0)); @@ -393,8 +393,8 @@ class ViolinWave extends SCPattern { LinearEnvelope dbValue = new LinearEnvelope(0, 0, 10); - ViolinWave(GLucose glucose) { - super(glucose); + ViolinWave(LX lx) { + super(lx); addParameter(level); addParameter(edge); addParameter(range); @@ -566,8 +566,8 @@ class BouncyBalls extends SCPattern { final BasicParameter flr = new BasicParameter("FLR", 0); final BasicParameter blobSize = new BasicParameter("SIZE", 0.5); - BouncyBalls(GLucose glucose) { - super(glucose); + BouncyBalls(LX lx) { + super(lx); for (int i = 0; i < balls.length; ++i) { balls[i] = new BouncyBall(i); } @@ -601,8 +601,8 @@ class SpaceTime extends SCPattern { BasicParameter sizeParameter = new BasicParameter("SIZE", 0.5); - public SpaceTime(GLucose glucose) { - super(glucose); + public SpaceTime(LX lx) { + super(lx); addModulator(pos).trigger(); addModulator(rate).trigger(); @@ -653,8 +653,8 @@ class Swarm extends SCPattern { SinLFO fY = new SinLFO(model.yMin, model.yMax, 11000); SinLFO hOffX = new SinLFO(model.xMin, model.xMax, 13000); - public Swarm(GLucose glucose) { - super(glucose); + public Swarm(LX lx) { + super(lx); addModulator(offset).trigger(); addModulator(rate).trigger(); @@ -695,12 +695,12 @@ class Swarm extends SCPattern { } } -class SwipeTransition extends SCTransition { +class SwipeTransition extends LXTransition { final BasicParameter bleed = new BasicParameter("WIDTH", 0.5); - SwipeTransition(GLucose glucose) { - super(glucose); + SwipeTransition(LX lx) { + super(lx); setDuration(5000); addParameter(bleed); } @@ -721,96 +721,18 @@ class SwipeTransition extends SCTransition { } } -abstract class BlendTransition extends SCTransition { - - final int blendType; - - BlendTransition(GLucose glucose, int blendType) { - super(glucose); - this.blendType = blendType; - } - - void computeBlend(int[] c1, int[] c2, double progress) { - if (progress < 0.5) { - for (int i = 0; i < c1.length; ++i) { - colors[i] = lerpColor( - c1[i], - blendColor(c1[i], c2[i], blendType), - (float) (2.*progress), - RGB); - } - } else { - for (int i = 0; i < c1.length; ++i) { - colors[i] = lerpColor( - c2[i], - blendColor(c1[i], c2[i], blendType), - (float) (2.*(1. - 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.5); - public BassPod(GLucose glucose) { - super(glucose); + public BassPod(LX lx) { + super(lx); addParameter(clr); } - protected void onActive() { + void onActive() { if (eq == null) { eq = new GraphicEQ(lx, 16); eq.range.setValue(0.4); @@ -858,11 +780,11 @@ class CubeEQ extends SCPattern { private final BasicParameter clr = new BasicParameter("CLR", 0.5); private final BasicParameter blockiness = new BasicParameter("BLK", 0.5); - public CubeEQ(GLucose glucose) { - super(glucose); + public CubeEQ(LX lx) { + super(lx); } - protected void onActive() { + void onActive() { if (eq == null) { eq = new GraphicEQ(lx, 16); addParameter(eq.level); @@ -909,7 +831,7 @@ class CubeEQ extends SCPattern { } } -class BoomEffect extends SCEffect { +class BoomEffect extends LXEffect { final BasicParameter falloff = new BasicParameter("WIDTH", 0.5); final BasicParameter speed = new BasicParameter("SPD", 0.5); @@ -946,8 +868,8 @@ class BoomEffect extends SCEffect { } } - BoomEffect(GLucose glucose) { - super(glucose, true); + BoomEffect(LX lx) { + super(lx, true); addParameter(falloff); addParameter(speed); addParameter(bright); @@ -989,8 +911,8 @@ public class PianoKeyPattern extends SCPattern { final BasicParameter release = new BasicParameter("REL", 0.5); final BasicParameter level = new BasicParameter("AMB", 0.6); - PianoKeyPattern(GLucose glucose) { - super(glucose); + PianoKeyPattern(LX lx) { + super(lx); addParameter(attack); addParameter(release); @@ -1064,8 +986,8 @@ class CrossSections extends SCPattern { final BasicParameter zl = new BasicParameter("ZLEV", 0.5); - CrossSections(GLucose glucose) { - super(glucose); + CrossSections(LX lx) { + super(lx); addModulator(x).trigger(); addModulator(y).trigger(); addModulator(z).trigger(); @@ -1142,8 +1064,8 @@ class Blinders extends SCPattern { final SinLFO s; final TriangleLFO hs; - public Blinders(GLucose glucose) { - super(glucose); + public Blinders(LX lx) { + super(lx); m = new SinLFO[12]; for (int i = 0; i < m.length; ++i) { addModulator(m[i] = new SinLFO(0.5, 120, (120000. / (3+i)))).trigger(); @@ -1181,8 +1103,8 @@ class Psychedelia extends SCPattern { TriangleLFO h = new TriangleLFO(0, 240, 19000); SinLFO c = new SinLFO(-.2, .8, 31000); - Psychedelia(GLucose glucose) { - super(glucose); + Psychedelia(LX lx) { + super(lx); addModulator(m).trigger(); addModulator(s).trigger(); addModulator(h).trigger(); @@ -1236,8 +1158,8 @@ class AskewPlanes extends SCPattern { final Plane[] planes; final int NUM_PLANES = 3; - AskewPlanes(GLucose glucose) { - super(glucose); + AskewPlanes(LX lx) { + super(lx); planes = new Plane[NUM_PLANES]; for (int i = 0; i < planes.length; ++i) { planes[i] = new Plane(i); @@ -1281,8 +1203,8 @@ class ShiftingPlane extends SCPattern { final SinLFO c = new SinLFO(-1.4, 1.4, 5700); final SinLFO d = new SinLFO(-10, 10, 9500); - ShiftingPlane(GLucose glucose) { - super(glucose); + ShiftingPlane(LX lx) { + super(lx); addModulator(a).trigger(); addModulator(b).trigger(); addModulator(c).trigger(); @@ -1319,8 +1241,8 @@ class Traktor extends SCPattern { private int index = 0; private GraphicEQ eq = null; - public Traktor(GLucose glucose) { - super(glucose); + public Traktor(LX lx) { + super(lx); for (int i = 0; i < FRAME_WIDTH; ++i) { bass[i] = 0; treble[i] = 0; @@ -1382,7 +1304,7 @@ class Traktor extends SCPattern { } } -class ColorFuckerEffect extends SCEffect { +class ColorFuckerEffect extends LXEffect { final BasicParameter level = new BasicParameter("BRT", 1); final BasicParameter desat = new BasicParameter("DSAT", 0); @@ -1395,8 +1317,8 @@ class ColorFuckerEffect extends SCEffect { float[] hsb = new float[3]; - ColorFuckerEffect(GLucose glucose) { - super(glucose); + ColorFuckerEffect(LX lx) { + super(lx); addParameter(level); addParameter(desat); addParameter(sharp); @@ -1407,7 +1329,7 @@ class ColorFuckerEffect extends SCEffect { } public void apply(int[] colors) { - if (!enabled) { + if (!isEnabled()) { return; } float bMod = level.getValuef(); @@ -1451,15 +1373,15 @@ class ColorFuckerEffect extends SCEffect { } } -class QuantizeEffect extends SCEffect { +class QuantizeEffect extends LXEffect { color[] quantizedFrame; float lastQuant; final BasicParameter amount = new BasicParameter("AMT", 0); - QuantizeEffect(GLucose glucose) { - super(glucose); - quantizedFrame = new color[glucose.lx.total]; + QuantizeEffect(LX lx) { + super(lx); + quantizedFrame = new color[lx.total]; lastQuant = 0; } @@ -1482,14 +1404,14 @@ class QuantizeEffect extends SCEffect { } } -class BlurEffect extends SCEffect { +class BlurEffect extends LXEffect { final BasicParameter amount = new BasicParameter("AMT", 0); final int[] frame; final LinearEnvelope env = new LinearEnvelope(0, 1, 100); - BlurEffect(GLucose glucose) { - super(glucose); + BlurEffect(LX lx) { + super(lx); addParameter(amount); addModulator(env); frame = new int[lx.total]; diff --git a/Model.pde b/Model.pde new file mode 100644 index 0000000..3376246 --- /dev/null +++ b/Model.pde @@ -0,0 +1,365 @@ +/** + * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND + * + * //\\ //\\ //\\ //\\ + * ///\\\ ///\\\ ///\\\ ///\\\ + * \\\/// \\\/// \\\/// \\\/// + * \\// \\// \\// \\// + * + * EXPERTS ONLY!! EXPERTS ONLY!! + * + * Contains the model definitions for the cube structures. + */ + +/** + * Top-level model of the entire sculpture. This contains a list of + * every cube on the sculpture, which forms a hierarchy of faces, strips + * and points. + */ +public static class Model extends LXModel { + + public final List towers; + public final List cubes; + public final List faces; + public final List strips; + + private final Cube[] _cubes; + + public Model(List towerList, Cube[] cubeArr) { + super(new Fixture(cubeArr)); + Fixture fixture = (Fixture) this.fixtures.get(0); + + _cubes = cubeArr; + + // Make unmodifiable accessors to the model data + List cubeList = new ArrayList(); + List faceList = new ArrayList(); + List stripList = new ArrayList(); + for (Cube cube : _cubes) { + if (cube != null) { + cubeList.add(cube); + for (Face face : cube.faces) { + faceList.add(face); + for (Strip strip : face.strips) { + stripList.add(strip); + } + } + } + } + + this.towers = Collections.unmodifiableList(towerList); + this.cubes = Collections.unmodifiableList(cubeList); + this.faces = Collections.unmodifiableList(faceList); + this.strips = Collections.unmodifiableList(stripList); + } + + private static class Fixture extends LXAbstractFixture { + + private Fixture(Cube[] cubeArr) { + for (Cube cube : cubeArr) { + if (cube != null) { + for (LXPoint point : cube.points) { + this.points.add(point); + } + } + } + } + } + + /** + * TODO(mcslee): figure out better solution + * + * @param index + * @return + */ + public Cube getCubeByRawIndex(int index) { + return _cubes[index]; + } +} + +/** + * Model of a set of cubes stacked in a tower + */ +public static class Tower extends LXModel { + /** + * Immutable list of cubes + */ + public final List cubes; + + /** + * Immutable list of faces + */ + public final List faces; + + /** + * Immutable list of strips + */ + public final List strips; + + /** + * Constructs a tower model from these cubes + * + * @param cubes Array of cubes + */ + public Tower(List cubes) { + super(cubes.toArray(new Cube[] {})); + + List cubeList = new ArrayList(); + List faceList = new ArrayList(); + List stripList = new ArrayList(); + + for (Cube cube : cubes) { + cubeList.add(cube); + for (Face face : cube.faces) { + faceList.add(face); + for (Strip strip : face.strips) { + stripList.add(strip); + } + } + } + this.cubes = Collections.unmodifiableList(cubeList); + this.faces = Collections.unmodifiableList(faceList); + this.strips = Collections.unmodifiableList(stripList); + } +} + +/** + * Model of a single cube, which has an orientation and position on the + * car. The position is specified in x,y,z coordinates with rotation. The + * x axis is left->right, y is bottom->top, and z is front->back. + * + * A cube's x,y,z position is specified as the left, bottom, front corner. + * + * Dimensions are all specified in real-world inches. + */ +public static class Cube extends LXModel { + + public final static int FACES_PER_CUBE = 4; + public static final int POINTS_PER_STRIP = 16; + + public final static int STRIPS_PER_CUBE = FACES_PER_CUBE*Face.STRIPS_PER_FACE; + public final static int POINTS_PER_CUBE = STRIPS_PER_CUBE*POINTS_PER_STRIP; + public final static int POINTS_PER_FACE = Face.STRIPS_PER_FACE*POINTS_PER_STRIP; + + public final static float EDGE_HEIGHT = 21.75f; + public final static float EDGE_WIDTH = 24.625f; + public final static float CHANNEL_WIDTH = 1.5f; + + public final static Face.Metrics FACE_METRICS = new Face.Metrics( + new Strip.Metrics(EDGE_WIDTH, POINTS_PER_STRIP), + new Strip.Metrics(EDGE_HEIGHT, POINTS_PER_STRIP) + ); + + /** + * Immutable list of all cube faces + */ + public final List faces; + + /** + * Immutable list of all strips + */ + public final List strips; + + /** + * Front left corner x coordinate + */ + public final float x; + + /** + * Front left corner y coordinate + */ + public final float y; + + /** + * Front left corner z coordinate + */ + public final float z; + + /** + * Rotation about the x-axis + */ + public final float rx; + + /** + * Rotation about the y-axis + */ + public final float ry; + + /** + * Rotation about the z-axis + */ + public final float rz; + + public Cube(double x, double y, double z, double rx, double ry, double rz) { + this((float) x, (float) y, (float) z, (float) rx, (float) ry, (float) rz); + } + + public Cube(float x, float y, float z, float rx, float ry, float rz) { + super(new Fixture(x, y, z, rx, ry, rz)); + Fixture fixture = (Fixture) this.fixtures.get(0); + + while (rx < 0) rx += 360; + while (ry < 0) ry += 360; + while (rz < 0) rz += 360; + rx = rx % 360; + ry = ry % 360; + rz = rz % 360; + + this.x = x; + this.y = y; + this.z = z; + this.rx = rx; + this.ry = ry; + this.rz = rz; + + this.faces = Collections.unmodifiableList(fixture.faces); + this.strips = Collections.unmodifiableList(fixture.strips); + } + + private static class Fixture extends LXAbstractFixture { + + private final List faces = new ArrayList(); + private final List strips = new ArrayList(); + + private Fixture(float x, float y, float z, float rx, float ry, float rz) { + LXTransform t = new LXTransform(); + t.translate(x, y, z); + t.rotateX(rx * PI / 180.); + t.rotateY(ry * PI / 180.); + t.rotateZ(rz * PI / 180.); + + for (int i = 0; i < FACES_PER_CUBE; i++) { + Face face = new Face(FACE_METRICS, (ry + 90*i) % 360, t); + this.faces.add(face); + for (Strip s : face.strips) { + this.strips.add(s); + } + for (LXPoint p : face.points) { + this.points.add(p); + } + t.translate(EDGE_WIDTH, 0, 0); + t.rotateY(HALF_PI); + } + } + } +} + +/** + * A face is a component of a cube. It is comprised of four strips forming + * the lights on this side of a cube. A whole cube is formed by four faces. + */ +public static class Face extends LXModel { + + public final static int STRIPS_PER_FACE = 4; + + public static class Metrics { + final Strip.Metrics horizontal; + final Strip.Metrics vertical; + + public Metrics(Strip.Metrics horizontal, Strip.Metrics vertical) { + this.horizontal = horizontal; + this.vertical = vertical; + } + } + + /** + * Immutable list of strips + */ + public final List strips; + + /** + * Rotation of the face about the y-axis + */ + public final float ry; + + Face(Metrics metrics, float ry, LXTransform transform) { + super(new Fixture(metrics, ry, transform)); + Fixture fixture = (Fixture) this.fixtures.get(0); + this.ry = ry; + this.strips = Collections.unmodifiableList(fixture.strips); + } + + private static class Fixture extends LXAbstractFixture { + + private final List strips = new ArrayList(); + + private Fixture(Metrics metrics, float ry, LXTransform transform) { + transform.push(); + transform.translate(0, metrics.vertical.length, 0); + for (int i = 0; i < STRIPS_PER_FACE; i++) { + boolean isHorizontal = (i % 2 == 0); + Strip.Metrics stripMetrics = isHorizontal ? metrics.horizontal : metrics.vertical; + Strip strip = new Strip(stripMetrics, ry, transform, isHorizontal); + this.strips.add(strip); + transform.translate(isHorizontal ? metrics.horizontal.length : metrics.vertical.length, 0, 0); + transform.rotateZ(HALF_PI); + for (LXPoint p : strip.points) { + this.points.add(p); + } + } + transform.pop(); + } + } +} + +/** + * A strip is a linear run of points along a single edge of one cube. + */ +public static class Strip extends LXModel { + + public static final float POINT_SPACING = 18.625f / 15.f; + + public static class Metrics { + + public final float length; + public final int numPoints; + + public Metrics(float length, int numPoints) { + this.length = length; + this.numPoints = numPoints; + } + } + + public final Metrics metrics; + + /** + * Whether this is a horizontal strip + */ + public final boolean isHorizontal; + + /** + * Rotation about the y axis + */ + public final float ry; + + public Object obj1 = null, obj2 = null; + + Strip(Metrics metrics, float ry, List points, boolean isHorizontal) { + super(points); + this.isHorizontal = isHorizontal; + this.metrics = metrics; + this.ry = ry; + } + + Strip(Metrics metrics, float ry, LXTransform transform, boolean isHorizontal) { + super(new Fixture(metrics, ry, transform)); + this.metrics = metrics; + this.isHorizontal = isHorizontal; + this.ry = ry; + } + + private static class Fixture extends LXAbstractFixture { + private Fixture(Metrics metrics, float ry, LXTransform transform) { + float offset = (metrics.length - (metrics.numPoints - 1) * POINT_SPACING) / 2.f; + transform.push(); + transform.translate(offset, -Cube.CHANNEL_WIDTH/2.f, 0); + for (int i = 0; i < metrics.numPoints; i++) { + LXPoint point = new LXPoint(transform.x(), transform.y(), transform.z()); + this.points.add(point); + transform.translate(POINT_SPACING, 0, 0); + } + transform.pop(); + } + } +} + diff --git a/PandaDriver.pde b/PandaDriver.pde deleted file mode 100644 index 5d8ad24..0000000 --- a/PandaDriver.pde +++ /dev/null @@ -1,359 +0,0 @@ -import netP5.*; -import oscP5.*; - -/** - * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND - * - * //\\ //\\ //\\ //\\ - * ///\\\ ///\\\ ///\\\ ///\\\ - * \\\/// \\\/// \\\/// \\\/// - * \\// \\// \\// \\// - * - * EXPERTS ONLY!! EXPERTS ONLY!! - * - * This class implements the output function to the Panda Boards. It - * will be moved into GLucose once stabilized. - */ -public static class PandaDriver { - - interface Listener { - public void onToggle(boolean enabled); - } - - private Listener listener = null; - - // IP address - public final String ip; - - // Address to send to - private final NetAddress address; - - // Whether board output is enabled - private boolean enabled = false; - - // OSC message - private final OscMessage message; - - // List of point indices that get sent to this board - private final int[] points; - - // Packet data - private final byte[] packet = new byte[4*352]; // magic number, our UDP packet size - - private static final int NO_POINT = -1; - - //////////////////////////////////////////////////////////////// - // - // READ THIS RIGHT NOW BEFORE YOU MODIFY THE BELOW!!!!!!!!!!!!! - // READ THIS RIGHT NOW BEFORE YOU MODIFY THE BELOW!!!!!!!!!!!!! - // READ THIS RIGHT NOW BEFORE YOU MODIFY THE BELOW!!!!!!!!!!!!! - // - // The mappings below indicate the physical order of strips - // connected to a pandaboard channel. The strip numbers are a - // reflection of how the model is built. - // - // For ANYTHING in the model which is a rectangular prism, - // which means Cubes, the BassBox, and each Speaker, the - // strips are numbered incrementally by face. The first - // face is always the FRONT, which you are looking at. - // The next face is the RIGHT, then the BACK, then the LEFT. - // - // For every face, the strips are ordered numerically moving - // clockwise from the the TOP LEFT. - // - // So, for a cube: - // - // Strip 0: front face, top strip, left to right - // Strip 1: front face, right strip, top to bottom - // Strip 2: front face, bottom strip, right to left - // Strip 3: front face, left strip, bottom to top - // - // Strip 4: right face, top strip, left to right - // ... and so on - // Strip 14: left face, bottom strip, right to left - // Strip 15: left face, left strip, bottom to top - // - //////////////////////////////////////////////////////////////// - - private final static int FORWARD = -1; - private final static int BACKWARD = -2; - - /** - * These constant arrays indicate the order in which the strips of a cube - * are wired. There are four different options, depending on which bottom - * corner of the cube the data wire comes in. - */ - private final static int[][] CUBE_STRIP_ORDERINGS = new int[][] { -// { 2, 1, 0, 3, 13, 12, 15, 14, 4, 7, 6, 5, 11, 10, 9, 8 }, // FRONT_LEFT -// { 6, 5, 4, 7, 1, 0, 3, 2, 8, 11, 10, 9, 15, 14, 13, 12 }, // FRONT_RIGHT -// { 14, 13, 12, 15, 9, 8, 11, 10, 0, 3, 2, 1, 7, 6, 5, 4 }, // REAR_LEFT -// { 10, 9, 8, 11, 5, 4, 7, 6, 12, 15, 14, 13, 3, 2, 1, 0 }, // REAR_RIGHT - - - { 2, 1, 0, 3, 13, 12, 15, 14, 4, 7, 6, 5, 11, 10, 9, 8 }, // FRONT_LEFT - { 6, 5, 4, 7, 1, 0, 3, 2, 8, 11, 10, 9, 15, 14, 13, 12 }, // FRONT_RIGHT - { 14, 13, 12, 15, 9, 8, 11, 10, 0, 3, 2, 1, 7, 6, 5, 4 }, // REAR_LEFT - { 9, 8, 11, 5, 4, 7, 6, 10, 14, 2, 1, 0, 3, 13, 12, 15 }, // REAR_RIGHT - - }; - - private final static int[][] BASS_STRIP_ORDERING = { - // front face, counterclockwise from bottom front left - {2, BACKWARD /* if this strip has extra pixels, you can add them here */ /*, 4 */ }, - {1, BACKWARD /* if this strip is short some pixels, substract them here */ /*, -3 */ }, - {0, BACKWARD }, - {3, BACKWARD }, - - // left face, counterclockwise from bottom front left - {13, BACKWARD }, - {12, BACKWARD }, - {15, BACKWARD }, - {14, BACKWARD }, - - // back face, counterclockwise from bottom rear left - {9, BACKWARD }, - {8, BACKWARD }, - {11, BACKWARD }, - {10, BACKWARD }, - - // right face, counterclockwise from bottom rear right - {5, BACKWARD }, - {4, BACKWARD }, - {7, BACKWARD }, - {6, BACKWARD }, - }; - - private final static int[][] STRUT_STRIP_ORDERING = { - {6, BACKWARD}, - {5, FORWARD}, - {4, BACKWARD}, - {3, FORWARD}, - {2, BACKWARD}, - {1, FORWARD}, - {0, BACKWARD}, - {7, FORWARD}, - }; - - private final static int[][] FLOOR_STRIP_ORDERING = { - {0, FORWARD}, - {1, FORWARD}, - {2, FORWARD}, - {3, BACKWARD}, - }; - - // The speakers are currently configured to be wired the same - // as cubes with Wiring.FRONT_LEFT. If this needs to be changed, - // remove this null assignment and change the below to have mappings - // for the LEFT and RIGHT speaker - private final static int[][][] SPEAKER_STRIP_ORDERING = { - // Left speaker - { - // Front face, counter-clockwise from bottom left - {2, BACKWARD }, - {1, BACKWARD }, - {0, BACKWARD }, - {3, BACKWARD }, - }, - // Right speaker - { - // Front face, counter-clockwise from bottom left - {2, BACKWARD }, - {1, BACKWARD }, - {0, BACKWARD }, - {3, BACKWARD }, - } - }; - - public PandaDriver(String ip) { - this.ip = ip; - - // Initialize our OSC output stuff - address = new NetAddress(ip, 9001); - message = new OscMessage("/shady/pointbuffer"); - - // Build the array of points, initialize all to nothing - points = new int[PandaMapping.PIXELS_PER_BOARD]; - for (int i = 0; i < points.length; ++i) { - points[i] = NO_POINT; - } - } - - public PandaDriver(String ip, Model model, PandaMapping pm) { - this(ip); - - // Ok, we are initialized, time to build the array if points in order to - // send out. We start at the head of our point buffer, and work our way - // down. This is the order in which points will be sent down the wire. - int ci = -1; - - // Iterate through all our channels - for (ChannelMapping channel : pm.channelList) { - ++ci; - int pi = ci * ChannelMapping.PIXELS_PER_CHANNEL; - - switch (channel.mode) { - - case ChannelMapping.MODE_CUBES: - // We have a list of cubes per channel - for (int rawCubeIndex : channel.objectIndices) { - if (rawCubeIndex < 0) { - // No cube here, skip ahead in the buffer - pi += Cube.POINTS_PER_CUBE; - } else { - // The cube exists, check which way it is wired to - // figure out the order of strips. - Cube cube = model.getCubeByRawIndex(rawCubeIndex); - int stripOrderIndex = 0; - switch (cube.wiring) { - case FRONT_LEFT: stripOrderIndex = 0; break; - case FRONT_RIGHT: stripOrderIndex = 1; break; - case REAR_LEFT: stripOrderIndex = 2; break; - case REAR_RIGHT: stripOrderIndex = 3; break; - } - - // Iterate through all the strips on the cube and add the points - for (int stripIndex : CUBE_STRIP_ORDERINGS[stripOrderIndex]) { - // We go backwards here... in the model strips go clockwise, but - // the physical wires are run counter-clockwise - pi = mapStrip(cube.strips.get(stripIndex), BACKWARD, points, pi); - } - } - } - break; - - case ChannelMapping.MODE_BASS: - for (int[] config : BASS_STRIP_ORDERING) { - pi = mapStrip(model.bassBox.strips.get(config[0]), config[1], points, pi); - if (config.length >= 3) pi += config[2]; - } - break; - - case ChannelMapping.MODE_STRUTS_AND_FLOOR: - for (int[] config : STRUT_STRIP_ORDERING) { - pi = mapStrip(model.bassBox.struts.get(config[0]), config[1], points, pi); - if (config.length >= 3) pi += config[2]; - } - for (int[] config : FLOOR_STRIP_ORDERING) { - pi = mapStrip(model.boothFloor.strips.get(config[0]), config[1], points, pi); - if (config.length >= 3) pi += config[2]; - } - break; - - case ChannelMapping.MODE_SPEAKER: - int [][] speakerStripOrdering; - if (SPEAKER_STRIP_ORDERING == null) { - // Copy the cube strip ordering - int[] frontLeftCubeWiring = CUBE_STRIP_ORDERINGS[0]; - speakerStripOrdering = new int[frontLeftCubeWiring.length][]; - for (int i = 0; i < frontLeftCubeWiring.length; ++i) { - speakerStripOrdering[i] = new int[] { frontLeftCubeWiring[0], BACKWARD }; - } - } else { - speakerStripOrdering = SPEAKER_STRIP_ORDERING[channel.objectIndices[0]]; - } - for (int[] config : speakerStripOrdering) { - Speaker speaker = model.speakers.get(channel.objectIndices[0]); - pi = mapStrip(speaker.strips.get(config[0]), config[1], points, pi); - if (config.length >= 3) pi += config[2]; - } - break; - - case ChannelMapping.MODE_NULL: - // No problem, nothing on this channel! - break; - - default: - throw new RuntimeException("Invalid/unhandled channel mapping mode: " + channel.mode); - } - - } - } - - private int mapStrip(Strip s, int direction, int[] points, int pi) { - if (direction == FORWARD) { - for (LXPoint p : s.points) { - points[pi++] = p.index; - } - } else if (direction == BACKWARD) { - for (int i = s.points.size()-1; i >= 0; --i) { - points[pi++] = s.points.get(i).index; - } - } else { - throw new RuntimeException("Unidentified strip mapping direction: " + direction); - } - return pi; - } - - public PandaDriver setListener(Listener listener) { - this.listener = listener; - return this; - } - - public void setEnabled(boolean enabled) { - if (this.enabled != enabled) { - this.enabled = enabled; - println("PandaBoard/" + ip + ": " + (enabled ? "ON" : "OFF")); - if (listener != null) { - listener.onToggle(enabled); - } - } - } - - public boolean isEnabled() { - return this.enabled; - } - - public void disable() { - setEnabled(false); - } - - public void enable() { - setEnabled(true); - } - - public void toggle() { - setEnabled(!enabled); - } - - public final void send(int[] colors) { - if (!enabled) { - return; - } - int len = 0; - int packetNum = 0; - for (int index : points) { - int c = (index < 0) ? 0 : colors[index]; - byte r = (byte) ((c >> 16) & 0xFF); - byte g = (byte) ((c >> 8) & 0xFF); - byte b = (byte) ((c) & 0xFF); - packet[len++] = 0; // alpha channel, unused but makes for 4-byte alignment - packet[len++] = r; - packet[len++] = g; - packet[len++] = b; - - // Flush once packet is full buffer size - if (len >= packet.length) { - sendPacket(packetNum++); - len = 0; - } - } - - // Flush any remaining data - if (len > 0) { - sendPacket(packetNum++); - } - } - - - private void sendPacket(int packetNum) { - message.clearArguments(); - message.add(packetNum); - message.add(packet.length); - message.add(packet); - try { - OscP5.flush(message, address); - } catch (Exception x) { - x.printStackTrace(); - } - } -} diff --git a/SamMorrow.pde b/SamMorrow.pde index 350615d..00ed073 100644 --- a/SamMorrow.pde +++ b/SamMorrow.pde @@ -1,13 +1,13 @@ abstract class SamPattern extends SCPattern { - public SamPattern(GLucose glucose) { - super(glucose); + public SamPattern(LX lx) { + super(lx); setEligible(false); } } class JazzRainbow extends SamPattern { - public JazzRainbow(GLucose glucose) { - super(glucose); + public JazzRainbow(LX lx) { + super(lx); } diff --git a/ShaheenGandhi.pde b/ShaheenGandhi.pde index 83b97cf..cda8fed 100644 --- a/ShaheenGandhi.pde +++ b/ShaheenGandhi.pde @@ -183,8 +183,8 @@ class HelixPattern extends SCPattern { private static final float tMin = -200; private static final float tMax = 200; - public HelixPattern(GLucose glucose) { - super(glucose); + public HelixPattern(LX lx) { + super(lx); addParameter(helix1On); addParameter(helix2On); diff --git a/SugarCubes.pde b/SugarCubes.pde index fbaccc3..0afeefe 100644 --- a/SugarCubes.pde +++ b/SugarCubes.pde @@ -15,148 +15,139 @@ * * 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. + * code guts are embedded in the HeronLX library, or files prefixed with + * an underscore. If you're an artist, you shouldn't need to worry about 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. */ - -LXPattern[] patterns(GLucose glucose) { + +LXPattern[] patterns(LX lx) { return new LXPattern[] { - new SineSphere(glucose), - //new CubeCurl(glucose), + new SineSphere(lx), + //new CubeCurl(lx), // Slee - // new Cathedrals(glucose), - new Swarm(glucose), - new MidiMusic(glucose), - new Pulley(glucose), + // new Cathedrals(lx), + new Swarm(lx), + new MidiMusic(lx), + new Pulley(lx), - 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 ViolinWave(lx), + new BouncyBalls(lx), + new SpaceTime(lx), + new ShiftingPlane(lx), + new AskewPlanes(lx), + new Blinders(lx), + new CrossSections(lx), + new Psychedelia(lx), - new MultipleCubes(glucose), + new MultipleCubes(lx), - new Traktor(glucose).setEligible(false), - new BassPod(glucose).setEligible(false), - new CubeEQ(glucose).setEligible(false), - new PianoKeyPattern(glucose).setEligible(false), + new Traktor(lx).setEligible(false), + new BassPod(lx).setEligible(false), + new CubeEQ(lx).setEligible(false), + new PianoKeyPattern(lx).setEligible(false), - // AntonK - new AKPong(glucose), + // AntonK + new AKPong(lx), // DanH - new Noise(glucose), - new Play (glucose), - new Pong (glucose), - new Worms(glucose), + new Noise(lx), + new Play (lx), + new Pong (lx), + new Worms(lx), // JR - new Gimbal(glucose), + new Gimbal(lx), // Alex G - // Tim - new TimMetronome(glucose), - new TimPlanes(glucose), - new TimPinwheels(glucose), - new TimRaindrops(glucose), - new TimCubes(glucose), - // new TimTrace(glucose), - new TimSpheres(glucose), + // Tim + new TimMetronome(lx), + new TimPlanes(lx), + new TimPinwheels(lx), + new TimRaindrops(lx), + new TimCubes(lx), + // new TimTrace(lx), + new TimSpheres(lx), // Jackie - new JackieSquares(glucose), - new JackieLines(glucose), - new JackieDots(glucose), + new JackieSquares(lx), + new JackieLines(lx), + new JackieDots(lx), // L8on - new L8onAutomata(glucose), - new L8onLife(glucose), - new L8onStripLife(glucose), + new L8onAutomata(lx), + new L8onLife(lx), + new L8onStripLife(lx), // Vincent - new VSTowers(glucose), + new VSTowers(lx), // 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), + new GlitchPlasma(lx), + new FireEffect(lx).setEligible(false), + new StripBounce(lx), + new SoundRain(lx).setEligible(false), + new SoundSpikes(lx).setEligible(false), + new FaceSync(lx), // Jack - new Swim(glucose), - new Balance(glucose), - - + new Swim(lx), + new Balance(lx), // Ben - // new Sandbox(glucose), - new TowerParams(glucose), - new DriveableCrossSections(glucose), - new GranimTestPattern2(glucose), + // new Sandbox(lx), + new TowerParams(lx), + new DriveableCrossSections(lx), + new GranimTestPattern2(lx), // Shaheen - //new HelixPattern(glucose).setEligible(false), + // new HelixPattern(lx).setEligible(false), // Sam - new JazzRainbow(glucose), + new JazzRainbow(lx), // Arjun - new TelevisionStatic(glucose), - new AbstractPainting(glucose), - new Spirality(glucose), + new TelevisionStatic(lx), + new AbstractPainting(lx), + new Spirality(lx), // 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 TestHuePattern(glucose), - // new TestXPattern(glucose), - // new TestYPattern(glucose), - // new TestZPattern(glucose), + new TestCubePattern(lx), + new TestTowerPattern(lx), + new TestProjectionPattern(lx), + new TestStripPattern(lx), + // new TestHuePattern(lx), + // new TestXPattern(lx), + // new TestYPattern(lx), + // new TestZPattern(lx), }; } -LXTransition[] transitions(GLucose glucose) { +LXTransition[] transitions(LX lx) { return new LXTransition[] { new DissolveTransition(lx), - new AddTransition(glucose), - new MultiplyTransition(glucose), - new OverlayTransition(glucose), - new DodgeTransition(glucose), - new SwipeTransition(glucose), + new AddTransition(lx), + new MultiplyTransition(lx), + new OverlayTransition(lx), + new DodgeTransition(lx), + new SwipeTransition(lx), 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); + FlashEffect flash = new FlashEffect(lx); + BoomEffect boom = new BoomEffect(lx); + BlurEffect blur = new BlurEffect(lx); + QuantizeEffect quantize = new QuantizeEffect(lx); + ColorFuckerEffect colorFucker = new ColorFuckerEffect(lx); Effects() { blur.enable(); diff --git a/SugarCubes.pde.orig b/SugarCubes.pde.orig deleted file mode 100644 index e989980..0000000 --- a/SugarCubes.pde.orig +++ /dev/null @@ -1,148 +0,0 @@ -/** - * +-+-+-+-+-+ +-+-+-+-+-+ - * / /| |\ \ - * / / + + \ \ - * +-+-+-+-+-+ | +-+-+-+-+ | +-+-+-+-+-+ - * | | + / \ + | | - * + 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. - */ - -LXPattern[] patterns(GLucose glucose) { - return new LXPattern[] { - -<<<<<<< HEAD - new SineSphere(glucose), - new CubeCurl(glucose), -======= ->>>>>>> b8bb27489db7dc687bf150576e9d9439f1fa17a6 - // 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 - - - // 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 TestHuePattern(glucose), - // new TestXPattern(glucose), - // new TestYPattern(glucose), - // new TestZPattern(glucose), - - }; -} - -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(); - } -} - diff --git a/TestPatterns.pde b/TestPatterns.pde index 6a662f2..728683e 100644 --- a/TestPatterns.pde +++ b/TestPatterns.pde @@ -1,6 +1,6 @@ class BlankPattern extends SCPattern { - BlankPattern(GLucose glucose) { - super(glucose); + BlankPattern(LX lx) { + super(lx); } public void run(double deltaMs) { @@ -9,87 +9,18 @@ class BlankPattern extends SCPattern { } abstract class TestPattern extends SCPattern { - public TestPattern(GLucose glucose) { - super(glucose); + public TestPattern(LX lx) { + super(lx); 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 (LXPoint 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 (LXPoint 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 (LXPoint 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 (LXPoint p : model.boothFloor.strips.get(fi).points) { - colors[p.index] = lx.hsb(h, 100, b); - b = max(0, b - 3); - } - h += 90; - } - } -} - class TestStripPattern extends TestPattern { SinLFO d = new SinLFO(4, 40, 4000); - public TestStripPattern(GLucose glucose) { - super(glucose); + public TestStripPattern(LX lx) { + super(lx); addModulator(d).trigger(); } @@ -111,8 +42,8 @@ class TestStripPattern extends TestPattern { * All pixels are full-on the same color. */ class TestHuePattern extends TestPattern { - public TestHuePattern(GLucose glucose) { - super(glucose); + public TestHuePattern(LX lx) { + super(lx); } public void run(double deltaMs) { @@ -129,8 +60,8 @@ class TestHuePattern extends TestPattern { */ class TestXPattern extends TestPattern { private final SinLFO xPos = new SinLFO(0, model.xMax, 4000); - public TestXPattern(GLucose glucose) { - super(glucose); + public TestXPattern(LX lx) { + super(lx); addModulator(xPos).trigger(); } public void run(double deltaMs) { @@ -151,8 +82,8 @@ class TestXPattern extends TestPattern { */ class TestYPattern extends TestPattern { private final SinLFO yPos = new SinLFO(0, model.yMax, 4000); - public TestYPattern(GLucose glucose) { - super(glucose); + public TestYPattern(LX lx) { + super(lx); addModulator(yPos).trigger(); } public void run(double deltaMs) { @@ -169,8 +100,8 @@ class TestYPattern extends TestPattern { */ class TestZPattern extends TestPattern { private final SinLFO zPos = new SinLFO(0, model.zMax, 4000); - public TestZPattern(GLucose glucose) { - super(glucose); + public TestZPattern(LX lx) { + super(lx); addModulator(zPos).trigger(); } public void run(double deltaMs) { @@ -188,8 +119,8 @@ class TestZPattern extends TestPattern { class TestTowerPattern extends TestPattern { private final SawLFO towerIndex = new SawLFO(0, model.towers.size(), 1000*model.towers.size()); - public TestTowerPattern(GLucose glucose) { - super(glucose); + public TestTowerPattern(LX lx) { + super(lx); addModulator(towerIndex).trigger(); } @@ -233,8 +164,8 @@ class TestProjectionPattern extends TestPattern { 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); + public TestProjectionPattern(LX lx) { + super(lx); projection = new LXProjection(model); addModulator(angle).trigger(); addModulator(yPos).trigger(); @@ -273,8 +204,8 @@ class TestCubePattern extends TestPattern { private SawLFO index = new SawLFO(0, Cube.POINTS_PER_CUBE, Cube.POINTS_PER_CUBE*60); - TestCubePattern(GLucose glucose) { - super(glucose); + TestCubePattern(LX lx) { + super(lx); addModulator(index).start(); } @@ -314,15 +245,11 @@ class MappingTool extends TestPattern { 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; + + MappingTool(LX lx) { + super(lx); + // TODO(mcslee): port channels to grizzly + numChannels = 1; setChannel(); } @@ -331,21 +258,12 @@ class MappingTool extends TestPattern { } private void setChannel() { - activePanda = pandaMappings[channelIndex / PandaMapping.CHANNELS_PER_BOARD]; - activeChannel = activePanda.channelList[channelIndex % PandaMapping.CHANNELS_PER_BOARD]; + // TODO(mcslee): port to grizzly } 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; + // TODO(mcslee): port to grizzly + return -1; } private void printInfo() { @@ -440,7 +358,9 @@ class MappingTool extends TestPattern { } public void setChannel(int index) { - channelIndex = index % numChannels; + if (numChannels > 0) { + channelIndex = index % numChannels; + } setChannel(); } diff --git a/TimBavaro.pde b/TimBavaro.pde index 3fcd5b1..2ca73d7 100644 --- a/TimBavaro.pde +++ b/TimBavaro.pde @@ -16,8 +16,8 @@ class TimSpheres extends SCPattern { private final Sphere[] spheres; - public TimSpheres(GLucose glucose) { - super(glucose); + public TimSpheres(LX lx) { + super(lx); addParameter(hueParameter); addParameter(periodParameter); addModulator(lfo).trigger(); @@ -236,8 +236,8 @@ class TimRaindrops extends SCPattern { private float msPerRaindrop = 40; private List raindrops; - public TimRaindrops(GLucose glucose) { - super(glucose); + public TimRaindrops(LX lx) { + super(lx); raindrops = new LinkedList(); } @@ -320,8 +320,8 @@ class TimCubes extends SCPattern { private float leftoverMs = 0; private List flashes; - public TimCubes(GLucose glucose) { - super(glucose); + public TimCubes(LX lx) { + super(lx); addParameter(rateParameter); addParameter(attackParameter); addParameter(decayParameter); @@ -397,8 +397,8 @@ class TimPlanes extends SCPattern { } } - TimPlanes(GLucose glucose) { - super(glucose); + TimPlanes(LX lx) { + super(lx); centerX = (model.xMin + model.xMax) / 2; centerY = (model.yMin + model.yMax) / 2; centerZ = (model.zMin + model.zMax) / 2; @@ -560,8 +560,8 @@ class TimPinwheels extends SCPattern { private final List pinwheels; private final float[] values; - TimPinwheels(GLucose glucose) { - super(glucose); + TimPinwheels(LX lx) { + super(lx); addParameter(horizSpreadParameter); // addParameter(vertSpreadParameter); @@ -727,8 +727,8 @@ class TimTrace extends SCPattern { List movingPoints; - TimTrace(GLucose glucose) { - super(glucose); + TimTrace(LX lx) { + super(lx); extraMs = 0; @@ -843,8 +843,8 @@ class TimMetronome extends SCPattern { private float[] values; private float[] hues; - TimMetronome(GLucose glucose) { - super(glucose); + TimMetronome(LX lx) { + super(lx); addParameter(clickyParameter); addParameter(derezParameter); addParameter(driftParameter); diff --git a/TobySegaran.pde b/TobySegaran.pde index 8aaacb1..8769b10 100644 --- a/TobySegaran.pde +++ b/TobySegaran.pde @@ -7,8 +7,8 @@ class GlitchPlasma extends SCPattern { BasicParameter speedParameter = new BasicParameter("SPEED", 0.1); BasicParameter glitchParameter = new BasicParameter("GLITCH", 0.0); - public GlitchPlasma(GLucose glucose) { - super(glucose); + public GlitchPlasma(LX lx) { + super(lx); addParameter(saturationParameter); addParameter(speedParameter); addParameter(glitchParameter); @@ -49,8 +49,8 @@ class FireEffect extends SCPattern { private int ym; BasicParameter decayParameter = new BasicParameter("DECAY", 0.3); - public FireEffect(GLucose glucose) { - super(glucose); + public FireEffect(LX lx) { + super(lx); xm = int(model.xMax); ym = int(model.yMax); @@ -97,8 +97,8 @@ class StripBounce extends SCPattern { SinLFO[] sat = new SinLFO[numOsc]; float[] colorOffset = new float[numOsc]; - public StripBounce(GLucose glucose) { - super(glucose); + public StripBounce(LX lx) { + super(lx); for (int i=0;i children = new ArrayList(); - - protected boolean needsRedraw = true; - protected boolean childNeedsRedraw = true; - - protected float x=0, y=0, w=0, h=0; - - public UIContainer parent = null; - - protected boolean visible = true; - - public UIObject() {} - - public UIObject(float x, float y, float w, float h) { - this.x = x; - this.y = y; - this.w = w; - this.h = h; - } - - public boolean isVisible() { - return visible; - } - - public UIObject setVisible(boolean visible) { - if (visible != this.visible) { - this.visible = visible; - redraw(); - } - return this; - } - - public final UIObject setPosition(float x, float y) { - this.x = x; - this.y = y; - redraw(); - return this; - } - - public final UIObject setSize(float w, float h) { - this.w = w; - this.h = h; - redraw(); - return this; - } - - public final UIObject addToContainer(UIContainer c) { - c.children.add(this); - this.parent = c; - return this; - } - - public final UIObject removeFromContainer(UIContainer c) { - c.children.remove(this); - this.parent = null; - return this; - } - - public final UIObject redraw() { - _redraw(); - UIObject p = this.parent; - while (p != null) { - p.childNeedsRedraw = true; - p = p.parent; - } - return this; - } - - private final void _redraw() { - needsRedraw = true; - for (UIObject child : children) { - childNeedsRedraw = true; - child._redraw(); - } - } - - public final void draw(PGraphics pg) { - if (!visible) { - return; - } - if (needsRedraw) { - needsRedraw = false; - onDraw(pg); - } - if (childNeedsRedraw) { - childNeedsRedraw = false; - for (UIObject child : children) { - if (needsRedraw || child.needsRedraw || child.childNeedsRedraw) { - pg.pushMatrix(); - pg.translate(child.x, child.y); - child.draw(pg); - pg.popMatrix(); - } - } - } - } - - public final boolean contains(float x, float y) { - return - (x >= this.x && x < (this.x + this.w)) && - (y >= this.y && y < (this.y + this.h)); - } - - protected void onDraw(PGraphics pg) {} - protected void onMousePressed(float mx, float my) {} - protected void onMouseReleased(float mx, float my) {} - protected void onMouseDragged(float mx, float my, float dx, float dy) {} - protected void onMouseWheel(float mx, float my, float dx) {} -} - -public class UIContainer extends UIObject { - - private UIObject focusedChild = null; - - public UIContainer() {} - - public UIContainer(float x, float y, float w, float h) { - super(x, y, w, h); - } - - public UIContainer(UIObject[] children) { - for (UIObject child : children) { - child.addToContainer(this); - } - } - - protected void onMousePressed(float mx, float my) { - for (int i = children.size() - 1; i >= 0; --i) { - UIObject child = children.get(i); - if (child.contains(mx, my)) { - child.onMousePressed(mx - child.x, my - child.y); - focusedChild = child; - break; - } - } - } - - protected void onMouseReleased(float mx, float my) { - if (focusedChild != null) { - focusedChild.onMouseReleased(mx - focusedChild.x, my - focusedChild.y); - } - focusedChild = null; - } - - protected void onMouseDragged(float mx, float my, float dx, float dy) { - if (focusedChild != null) { - focusedChild.onMouseDragged(mx - focusedChild.x, my - focusedChild.y, dx, dy); - } - } - - protected void onMouseWheel(float mx, float my, float delta) { - for (UIObject child : children) { - if (child.contains(mx, my)) { - child.onMouseWheel(mx - child.x, mx - child.y, delta); - } - } - } - -} - -public class UIContext extends UIContainer { - - final public PGraphics pg; - - UIContext(float x, float y, float w, float h) { - super(x, y, w, h); - pg = createGraphics((int)w, (int)h, JAVA2D); - pg.smooth(); - } - - public void draw() { - if (!visible) { - return; - } - if (needsRedraw || childNeedsRedraw) { - pg.beginDraw(); - draw(pg); - pg.endDraw(); - } - image(pg, x, y); - } - - private float px, py; - private boolean dragging = false; - - public boolean mousePressed(float mx, float my) { - if (!visible) { - return false; - } - if (contains(mx, my)) { - dragging = true; - px = mx; - py = my; - onMousePressed(mx - x, my - y); - return true; - } - return false; - } - - public boolean mouseReleased(float mx, float my) { - if (!visible) { - return false; - } - dragging = false; - onMouseReleased(mx - x, my - y); - return true; - } - - public boolean mouseDragged(float mx, float my) { - if (!visible) { - return false; - } - if (dragging) { - float dx = mx - px; - float dy = my - py; - onMouseDragged(mx - x, my - y, dx, dy); - px = mx; - py = my; - return true; - } - return false; - } - - public boolean mouseWheel(float mx, float my, float delta) { - if (!visible) { - return false; - } - if (contains(mx, my)) { - onMouseWheel(mx - x, my - y, delta); - return true; - } - return false; - } -} - -public class UIWindow extends UIContext { - - protected final static int titleHeight = 24; - - public UIWindow(String label, float x, float y, float w, float h) { - super(x, y, w, h); - new UILabel(6, 8, w-6, titleHeight-8) { - protected void onMouseDragged(float mx, float my, float dx, float dy) { - parent.x = constrain(parent.x + dx, 0, width - w); - parent.y = constrain(parent.y + dy, 0, height - h); - } - }.setLabel(label).setFont(defaultTitleFont).addToContainer(this); - } - - protected void onDraw(PGraphics pg) { - pg.noStroke(); - pg.fill(#444444); - pg.stroke(#292929); - pg.rect(0, 0, w-1, h-1); - } -} - -public class UILabel extends UIObject { - - private PFont font = defaultTitleFont; - private color fontColor = #CCCCCC; - private String label = ""; - - public UILabel(float x, float y, float w, float h) { - super(x, y, w, h); - } - - protected void onDraw(PGraphics pg) { - pg.textAlign(LEFT, TOP); - pg.textFont(font); - pg.fill(fontColor); - pg.text(label, 0, 0); - } - - public UILabel setFont(PFont font) { - this.font = font; - redraw(); - return this; - } - - public UILabel setFontColor(color fontColor) { - this.fontColor = fontColor; - redraw(); - return this; - } - - public UILabel setLabel(String label) { - this.label = label; - redraw(); - return this; - } -} - -public class UICheckbox extends UIButton { - - private boolean firstDraw = true; - - public UICheckbox(float x, float y, float w, float h) { - super(x, y, w, h); - setMomentary(false); - } - - public void onDraw(PGraphics pg) { - pg.stroke(borderColor); - pg.fill(active ? activeColor : inactiveColor); - pg.rect(0, 0, h, h); - if (firstDraw) { - pg.fill(labelColor); - pg.textFont(defaultItemFont); - pg.textAlign(LEFT, CENTER); - pg.text(label, h + 4, h/2); - firstDraw = false; - } - } - -} - -public class UIButton extends UIObject { - - protected boolean active = false; - protected boolean isMomentary = false; - protected color borderColor = #666666; - protected color inactiveColor = #222222; - protected color activeColor = #669966; - protected color labelColor = #999999; - protected String label = ""; - - public UIButton(float x, float y, float w, float h) { - super(x, y, w, h); - } - - public UIButton setMomentary(boolean momentary) { - isMomentary = momentary; - return this; - } - - protected void onDraw(PGraphics pg) { - pg.stroke(borderColor); - pg.fill(active ? activeColor : inactiveColor); - pg.rect(0, 0, w, h); - if (label != null && label.length() > 0) { - pg.fill(active ? #FFFFFF : labelColor); - pg.textFont(defaultItemFont); - pg.textAlign(CENTER); - pg.text(label, w/2, h-5); - } - } - - protected void onMousePressed(float mx, float my) { - if (isMomentary) { - setActive(true); - } else { - setActive(!active); - } - } - - protected void onMouseReleased(float mx, float my) { - if (isMomentary) { - setActive(false); - } - } - - public boolean isActive() { - return active; - } - - public UIButton setActive(boolean active) { - this.active = active; - onToggle(active); - redraw(); - return this; - } - - public UIButton toggle() { - return setActive(!active); - } - - protected void onToggle(boolean active) {} - - public UIButton setBorderColor(color borderColor) { - if (this.borderColor != borderColor) { - this.borderColor = borderColor; - redraw(); - } - return this; - } - - public UIButton setActiveColor(color activeColor) { - if (this.activeColor != activeColor) { - this.activeColor = activeColor; - if (active) { - redraw(); - } - } - return this; - } - - public UIButton setInactiveColor(color inactiveColor) { - if (this.inactiveColor != inactiveColor) { - this.inactiveColor = inactiveColor; - if (!active) { - redraw(); - } - } - return this; - } - - public UIButton setLabelColor(color labelColor) { - if (this.labelColor != labelColor) { - this.labelColor = labelColor; - redraw(); - } - return this; - } - - public UIButton setLabel(String label) { - if (!this.label.equals(label)) { - this.label = label; - redraw(); - } - return this; - } - - public void onMousePressed() { - setActive(!active); - } -} - -public class UIToggleSet extends UIObject { - - private String[] options; - private int[] boundaries; - private String value; - - public UIToggleSet(float x, float y, float w, float h) { - super(x, y, w, h); - } - - public UIToggleSet setOptions(String[] options) { - this.options = options; - boundaries = new int[options.length]; - int totalLength = 0; - for (String s : options) { - totalLength += s.length(); - } - int lengthSoFar = 0; - for (int i = 0; i < options.length; ++i) { - lengthSoFar += options[i].length(); - boundaries[i] = (int) (lengthSoFar * w / totalLength); - } - value = options[0]; - redraw(); - return this; - } - - public String getValue() { - return value; - } - - public UIToggleSet setValue(String option) { - value = option; - onToggle(value); - redraw(); - return this; - } - - public void onDraw(PGraphics pg) { - pg.stroke(#666666); - pg.fill(#222222); - pg.rect(0, 0, w, h); - for (int b : boundaries) { - pg.line(b, 1, b, h-1); - } - pg.noStroke(); - pg.textAlign(CENTER); - pg.textFont(defaultItemFont); - int leftBoundary = 0; - - for (int i = 0; i < options.length; ++i) { - boolean isActive = options[i] == value; - if (isActive) { - pg.fill(lightGreen); - pg.rect(leftBoundary + 1, 1, boundaries[i] - leftBoundary - 1, h-1); - } - pg.fill(isActive ? #FFFFFF : #999999); - pg.text(options[i], (leftBoundary + boundaries[i]) / 2., h-6); - leftBoundary = boundaries[i]; - } - } - - public void onMousePressed(float mx, float my) { - for (int i = 0; i < boundaries.length; ++i) { - if (mx < boundaries[i]) { - setValue(options[i]); - break; - } - } - } - - protected void onToggle(String option) {} - -} - - -public abstract class UIParameterControl extends UIObject implements LXParameterListener { - protected LXParameter parameter = null; - - protected UIParameterControl(float x, float y, float w, float h) { - super(x, y, w, h); - } - - public void onParameterChanged(LXParameter parameter) { - redraw(); - } - - protected float getNormalized() { - if (parameter != null) { - if (parameter instanceof BasicParameter) { - return ((BasicParameter)parameter).getNormalizedf(); - } - return parameter.getValuef(); - } - return 0; - } - - protected UIParameterControl setNormalized(float value) { - if (parameter != null) { - if (parameter instanceof BasicParameter) { - ((BasicParameter)parameter).setNormalized(value); - } else { - parameter.setValue(value); - } - } - return this; - } - - public UIParameterControl setParameter(LXParameter parameter) { - if (this.parameter != null) { - if (this.parameter instanceof LXListenableParameter) { - ((LXListenableParameter)this.parameter).removeListener(this); - } - } - this.parameter = parameter; - if (this.parameter != null) { - if (this.parameter instanceof LXListenableParameter) { - ((LXListenableParameter)this.parameter).addListener(this); - } - } - redraw(); - return this; - } -} - -public class UIParameterKnob extends UIParameterControl { - private int knobSize = 28; - private final float knobIndent = .4; - private final int knobLabelHeight = 14; - private boolean showValue = false; - - public UIParameterKnob(float x, float y) { - this(x, y, 0, 0); - setSize(knobSize, knobSize + knobLabelHeight); - } - - public UIParameterKnob(float x, float y, float w, float h) { - super(x, y, w, h); - } - - protected void onDraw(PGraphics pg) { - float knobValue = getNormalized(); - - pg.ellipseMode(CENTER); - pg.noStroke(); - - pg.fill(bgGray); - pg.rect(0, 0, knobSize, knobSize); - - // Full outer dark ring - pg.fill(#222222); - pg.arc(knobSize/2, knobSize/2, knobSize, knobSize, HALF_PI + knobIndent, HALF_PI + knobIndent + (TWO_PI-2*knobIndent)); - - // Light ring indicating value - pg.fill(lightGreen); - pg.arc(knobSize/2, knobSize/2, knobSize, knobSize, HALF_PI + knobIndent, HALF_PI + knobIndent + knobValue*(TWO_PI-2*knobIndent)); - - // Center circle of knob - pg.fill(#333333); - pg.ellipse(knobSize/2, knobSize/2, knobSize/2, knobSize/2); - - String knobLabel; - if (showValue) { - knobLabel = (parameter != null) ? ("" + parameter.getValue()) : null; - } else { - knobLabel = (parameter != null) ? parameter.getLabel() : null; - } - if (knobLabel == null) { - knobLabel = "-"; - } else if (knobLabel.length() > 4) { - knobLabel = knobLabel.substring(0, 4); - } - pg.fill(#000000); - pg.rect(0, knobSize + 2, knobSize, knobLabelHeight - 2); - pg.fill(#999999); - pg.textAlign(CENTER); - pg.textFont(defaultTitleFont); - pg.text(knobLabel, knobSize/2, knobSize + knobLabelHeight - 2); - } - - private long lastMousePress = 0; - public void onMousePressed(float mx, float my) { - super.onMousePressed(mx, my); - long now = millis(); - if (now - lastMousePress < DOUBLE_CLICK_THRESHOLD) { - parameter.reset(); - lastMousePress = 0; - } else { - lastMousePress = now; - } - showValue = true; - redraw(); - } - - public void onMouseReleased(float mx, float my) { - showValue = false; - redraw(); - } - - public void onMouseDragged(float mx, float my, float dx, float dy) { - float value = constrain(getNormalized() - dy / 100., 0, 1); - setNormalized(value); - } -} - -public class UIParameterSlider extends UIParameterControl { - - private static final float handleWidth = 12; - - UIParameterSlider(float x, float y, float w, float h) { - super(x, y, w, h); - } - - protected void onDraw(PGraphics pg) { - pg.noStroke(); - pg.fill(#333333); - pg.rect(0, 0, w, h); - pg.fill(#222222); - pg.rect(4, h/2-2, w-8, 4); - pg.fill(#666666); - pg.stroke(#222222); - pg.rect((int) (4 + parameter.getValuef() * (w-8-handleWidth)), 4, handleWidth, h-8); - } - - private boolean editing = false; - private long lastClick = 0; - private float doubleClickMode = 0; - private float doubleClickX = 0; - protected void onMousePressed(float mx, float my) { - long now = millis(); - float handleLeft = 4 + getNormalized() * (w-8-handleWidth); - if (mx >= handleLeft && mx < handleLeft + handleWidth) { - editing = true; - } else { - if ((now - lastClick) < DOUBLE_CLICK_THRESHOLD && abs(mx - doubleClickX) < 3) { - setNormalized(doubleClickMode); - } - doubleClickX = mx; - if (mx < w*.25) { - doubleClickMode = 0; - } else if (mx > w*.75) { - doubleClickMode = 1; - } else { - doubleClickMode = 0.5; - } - } - lastClick = now; - } - - protected void onMouseReleased(float mx, float my) { - editing = false; - } - - protected void onMouseDragged(float mx, float my, float dx, float dy) { - if (editing) { - setNormalized(constrain((mx - handleWidth/2. - 4) / (w-8-handleWidth), 0, 1)); - } - } -} - -public class UIScrollList extends UIObject { - - private List items = new ArrayList(); - - private PFont itemFont = defaultItemFont; - private int itemHeight = 20; - private color selectedColor = lightGreen; - private color pendingColor = lightBlue; - private int scrollOffset = 0; - private int numVisibleItems = 0; - - private boolean hasScroll; - private float scrollYStart; - private float scrollYHeight; - - public UIScrollList(float x, float y, float w, float h) { - super(x, y, w, h); - } - - protected void onDraw(PGraphics pg) { - int yp = 0; - boolean even = true; - for (int i = 0; i < numVisibleItems; ++i) { - if (i + scrollOffset >= items.size()) { - break; - } - ScrollItem item = items.get(i + scrollOffset); - color itemColor; - color labelColor = #FFFFFF; - if (item.isSelected()) { - itemColor = selectedColor; - } else if (item.isPending()) { - itemColor = pendingColor; - } else { - labelColor = #000000; - itemColor = #707070; - } - float factor = even ? .92 : 1.08; - itemColor = lx.scaleBrightness(itemColor, factor); - - pg.noStroke(); - pg.fill(itemColor); - pg.rect(0, yp, w, itemHeight); - pg.fill(labelColor); - pg.textFont(itemFont); - pg.textAlign(LEFT, TOP); - pg.text(item.getLabel(), 6, yp+4); - - yp += itemHeight; - even = !even; - } - if (hasScroll) { - pg.noStroke(); - pg.fill(0x26ffffff); - pg.rect(w-12, 0, 12, h); - pg.fill(#333333); - pg.rect(w-12, scrollYStart, 12, scrollYHeight); - } - - } - - private boolean scrolling = false; - private ScrollItem pressedItem = null; - - public void onMousePressed(float mx, float my) { - pressedItem = null; - if (hasScroll && mx >= w-12) { - if (my >= scrollYStart && my < (scrollYStart + scrollYHeight)) { - scrolling = true; - dAccum = 0; - } - } else { - int index = (int) my / itemHeight; - if (scrollOffset + index < items.size()) { - pressedItem = items.get(scrollOffset + index); - pressedItem.onMousePressed(); - redraw(); - } - } - } - - public void onMouseReleased(float mx, float my) { - scrolling = false; - if (pressedItem != null) { - pressedItem.onMouseReleased(); - redraw(); - } - } - - private float dAccum = 0; - public void onMouseDragged(float mx, float my, float dx, float dy) { - if (scrolling) { - dAccum += dy; - float scrollOne = h / items.size(); - int offset = (int) (dAccum / scrollOne); - if (offset != 0) { - dAccum -= offset * scrollOne; - setScrollOffset(scrollOffset + offset); - } - } - } - - private float wAccum = 0; - public void onMouseWheel(float mx, float my, float delta) { - wAccum += delta; - int offset = (int) (wAccum / 5); - if (offset != 0) { - wAccum -= offset * 5; - setScrollOffset(scrollOffset + offset); - } - } - - public void setScrollOffset(int offset) { - scrollOffset = constrain(offset, 0, max(0, items.size() - numVisibleItems)); - scrollYStart = round(scrollOffset * h / items.size()); - scrollYHeight = round(numVisibleItems * h / items.size()); - redraw(); - } - - public UIScrollList setItems(List items) { - this.items = items; - numVisibleItems = (int) (h / itemHeight); - hasScroll = items.size() > numVisibleItems; - setScrollOffset(0); - redraw(); - return this; - } -} - -public interface ScrollItem { - public boolean isSelected(); - public boolean isPending(); - public String getLabel(); - public void onMousePressed(); - public void onMouseReleased(); -} - -public abstract class AbstractScrollItem implements ScrollItem { - public boolean isPending() { - return false; - } - public void select() {} - public void onMousePressed() {} - public void onMouseReleased() {} -} - -public class UIIntegerBox extends UIObject { - - private int minValue = 0; - private int maxValue = MAX_INT; - private int value = 0; - - UIIntegerBox(float x, float y, float w, float h) { - super(x, y, w, h); - } - - public UIIntegerBox setRange(int minValue, int maxValue) { - this.minValue = minValue; - this.maxValue = maxValue; - setValue(constrain(value, minValue, maxValue)); - return this; - } - - protected void onDraw(PGraphics pg) { - pg.stroke(#666666); - pg.fill(#222222); - pg.rect(0, 0, w, h); - pg.textAlign(CENTER, CENTER); - pg.textFont(defaultItemFont); - pg.fill(#999999); - pg.text("" + value, w/2, h/2); - } - - protected void onValueChange(int value) {} - - float dAccum = 0; - protected void onMousePressed(float mx, float my) { - dAccum = 0; - } - - protected void onMouseDragged(float mx, float my, float dx, float dy) { - dAccum -= dy; - int offset = (int) (dAccum / 5); - dAccum = dAccum - (offset * 5); - setValue(value + offset); - } - - public int getValue() { - return value; - } - - public UIIntegerBox setValue(int value) { - if (this.value != value) { - int range = (maxValue - minValue + 1); - while (value < minValue) { - value += range; - } - this.value = minValue + (value - minValue) % range; - this.onValueChange(this.value); - redraw(); - } - return this; - } -} diff --git a/UIImplementation.pde b/UIImplementation.pde index 0ea8073..7750ab9 100644 --- a/UIImplementation.pde +++ b/UIImplementation.pde @@ -10,106 +10,130 @@ * * Custom UI components using the framework. */ - -class UIPatternDeck extends UIWindow { - - LXDeck deck; - - public UIPatternDeck(LXDeck deck, String label, float x, float y, float w, float h) { - super(label, x, y, w, h); - this.deck = deck; - int yp = titleHeight; - - List items = new ArrayList(); - for (LXPattern p : deck.getPatterns()) { - items.add(new PatternScrollItem(p)); - } - final UIScrollList patternList = new UIScrollList(1, yp, w-2, 140).setItems(items); - patternList.addToContainer(this); - yp += patternList.h + 10; - - final UIParameterKnob[] parameterKnobs = new UIParameterKnob[12]; - for (int ki = 0; ki < parameterKnobs.length; ++ki) { - parameterKnobs[ki] = new UIParameterKnob(5 + 34*(ki % 4), yp + (ki/4) * 48); - parameterKnobs[ki].addToContainer(this); +import java.util.Arrays; +class UICubesLayer extends UICameraComponent { + void onDraw(UI ui) { + color[] simulationColors = lx.getColors(); + String displayMode = uiCrossfader.getDisplayMode(); + if (displayMode == "A") { + simulationColors = lx.engine.getDeck(LEFT_DECK).getColors(); + } else if (displayMode == "B") { + simulationColors = lx.engine.getDeck(RIGHT_DECK).getColors(); } + + long simulationStart = System.nanoTime(); + if (simulationOn) { + drawSimulation(simulationColors); + } + simulationNanos = System.nanoTime() - simulationStart; - LXDeck.Listener lxListener = new LXDeck.AbstractListener() { - public void patternWillChange(LXDeck deck, LXPattern pattern, LXPattern nextPattern) { - patternList.redraw(); - } - public void patternDidChange(LXDeck deck, LXPattern pattern) { - patternList.redraw(); - int pi = 0; - for (LXParameter parameter : pattern.getParameters()) { - if (pi >= parameterKnobs.length) { - break; - } - parameterKnobs[pi++].setParameter(parameter); - } - while (pi < parameterKnobs.length) { - parameterKnobs[pi++].setParameter(null); - } - } - }; - - deck.addListener(lxListener); - lxListener.patternDidChange(deck, deck.getActivePattern()); - + camera(); + PGraphicsOpenGL gl = (PGraphicsOpenGL) g; + strokeWeight(1); } - class PatternScrollItem extends AbstractScrollItem { - - private LXPattern pattern; - private String label; - - PatternScrollItem(LXPattern pattern) { - this.pattern = pattern; - label = className(pattern, "Pattern"); - } - - public String getLabel() { - return label; - } - - public boolean isSelected() { - return deck.getActivePattern() == pattern; - } + void drawSimulation(color[] simulationColors) { + translate(0, 30, 0); + + noStroke(); + fill(#141414); + drawBox(0, -TRAILER_HEIGHT, 0, 0, 0, 0, TRAILER_WIDTH, TRAILER_HEIGHT, TRAILER_DEPTH, TRAILER_HEIGHT/2.); + fill(#070707); + stroke(#222222); + beginShape(); + vertex(0, 0, 0); + vertex(TRAILER_WIDTH, 0, 0); + vertex(TRAILER_WIDTH, 0, TRAILER_DEPTH); + vertex(0, 0, TRAILER_DEPTH); + endShape(); + + // Draw the logo on the front of platform + pushMatrix(); + translate(0, 0, -1); + float s = .07; + scale(s, -s, s); + image(logo, TRAILER_WIDTH/2/s-logo.width/2, TRAILER_HEIGHT/2/s-logo.height/2-2/s); + popMatrix(); - public boolean isPending() { - return deck.getNextPattern() == pattern; + noStroke(); + for (Cube c : model.cubes) { + drawCube(c); } - - public void onMousePressed() { - deck.goPattern(pattern); + + noFill(); + strokeWeight(2); + beginShape(POINTS); + for (LXPoint p : model.points) { + stroke(simulationColors[p.index]); + vertex(p.x, p.y, p.z); + } + endShape(); + } + + void drawCube(Cube c) { + float in = .15; + noStroke(); + fill(#393939); + drawBox(c.x+in, c.y+in, c.z+in, c.rx, c.ry, c.rz, Cube.EDGE_WIDTH-in*2, Cube.EDGE_HEIGHT-in*2, Cube.EDGE_WIDTH-in*2, Cube.CHANNEL_WIDTH-in); + } + + void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) { + pushMatrix(); + translate(x, y, z); + rotate(rx / 180. * PI, -1, 0, 0); + rotate(ry / 180. * PI, 0, -1, 0); + rotate(rz / 180. * PI, 0, 0, -1); + for (int i = 0; i < 4; ++i) { + float wid = (i % 2 == 0) ? xd : zd; + + beginShape(); + vertex(0, 0); + vertex(wid, 0); + vertex(wid, yd); + vertex(wid - sw, yd); + vertex(wid - sw, sw); + vertex(0, sw); + endShape(); + beginShape(); + vertex(0, sw); + vertex(0, yd); + vertex(wid - sw, yd); + vertex(wid - sw, yd - sw); + vertex(sw, yd - sw); + vertex(sw, sw); + endShape(); + + translate(wid, 0, 0); + rotate(HALF_PI, 0, -1, 0); } + popMatrix(); } } class UIBlendMode extends UIWindow { public UIBlendMode(float x, float y, float w, float h) { - super("BLEND MODE", x, y, w, h); - List items = new ArrayList(); - for (LXTransition t : glucose.getTransitions()) { + super(lx.ui, "BLEND MODE", x, y, w, h); + List items = new ArrayList(); + for (LXTransition t : transitions) { items.add(new TransitionScrollItem(t)); } final UIScrollList tList; - (tList = new UIScrollList(1, titleHeight, w-2, 60)).setItems(items).addToContainer(this); + (tList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 60)).setItems(items).addToContainer(this); - lx.engine.getDeck(GLucose.RIGHT_DECK).addListener(new LXDeck.AbstractListener() { + lx.engine.getDeck(RIGHT_DECK).addListener(new LXDeck.AbstractListener() { public void faderTransitionDidChange(LXDeck deck, LXTransition transition) { tList.redraw(); } }); } - class TransitionScrollItem extends AbstractScrollItem { + class TransitionScrollItem extends UIScrollList.AbstractItem { private final LXTransition transition; - private String label; + private final String label; TransitionScrollItem(LXTransition transition) { this.transition = transition; - label = className(transition, "Transition"); + this.label = className(transition, "Transition"); } public String getLabel() { @@ -117,7 +141,7 @@ class UIBlendMode extends UIWindow { } public boolean isSelected() { - return transition == glucose.getSelectedTransition(); + return this.transition == lx.engine.getDeck(RIGHT_DECK).getFaderTransition(); } public boolean isPending() { @@ -125,7 +149,7 @@ class UIBlendMode extends UIWindow { } public void onMousePressed() { - glucose.setSelectedTransition(transition); + lx.engine.getDeck(RIGHT_DECK).setFaderTransition(this.transition); } } @@ -136,10 +160,10 @@ class UICrossfader extends UIWindow { private final UIToggleSet displayMode; public UICrossfader(float x, float y, float w, float h) { - super("CROSSFADER", x, y, w, h); + super(lx.ui, "CROSSFADER", x, y, w, h); - new UIParameterSlider(4, titleHeight, w-9, 32).setParameter(lx.engine.getDeck(GLucose.RIGHT_DECK).getFader()).addToContainer(this); - (displayMode = new UIToggleSet(4, titleHeight + 36, w-9, 20)).setOptions(new String[] { "A", "COMP", "B" }).setValue("COMP").addToContainer(this); + new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-9, 32).setParameter(lx.engine.getDeck(RIGHT_DECK).getFader()).addToContainer(this); + (displayMode = new UIToggleSet(4, UIWindow.TITLE_LABEL_HEIGHT + 36, w-9, 20)).setOptions(new String[] { "A", "COMP", "B" }).setValue("COMP").addToContainer(this); } public UICrossfader setDisplayMode(String value) { @@ -154,31 +178,34 @@ class UICrossfader extends UIWindow { class UIEffects extends UIWindow { UIEffects(float x, float y, float w, float h) { - super("FX", x, y, w, h); + super(lx.ui, "FX", x, y, w, h); - int yp = titleHeight; - List items = new ArrayList(); - for (LXEffect fx : glucose.lx.getEffects()) { - items.add(new FXScrollItem(fx)); + int yp = UIWindow.TITLE_LABEL_HEIGHT; + List items = new ArrayList(); + int i = 0; + for (LXEffect fx : effectsArr) { + items.add(new FXScrollItem(fx, i++)); } final UIScrollList effectsList = new UIScrollList(1, yp, w-2, 60).setItems(items); effectsList.addToContainer(this); - yp += effectsList.h + 10; + yp += effectsList.getHeight() + 10; - final UIParameterKnob[] parameterKnobs = new UIParameterKnob[4]; + final UIKnob[] parameterKnobs = new UIKnob[4]; for (int ki = 0; ki < parameterKnobs.length; ++ki) { - parameterKnobs[ki] = new UIParameterKnob(5 + 34*(ki % 4), yp + (ki/4) * 48); + parameterKnobs[ki] = new UIKnob(5 + 34*(ki % 4), yp + (ki/4) * 48); parameterKnobs[ki].addToContainer(this); } - GLucose.EffectListener fxListener = new GLucose.EffectListener() { - public void effectSelected(LXEffect effect) { + LXParameterListener fxListener = new LXParameterListener() { + public void onParameterChanged(LXParameter parameter) { int i = 0; - for (LXParameter p : effect.getParameters()) { + for (LXParameter p : getSelectedEffect().getParameters()) { if (i >= parameterKnobs.length) { break; } - parameterKnobs[i++].setParameter(p); + if (p instanceof BasicParameter) { + parameterKnobs[i++].setParameter((BasicParameter) p); + } } while (i < parameterKnobs.length) { parameterKnobs[i++].setParameter(null); @@ -186,19 +213,21 @@ class UIEffects extends UIWindow { } }; - glucose.addEffectListener(fxListener); - fxListener.effectSelected(glucose.getSelectedEffect()); + selectedEffect.addListener(fxListener); + fxListener.onParameterChanged(null); } - class FXScrollItem extends AbstractScrollItem { + class FXScrollItem extends UIScrollList.AbstractItem { - private LXEffect effect; - private String label; + private final LXEffect effect; + private final int index; + private final String label; - FXScrollItem(LXEffect effect) { + FXScrollItem(LXEffect effect, int index) { this.effect = effect; - label = className(effect, "Effect"); + this.index = index; + this.label = className(effect, "Effect"); } public String getLabel() { @@ -206,7 +235,7 @@ class UIEffects extends UIWindow { } public boolean isSelected() { - return !effect.isEnabled() && (glucose.getSelectedEffect() == effect); + return !effect.isEnabled() && (effect == getSelectedEffect()); } public boolean isPending() { @@ -214,14 +243,14 @@ class UIEffects extends UIWindow { } public void onMousePressed() { - if (glucose.getSelectedEffect() == effect) { + if (effect == getSelectedEffect()) { if (effect.isMomentary()) { effect.enable(); } else { effect.toggle(); } } else { - glucose.setSelectedEffect(effect); + selectedEffect.setValue(index); } } @@ -236,17 +265,17 @@ class UIEffects extends UIWindow { } class UIOutput extends UIWindow { - public UIOutput(float x, float y, float w, float h) { - super("OUTPUT", x, y, w, h); - float yp = titleHeight; + public UIOutput(GrizzlyOutput[] grizzlies, float x, float y, float w, float h) { + super(lx.ui, "OUTPUT", x, y, w, h); + float yp = UIWindow.TITLE_LABEL_HEIGHT; - final UIScrollList outputs = new UIScrollList(1, titleHeight, w-2, 80); + final UIScrollList outputs = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 80); - List items = new ArrayList(); - for (final PandaDriver panda : pandaBoards) { - items.add(new PandaScrollItem(panda)); - panda.setListener(new PandaDriver.Listener() { - public void onToggle(boolean active) { + List items = new ArrayList(); + for (GrizzlyOutput grizzly : grizzlies) { + items.add(new GrizzlyScrollItem(grizzly)); + grizzly.enabled.addListener(new LXParameterListener() { + public void onParameterChanged(LXParameter parameter) { outputs.redraw(); } }); @@ -254,22 +283,23 @@ class UIOutput extends UIWindow { outputs.setItems(items).addToContainer(this); } - class PandaScrollItem extends AbstractScrollItem { - final PandaDriver panda; - PandaScrollItem(PandaDriver panda) { - this.panda = panda; + class GrizzlyScrollItem extends UIScrollList.AbstractItem { + final GrizzlyOutput output; + + GrizzlyScrollItem(GrizzlyOutput output) { + this.output = output; } public String getLabel() { - return panda.ip; + return output.ipAddress; } public boolean isSelected() { - return panda.isEnabled(); + return output.enabled.isOn(); } public void onMousePressed() { - panda.toggle(); + output.enabled.setValue(!isSelected()); } } } @@ -279,8 +309,8 @@ class UITempo extends UIWindow { private final UIButton tempoButton; UITempo(float x, float y, float w, float h) { - super("TEMPO", x, y, w, h); - tempoButton = new UIButton(4, titleHeight, w-10, 20) { + super(lx.ui, "TEMPO", x, y, w, h); + tempoButton = new UIButton(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20) { protected void onToggle(boolean active) { if (active) { lx.tempo.tap(); @@ -288,17 +318,26 @@ class UITempo extends UIWindow { } }.setMomentary(true); tempoButton.addToContainer(this); + new UITempoBlipper(8, UIWindow.TITLE_LABEL_HEIGHT + 5, 12, 12).addToContainer(this); } - public void draw() { - tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.); - super.draw(); + class UITempoBlipper extends UIObject { + UITempoBlipper(float x, float y, float w, float h) { + super(x, y, w, h); + } - // Overlay tempo thing with openGL, redraw faster than button UI - fill(color(0, 0, 24 - 8*lx.tempo.rampf())); - noStroke(); - rect(x + 8, y + titleHeight + 5, 12, 12); + void onDraw(UI ui, PGraphics pg) { + tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.); + + // Overlay tempo thing with openGL, redraw faster than button UI + pg.fill(color(0, 0, 24 - 8*lx.tempo.rampf())); + pg.noStroke(); + pg.rect(0, 0, width, height); + + redraw(); + } } + } class UIMapping extends UIWindow { @@ -318,10 +357,10 @@ class UIMapping extends UIWindow { private final UIIntegerBox stripBox; UIMapping(MappingTool tool, float x, float y, float w, float h) { - super("MAPPING", x, y, w, h); + super(lx.ui, "MAPPING", x, y, w, h); mappingTool = tool; - int yp = titleHeight; + int yp = UIWindow.TITLE_LABEL_HEIGHT; new UIToggleSet(4, yp, w-10, 20) { protected void onToggle(String value) { if (value == MAP_MODE_ALL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_ALL; @@ -345,12 +384,12 @@ class UIMapping extends UIWindow { protected void onValueChange(int value) { mappingTool.setCube(value-1); } - }).setRange(1, glucose.model.cubes.size()).addToContainer(this); + }).setRange(1, model.cubes.size()).addToContainer(this); yp += 24; yp += 10; - new UIScrollList(1, yp, w-2, 60).setItems(Arrays.asList(new ScrollItem[] { + new UIScrollList(1, yp, w-2, 60).setItems(Arrays.asList(new UIScrollList.Item[] { new ColorScrollItem(ColorScrollItem.COLOR_RED), new ColorScrollItem(ColorScrollItem.COLOR_GREEN), new ColorScrollItem(ColorScrollItem.COLOR_BLUE), @@ -392,7 +431,7 @@ class UIMapping extends UIWindow { stripBox.setValue(value); } - class ColorScrollItem extends AbstractScrollItem { + class ColorScrollItem extends UIScrollList.AbstractItem { public static final int COLOR_RED = 1; public static final int COLOR_GREEN = 2; @@ -438,7 +477,7 @@ class UIDebugText extends UIContext { private String line2 = ""; UIDebugText(float x, float y, float w, float h) { - super(x, y, w, h); + super(lx.ui, x, y, w, h); } public UIDebugText setText(String line1) { @@ -455,13 +494,13 @@ class UIDebugText extends UIContext { return this; } - protected void onDraw(PGraphics pg) { - super.onDraw(pg); + protected void onDraw(UI ui, PGraphics pg) { + super.onDraw(ui, pg); if (line1.length() + line2.length() > 0) { pg.noStroke(); pg.fill(#444444); - pg.rect(0, 0, w, h); - pg.textFont(defaultItemFont); + pg.rect(0, 0, width, height); + pg.textFont(ui.getItemFont()); pg.textSize(10); pg.textAlign(LEFT, TOP); pg.fill(#cccccc); @@ -476,14 +515,14 @@ class UISpeed extends UIWindow { final BasicParameter speed; UISpeed(float x, float y, float w, float h) { - super("SPEED", x, y, w, h); + super(lx.ui, "SPEED", x, y, w, h); speed = new BasicParameter("SPEED", 0.5); - new UIParameterSlider(4, titleHeight, w-10, 20) - .setParameter(speed.addListener(new LXParameterListener() { + speed.addListener(new LXParameterListener() { public void onParameterChanged(LXParameter parameter) { lx.setSpeed(parameter.getValuef() * 2); } - })).addToContainer(this); + }); + new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20).setParameter(speed).addToContainer(this); } } @@ -493,15 +532,15 @@ class UIMidi extends UIWindow { private final UIButton logMode; UIMidi(final MidiEngine midiEngine, float x, float y, float w, float h) { - super("MIDI", x, y, w, h); + super(lx.ui, "MIDI", x, y, w, h); // Processing compiler doesn't seem to get that list of class objects also conform to interface - List scrollItems = new ArrayList(); + List scrollItems = new ArrayList(); for (SCMidiInput mc : midiEngine.getControllers()) { scrollItems.add(mc); } final UIScrollList scrollList; - (scrollList = new UIScrollList(1, titleHeight, w-2, 100)).setItems(scrollItems).addToContainer(this); + (scrollList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 100)).setItems(scrollItems).addToContainer(this); (deckMode = new UIToggleSet(4, 130, 90, 20) { protected void onToggle(String value) { midiEngine.setFocusedDeck(value == "A" ? 0 : 1); @@ -531,7 +570,7 @@ class UIMidi extends UIWindow { } public LXDeck getFocusedDeck() { - return lx.engine.getDeck(deckMode.getValue() == "A" ? GLucose.LEFT_DECK : GLucose.RIGHT_DECK); + return lx.engine.getDeck(deckMode.getValue() == "A" ? LEFT_DECK : RIGHT_DECK); } } diff --git a/VincentSiao.pde b/VincentSiao.pde index 48a368e..797651a 100644 --- a/VincentSiao.pde +++ b/VincentSiao.pde @@ -42,8 +42,8 @@ class VSTowers extends SCPattern { } } - public VSTowers(GLucose glucose) { - super(glucose); + public VSTowers(LX lx) { + super(lx); addParameter(saturationParameter); addParameter(attackParameter); addParameter(decayParameter); diff --git a/build-tmp/source/SugarCubes.java b/build-tmp/source/SugarCubes.java deleted file mode 100644 index edd72f4..0000000 --- a/build-tmp/source/SugarCubes.java +++ /dev/null @@ -1,6279 +0,0 @@ -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 cubeorigin = new ArrayList(); -ArrayList centerlist = new ArrayList(); -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 centerlistrelative = new ArrayList(); -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 towerParams; - int towerSize; - int colorSpan; - TowerParams(GLucose glucose) { - super(glucose); - - towerParams = new ArrayList(); - 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; i0.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 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 waves = new ArrayList(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 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-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 .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 cur = new ArrayList(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 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(); i0) 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 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; i0; i--){ - frames[i] = frames[i-1]; - } - frames[0] = new int[model.points.size()]; - - for(int i=0; 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 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= 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 picks = new ArrayList (); - ArrayList bools = new ArrayList (); - - 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= 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 100) return; - - if (this == midiEngine.getFocusedDeck().getActivePattern()) { - String Text1="", Text2=""; - for (int i=0; i 0) { - for (int i=0; i 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 graphicBuffer; - Graphic() - { - graphicBuffer = new ArrayList(); - } - public int width() - { - return graphicBuffer.size(); - } - - -}; -class Granim extends Graphic -{ - HashMap displayList; - - Granim() - { - displayList = new HashMap(); - } - 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 displayList; - - GranimPattern(GLucose glucose) - { - super(glucose); - displayList = new HashMap(); - } - - 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 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 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 newLayers = new Stack(); - - private final Map lightMap = new HashMap(); - private final List lights = new ArrayList(); - private final BasicParameter lightSize = new BasicParameter("SIZE", 0.5f); - - private final List sweeps = new ArrayList(); - - 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 particles = new ArrayList(); - - 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 layers = new ArrayList(); - 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 raindrops; - - public TimRaindrops(GLucose glucose) { - super(glucose); - raindrops = new LinkedList(); - } - - 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 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 flashes; - - public TimCubes(GLucose glucose) { - super(glucose); - addParameter(rateParameter); - addParameter(attackParameter); - addParameter(decayParameter); - addParameter(hueParameter); - addParameter(hueVarianceParameter); - addParameter(saturationParameter); - flashes = new LinkedList(); - } - - 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 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 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> pointToNeighbors; - private Map pointToStrip; - // private final Map> 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 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 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> buildStripToNearbyStripsMap() { - Map 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> stripToNeighbors = new HashMap(); - for (Strip s : model.strips) { - List 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> buildPointToNeighborsMap() { - Map> m = new HashMap(); - Map> stripToNearbyStrips = this.buildStripToNearbyStripsMap(); - - for (Strip s : model.strips) { - List nearbyStrips = stripToNearbyStrips.get(s); - - for (Point p : s.points) { - Vector3 v = new Vector3(p.x, p.y, p.z); - - List 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 buildPointToStripMap() { - Map 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)= 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;x45 || x%50<5) { - intensity[x][ym-1] = random(30,100); - } else { - intensity[x][ym-1] = random(0,50); - } - } - for (int x=1;xbright[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; jlightVals[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; javgSize) 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); - } - } -} diff --git a/code/GLucose.jar b/code/GLucose.jar deleted file mode 100755 index e8290f8..0000000 Binary files a/code/GLucose.jar and /dev/null differ diff --git a/code/HeronLX.jar b/code/HeronLX.jar index 23d5bf8..7c388a7 100755 Binary files a/code/HeronLX.jar and b/code/HeronLX.jar differ diff --git a/code/JGraphT.jar b/code/JGraphT.jar new file mode 100644 index 0000000..1db92e6 Binary files /dev/null and b/code/JGraphT.jar differ diff --git a/code/oscP5.jar b/code/oscP5.jar deleted file mode 100755 index 24c6756..0000000 Binary files a/code/oscP5.jar and /dev/null differ diff --git a/libraries/HeronLX.jar b/libraries/HeronLX.jar new file mode 100755 index 0000000..7c388a7 Binary files /dev/null and b/libraries/HeronLX.jar differ diff --git a/libraries/JGraphT.jar b/libraries/JGraphT.jar new file mode 100644 index 0000000..1db92e6 Binary files /dev/null and b/libraries/JGraphT.jar differ diff --git a/libraries/ScreenShot.dll b/libraries/ScreenShot.dll new file mode 100755 index 0000000..68a6c99 Binary files /dev/null and b/libraries/ScreenShot.dll differ diff --git a/libraries/ScreenShot.jar b/libraries/ScreenShot.jar new file mode 100755 index 0000000..c75b8de Binary files /dev/null and b/libraries/ScreenShot.jar differ diff --git a/libraries/rwmidi.jar b/libraries/rwmidi.jar new file mode 100755 index 0000000..4788ff6 Binary files /dev/null and b/libraries/rwmidi.jar differ diff --git a/libraries/toxiclibscore.jar b/libraries/toxiclibscore.jar new file mode 100755 index 0000000..18fbbfe Binary files /dev/null and b/libraries/toxiclibscore.jar differ diff --git a/sketch.properties b/sketch.properties new file mode 100644 index 0000000..8630fa2 --- /dev/null +++ b/sketch.properties @@ -0,0 +1,2 @@ +mode.id=processing.mode.java.JavaMode +mode=Java