-class SineSphere extends SCPattern {
+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);
private BasicParameter yrot2speed = new BasicParameter("y2speed", 4000, 1, 15000);
private SawLFO yrot = new SawLFO(0, TWO_PI, yrotspeed);
private SawLFO yrot2 = new SawLFO(0, -TWO_PI, yrot2speed);
private SawLFO yrot3 = new SawLFO(0, -TWO_PI, yrot3speed);
- public BasicParameter huespread = new BasicParameter("Hue", 0, 360);
+ public BasicParameter huespread = new BasicParameter("Hue", 0, 180);
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 Sshape;
+ Pick Galaxy, STime;
public BasicParameter rotationx = new BasicParameter("rotx", 0, 0, 1 );
public BasicParameter rotationy = new BasicParameter("roty", 1, 0, 1);
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;
private SinLFO zbounce;
- float vibration_magnitude, vperiod; //vibration_min; vibration_max;
+ float vibration_magnitude, vperiod, radius, vibration_min, vibration_max;
//public BasicParameter huespread;
public BasicParameter bouncerate;
public BasicParameter bounceamp;
public BasicParameter vibrationrate;
- public final PVector circlecenter = new PVector();
+ public final PVector circlecenter;
- public Sphery(float f1xcenter, float f1ycenter, float f1zcenter, 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.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);
- addModulator( vibration = new SinLFO( modelrad/15 - vibration_magnitude , modelrad/15 + vibration_magnitude, vperiod)).trigger(); //vibration.setPeriod(240000/lx.tempo.bpm());
+ addModulator( vibration = new SinLFO( this.radius - vibration_magnitude , this.radius + vibration_magnitude, vperiod)).trigger(); //vibration.setPeriod(240000/lx.tempo.bpm());
}
- // 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);
}
}
-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 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, 180-huespread.getValuef(), 220+huespread.getValuef());
+ 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()) );
// 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() ) ) ) ;
}
-void run(double deltaMs) {
- float vv = vibration.getValuef();
- float ybv = ybounce.getValuef();
-
- }
-}
+}
+
+boolean noteOn(Note note) {
+ int row = note.getPitch(), col = note.getChannel();
+ // if (row == 57) {KeyPressed = col; return true; }
+ return super.noteOn(note);
+ }
-// public boolean gridPressed(int row, int co){
-// midiengine.grid.setState();
+// public boolean noteOn(Note note) {
+// pitch= note.getPitch();
+// velocity=note.getVelocity();
+// channel=note.getChannel();
// return true;
-
// }
-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);
-return true;
-}
+// public boolean gridPressed(int row, int col) {
+// 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);
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" });
- //addParameter(huespread);
- //Sshape = addPick("Shape", , 1);
spherys = new Sphery[] {
- new Sphery(model.xMax/4, model.yMax/2, model.zMax/2, modelrad/8, 3000),
- new Sphery(.75*model.xMax, model.yMax/2, model.zMax/2, modelrad/10, 2000),
- new Sphery(model.xMax/2, model.yMax/2, model.zMax/2, modelrad/5, 2300),
- new Sphery(.7*model.xMax, .65*model.yMax, .5*model.zMax, modelrad/7, 3500),
- new Sphery(.75*model.xMax, .8*model.yMax, .7*model.zMax, modelrad/10, 2000),
- new Sphery(model.xMax/2, model.yMax/2, model.zMax/2, modelrad/4, 2300),
-
-
-
-
- // 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),
-
- };
+ 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(.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)
+
+
+ };
}
// 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();
+
- // switch (cur) {
+ switch (spherytime) {
- // case 1: 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 2: t = t; bpm = bpm; break;
+ case 1: t = t; bpm = bpm; break;
- // case 3: 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
.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);
+
+
+
+
}
color blendIfColor(color c1, color c2, int mode) {
}
- // 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. */
+
+public class APat extends SCPattern
+
+
+{
+ ArrayList<Pick> picks = new ArrayList<Pick> ();
+ ArrayList<DBool> bools = new ArrayList<DBool> ();
+
+ PVector mMax, mCtr, mHalf;
+
+ MidiOutput APCOut;
+ int nMaxRow = 53;
+ float LastJog = -1;
+ float[] xWaveNz, yWaveNz;
+ int nPoint , nPoints;
+ PVector xyzJog = new PVector(), modmin;
+
+ float NoiseMove = random(10000);
+ BasicParameter pSpark, pWave, pRotX, pRotY, pRotZ, pSpin, pTransX, pTransY;
+ DBool pXsym, pYsym, pRsym, pXdup, pXtrip, pJog, pGrey;
+
+ 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;
+ picks.add(P);
+ return P;
+ }
+
+ boolean noteOff(Note note) {
+ int row = note.getPitch(), col = note.getChannel();
+ for (int i=0; i<bools.size(); i++) if (bools.get(i).set(row, col, false)) { presetManager.dirty(this); return true; }
+ updateLights(); return false;
+ }
+
+ boolean noteOn(Note note) {
+ int row = note.getPitch(), col = note.getChannel();
+ for (int i=0; i<picks.size(); i++) if (picks.get(i).set(row, col)) { presetManager.dirty(this); return true; }
+ for (int i=0; i<bools.size(); i++) if (bools.get(i).set(row, col, true)) { presetManager.dirty(this); return true; }
+ println("row: " + row + " col: " + col); return false;
+ }
+
+ void onInactive() { uiDebugText.setText(""); }
+ void onReset() {
+ for (int i=0; i<bools .size(); i++) bools.get(i).reset();
+ for (int i=0; i<picks .size(); i++) picks.get(i).reset();
+ presetManager.dirty(this);
+ updateLights();
+ }
+
+ APat(LX lx) {
+ super(lx);
+
+
+
+ nPoints = model.points.size();
+ pXsym = new DBool("X-SYM", false, 48, 0); bools.add(pXsym );
+ pYsym = new DBool("Y-SYM", false, 48, 1); bools.add(pYsym );
+ pRsym = new DBool("R-SYM", false, 48, 2); bools.add(pRsym );
+ pXdup = new DBool("X-DUP", false, 48, 3); bools.add(pXdup );
+ pJog = new DBool("JOG" , false, 48, 4); bools.add(pJog );
+ pGrey = new DBool("GREY" , false, 48, 5); bools.add(pGrey );
+
+ modmin = new PVector(model.xMin, model.yMin, model.zMin);
+ mMax = new PVector(model.xMax, model.yMax, model.zMax); mMax.sub(modmin);
+ mCtr = new PVector(); mCtr.set(mMax); mCtr.mult(.5);
+ mHalf = new PVector(.5,.5,.5);
+ xWaveNz = new float[ceil(mMax.y)+1];
+ yWaveNz = new float[ceil(mMax.x)+1];
+
+ //println (model.xMin + " " + model.yMin + " " + model.zMin);
+ //println (model.xMax + " " + model.yMax + " " + model.zMax);
+ //for (MidiOutputDevice o: RWMidi.getOutputDevices()) { if (o.toString().contains("APC")) { APCOut = o.createOutput(); break;}}
+ }
+
+ float spin() {
+ float raw = val(pSpin);
+ if (raw <= 0.45) {
+ return raw + 0.05;
+ } else if (raw >= 0.55) {
+ return raw - 0.05;
+ }
+ return 0.5;
+ }
+
+ void setAPCOutput(MidiOutput output) {
+ APCOut = output;
+ }
+
+ void updateLights() { if (APCOut == null) return;
+ for (int i = 0; i < NumApcRows; ++i)
+ for (int j = 0; j < 8; ++j) APCOut.sendNoteOn(j, 53+i, 0);
+ for (int i=0; i<picks .size(); i++) APCOut.sendNoteOn(picks.get(i).CurCol, picks.get(i).CurRow, 3);
+ for (int i=0; i<bools .size(); i++) if (bools.get(i).b) APCOut.sendNoteOn (bools.get(i).col, bools.get(i).row, 1);
+ else APCOut.sendNoteOff (bools.get(i).col, bools.get(i).row, 0);
+ }
+
+ void run(double deltaMs)
+ {
+ if (deltaMs > 100) return;
+
+ if (this == midiEngine.getFocusedDeck().getActivePattern()) {
+ String Text1="", Text2="";
+ for (int i=0; i<bools.size(); i++) if (bools.get(i).b) Text1 += " " + bools.get(i).tag + " ";
+ for (int i=0; i<picks.size(); i++) Text1 += picks.get(i).tag + ": " + picks.get(i).CurDesc() + " ";
+ uiDebugText.setText(Text1, Text2);
+ }
+
+ NoiseMove += deltaMs; NoiseMove = NoiseMove % 1e7;
+ StartRun (deltaMs);
+ PVector P = new PVector(), tP = new PVector(), pSave = new PVector();
+ PVector pTrans = new PVector(val(pTransX)*200-100, val(pTransY)*100-50,0);
+ nPoint = 0;
+
+ if (pJog.b) {
+ float tRamp = (lx.tempo.rampf() % .25);
+ if (tRamp < LastJog) xyzJog.set(randctr(mMax.x*.2), randctr(mMax.y*.2), randctr(mMax.z*.2));
+ LastJog = tRamp;
+ }
+
+ // precalculate this stuff
+ float wvAmp = val(pWave), sprk = val(pSpark);
+ if (wvAmp > 0) {
+ for (int i=0; i<ceil(mMax.x)+1; i++)
+ yWaveNz[i] = wvAmp * (noise(i/(mMax.x*.3)-(2e3+NoiseMove)/1500.) - .5) * (mMax.y/2.);
+
+ for (int i=0; i<ceil(mMax.y)+1; i++)
+ xWaveNz[i] = wvAmp * (noise(i/(mMax.y*.3)-(1e3+NoiseMove)/1500.) - .5) * (mMax.x/2.);
+ }
+
+ for (LXPoint p : model.points) { nPoint++;
+ setVec(P,p);
+ P.sub(modmin);
+ P.sub(pTrans);
+ if (sprk > 0) {P.y += sprk*randctr(50); P.x += sprk*randctr(50); P.z += sprk*randctr(50); }
+ if (wvAmp > 0) P.y += interpWv(p.x-modmin.x, yWaveNz);
+ if (wvAmp > 0) P.x += interpWv(p.y-modmin.y, xWaveNz);
+ if (pJog.b) P.add(xyzJog);
+
+
+ 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;
+ }
+ }
+}
class CubeCurl extends SCPattern{
float CH, CW, diag;
ArrayList<PVector> cubeorigin = new ArrayList<PVector>();
ArrayList<PVector> centerlist = new ArrayList<PVector>();
-private SinLFO curl = new SinLFO(0, Cube.EDGE_HEIGHT, 5000 );
+private SinLFO 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;
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);
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), );
}
}
}
}
+ JGraphAdapterDemo graph1;
+
+
+// class SpinningCube extends SCPattern{
+// LXProjection spin1, spin2, spin3;
+// SawLFO
+
+//}
+
+
+
+
+
+class PixelGraph implements EdgeFactory<dPixel, dVertex> {
+
+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);
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());
}
}
+++ /dev/null
-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<PVector> cubeorigin = new ArrayList<PVector>();
-ArrayList<PVector> centerlist = new ArrayList<PVector>();
-private SinLFO curl = new SinLFO(0, Cube.EDGE_HEIGHT, 5000 );
-
-private SinLFO bg = new SinLFO(180, 220, 3000);
-
-CubeCurl(GLucose glucose){
-super(glucose);
-addModulator(curl).trigger();
-addModulator(bg).trigger();
- this.CH = Cube.EDGE_HEIGHT;
- this.CW = Cube.EDGE_WIDTH;
- this.diag = sqrt(CW*CW + CW*CW);
-
-
-ArrayList<PVector> centerlistrelative = new ArrayList<PVector>();
-for (int i = 0; i < model.cubes.size(); i++){
- Cube a = model.cubes.get(i);
- cubeorigin.add(new PVector(a.x, a.y, a.z));
- centerlist.add(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());
- }
- }
-
- }
return true;
}
- public AKPong(GLucose glucose)
+ public AKPong(LX lx)
{
- super(glucose);
+ super(lx);
addParameter(speed);
addParameter(leftKnob);
addParameter(rightKnob);
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();
}
}
}
- public AKTetris(GLucose glucose)
+ public AKTetris(LX lx)
{
- super(glucose);
+ super(lx);
}
public boolean noteOn(Note note)
}
}
- public AKMatrix(GLucose glucose)
+ public AKMatrix(LX lx)
{
- super(glucose);
+ super(lx);
// for (Tower t : model.towers)
{
Tower t = model.towers.get(0);
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();
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;
}
class AKSpiral extends SCPattern
{
private int ms;
- public AKSpiral(GLucose glucose)
+ public AKSpiral(LX lx)
{
- super(glucose);
+ super(lx);
ms = 0;
}
}
}
- public AKSpace(GLucose glucose)
+ public AKSpace(LX lx)
{
- super(glucose);
+ super(lx);
stars = new LinkedList<Star>();
for (int i = 0; i < 50; ++i)
stars.add(new Star());
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);
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();
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);
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);
}
float minIS;
- MultipleCubes(GLucose glucose) {
- super(glucose);
+ MultipleCubes(LX lx) {
+ super(lx);
minIS = 200;
}
ArrayList<BasicParameter> towerParams;
int towerSize;
int colorSpan;
- TowerParams(GLucose glucose) {
- super(glucose);
+ TowerParams(LX lx) {
+ super(lx);
towerParams = new ArrayList<BasicParameter>();
addParameter(hueoff);
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);
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));
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)));
BasicParameter zd;
BasicParameter mode;
- DriveableCrossSections(GLucose glucose) {
- super(glucose);
+ DriveableCrossSections(LX lx) {
+ super(lx);
}
public void addParams()
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();
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);
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 );
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);
-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; i<s.points.size(); i++){
- int index = s.points.get(i).index;
- color c = colors[index];
- colors[index] = lx.hsb((i*22.5), saturation(c), brightness(c));
- }
- }*/
- }
-}
-
-class BlendFrames extends SCEffect {
- int fcount;
- int frames[][];
- int maxfbuf;
- int blendfactor;
- BlendFrames(GLucose glucose) {
- super(glucose);
- maxfbuf = 30;
- blendfactor=30;
- fcount=0;
- frames = new int[maxfbuf][];
- for(int i=0; i<maxfbuf; i++){
- frames[i] = new int[model.points.size()];
- }
- }
- public void apply(int[] colors) {
- if(fcount<maxfbuf){
- for(int i=0; i<colors.length; i++){
- frames[(maxfbuf-1)-fcount][i]=colors[i];
- }
- fcount++;
- return;
- } else {
- for(int i=maxfbuf-1; i>0; i--){
- frames[i] = frames[i-1];
- }
- frames[0] = new int[model.points.size()];
+// 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; i<s.points.size(); i++){
+// int index = s.points.get(i).index;
+// color c = colors[index];
+// colors[index] = lx.hsb((i*22.5), saturation(c), brightness(c));
+// }
+// }*/
+// }
+// }
+
+// class BlendFrames extends LXEffect {
+// int fcount;
+// int frames[][];
+// int maxfbuf;
+// int blendfactor;
+// BlendFrames(LX lx) {
+// super(lx);
+// maxfbuf = 30;
+// blendfactor=30;
+// fcount=0;
+// frames = new int[maxfbuf][];
+// for(int i=0; i<maxfbuf; i++){
+// frames[i] = new int[model.points.size()];
+// }
+// }
+// public void apply(int[] colors) {
+// if(fcount<maxfbuf){
+// for(int i=0; i<colors.length; i++){
+// frames[(maxfbuf-1)-fcount][i]=colors[i];
+// }
+// fcount++;
+// return;
+// } else {
+// for(int i=maxfbuf-1; i>0; i--){
+// frames[i] = frames[i-1];
+// }
+// frames[0] = new int[model.points.size()];
- for(int i=0; i<colors.length; i++){
- int r,g,b;
- r=g=b=0;
- for(int j=0; j<blendfactor; j++){
- if(j==0) { frames[0][i] = colors[i]; }
- r += ((frames[j][i] >> 16) & 0xFF);
- g += ((frames[j][i] >> 8) & 0xFF);
- b += ((frames[j][i] >> 0) & 0xFF);
- }
- r/=blendfactor;
- g/=blendfactor;
- b/=blendfactor;
- colorMode(ARGB);
- colors[i] = (0xFF << 24) | (r << 16) | (g << 8) | b;
- colorMode(HSB);
- }
+// for(int i=0; i<colors.length; i++){
+// int r,g,b;
+// r=g=b=0;
+// for(int j=0; j<blendfactor; j++){
+// if(j==0) { frames[0][i] = colors[i]; }
+// r += ((frames[j][i] >> 16) & 0xFF);
+// g += ((frames[j][i] >> 8) & 0xFF);
+// b += ((frames[j][i] >> 0) & 0xFF);
+// }
+// r/=blendfactor;
+// g/=blendfactor;
+// b/=blendfactor;
+// colorMode(ARGB);
+// colors[i] = (0xFF << 24) | (r << 16) | (g << 8) | b;
+// colorMode(HSB);
+// }
- }
- }
-}
-
-
-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<balls.length; i++) { balls[i] = new Ball(); }
- }
- void oscEvent(OscMessage msg){
- String pattern[] = split(msg.addrPattern(), "/");
- int ballnum = int(pattern[3]);
- balls[ballnum].lastSeen=millis();
- balls[ballnum].x = msg.get(0).floatValue();
- balls[ballnum].y = msg.get(1).floatValue();
- }
+// }
+// }
+// }
+
+
+
+// abstract class OSCPattern extends SCPattern {
+// public OSCPattern(LX lx){super(lx);}
+// 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(LX lx){
+// super(lx);
+// balls = new Ball[20];
+// for(int i=0; i<balls.length; i++) { balls[i] = new Ball(); }
+// }
+// void oscEvent(OscMessage msg){
+// String pattern[] = split(msg.addrPattern(), "/");
+// int ballnum = int(pattern[3]);
+// balls[ballnum].lastSeen=millis();
+// balls[ballnum].x = msg.get(0).floatValue();
+// balls[ballnum].y = msg.get(1).floatValue();
+// }
- void run(double deltaMs){
- for(LXPoint p: model.points){ colors[p.index]=0; }
- for(int i=1; i<balls.length; i++){
- if(millis() - balls[i].lastSeen < 1000) {
- for(LXPoint p: model.points){
- int x = int(balls[i].x * 255.0);
- int y = int(balls[i].y * 127.0);
- if(p.x < x+4 && p.x > 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<px.length; i++){ pret.pixels[i] = px[i]; }
- //println(pret.get(10,10));
- for(LXPoint p: model.points){
- colors[p.index] = pret.get((int(p.x)/8)*8, 128-int(p.y));
- }
- }
-}*/
+// void run(double deltaMs){
+// for(LXPoint p: model.points){ colors[p.index]=0; }
+// for(int i=1; i<balls.length; i++){
+// if(millis() - balls[i].lastSeen < 1000) {
+// for(LXPoint p: model.points){
+// int x = int(balls[i].x * 255.0);
+// int y = int(balls[i].y * 127.0);
+// if(p.x < x+4 && p.x > 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<px.length; i++){ pret.pixels[i] = px[i]; }
+// //println(pret.get(10,10));
+// for(LXPoint p: model.points){
+// colors[p.index] = pret.get((int(p.x)/8)*8, 128-int(p.y));
+// }
+// }
+// }*/
updateLights();
}
- DPat(GLucose glucose) {
- super(glucose);
+ DPat(LX lx) {
+ super(lx);
pSpark = addParam("Sprk", 0);
pWave = addParam("Wave", 0);
dPixel getClosest(PVector p) {
dVertex v = null; int pos=0; float d = 500;
- for (Strip s : glucose.model.strips) {
+ for (Strip s : 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++) {
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);
{
HashMap<String,Graphic> displayList;
- GranimPattern(GLucose glucose)
+ GranimPattern(LX lx)
{
- super(glucose);
+ super(lx);
displayList = new HashMap<String,Graphic>();
}
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);
_P size;
*/
- Zebra(GLucose glucose) {
- super(glucose);
+ Zebra(LX lx) {
+ super(lx);
projection = new LXProjection(model);
addModulator(angleM).trigger();
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);
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);
private List<FaceFlash> flashes;
private int faceNum = 0;
- public JackieSquares(GLucose glucose) {
- super(glucose);
+ public JackieSquares(LX lx) {
+ super(lx);
addParameter(rateParameter);
addParameter(attackParameter);
addParameter(decayParameter);
private List<StripFlash> flashes;
private int stripNum = 0;
- public JackieLines(GLucose glucose) {
- super(glucose);
+ public JackieLines(LX lx) {
+ super(lx);
addParameter(rateParameter);
addParameter(attackParameter);
addParameter(decayParameter);
private List<PointFlash> flashes;
private int pointNum = 0;
- public JackieDots(GLucose glucose) {
- super(glucose);
+ public JackieDots(LX lx) {
+ super(lx);
addParameter(rateParameter);
addParameter(attackParameter);
addParameter(decayParameter);
// Hold the new lives
private List<Boolean> new_lives;
- public L8onLife(GLucose glucose) {
- super(glucose);
+ public L8onLife(LX lx) {
+ super(lx);
//Print debug info about the cubes.
//outputCubeInfo();
// Hold the new lives
private List<Boolean> new_states;
- public L8onAutomata(GLucose glucose) {
- super(glucose);
+ public L8onAutomata(LX lx) {
+ super(lx);
//Print debug info about the cubes.
//outputCubeInfo();
// Hold the new lives
private List<Boolean> new_lives;
- public L8onStripLife(GLucose glucose) {
- super(glucose);
+ public L8onStripLife(LX lx) {
+ super(lx);
//Print debug info about the strips.
//outputStripInfo();
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);
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);
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));
LinearEnvelope dbValue = new LinearEnvelope(0, 0, 10);
- ViolinWave(GLucose glucose) {
- super(glucose);
+ ViolinWave(LX lx) {
+ super(lx);
addParameter(level);
addParameter(edge);
addParameter(range);
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);
}
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();
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();
}
}
-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);
}
}
}
-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);
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);
}
}
-class BoomEffect extends SCEffect {
+class BoomEffect extends LXEffect {
final BasicParameter falloff = new BasicParameter("WIDTH", 0.5);
final BasicParameter speed = new BasicParameter("SPD", 0.5);
}
}
- BoomEffect(GLucose glucose) {
- super(glucose, true);
+ BoomEffect(LX lx) {
+ super(lx, true);
addParameter(falloff);
addParameter(speed);
addParameter(bright);
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);
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();
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();
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();
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);
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();
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;
}
}
-class ColorFuckerEffect extends SCEffect {
+class ColorFuckerEffect extends LXEffect {
final BasicParameter level = new BasicParameter("BRT", 1);
final BasicParameter desat = new BasicParameter("DSAT", 0);
float[] hsb = new float[3];
- ColorFuckerEffect(GLucose glucose) {
- super(glucose);
+ ColorFuckerEffect(LX lx) {
+ super(lx);
addParameter(level);
addParameter(desat);
addParameter(sharp);
}
public void apply(int[] colors) {
- if (!enabled) {
+ if (!isEnabled()) {
return;
}
float bMod = level.getValuef();
}
}
-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;
}
}
}
-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];
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);
}
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);
*
* 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 MultipleCubes(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(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),
// Micah
new Rings(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),
+ 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);
+ BoomEffect boom = new BoomEffect(lx);
+ BlurEffect blur = new BlurEffect(lx);
+ QuantizeEffect quantize = new QuantizeEffect(lx);
+ ColorFuckerEffect colorFucker = new ColorFuckerEffect(lx);
Effects() {
blur.enable();
+++ /dev/null
-/**
- * +-+-+-+-+-+ +-+-+-+-+-+
- * / /| |\ \
- * / / + + \ \
- * +-+-+-+-+-+ | +-+-+-+-+ | +-+-+-+-+-+
- * | | + / \ + | |
- * + 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();
- }
-}
-
class BlankPattern extends SCPattern {
- BlankPattern(GLucose glucose) {
- super(glucose);
+ BlankPattern(LX lx) {
+ super(lx);
}
public void run(double deltaMs) {
}
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();
}
* 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) {
*/
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) {
*/
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) {
*/
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) {
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();
}
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();
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();
}
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();
}
}
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() {
}
public void setChannel(int index) {
- channelIndex = index % numChannels;
+ if (numChannels > 0) {
+ channelIndex = index % numChannels;
+ }
setChannel();
}
private final Sphere[] spheres;
- public TimSpheres(GLucose glucose) {
- super(glucose);
+ public TimSpheres(LX lx) {
+ super(lx);
addParameter(hueParameter);
addParameter(periodParameter);
addModulator(lfo).trigger();
private float msPerRaindrop = 40;
private List<Raindrop> raindrops;
- public TimRaindrops(GLucose glucose) {
- super(glucose);
+ public TimRaindrops(LX lx) {
+ super(lx);
raindrops = new LinkedList<Raindrop>();
}
private float leftoverMs = 0;
private List<CubeFlash> flashes;
- public TimCubes(GLucose glucose) {
- super(glucose);
+ public TimCubes(LX lx) {
+ super(lx);
addParameter(rateParameter);
addParameter(attackParameter);
addParameter(decayParameter);
}
}
- 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;
private final List<Pinwheel> pinwheels;
private final float[] values;
- TimPinwheels(GLucose glucose) {
- super(glucose);
+ TimPinwheels(LX lx) {
+ super(lx);
addParameter(horizSpreadParameter);
// addParameter(vertSpreadParameter);
List<MovingPoint> movingPoints;
- TimTrace(GLucose glucose) {
- super(glucose);
+ TimTrace(LX lx) {
+ super(lx);
extraMs = 0;
private float[] values;
private float[] hues;
- TimMetronome(GLucose glucose) {
- super(glucose);
+ TimMetronome(LX lx) {
+ super(lx);
addParameter(clickyParameter);
addParameter(derezParameter);
addParameter(driftParameter);
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);
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);
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<numOsc;i++) {
fX[i] = new SinLFO(0, model.xMax, random(2000,20000));
fY[i] = new SinLFO(0, model.yMax, random(2000,20000));
SinLFO col1 = new SinLFO(0, model.xMax, 5000);
BasicParameter gainParameter = new BasicParameter("GAIN", 0.5);
- public SoundRain(GLucose glucose) {
- super(glucose);
+ public SoundRain(LX lx) {
+ super(lx);
addModulator(pos).trigger();
addModulator(col1).trigger();
addParameter(gainParameter);
gain = 50*parameter.getValuef();
}
}
- protected void onActive() {
+ void onActive() {
if (this.fft == null) {
this.fft = new FFT(lx.audioInput().bufferSize(), lx.audioInput().sampleRate());
this.fft.window(FFT.HAMMING);
SinLFO col1 = new SinLFO(0, model.xMax, 5000);
SinLFO col2 = new SinLFO(0, model.xMax, 4000);
- public FaceSync(GLucose glucose) {
- super(glucose);
+ public FaceSync(LX lx) {
+ super(lx);
addModulator(xosc).trigger();
addModulator(zosc).trigger();
zosc.setValue(0);
BasicParameter gainParameter = new BasicParameter("GAIN", 0.5);
SawLFO pos = new SawLFO(0, model.xMax, 8000);
- public SoundSpikes(GLucose glucose) {
- super(glucose);
+ public SoundSpikes(LX lx) {
+ super(lx);
addParameter(gainParameter);
addModulator(pos).trigger();
}
gain = 50*parameter.getValuef();
}
}
- protected void onActive() {
+ void onActive() {
if (this.fft == null) {
this.fft = new FFT(lx.audioInput().bufferSize(), lx.audioInput().sampleRate());
this.fft.window(FFT.HAMMING);
}
}
- public VSTowers(GLucose glucose) {
- super(glucose);
+ public VSTowers(LX lx) {
+ super(lx);
addParameter(saturationParameter);
addParameter(attackParameter);
addParameter(decayParameter);
+++ /dev/null
-/**
- * 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;
- }
-}
-
--- /dev/null
+/**
+ * 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.
+ */
+
+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;
+ }
+ }
+}
* 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 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;
float[] hsb = new float[3];
// Handles to UI objects
-UIContext[] overlays;
UIPatternDeck uiPatternA;
UICrossfader uiCrossfader;
UIMidi uiMidi;
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;
}
} catch (IllegalAccessException iax) {}
}
return effectList.toArray(new LXEffect[]{});
-}
+}
+
+LXEffect getSelectedEffect() {
+ return effectsArr[selectedEffect.getValuei()];
+}
void logTime(String evt) {
int now = millis();
// 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
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
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;
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;
}
}
-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();
- javax.media.opengl.GL gl = ((PGraphicsOpenGL)g).beginGL();
- 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();
- }
}
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':
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);
- }
-}
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;
// Crossfader
case 15:
- lx.engine.getDeck(GLucose.RIGHT_DECK).getFader().setNormalized(value);
+ lx.engine.getDeck(RIGHT_DECK).getFader().setNormalized(value);
return true;
// Cue level
if (number >= 20 && number <= 23) {
int effectIndex = number - 20;
- List<LXParameter> parameters = glucose.getSelectedEffect().getParameters();
+ // TODO(mclsee): fix selected effect
+ List<LXParameter> parameters = getSelectedEffect().getParameters();
if (effectIndex < parameters.size()) {
setNormalized(parameters.get(effectIndex), value);
return true;
case 91: // play
if (shiftOn) {
- midiEngine.setFocusedDeck(GLucose.LEFT_DECK);
+ midiEngine.setFocusedDeck(LEFT_DECK);
} else {
uiCrossfader.setDisplayMode("A");
}
case 93: // rec
if (shiftOn) {
- midiEngine.setFocusedDeck(GLucose.RIGHT_DECK);
+ midiEngine.setFocusedDeck(RIGHT_DECK);
} else {
uiCrossfader.setDisplayMode("B");
}
case 94: // up bank
if (shiftOn) {
- glucose.incrementSelectedEffectBy(-1);
+ selectedEffect.setValue(selectedEffect.getValuei() - 1);
} else {
getTargetDeck().goPrev();
}
case 95: // down bank
if (shiftOn) {
- glucose.incrementSelectedEffectBy(1);
+ selectedEffect.setValue(selectedEffect.getValuei() + 1);
} else {
getTargetDeck().goNext();
}
return true;
case 62: // Detail View / red 5
- releaseEffect = glucose.getSelectedEffect();
+ releaseEffect = getSelectedEffect();
if (releaseEffect.isMomentary()) {
releaseEffect.enable();
} else {
return true;
case 63: // rec quantize / red 6
- glucose.getSelectedEffect().disable();
+ getSelectedEffect().disable();
return true;
}
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
}
});
}
- glucose.addEffectListener(new GLucose.EffectListener() {
- public void effectSelected(LXEffect effect) {
+ selectedEffect.addListener(new LXParameterListener() {
+ public void onParameterChanged(LXParameter parameter) {
resetEffectParameters();
}
});
}
private void resetEffectParameters() {
- LXEffect newEffect = glucose.getSelectedEffect();
+ LXEffect newEffect = getSelectedEffect();
if (newEffect == focusedEffect) {
return;
}
* when physical changes or tuning is being done to the structure.
*/
-final int MaxCubeHeight = 6;
-final int NumBackTowers = 16;
-
-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<Speaker> 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<StaggeredTower> scubes = new ArrayList<StaggeredTower>();
- //if (NumBackTowers != 25) exit();
- // for (int i=0; i<NumBackTowers/2; i++) scubes.add(new StaggeredTower(
- // (i+1)*CW, // x
- // (i % 2 == 0) ? 0 : CH * 2./3. , // y
- // - ((i % 2 == 0) ? 11 : 0) + 80 , // z
- // -45, (i % 2 == 0) ? MaxCubeHeight : MaxCubeHeight) ); // num cubes
-
- // for (int i=0; i<NumBackTowers/2; i++) scubes.add(new StaggeredTower(
- // (i+1)*CW, // x
- // (i % 2 == 0) ? 0 : CH * 2./3. , // y
- // - ((i % 2 == 0) ? 0 : 11) + 80 - pow(CH*CH + CW*CW, .5), // z
- // 225, (i % 2 == 0) ? MaxCubeHeight : MaxCubeHeight-1) );
-
- // for (int i=0; i<2 ; i++) scubes.add(new StaggeredTower(
- // (i+1)*CW, // x
- // 0 , // y
- // - 0 + 97 - 2*pow(CH*CH + CW*CW, .5), // z
- // 225, MaxCubeHeight ) );
-
- ArrayList<Cube> dcubes = new ArrayList<Cube>();
- // 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[] pos = new float[3];
-pos[0] = 50;
-pos[2] = 100;
-scubes.add(new StaggeredTower(//tower 1
- pos[0], // x
- 0 , // y
- pos[2], // z
- 0, 4, new Cube.Wiring[] { WRR, WRR, WRR, WRR, WRR, WRR}) );
-
-
-pos[0] += 25;
-pos[2] -= 10;
-scubes.add(new StaggeredTower(// tower 2
- pos[0], // x
- 15 , // y
- pos[2], // z
- 0, 4, new Cube.Wiring[] { WRR, WRR, WRR, WRR, WRR, WRR}) );
-
-pos[0] += 25;
-pos[2] += -12.5;
-scubes.add(new StaggeredTower(//tower 3
- pos[0], // x
- 0 , // y
- pos[2], // z
- 0, 5, new Cube.Wiring[] { WRR, WRR, WRR, WRR, WRR, WRR}) );
-
-pos[0] += -32.75;
-pos[2] += -13;
-scubes.add(new StaggeredTower(//tower 4
- pos[0], // x
- 0, // y
- pos[2], // z
- 0, 6, new Cube.Wiring[] { WRR, WRR, WRR, WRR, WRR, WRR}) );
-
-pos[0] += 26;
-pos[2] += -16;
-scubes.add(new StaggeredTower(//tower 5
- pos[0], // x
- 15 , // y
- pos[2], // z
- 0, 6, new Cube.Wiring[] { WRR, WRR, WRR, WRR, WRR, WRR}) );
-
-pos[0] += 26;
-pos[2] += -4.5;
-scubes.add(new StaggeredTower(//tower 6
- pos[0], // x
- 0 , // y
- pos[2], // z
- 0, 6, new Cube.Wiring[] { WRR, WRR, WRR, WRR, WRR, WRR}) );
-
-pos[0] += -56.5;
-pos[2] += -6.5;
-scubes.add(new StaggeredTower(// tower 7
- pos[0], // x
- 15 , // y
- pos[2], // z
- 0, 4, new Cube.Wiring[] { WRR, WRR, WRR, WRR, WRR, WRR}) );
-
-pos[0] += 26;
-pos[2] += -16.5;
-scubes.add(new StaggeredTower(//tower 8
- pos[0], // x
- 0 , // y
- pos[2], // z
- 0, 5, new Cube.Wiring[] { WRR, WRR, WRR, WRR, WRR, WRR}) );
-
-pos[0] += 27;
-pos[2] += -4.5;
-scubes.add(new StaggeredTower(//tower 9
- pos[0], // x
- 15 , // y
- pos[2], // z
- 0, 5, new Cube.Wiring[] { WRR, WRR, WRR, WRR, WRR, WRR}) );
-
-// //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, WRR, WRR, WRR}) );
-// scubes.add(new StaggeredTower(//tower 11
-// 83.75, // x
-// 0, // y
-// -47.5, // z
-// 45, 4, new Cube.Wiring[]{ WRR, WRR, WRR, WRR}) );
-// scubes.add(new StaggeredTower(//tower 12
-// 83.75+39, // x
-// 0, // y
-// -47.5, // z
-// 45, 4, new Cube.Wiring[]{ WRR, WRR, WRR, WRR}) );
-// scubes.add(new StaggeredTower(//tower 13
-// 83.75+39+43, // x
-// 0, // y
-// -47.5-43, // z
-// 45, 4, new Cube.Wiring[]{ WRR, WRR, WRR, 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<Tower> towerList = new ArrayList<Tower>();
- ArrayList<Cube> tower;
- 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<Cube>();
- 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;
- }
- 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<Cube>();
- 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);
-}
+static final float SPACING = 27;
+static final float RISER = 13.5;
+static final float FLOOR = 0;
/**
- * This function maps the panda boards. We have an array of them, each has
- * an IP address and a list of channels.
+ * 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).
*/
-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(
- "192.168.88.100", new ChannelMapping[] { // G1
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 6}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 5}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 6}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 7}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 7}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 8}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 2}),
-
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 4}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 3}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 11}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 10}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 9}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 9}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 12}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 13}),
- }),
-
- new PandaMapping(
- "192.168.88.101", new ChannelMapping[] { //G4
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 25}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 23}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 24}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 43}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 45}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 44}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
-
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 41}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 42}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 21}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 20}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 22}),
- }),
-
- new PandaMapping(
- "192.168.88.104", new ChannelMapping[] { // G3
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 26}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 28}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 27}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 19}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 18}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 17}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
-
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 18}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 19}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 15}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 16}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 14}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 29}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 30}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 31}),
- }),
-
- new PandaMapping(
- "192.168.88.105", new ChannelMapping[] { // G2
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 39}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 38}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 40}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 34}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 35}),
-
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 33}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 32}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 37}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 37}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1}),
- }),
- };
-}
-
-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;}
-}
+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 },
+
+};
-/**
- * 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 = 16;
-
- // 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();
- }
- }
- }
-}
-
-/**
- * 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 = 1;
+public Model buildModel() {
- // 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);
- }
- }
+ List<Tower> towers = new ArrayList<Tower>();
+ Cube[] cubes = new Cube[200];
+ 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;
}
-
- this.mode = mode;
- for (int i = 0; i < objectIndices.length; ++i) {
- objectIndices[i] = (i < rawObjectIndices.length) ? rawObjectIndices[i] : NO_OBJECT;
+ List<Cube> tower = new ArrayList<Cube>();
+ 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));
}
+
+ return new Model(towers, cubes);
}
--- /dev/null
+/**
+ * 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<Tower> towers;
+ public final List<Cube> cubes;
+ public final List<Face> faces;
+ public final List<Strip> strips;
+
+ private final Cube[] _cubes;
+
+ public Model(List<Tower> towerList, Cube[] cubeArr) {
+ super(new Fixture(cubeArr));
+ Fixture fixture = (Fixture) this.fixtures.get(0);
+
+ _cubes = cubeArr;
+
+ // Make unmodifiable accessors to the model data
+ List<Cube> cubeList = new ArrayList<Cube>();
+ List<Face> faceList = new ArrayList<Face>();
+ List<Strip> stripList = new ArrayList<Strip>();
+ 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<Cube> cubes;
+
+ /**
+ * Immutable list of faces
+ */
+ public final List<Face> faces;
+
+ /**
+ * Immutable list of strips
+ */
+ public final List<Strip> strips;
+
+ /**
+ * Constructs a tower model from these cubes
+ *
+ * @param cubes Array of cubes
+ */
+ public Tower(List<Cube> cubes) {
+ super(cubes.toArray(new Cube[] {}));
+
+ List<Cube> cubeList = new ArrayList<Cube>();
+ List<Face> faceList = new ArrayList<Face>();
+ List<Strip> stripList = new ArrayList<Strip>();
+
+ 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<Face> faces;
+
+ /**
+ * Immutable list of all strips
+ */
+ public final List<Strip> 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<Face> faces = new ArrayList<Face>();
+ private final List<Strip> strips = new ArrayList<Strip>();
+
+ 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<Strip> 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<Strip> strips = new ArrayList<Strip>();
+
+ 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<LXPoint> 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();
+ }
+ }
+}
+
+++ /dev/null
-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;
-
- public PandaMapping pm;
-
- private final static int PORT = 779;
-
- private final DatagramSocket socket;
-
- // Address to send to
- private final NetAddress address;
-
- // Whether board output is enabled
- private boolean enabled = false;
-
- // Frame count for Grizzlies
- private int frameNum = 1;
-
- // 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*280]; // magic number, our UDP packet size
-
- private static final int NO_POINT = -1;
-
- private Model _model;
-
- ////////////////////////////////////////////////////////////////
- //
- // 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, 779);
- message = new OscMessage("/shady/pointbuffer");
-
- try {
- socket = new DatagramSocket();
- } catch (Exception x) {
- throw new RuntimeException(x);
- }
-
- // 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);
- pm = _pm;
- _model = model;
- // 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 channelq s
- 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;
- }
-
- // TODO(mcslee): clean up, ordering always consistent now
- stripOrderIndex = 2;
-
- // 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) {
- return mapStrip(s, direction, points, pi, s.points.size());
- }
-
- private int mapStrip(Strip s, int direction, int[] points, int pi, int len) {
- if (direction == FORWARD) {
- int i = 0;
- for (LXPoint p : s.points) {
- points[pi++] = p.index;
- if (++i >= len) {
- break;
- }
- }
- } else if (direction == BACKWARD) {
- for (int i = len-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);
- }
-
- private final int[] GRIZZLY_STRIP_ORDERING = new int[] { 9, 8, 11, 5, 4, 7, 6, 10, 14, 2, 1, 0, 3, 13, 12, 15 };
-
- public final void send(int[] colors) {
- if (!enabled) {
- return;
- }
- frameNum++;
- int len = 0;
- int packetNum = 0;
- for (ChannelMapping channel : pm.channelList) {
- for (int rawCubeIndex : channel.objectIndices) {
- if (rawCubeIndex > 0) {
- Cube cube = _model.getCubeByRawIndex(rawCubeIndex);
-
- // TODO(mcslee): clean this up, precompute paths
- for (int stripIndex : GRIZZLY_STRIP_ORDERING) {
- Strip strip = cube.strips.get(stripIndex);
- int stripLen = ((stripIndex == 9) || (stripIndex == 16)) ? 15 : 16;
- for (int i = stripLen-1; i >= 0; --i) {
- int c = colors[strip.points.get(i).index];
- byte r = (byte) ((c >> 16) & 0xFF);
- byte g = (byte) ((c >> 8) & 0xFF);
- byte b = (byte) ((c) & 0xFF);
- packet[len++] = (byte) 0; // alpha channel, unused but makes for 4-byte alignment
- packet[len++] = (byte) r;
- packet[len++] = (byte) g;
- packet[len++] = (byte) b;
- }
- }
-
-// for (LXPoint p : cube.points) {
-// int c = (p.index < 0) ? 0 : colors[p.index];
-// byte r = (byte) ((c >> 16) & 0xFF);
-// byte g = (byte) ((c >> 8) & 0xFF);
-// byte b = (byte) ((c) & 0xFF);
-// packet[len++] = (byte) 0; // alpha channel, unused but makes for 4-byte alignment
-// packet[len++] = (byte) r;
-// packet[len++] = (byte) g;
-// packet[len++] = (byte) b;
-// }
- }
- }
- // println("Packet number: " + packetNum);
- sendPacket(frameNum, packetNum++);
- len = 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 frameNum, int packetNum) {
- // println("Sending frame #" + frameNum + ", channel # " + packetNum);
- message.clearArguments();
- message.add(frameNum);
- message.add(0xDEADBEEF);
- message.add(packetNum);
- message.add(0xFEEDBEEF);
- message.add(packet.length);
- message.add(packet);
- message.add(0xBEFFFFEB);
-
- try {
- // OscP5.flush(message, address); // new DatagramSocket every time, no thanks
- byte[] bytes = message.getBytes();
- DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address.inetaddress(), PORT);
- socket.send(packet);
- } catch (Exception x) {
- x.printStackTrace();
- }
- }
-}
+++ /dev/null
-/**
- * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND
- *
- * //\\ //\\ //\\ //\\
- * ///\\\ ///\\\ ///\\\ ///\\\
- * \\\/// \\\/// \\\/// \\\///
- * \\// \\// \\// \\//
- *
- * EXPERTS ONLY!! EXPERTS ONLY!!
- *
- * Little UI framework in progress to handle mouse events, layout,
- * redrawing, etc.
- */
-
-final color lightGreen = #669966;
-final color lightBlue = #666699;
-final color bgGray = #444444;
-final color defaultTextColor = #999999;
-final PFont defaultItemFont = createFont("Lucida Grande", 11);
-final PFont defaultTitleFont = createFont("Myriad Pro", 10);
-
-public abstract class UIObject {
-
- protected final static int DOUBLE_CLICK_THRESHOLD = 300;
-
- protected final List<UIObject> children = new ArrayList<UIObject>();
-
- 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<ScrollItem> items = new ArrayList<ScrollItem>();
-
- 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<ScrollItem> 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;
- }
-}
*
* 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<ScrollItem> items = new ArrayList<ScrollItem>();
- 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);
+
+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();
+ javax.media.opengl.GL gl = ((PGraphicsOpenGL)g).beginGL();
+ gl.glClear(javax.media.opengl.GL.GL_DEPTH_BUFFER_BIT);
+ ((PGraphicsOpenGL)g).endGL();
+ 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<ScrollItem> items = new ArrayList<ScrollItem>();
- for (LXTransition t : glucose.getTransitions()) {
+ super(lx.ui, "BLEND MODE", x, y, w, h);
+ List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
+ 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() {
}
public boolean isSelected() {
- return transition == glucose.getSelectedTransition();
+ return this.transition == lx.engine.getDeck(RIGHT_DECK).getFaderTransition();
}
public boolean isPending() {
}
public void onMousePressed() {
- glucose.setSelectedTransition(transition);
+ lx.engine.getDeck(RIGHT_DECK).setFaderTransition(this.transition);
}
}
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) {
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<ScrollItem> items = new ArrayList<ScrollItem>();
- for (LXEffect fx : glucose.lx.getEffects()) {
- items.add(new FXScrollItem(fx));
+ int yp = UIWindow.TITLE_LABEL_HEIGHT;
+ List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
+ 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);
}
};
- 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() {
}
public boolean isSelected() {
- return !effect.isEnabled() && (glucose.getSelectedEffect() == effect);
+ return !effect.isEnabled() && (effect == getSelectedEffect());
}
public boolean isPending() {
}
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);
}
}
}
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<ScrollItem> items = new ArrayList<ScrollItem>();
- for (final PandaDriver panda : pandaBoards) {
- items.add(new PandaScrollItem(panda));
- panda.setListener(new PandaDriver.Listener() {
- public void onToggle(boolean active) {
+ List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
+ for (GrizzlyOutput grizzly : grizzlies) {
+ items.add(new GrizzlyScrollItem(grizzly));
+ grizzly.enabled.addListener(new LXParameterListener() {
+ public void onParameterChanged(LXParameter parameter) {
outputs.redraw();
}
});
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());
}
}
}
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();
}
}.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 {
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;
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),
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;
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) {
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);
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);
}
}
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<ScrollItem> scrollItems = new ArrayList<ScrollItem>();
+ List<UIScrollList.Item> scrollItems = new ArrayList<UIScrollList.Item>();
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);
}
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);
}
}