++
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);
public BasicParameter widthparameter= new BasicParameter("Width", 20, 1, 60);
public BasicParameter vibration_magnitude = new BasicParameter("Vmag", 20, 2, modelrad/2);
public BasicParameter scale = new BasicParameter("Scale", 1, .1, 5);
- private int pitch = 0;
- private int channel = 0;
- private int velocity = 0;
- private int cur = 0;
- public final LXProjection sinespin;
+ private int pitch = 0;
+ private int channel = 0;
+ private int velocity = 0;
+ private int cur = 0;
+ public final LXProjection sinespin;
public final LXProjection sinespin2;
public final LXProjection sinespin3;
- Pick Galaxy, STime;
+ Pick Galaxy, STime;
public BasicParameter rotationx = new BasicParameter("rotx", 0, 0, 1 );
public BasicParameter rotationy = new BasicParameter("roty", 1, 0, 1);
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;
public BasicParameter vibrationrate;
public final PVector circlecenter;
- public Sphery(float f1xcenter, float f1ycenter, float f1zcenter, float radius, float vibration_magnitude , float vperiod)
+ public Sphery(float f1xcenter, float f1ycenter, float f1zcenter, float radius, float vibration_magnitude , float vperiod)
{
this.f1xcenter = f1xcenter;
this.f1ycenter = f1ycenter;
this.f1zcenter = f1zcenter;
- this.radius = radius;
+ this.radius = radius;
this.circlecenter= new PVector(f1xcenter,f1ycenter,f1zcenter);
this.vibration_magnitude = vibration_magnitude;
this.vperiod = vperiod;
//addParameter(bounceamp = new BasicParameter("Amp", .5));
- //addParameter(bouncerate = new BasicParameter("Rate", .5)); //ybounce.modulateDurationBy(bouncerate);
+ //addParameter(bouncerate = new BasicParameter("Rate", .5)); //ybounce.modulateDurationBy(bouncerate);
//addParameter(vibrationrate = new BasicParameter("vibration", 1000, 10000));
//addParameter(widthparameter = new BasicParameter("Width", .2));
- //addModulator(xbounce = new SinLFO(model.xMax/3, 2*model.yMax/3, 2000)).trigger();
+ //addModulator(xbounce = new SinLFO(model.xMax/3, 2*model.yMax/3, 2000)).trigger();
addModulator(ybounce= new SinLFO(model.yMax/3, 2*model.yMax/3, 240000)).trigger(); //bounce.modulateDurationBy
//addModulator(bounceamp); //ybounce.setMagnitude(bouncerate);
}
- // 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 qphi = acos( (q.z-f1zcenter)/(PVector.dist(q,circlecenter)) );
+ float qtheta = atan2( (q.x-f1xcenter) , (q.z - f1zcenter) );
+ float qphi = acos( (q.z-f1zcenter)/(PVector.dist(q,circlecenter)) );
return map(qtheta, -PI/2, PI/2, 200-huespread.getValuef(), 240+huespread.getValuef());
//if (q.x > f1xcenter ) {return 140 ;}
- //else {return 250;}
+ //else {return 250;}
}
// float noisesat(PVector q) {
- // return noise()
+ // return noise()
// }
color spheryvalue (PVector p) {
- circlecenter.set(this.f1xcenter, this.f1ycenter, this.f1zcenter);
+ circlecenter.set(this.f1xcenter, this.f1ycenter, this.f1zcenter);
- //switch(sShpape.cur() ) {}
+ //switch(sShpape.cur() ) {}
float b = max(0, 100 - widthparameter.getValuef()*abs(p.dist(circlecenter)
- vibration.getValuef()) );
// constrain(100*noise(quadrant(p)), 0, 100),
100,
b
- );
+ );
}
color ellipsevalue(float px, float py, float pz , float f1xc, float f1yc, float f1zc, float f2xc, float f2yc, float f2zc)
{
- //switch(sShpape.cur() ) {}
- return lx.hsb(huespread.getValuef()*5*px, dist(model.xMax-px, model.yMax-py, model.zMax-pz, f1xc, f1yc, f1zc) ,
+ //switch(sShpape.cur() ) {}
+ return lx.hsb(huespread.getValuef()*5*px, dist(model.xMax-px, model.yMax-py, model.zMax-pz, f1xc, f1yc, f1zc) ,
max(0, 100 - 100*widthparameter.getValuef() *
- abs( (dist(px, py, pz, f1xc, ybounce.getValuef(), f1zc) +
- (dist(px, py , pz, f2xc, ybounce.getValuef(), f2zc) ) )/2
- - 1.2*vibration.getValuef() ) ) ) ;
+ abs( (dist(px, py, pz, f1xc, ybounce.getValuef(), f1zc) +
+ (dist(px, py , pz, f2xc, ybounce.getValuef(), f2zc) ) )/2
+ - 1.2*vibration.getValuef() ) ) ) ;
}
- }
+ }
boolean noteOn(Note note) {
int row = note.getPitch(), col = note.getChannel();
- // if (row == 57) {KeyPressed = col; return true; }
+ // if (row == 57) {KeyPressed = col; return true; }
return super.noteOn(note);
}
- // public boolean noteOn(Note note) {
- // pitch= note.getPitch();
+ // public boolean noteOn(Note note) {
+ // pitch= note.getPitch();
// velocity=note.getVelocity();
// channel=note.getChannel();
// return true;
// }
// public boolean gridPressed(int row, int col) {
- // pitch = row; channel = col;
- // cur = NumApcCols*(pitch-53)+col;
- // //setState(row, col, 0 ? 1 : 0);
+ // pitch = row; channel = col;
+ // cur = NumApcCols*(pitch-53)+col;
+ // //setState(row, col, 0 ? 1 : 0);
// return true;
// }
//public grid
final Sphery[] spherys;
- SineSphere(GLucose glucose)
+ SineSphere(LX lx)
{
- super(glucose);
- println("modelrad " + modelrad);
+ super(lx);
+ println("modelrad " + modelrad);
sinespin = new LXProjection(model);
sinespin2 = new LXProjection(model);
sinespin3= new LXProjection(model);
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" });
spherys = new Sphery[] {
new Sphery(model.xMax/4, model.yMax/2, model.zMax/2, modelrad/12, modelrad/25, 3000),
new Sphery(.75*model.xMax, model.yMax/2, model.zMax/2, modelrad/14, modelrad/28, 2000),
- new Sphery(model.cx, model.cy, model.cz, modelrad/5, modelrad/15, 2300),
+ new Sphery(model.cx, model.cy, model.cz, modelrad/5, modelrad/15, 2300),
new Sphery(.7*model.xMax, .65*model.yMax, .5*model.zMax, modelrad/11, modelrad/25, 3500),
new Sphery(.75*model.xMax, .8*model.yMax, .7*model.zMax, modelrad/12, modelrad/30, 2000)
-
-
-
-
- // new Sphery(model.xMax/4, model.yMax/2, model.zMax/2, modelrad/16, modelrad/8, 3000),
- // new Sphery(.75*model.xMax, model.yMax/2, model.zMax/2, modelrad/20, modelrad/10, 2000),
- // new Sphery(model.xMax/2, model.yMax/2, model.zMax/2, modelrad/4, modelrad/8, 2300),
-
- // new Sphery(.7*model.xMax, .65*model.yMax, .5*model.zMax, modelrad/14, modelrad/7, 3500),
- // new Sphery(.75*model.xMax, .8*model.yMax, .7*model.zMax, modelrad/20, modelrad/10, 2000),
- // new Sphery(model.xMax/2, model.yMax/2, model.zMax/2, modelrad/4, modelrad/8, 2300),
-
- };
+
+ };
}
// public void onParameterChanged(LXParameter parameter)
// {
- // for (Sphery s : spherys) {
- // if (s == null) continue;
- // double bampv = s.bounceamp.getValue();
- // double brv = s.bouncerate.getValue();
- // double tempobounce = lx.tempo.bpm();
- // if (parameter == s.bounceamp)
- // {
- // s.ybounce.setRange(bampv*model.yMax/3 , bampv*2*model.yMax/3, brv);
- // }
- // else if ( parameter == s.bouncerate )
- // {
- // s.ybounce.setDuration(120000./tempobounce);
- // }
- // }
- // }
+ // for (Sphery s : spherys) {
+ // if (s == null) continue;
+ // double bampv = s.bounceamp.getValue();
+ // double brv = s.bouncerate.getValue();
+ // double tempobounce = lx.tempo.bpm();
+ // if (parameter == s.bounceamp)
+ // {
+ // s.ybounce.setRange(bampv*model.yMax/3 , bampv*2*model.yMax/3, brv);
+ // }
+ // else if ( parameter == s.bouncerate )
+ // {
+ // s.ybounce.setDuration(120000./tempobounce);
+ // }
+ // }
+ // }
public void run( double deltaMs) {
- float t = lx.tempo.rampf();
+ float t = lx.tempo.rampf();
float bpm = lx.tempo.bpmf();
float scalevalue = scale.getValuef();
int spherytime= STime.Cur();
switch (spherytime) {
- case 0: t = map(.5*t ,0,.5, 0,1); bpm = .5*bpm; break;
+ case 0: t = map(.5*t ,0,.5, 0,1); bpm = .5*bpm; break;
- case 1: t = t; bpm = bpm; break;
+ case 1: t = t; bpm = bpm; break;
- case 2: t = map(2*t,0,2,0,1); bpm = 2*bpm; break;
+ case 2: t = map(2*t,0,2,0,1); bpm = 2*bpm; break;
- default: t= t; bpm = bpm;
+ default: t= t; bpm = bpm;
}
//switch(sphery.colorscheme)
for ( Sphery s: spherys){
-
- //s.vibration.setBasis(t);
s.setVibrationPeriod(vibrationrate.getValuef());
- // s.setVibrationMagnitude(vibration_magnitude.getValuef());
+ // s.setVibrationMagnitude(vibration_magnitude.getValuef());
}
sinespin.reset()
- // Translate so the center of the car is the origin, offset
+ // Translate so the center of the car is the origin, offset
.center()
.scale(scalevalue, scalevalue, scalevalue)
// Rotate around the origin (now the center of the car) about an y-vector
.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 c = 0;
- // c = blendColor(c, spherys[3].ellipsevalue(Px.x, Px.y, Px.z, model.xMax/4, model.yMax/4, model.zMax/4, 3*model.xMax/4, 3*model.yMax/4, 3*model.zMax/4),ADD);
- // return c;
+ // color c = 0;
+ // c = blendColor(c, spherys[3].ellipsevalue(Px.x, Px.y, Px.z, model.xMax/4, model.yMax/4, model.zMax/4, 3*model.xMax/4, 3*model.yMax/4, 3*model.zMax/4),ADD);
+ // return c;
// }
// return lx.hsb(0,0,0);
- // // else if(spheremode ==2)
+ // // else if(spheremode ==2)
// { color c = 0;
- // return lx.hsb(CalcCone( (xyz by = new xyz(0,spherys[2].ybounce.getValuef(),0) ), Px, mid) );
+ // return lx.hsb(CalcCone( (xyz by = new xyz(0,spherys[2].ybounce.getValuef(),0) ), Px, mid) );
// }
- // }
+ // }
}
/*This just takes all of Dan Horwitz's code that I want to inherit and leaves the rest behind.
- A work in progress. */
+ A work in progress. */
public class APat extends SCPattern
{
- ArrayList<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);
+ 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;
+ Pick addPick(String name, int def, int _max, String[] desc) {
+ Pick P = new Pick(name, def, _max+1, nMaxRow, desc);
+ nMaxRow = P.EndRow + 1;
picks.add(P);
return P;
}
- boolean noteOff(Note note) {
+ boolean noteOff(Note note) {
int row = note.getPitch(), col = note.getChannel();
for (int i=0; i<bools.size(); i++) if (bools.get(i).set(row, col, false)) { presetManager.dirty(this); return true; }
updateLights(); return false;
}
- boolean noteOn(Note note) {
+ 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;
+ 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() {
+ 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();
+ presetManager.dirty(this);
+ updateLights();
}
- APat(GLucose glucose) {
- super(glucose);
+ 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);
+ 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;}}
}
}
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);
+ 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 (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() + " ";
+ 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;
+ }
}
}
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());
}
}
/**************************************************************
* WORKING PATTERNS
**************************************************************/
-
+import java.util.List;
+import java.util.LinkedList;
class AKPong extends SCPattern
{
private final BasicParameter speed = new BasicParameter("Speed", 0);
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());
--- /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.
+ */
++import java.net.*;
+ GrizzlyOutput[] buildGrizzlies() throws SocketException, UnknownHostException {
+ return new GrizzlyOutput[] {
+ new GrizzlyOutput(lx, "192.168.88.100", 6, 5, 6, 7, 7, 8, 1, 2, 4, 3, 11, 10, 9, 9, 12, 13),
+ new GrizzlyOutput(lx, "192.168.88.101", 25, 23, 24, 43, 45, 44, 1, 1, 1, 1, 1, 41, 42, 21, 20, 22),
+ new GrizzlyOutput(lx, "192.168.88.104", 26, 28, 27, 19, 18, 17, 1, 1, 18, 19, 15, 16, 14, 29, 30, 31),
+ new GrizzlyOutput(lx, "192.168.88.105", 1, 1, 1, 39, 38, 40, 34, 35, 33, 32, 37, 37, 1, 1, 1, 1),
+ };
+ }
+
+ /**
+ * Grizzly Output, sends packets to one grizzly board with a fixed IP and a number
+ * of channels.
+ */
+ class GrizzlyOutput extends LXDatagramOutput {
+
+ public final String ipAddress;
+
+ private int frameNumber = 0;
+
+ public GrizzlyOutput(LX lx, String ipAddress, int ... cubeIndices) throws UnknownHostException, SocketException {
+ super(lx);
+ this.ipAddress = ipAddress;
+ int channelNum = 0;
+ for (int rawCubeIndex : cubeIndices) {
+ if (rawCubeIndex > 0) {
+ Cube cube = model.getCubeByRawIndex(rawCubeIndex);
+ addDatagram(new GrizzlyDatagram(this, channelNum, cube).setAddress(ipAddress));
+ }
+ ++channelNum;
+ }
+ this.enabled.setValue(false);
+ }
+
+ protected void beforeSend(int[] colors) {
+ ++frameNumber;
+ }
+
+ public int getFrameNumber() {
+ return this.frameNumber;
+ }
+ }
+
+ /**
+ * Datagram to a Grizzlyboard. A simple fixed OSC packet.
+ */
+ static class GrizzlyDatagram extends LXDatagram {
+
+ private static byte[] oscString(String s) {
+ int len = s.length();
+ int padding = (4 - ((len + 1) % 4)) % 4;
+ byte[] bytes = new byte[len + 1 + padding];
+ System.arraycopy(s.getBytes(), 0, bytes, 0, len);
+ for (int i = len; i < bytes.length; ++i) {
+ bytes[i] = 0;
+ }
+ return bytes;
+ }
+
+ private static int oscIntCopy(int i, byte[] buffer, int pos) {
+ buffer[pos] = (byte) ((i >> 24) & 0xff);
+ buffer[pos + 1] = (byte) ((i >> 16) & 0xff);
+ buffer[pos + 2] = (byte) ((i >> 8) & 0xff);
+ buffer[pos + 3] = (byte) (i & 0xff);
+ return 4;
+ }
+
+ private final static int[] STRIP_ORDERING = new int[] { 9, 8, 11, 5, 4, 7, 6, 10, 14, 2, 1, 0, 3, 13, 12, 15 };
+
+ private static int[] cubePointIndices(Cube cube) {
+ int[] pointIndices = new int[Cube.POINTS_PER_CUBE - 2];
+ int pi = 0;
+ for (int stripIndex : STRIP_ORDERING) {
+ Strip strip = cube.strips.get(stripIndex);
+ int stripLen = ((stripIndex == 9) || (stripIndex == 15)) ? 15 : 16;
+ for (int i = stripLen-1; i >= 0; --i) {
+ pointIndices[pi++] = strip.points.get(i).index;
+ }
+ }
+ return pointIndices;
+ }
+
+ private final static byte[] OSC_ADDRESS = oscString("/shady/pointbuffer");
+ private final static byte[] OSC_TYPETAG = oscString(",iiiiibi");
+
+ private final static int HEADER_LENGTH = OSC_ADDRESS.length + OSC_TYPETAG.length + 24;
+ private final static int FOOTER_LENGTH = 4;
+
+ private final static int OSC_PORT = 779;
+
+ private GrizzlyOutput output;
+
+ private int[] pointIndices;
+
+ private final int frameNumberPos;
+
+ private final int dataPos;
+
+ public GrizzlyDatagram(GrizzlyOutput output, int channelNum, Cube cube) {
+ this(output, channelNum, cubePointIndices(cube));
+ }
+
+ public GrizzlyDatagram(GrizzlyOutput output, int channelNum, int[] pointIndices) {
+ super(HEADER_LENGTH + 4*pointIndices.length + FOOTER_LENGTH);
+ setPort(OSC_PORT);
+
+ this.output = output;
+ this.pointIndices = pointIndices;
+ int dataLength = 4*pointIndices.length;
+
+ int pos = 0;
+
+ // OSC address
+ System.arraycopy(OSC_ADDRESS, 0, this.buffer, pos, OSC_ADDRESS.length);
+ pos += OSC_ADDRESS.length;
+
+ // OSC typetag
+ System.arraycopy(OSC_TYPETAG, 0, this.buffer, pos, OSC_TYPETAG.length);
+ pos += OSC_TYPETAG.length;
+ this.frameNumberPos = pos;
+ pos += oscIntCopy(0, this.buffer, pos); // placeholder for frame number
+ pos += oscIntCopy(0xDEADBEEF, this.buffer, pos);
+ pos += oscIntCopy(channelNum, this.buffer, pos);
+ pos += oscIntCopy(0xFEEDBEEF, this.buffer, pos);
+ pos += oscIntCopy(dataLength, this.buffer, pos);
+ pos += oscIntCopy(dataLength, this.buffer, pos);
+ this.dataPos = pos;
+
+ // end header
+ oscIntCopy(0xBEFFFFEB, this.buffer, this.buffer.length - 4);
+ }
+
+ void onSend(int[] colors) {
+ oscIntCopy(this.output.getFrameNumber(), this.buffer, frameNumberPos);
+ int dataIndex = this.dataPos;
+ for (int index : this.pointIndices) {
+ color c = (index >= 0) ? colors[index] : 0;
+ this.buffer[dataIndex] = (byte) 0; // unused, alpha
+ this.buffer[dataIndex + 1] = (byte) ((c >> 16) & 0xff); // r
+ this.buffer[dataIndex + 2] = (byte) ((c >> 8) & 0xff); // g
+ this.buffer[dataIndex + 3] = (byte) (c & 0xff); // b
+ dataIndex += 4;
+ }
+ }
+ }
* for general animation work.
*/
- import glucose.*;
- import glucose.model.*;
import heronarts.lx.*;
import heronarts.lx.effect.*;
+ import heronarts.lx.model.*;
import heronarts.lx.modulator.*;
import heronarts.lx.parameter.*;
import heronarts.lx.pattern.*;
import heronarts.lx.transform.*;
import heronarts.lx.transition.*;
+ import heronarts.lx.ui.*;
+ import heronarts.lx.ui.component.*;
+ import heronarts.lx.ui.control.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import processing.opengl.*;
import rwmidi.*;
import java.lang.reflect.*;
- import javax.media.opengl.*;
+ import java.util.ArrayList;
+ import java.util.Collections;
+ import java.util.List;
- final int VIEWPORT_WIDTH = 900;
- final int VIEWPORT_HEIGHT = 700;
+ static final int VIEWPORT_WIDTH = 900;
+ static final int VIEWPORT_HEIGHT = 700;
+
+ static final int LEFT_DECK = 0;
+ static final int RIGHT_DECK = 1;
// The trailer is measured from the outside of the black metal (but not including the higher welded part on the front)
- final float TRAILER_WIDTH = 240;
- final float TRAILER_DEPTH = 97;
- final float TRAILER_HEIGHT = 33;
+ static final float TRAILER_WIDTH = 192;
+ static final float TRAILER_DEPTH = 192;
+ static final float TRAILER_HEIGHT = 33;
int targetFramerate = 60;
int startMillis, lastMillis;
// Core engine variables
- GLucose glucose;
LX lx;
+ Model model;
LXPattern[] patterns;
+ LXTransition[] transitions;
Effects effects;
+ LXEffect[] effectsArr;
+ DiscreteParameter selectedEffect;
MappingTool mappingTool;
- PandaDriver[] pandaBoards;
+ GrizzlyOutput[] grizzlies;
PresetManager presetManager;
MidiEngine midiEngine;
// Display configuration mode
boolean mappingMode = false;
boolean debugMode = false;
- DebugUI debugUI;
- boolean uiOn = true;
boolean simulationOn = true;
boolean diagnosticsOn = false;
LXPattern restoreToPattern = null;
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();
- PGraphicsOpenGL gl = (PGraphicsOpenGL) g;
-
- //gl.glClear(javax.media.opengl.GL.GL_DEPTH_BUFFER_BIT);
- //((PGraphicsOpenGL)g).endGL();
- strokeWeight(1);
-
- if (uiOn) {
- for (UIContext context : overlays) {
- context.draw();
- }
- }
-
+ void drawFPS() {
// Always draw FPS meter
fill(#555555);
textSize(9);
textAlign(LEFT, BASELINE);
text("FPS: " + ((int) (frameRate*10)) / 10. + " / " + targetFramerate + " (-/+)", 4, height-4);
-
- if (debugMode) {
- debugUI.draw();
- }
}
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);
- }
- }
+import java.util.Map;
+import java.util.TreeMap;
color BLACK = #000000;
class Gimbal extends SCPattern {
private final BasicParameter bP = new BasicParameter("b", 0);
private final BasicParameter gP = new BasicParameter("g", 0);
- Gimbal(GLucose glucose) {
- super(glucose);
+ Gimbal(LX lx) {
+ super(lx);
projection = new LXProjection(model);
addParameter(beatsPerRevolutionParam);
addParameter(hueDeltaParam);
_P size;
*/
- Zebra(GLucose glucose) {
- super(glucose);
+ Zebra(LX lx) {
+ super(lx);
projection = new LXProjection(model);
addModulator(angleM).trigger();
+import java.util.Iterator;
class JackieSquares extends SCPattern {
private BasicParameter rateParameter = new BasicParameter("RATE", 0.25);
private BasicParameter attackParameter = new BasicParameter("ATTK", 0.3);
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);
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;
} else {
mapKeys();
}
- registerKeyEvent(this);
+ //registerKeyEvent(this);
}
private void mapAPC() {
if (!enabled) {
return;
}
- char c = Character.toLowerCase(e.getKeyChar());
+ /* char c = 0;//0Character.toLowerCase(e.getKeyChar());
NoteMeta nm = keyToNote.get(c);
if (nm != null) {
switch (e.getID()) {
octaveShift = constrain(octaveShift+1, -4, 4);
break;
}
- }
+ }*/
}
}
// 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;
return true;
case 83: // scene 2
- effects.flash.trigger();
+ //effects.flash.trigger();
return true;
case 84: // scene 3
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.
*/
- import java.util.Arrays;
+ static final float SPACING = 27;
+ static final float RISER = 13.5;
+ static final float FLOOR = 0;
- final int MaxCubeHeight = 6;
- final int NumBackTowers = 16;
+ /**
+ * Definitions of tower positions. This is all that should need
+ * to be modified. Distances are measured from the left-most cube.
+ * The first value is the offset moving NE (towards back-right).
+ * The second value is the offset moving NW (negative comes forward-right).
+ */
+ static final float[][] TOWER_CONFIG = new float[][] {
+ new float[] { 0, 0, RISER, 4 },
+ new float[] { 25, -10, RISER, 4 },
+ new float[] { 50, -22.5, FLOOR, 5 },
+ new float[] { 17.25, -35.5, FLOOR, 6 },
+ new float[] { 43.25, -51.5, RISER, 6 },
+ new float[] { 69.25, -56, FLOOR, 6 },
+ new float[] { 12.75, -62.5, RISER, 4 },
+ new float[] { 38.75, -78.5, FLOOR, 5 },
+ new float[] { 65.75, -83, RISER, 5 },
+
+ };
public Model buildModel() {
- // Shorthand helpers for specifying wiring more quickly
- final Cube.Wiring WFL = Cube.Wiring.FRONT_LEFT;
- final Cube.Wiring WFR = Cube.Wiring.FRONT_RIGHT;
- final Cube.Wiring WRL = Cube.Wiring.REAR_LEFT;
- final Cube.Wiring WRR = Cube.Wiring.REAR_RIGHT;
-
- // Utility value if you need the height of a cube shorthand
- final float CH = Cube.EDGE_HEIGHT;
- final float CW = Cube.EDGE_WIDTH ;
-
- // Positions for the bass box
- final float BBY = BassBox.EDGE_HEIGHT + BoothFloor.PLEXI_WIDTH;
- final float BBX = 56;
- final float BBZ = 2;
-
- // The model is represented as an array of towers. The cubes in the tower
- // are represenented relatively. Each tower has an x, y, z reference position,
- // which is typically the base cube's bottom left corner.
- //
- // Following that is an array of floats. A 2-d array contains an x-offset
- // and a z-offset from the previous reference position. Typically the first cube
- // will just be {0, 0}. Each successive cube uses the position of the previous
- // cube as its reference.
- //
- // A 3-d array contains an x-offset, a z-offset, and a rotation about the
- // y-axis.
- //
- // The cubes automatically increment their y-position by Cube.EDGE_HEIGHT.
-
- // To-Do: (Mark Slee, Alex Green, or Ben Morrow): The Cube # is determined by the order in this list.
- // "raw object index" is serialized by running through towermapping and then individual cube mapping below.
- // We can do better than this. The raw object index should be obvious from the code-- looking through the
- // rendered simulation and counting through cubes in mapping mode is grossly inefficient.
-
- TowerMapping[] towerCubes = new TowerMapping[] {};
-
- // Single cubes can be constructed directly here if you need them
- Cube[] singleCubes = new Cube[] {
- // new Cube(15, int( Cube.EDGE_HEIGHT), 39, 0, 10, 0, WRL), // Back left channel behind speaker
- //new Cube(x, y, z, rx, ry, rz, wiring),
- //new Cube(0,0,0,0,225,0, WRR),
- };
-
- // The bass box!
- // BassBox bassBox = BassBox.unlitBassBox(BBX, 0, BBZ); // frame exists, no lights
- BassBox bassBox = BassBox.noBassBox(); // no bass box at all
- // BassBox bassBox = new BassBox(BBX, 0, BBZ); // bass box with lights
-
- // The speakers!
- List<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 current_x_position = 0;
- // scubes.add(new StaggeredTower(//tower 1
- // current_x_position, // x
- // 15 , // y
- // 0 , // z
- // 45, 6, new Cube.Wiring[] { WFL, WRR, WFL, WRR, WFL, WRR}) );
- // current_x_position += 25.25;
- // scubes.add(new StaggeredTower(// tower 2
- // current_x_position, // x
- // 0 , // y
- // -10.5 , // z
- // 45, 6, new Cube.Wiring[] { WFR, WFL, WRR, WRR, WFL, WRR}) );
- // current_x_position += 25.25;
- // scubes.add(new StaggeredTower(//tower 3
- // current_x_position, // x
- // 15 , // y
- // 0, // z
- // 45, 6, new Cube.Wiring[] { WRR, WFL, WRR, WRR, WFL, WRR}) );
- // current_x_position += 25.25;
- // scubes.add(new StaggeredTower(//tower 4
- // current_x_position, // x
- // 0, // y
- // -10.5 , // z
- // 45, 6, new Cube.Wiring[] { WFL, WRR, WFL, WRR, WFL, WRR}) );
- // current_x_position += 28;
- // scubes.add(new StaggeredTower(//tower 5
- // current_x_position, // x
- // 15 , // y
- // -4.5 , // z
- // 45, 6, new Cube.Wiring[] { WRR, WFL, WRR, WFL, WRR, WFL}) );
- // current_x_position += 28;
- // scubes.add(new StaggeredTower(//tower 6
- // current_x_position, // x
- // 0 , // y
- // -10.5, // z
- // 45, 6, new Cube.Wiring[] { WFL, WRR, WFL, WRR, WFL, WRR}) );
- // current_x_position += 25.25;
- // scubes.add(new StaggeredTower(// tower 7
- // current_x_position, // x
- // 15 , // y
- // 0, // z
- // 45, 6, new Cube.Wiring[] { WRR, WFL, WRR, WFL, WRR, WFL}) );
- // current_x_position += 25.25;
- // scubes.add(new StaggeredTower(//tower 8
- // current_x_position, // x
- // 0 , // y
- // -10.5 , // z
- // 45, 6, new Cube.Wiring[] { WFL, WRR, WFL, WRR, WFL, WRR}) );
- // current_x_position += 25.25;
- // scubes.add(new StaggeredTower(//tower 9
- // current_x_position, // x
- // 15 , // y
- // 0, // z
- // 45, 6, new Cube.Wiring[] { WFL, WRR, WFL, WRR, WFL, WRR}) );
- // current_x_position += 25.25;
-
- // //TOWERS ON DANCE FLOOR
- // scubes.add(new StaggeredTower(//tower 10
- // 83.75+39+43-124.5, // x
- // 0, // y
- // -47.5-43, // z
- // 45, 4, new Cube.Wiring[]{ WRR, WFL, WFL, WRR}) );
- // scubes.add(new StaggeredTower(//tower 11
- // 83.75, // x
- // 0, // y
- // -47.5, // z
- // 45, 4, new Cube.Wiring[]{ WFL, WRR, WRR, WFL}) );
- // scubes.add(new StaggeredTower(//tower 12
- // 83.75+39, // x
- // 0, // y
- // -47.5, // z
- // 45, 4, new Cube.Wiring[]{ WRR, WFL, WFL, WRR}) );
- // scubes.add(new StaggeredTower(//tower 13
- // 83.75+39+43, // x
- // 0, // y
- // -47.5-43, // z
- // 45, 4, new Cube.Wiring[]{ WFL, WRR, WFL, WRR}) );
-
- // scubes.add(new StaggeredTower(// Single cube on top of tower 4
- // 42, // x
- // 112 , // y
- // 72, // z
- // -10, 1, new Cube.Wiring[]{ WRL}) );
-
-
-
-
-
-
-
- //////////////////////////////////////////////////////////////////////
- // BENEATH HERE SHOULD NOT REQUIRE ANY MODIFICATION!!!! //
- //////////////////////////////////////////////////////////////////////
-
- // These guts just convert the shorthand mappings into usable objects
- ArrayList<Tower> towerList = new ArrayList<Tower>();
- ArrayList<Cube> tower;
+ List<Tower> towers = new ArrayList<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;
+ int cubeIndex = 1;
+
+ float rt2 = sqrt(2);
+ float x, y, z, xd, zd, num;
+ for (float[] tc : TOWER_CONFIG) {
+ x = -tc[1];
+ z = tc[0];
+ y = tc[2];
+ num = tc[3];
+ if (z < x) {
+ zd = -(x-z)/rt2;
+ xd = z*rt2 - zd;
+ } else {
+ zd = (z-x)/rt2;
+ xd = z*rt2 - zd;
}
- towerList.add(new Tower(tower));
- }
-
-
- for (Cube cube : singleCubes) {
- cubes[cubeIndex++] = cube;
- }
- for (Cube cube : dcubes) {
- cubes[cubeIndex++] = cube;
- }
- for (StaggeredTower st : scubes) {
- tower = new ArrayList<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);
- }
-
- /**
- * This function maps the panda boards. We have an array of them, each has
- * an IP address and a list of channels.
- */
- public PandaMapping[] buildPandaList() {
- final int LEFT_SPEAKER = 0;
- final int RIGHT_SPEAKER = 1;
-
- // 8 channels map to: 3, 4, 7, 8, 13, 14, 15, 16.
- return new PandaMapping[] {
- new PandaMapping(
- "10.200.1.28", new ChannelMapping[] {
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 37, 38, 39 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 43, 44, 45 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 46, 47, 48 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // new front thing
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // new back thing
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 13, 14, 15 }), // new back thing
- }),
- new PandaMapping(
- "10.200.1.29", new ChannelMapping[] {
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 19, 20, 21 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1, 2, 3 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 4, 5, 6 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 7, 8, 9 }),
-
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 10, 11, 12 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 16, 17, 18 }),
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 34, 35, 36}),
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }),
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 19, 20, 21}),
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 22, 23, 24}),
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 25, 26, 27}),
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 28, 29, 30}),
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 31, 32, 33}),
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }),
- }),
- new PandaMapping(
- "10.200.1.30", new ChannelMapping[] {
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 40, 41, 42 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 22, 23, 24 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 25, 26, 27 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 28, 29, 30 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 31, 32, 33 }),
- new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 34, 35, 36 }),
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1,1}), // 30 J3 *
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1,1}), // 30 J4 //ORIG *
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 37, 38, 39}), // 30 J7 *
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 40, 41, 42}), // 30 J8 *
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 43, 44, 45}), // 30 J13 (not working)
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 46, 47, 48}), // 30 J14 (unplugged)
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 49, 50, 51}), // 30 J15 (unplugged)
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 52, 53, 54}), // 30 J16
- }),
- // new PandaMapping(
- // "10.200.1.31", new ChannelMapping[] {
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 65, 66}), // J3
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1}), // J4
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 55, 56}), // 30 J7
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 57, 58}), // J8
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 59, 60}), // J13
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 61, 62}), // 30 J14
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 63, 64}), // J15
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1}), // J16
- // }),
-
- // new PandaMapping(
- // "10.200.1.32", new ChannelMapping[] {
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // J3
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // J4
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 67, 68}), // 30 J7
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 69, 70}), // J8
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // J13
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // 30 J14
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // J15
- // new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { }), // J16
- // }),
- };
- }
-
- class TowerMapping {
- public final float x, y, z;
- public final CubeMapping[] cubeMappings;
-
- TowerMapping(float x, float y, float z, CubeMapping[] cubeMappings) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.cubeMappings = cubeMappings;
- }
- }
-
- class CubeMapping {
- public final float dx, dz, ry;
- public final Cube.Wiring wiring;
-
- CubeMapping(float dx, float dz, Cube.Wiring wiring) {
- this(dx, dz, 0., wiring);
- }
- CubeMapping(float dx, float dz, float ry) {
- this(dz, dz, ry, Cube.Wiring.FRONT_LEFT);
- }
-
- CubeMapping(float dx, float dz, float ry, Cube.Wiring wiring) {
- this.dx = dx;
- this.dz = dz;
- this.ry = ry;
- this.wiring = wiring;
- }
- }
-
- class StaggeredTower {
- public final float x, y, z, r;
- public final int n;
- public final Cube.Wiring[] wiring;
- StaggeredTower(float _x, float _y, float _z, float _r, int _n) { this(_x, _y, _z, _r, _n, new Cube.Wiring[]{}); }
- StaggeredTower(float _x, float _y, float _z, float _r, int _n, Cube.Wiring[] _wiring) { x=_x; y=_y; z=_z; r=_r; n=_n; wiring=_wiring;}
- }
-
- /**
- * Each panda board has an IP address and a fixed number of channels. The channels
- * each have a fixed number of pixels on them. Whether or not that many physical
- * pixels are connected to the channel, we still send it that much data.
- */
- class PandaMapping {
-
- // How many channels are on the panda board
- public final static int CHANNELS_PER_BOARD = 8;
-
- // How many total pixels on the whole board
- public final static int PIXELS_PER_BOARD = ChannelMapping.PIXELS_PER_CHANNEL * CHANNELS_PER_BOARD;
-
- final String ip;
- final ChannelMapping[] channelList = new ChannelMapping[CHANNELS_PER_BOARD];
-
- PandaMapping(String ip, ChannelMapping[] rawChannelList) {
- this.ip = ip;
-
- // Ensure our array is the right length and has all valid items in it
- for (int i = 0; i < channelList.length; ++i) {
- channelList[i] = (i < rawChannelList.length) ? rawChannelList[i] : new ChannelMapping();
- if (channelList[i] == null) {
- channelList[i] = new ChannelMapping();
- }
+ List<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));
}
- }
-
- /**
- * Each channel on a pandaboard can be mapped in a number of modes. The typical is
- * to a series of connected cubes, but we also have special mappings for the bass box,
- * the speaker enclosures, and the DJ booth floor.
- *
- * This class is just the mapping meta-data. It sanitizes the input to make sure
- * that the cubes and objects being referenced actually exist in the model.
- *
- * The logic for how to encode the pixels is contained in the PandaDriver.
- */
- class ChannelMapping {
-
- // How many cubes per channel xc_PB is configured for
- public final static int CUBES_PER_CHANNEL = 4;
- // How many total pixels on each channel
- public final static int PIXELS_PER_CHANNEL = Cube.POINTS_PER_CUBE * CUBES_PER_CHANNEL;
-
- public static final int MODE_NULL = 0;
- public static final int MODE_CUBES = 1;
- public static final int MODE_BASS = 2;
- public static final int MODE_SPEAKER = 3;
- public static final int MODE_STRUTS_AND_FLOOR = 4;
- public static final int MODE_INVALID = 5;
-
- public static final int NO_OBJECT = -1;
-
- final int mode;
- final int[] objectIndices = new int[CUBES_PER_CHANNEL];
-
- ChannelMapping() {
- this(MODE_NULL);
- }
-
- ChannelMapping(int mode) {
- this(mode, new int[]{});
- }
-
- ChannelMapping(int mode, int rawObjectIndex) {
- this(mode, new int[]{ rawObjectIndex });
- }
-
- ChannelMapping(int mode, int[] rawObjectIndices) {
- if (mode < 0 || mode >= MODE_INVALID) {
- throw new RuntimeException("Invalid channel mapping mode: " + mode);
- }
- if (mode == MODE_SPEAKER) {
- if (rawObjectIndices.length != 1) {
- throw new RuntimeException("Speaker channel mapping mode must specify one speaker index");
- }
- int speakerIndex = rawObjectIndices[0];
- if (speakerIndex < 0 || speakerIndex >= glucose.model.speakers.size()) {
- throw new RuntimeException("Invalid speaker channel mapping: " + speakerIndex);
- }
- } else if ((mode == MODE_STRUTS_AND_FLOOR) || (mode == MODE_BASS) || (mode == MODE_NULL)) {
- if (rawObjectIndices.length > 0) {
- throw new RuntimeException("Bass/floor/null mappings cannot specify object indices");
- }
- } else if (mode == MODE_CUBES) {
- for (int rawCubeIndex : rawObjectIndices) {
- if (glucose.model.getCubeByRawIndex(rawCubeIndex) == null) {
- throw new RuntimeException("Non-existing cube specified in cube mapping: " + rawCubeIndex);
- }
- }
- }
-
- this.mode = mode;
- for (int i = 0; i < objectIndices.length; ++i) {
- objectIndices[i] = (i < rawObjectIndices.length) ? rawObjectIndices[i] : NO_OBJECT;
- }
- }
+ return new Model(towers, cubes);
}
+import java.util.Stack;
class Cathedrals extends SCPattern {
private final BasicParameter xpos = new BasicParameter("XPOS", 0.5);
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);
effects.boom.trigger();
break;
case 40:
- effects.flash.trigger();
+ //effects.flash.trigger();
break;
}
}
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];
--- /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();
+ }
+ }
+ }
+
*
* 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);
-
++import java.util.Arrays;
+ class UICubesLayer extends UICameraComponent {
+ void onDraw(UI ui) {
+ color[] simulationColors = lx.getColors();
+ String displayMode = uiCrossfader.getDisplayMode();
+ if (displayMode == "A") {
+ simulationColors = lx.engine.getDeck(LEFT_DECK).getColors();
+ } else if (displayMode == "B") {
+ simulationColors = lx.engine.getDeck(RIGHT_DECK).getColors();
}
+
+ long simulationStart = System.nanoTime();
+ if (simulationOn) {
+ drawSimulation(simulationColors);
+ }
+ simulationNanos = System.nanoTime() - simulationStart;
- LXDeck.Listener lxListener = new LXDeck.AbstractListener() {
- public void patternWillChange(LXDeck deck, LXPattern pattern, LXPattern nextPattern) {
- patternList.redraw();
- }
- public void patternDidChange(LXDeck deck, LXPattern pattern) {
- patternList.redraw();
- int pi = 0;
- for (LXParameter parameter : pattern.getParameters()) {
- if (pi >= parameterKnobs.length) {
- break;
- }
- parameterKnobs[pi++].setParameter(parameter);
- }
- while (pi < parameterKnobs.length) {
- parameterKnobs[pi++].setParameter(null);
- }
- }
- };
-
- deck.addListener(lxListener);
- lxListener.patternDidChange(deck, deck.getActivePattern());
-
+ camera();
- javax.media.opengl.GL gl = ((PGraphicsOpenGL)g).beginGL();
- gl.glClear(javax.media.opengl.GL.GL_DEPTH_BUFFER_BIT);
- ((PGraphicsOpenGL)g).endGL();
++ PGraphicsOpenGL gl = (PGraphicsOpenGL) g;
+ strokeWeight(1);
}
- class PatternScrollItem extends AbstractScrollItem {
-
- private LXPattern pattern;
- private String label;
-
- PatternScrollItem(LXPattern pattern) {
- this.pattern = pattern;
- label = className(pattern, "Pattern");
- }
-
- public String getLabel() {
- return label;
- }
-
- public boolean isSelected() {
- return deck.getActivePattern() == pattern;
- }
+ void drawSimulation(color[] simulationColors) {
+ translate(0, 30, 0);
+
+ noStroke();
+ fill(#141414);
+ drawBox(0, -TRAILER_HEIGHT, 0, 0, 0, 0, TRAILER_WIDTH, TRAILER_HEIGHT, TRAILER_DEPTH, TRAILER_HEIGHT/2.);
+ fill(#070707);
+ stroke(#222222);
+ beginShape();
+ vertex(0, 0, 0);
+ vertex(TRAILER_WIDTH, 0, 0);
+ vertex(TRAILER_WIDTH, 0, TRAILER_DEPTH);
+ vertex(0, 0, TRAILER_DEPTH);
+ endShape();
+
+ // Draw the logo on the front of platform
+ pushMatrix();
+ translate(0, 0, -1);
+ float s = .07;
+ scale(s, -s, s);
+ image(logo, TRAILER_WIDTH/2/s-logo.width/2, TRAILER_HEIGHT/2/s-logo.height/2-2/s);
+ popMatrix();
- public boolean isPending() {
- return deck.getNextPattern() == pattern;
+ noStroke();
+ for (Cube c : model.cubes) {
+ drawCube(c);
}
-
- public void onMousePressed() {
- deck.goPattern(pattern);
+
+ noFill();
+ strokeWeight(2);
+ beginShape(POINTS);
+ for (LXPoint p : model.points) {
+ stroke(simulationColors[p.index]);
+ vertex(p.x, p.y, p.z);
+ }
+ endShape();
+ }
+
+ void drawCube(Cube c) {
+ float in = .15;
+ noStroke();
+ fill(#393939);
+ drawBox(c.x+in, c.y+in, c.z+in, c.rx, c.ry, c.rz, Cube.EDGE_WIDTH-in*2, Cube.EDGE_HEIGHT-in*2, Cube.EDGE_WIDTH-in*2, Cube.CHANNEL_WIDTH-in);
+ }
+
+ void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) {
+ pushMatrix();
+ translate(x, y, z);
+ rotate(rx / 180. * PI, -1, 0, 0);
+ rotate(ry / 180. * PI, 0, -1, 0);
+ rotate(rz / 180. * PI, 0, 0, -1);
+ for (int i = 0; i < 4; ++i) {
+ float wid = (i % 2 == 0) ? xd : zd;
+
+ beginShape();
+ vertex(0, 0);
+ vertex(wid, 0);
+ vertex(wid, yd);
+ vertex(wid - sw, yd);
+ vertex(wid - sw, sw);
+ vertex(0, sw);
+ endShape();
+ beginShape();
+ vertex(0, sw);
+ vertex(0, yd);
+ vertex(wid - sw, yd);
+ vertex(wid - sw, yd - sw);
+ vertex(sw, yd - sw);
+ vertex(sw, sw);
+ endShape();
+
+ translate(wid, 0, 0);
+ rotate(HALF_PI, 0, -1, 0);
}
+ popMatrix();
}
}
class UIBlendMode extends UIWindow {
public UIBlendMode(float x, float y, float w, float h) {
- super("BLEND MODE", x, y, w, h);
- List<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);
}
}
--- /dev/null
--- /dev/null
++mode.id=processing.mode.java.JavaMode
++mode=Java