color spheryvalue (float px, float py, float pz , float f1xc, float f1yc, float f1zc)
{
//switch(sShpape.cur() ) {}
- return color(constrain(huespread.getValuef()*5*px, 0, 360) , dist(px, py, pz, f1xc, f1yc, f1zc) ,
+ return lx.hsb(constrain(huespread.getValuef()*5*px, 0, 360) , dist(px, py, pz, f1xc, f1yc, f1zc) ,
max(0, 100 - 100*widthparameter.getValuef()*abs(dist(px, py, pz, f1xcenter, ybounce.getValuef(), f1zcenter)
- vibration.getValuef() ) ) );
}
color ellipsevalue(float px, float py, float pz , float f1xc, float f1yc, float f1zc, float f2xc, float f2yc, float f2zc)
{
//switch(sShpape.cur() ) {}
- return color(huespread.getValuef()*5*px, dist(model.xMax-px, model.yMax-py, model.zMax-pz, f1xc, f1yc, f1zc) ,
+ 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
// 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 color(0,0,0);
+ // return lx.hsb(0,0,0);
// // else if(spheremode ==2)
// { color c = 0;
- // return color(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) );
// }
for (Point p : model.points) {
color c = 0;
- c = blendColor(c, color(360*HueT.getValuef(), 100*SatT.getValuef(), 100*BriT.getValuef()), ADD);
+ c = blendColor(c, lx.hsb(360*HueT.getValuef(), 100*SatT.getValuef(), 100*BriT.getValuef()), ADD);
colors[p.index]= c;
}
int now= millis();
}
}
- }
\ No newline at end of file
+ }
void run(double deltaMs) {
boolean d = direction.getValuef() > 5.0;
for (Point p : model.points) {
- colors[p.index] = color((lx.getBaseHuef() + random(hueParameter.getValuef() * 360))%360, random(saturationParameter.getValuef() * 100), random(brightParameter.getValuef() * 100));
+ colors[p.index] = lx.hsb((lx.getBaseHuef() + random(hueParameter.getValuef() * 360))%360, random(saturationParameter.getValuef() * 100), random(brightParameter.getValuef() * 100));
}
}
}
void run(double deltaMs) {
for (Point p : model.points) {
color c = img.get((int)((p.x / model.xMax) * img.width), img.height - (int)((p.y / model.yMax) * img.height));
- colors[p.index] = color(hue(c) + colorMod.getValuef()%360, saturation(c), brightness(c) - ((p.fz - brightMod.getValuef())/p.fz));
+ colors[p.index] = lx.hsb(hue(c) + colorMod.getValuef()%360, saturation(c), brightness(c) - ((p.z - brightMod.getValuef())/p.z));
}
}
}
super(glucose);
addParameter(r);
for (Point p : model.points) {
- colors[p.index] = color(0, 0, 0);
+ colors[p.index] = lx.hsb(0, 0, 0);
}
}
float x = model.xMax / 2 + cos(angle) * rad;
float y = model.yMax / 2 + sin(angle) * rad;
for (Point p : model.points) {
- float b = dist(x,y,p.fx,p.fy);
+ float b = dist(x,y,p.x,p.y);
if (b < 90) {
colors[p.index] = blendColor(
colors[p.index],
- color(lx.getBaseHuef() + 25, 10, map(b, 0, 10, 100, 0)),
+ lx.hsb(lx.getBaseHuef() + 25, 10, map(b, 0, 10, 100, 0)),
ADD);
} else {
colors[p.index] = blendColor(
colors[p.index],
- color(25, 10, map(b, 0, 10, 0, 15)),
+ lx.hsb(25, 10, map(b, 0, 10, 0, 15)),
SUBTRACT);
}
}
}
towerSize = model.towers.size();
colorSpan = 255 / towerSize;
- println("towers "+towerSize);
}
void run(double deltaMs)
{
if(p.y<towerParams.get(i).getValuef()*200)
{
- colors[p.index]=color(255 * hueoff.getValuef()+colorSpan * hueSpan.getValuef() * i, 255, 255);
+ colors[p.index]=lx.hsb(255 * hueoff.getValuef()+colorSpan * hueSpan.getValuef() * i, 255, 255);
}
}
}
{
doDraw(c,0);
c = (c + 1) % towerrange;
- long col = color(Math.round(Math.random()*255),255,255) ;
+ long col = lx.hsb(Math.round(Math.random()*255),255,255) ;
doDraw(c,col);
}
counter++;
-//----------------------------------------------------------------------------------------------------------------------------------\r
-public class Pong extends DPat {\r
- SinLFO x,y,z,dx,dy,dz; \r
- float cRad; DParam pSize;\r
- Pick pChoose;\r
- xyz v = new xyz(), vMir = new xyz();\r
-\r
- Pong(GLucose glucose) {\r
- super(glucose);\r
- cRad = mMax.x/10;\r
- addModulator(dx = new SinLFO(6000, 500, 30000 )).trigger();\r
- addModulator(dy = new SinLFO(3000, 500, 22472 )).trigger();\r
- addModulator(dz = new SinLFO(1000, 500, 18420 )).trigger();\r
- addModulator(x = new SinLFO(cRad, mMax.x - cRad, 0)).trigger(); x.modulateDurationBy(dx);\r
- addModulator(y = new SinLFO(cRad, mMax.y - cRad, 0)).trigger(); y.modulateDurationBy(dy);\r
- addModulator(z = new SinLFO(cRad, mMax.z - cRad, 0)).trigger(); z.modulateDurationBy(dz);\r
- pSize = addParam ("Size" , 0.4 );\r
- pChoose = addPick ("Animiation" , 0, 2, new String[] {"Pong", "Ball", "Cone"} );\r
- }\r
-\r
- void StartRun(double deltaMs) { cRad = mMax.x*pSize.Val()/6; }\r
- color CalcPoint(xyz p) {\r
- v.set(x.getValuef(), y.getValuef(), z.getValuef());\r
- v.z=0;p.z=0;// ignore z dimension\r
- switch(pChoose.Cur()) {\r
- case 0: vMir.set(mMax); vMir.subtract(p);\r
- return color(0,0,c1c(1 - min(v.distance(p), v.distance(vMir))*.5/cRad)); // balls\r
- case 1: return color(0,0,c1c(1 - v.distance(p)*.5/cRad)); // ball\r
- case 2: vMir.set(mMax.x/2,0,mMax.z/2);\r
- return color(0,0,c1c(1 - CalcCone(p,v,vMir) * max(.02,.45-pSize.Val()))); // spot\r
- }\r
- return color(0,0,0);\r
- }\r
-}\r
-//----------------------------------------------------------------------------------------------------------------------------------\r
-public class NDat {\r
- float xz, yz, zz, hue, sat, speed, angle, den;\r
- float xoff,yoff,zoff;\r
- float sinAngle, cosAngle;\r
- boolean isActive;\r
- NDat () { isActive=false; }\r
- boolean Active() { return isActive; }\r
- void set (float _hue, float _sat, float _xz, float _yz, float _zz, float _den, float _speed, float _angle) {\r
- isActive = true;\r
- hue=_hue; sat=_sat; xz=_xz; yz=_yz; zz =_zz; den=_den; speed=_speed; angle=_angle;\r
- xoff = random(100e3); yoff = random(100e3); zoff = random(100e3);\r
- }\r
-}\r
-\r
-public class Noise extends DPat\r
-{\r
- int CurAnim, iSymm;\r
- int XSym=1,YSym=2,RadSym=3;\r
- float zTime , zTheta=0, zSin, zCos, rtime, ttime, transAdd;\r
- DParam pSpeed , pDensity;\r
- Pick pChoose, pSymm;\r
- int _ND = 4;\r
- NDat N[] = new NDat[_ND];\r
-\r
- Noise(GLucose glucose) {\r
- super(glucose);\r
- pSpeed = addParam("Fast" , .55);\r
- pDensity = addParam("Dens" , .5);\r
- pSymm = addPick("Symmetry" , 0, 3, new String[] {"None", "X", "Y", "Radial"} );\r
- pChoose = addPick("Animation", 6, 7, new String[] {"Drip", "Cloud", "Rain", "Fire", "Machine", "Spark","VWave", "Wave"} );\r
- for (int i=0; i<_ND; i++) N[i] = new NDat();\r
- }\r
-\r
- void StartPattern() { zTime = random(500); zTheta=0; rtime = 0; ttime = 0; transAdd=0; }\r
- void StartRun(double deltaMs) {\r
- zTime += deltaMs*(pSpeed.Val()-.5)*.002 ;\r
- zTheta += deltaMs*(pSpin .Val()-.5)*.01 ;\r
- rtime += deltaMs;\r
- iSymm = pSymm.Cur();\r
- transAdd = 1*(1 - constrain(rtime - ttime,0,1000)/1000);\r
- zSin = sin(zTheta);\r
- zCos = cos(zTheta);\r
-\r
- if (pChoose.Cur() != CurAnim) {\r
- CurAnim = pChoose.Cur(); ttime = rtime;\r
- pSpin .reset(); zTheta = 0;\r
- pDensity .reset(); pSpeed .reset();\r
- for (int i=0; i<_ND; i++) { N[i].isActive = false; }\r
- \r
- switch(CurAnim) {\r
- // hue sat xz yz zz den mph angle\r
- case 0: N[0].set(0 ,0 ,75 ,75 ,150,45 ,3 ,0 ); pSharp.set(1 ); break; // drip\r
- case 1: N[0].set(0 ,0 ,100,100,200,45 ,3 ,180); pSharp.set(0 ); break; // clouds\r
- case 2: N[0].set(0 ,0 ,2 ,400,2 ,20 ,3 ,0 ); pSharp.set(.5); break; // rain\r
- case 3: N[0].set(40 ,1 ,100,100,200,10 ,1 ,180); \r
- N[1].set(0 ,1 ,100,100,200,10 ,5 ,180); pSharp.set(0 ); break; // fire 1\r
- case 4: N[0].set(0 ,1 ,40 ,40 ,40 ,15 ,2.5,180);\r
- N[1].set(20 ,1 ,40 ,40 ,40 ,15 ,4 ,0 );\r
- N[2].set(40 ,1 ,40 ,40 ,40 ,15 ,2 ,90 );\r
- N[3].set(60 ,1 ,40 ,40 ,40 ,15 ,3 ,-90); pSharp.set(.5); break; // machine\r
- case 5: N[0].set(0 ,1 ,400,100,2 ,15 ,3 ,90 );\r
- N[1].set(20 ,1 ,400,100,2 ,15 ,2.5,0 );\r
- N[2].set(40 ,1 ,100,100,2 ,15 ,2 ,180);\r
- N[3].set(60 ,1 ,100,100,2 ,15 ,1.5,270); pSharp.set(.5); break; // spark\r
- }\r
-\r
- DG.UpdateLights();\r
- }\r
- \r
- for (int i=0; i<_ND; i++) if (N[i].Active()) {\r
- N[i].sinAngle = sin(radians(N[i].angle));\r
- N[i].cosAngle = cos(radians(N[i].angle));\r
- }\r
- }\r
-\r
- color CalcPoint(xyz P) {\r
- color c = 0;\r
- P.RotateZ(mCtr, zSin, zCos);\r
- \r
- if (CurAnim == 6 || CurAnim == 7) {\r
- P.setNorm();\r
- return color(0,0, 100 * (\r
- constrain(1-50*(1-pDensity.Val())*abs(P.y-sin(zTime*10 + P.x*(300))*.5 - .5),0,1) + \r
- (CurAnim == 7 ? constrain(1-50*(1-pDensity.Val())*abs(P.x-sin(zTime*10 + P.y*(300))*.5 - .5),0,1) : 0))\r
- );\r
- } \r
- \r
- if (iSymm == XSym && P.x > mMax.x/2) P.x = mMax.x-P.x;\r
- if (iSymm == YSym && P.y > mMax.y/2) P.y = mMax.y-P.y;\r
-\r
- for (int i=0;i<_ND; i++) if (N[i].Active()) {\r
- NDat n = N[i];\r
- float zx = zTime * n.speed * n.sinAngle,\r
- zy = zTime * n.speed * n.cosAngle;\r
- \r
- float b = (iSymm==RadSym ? noise(zTime*n.speed+n.xoff-Dist(P,mCtr)/n.xz)\r
- : noise(P.x/n.xz+zx+n.xoff,P.y/n.yz+zy+n.yoff,P.z/n.zz+n.zoff))\r
- *1.8;\r
-\r
- b += n.den/100 -.4 + pDensity.Val() -1;\r
- b += transAdd;\r
- c = blendColor(c,color(n.hue,100*n.sat,c1c(b)),ADD);\r
- }\r
- return c;\r
- }\r
-}\r
-//----------------------------------------------------------------------------------------------------------------------------------\r
-public class Play extends DPat\r
-{\r
- public class rAngle {\r
- float prvA, dstA, c;\r
- float prvR, dstR, r; \r
- float _cos, _sin, x, y;\r
- float fixAngle (float a, float b) { return a<b ?\r
- (abs(a-b) > abs(a+2*PI-b) ? a : a+2*PI) :\r
- (abs(a-b) > abs(a-2*PI-b) ? a : a-2*PI) ; }\r
- float getX(float r) { return mCtr.x + _cos*r; }\r
- float getY(float r) { return mCtr.y + _sin*r; }\r
- void move() { c = interp(t,prvA,dstA); \r
- r = interp(t,prvR,dstR);\r
- _cos = cos(c); _sin = sin(c);\r
- x = getX(r); y = getY(r); } \r
- void set() { prvA = dstA; dstA = random(2*PI); prvA = fixAngle(prvA, dstA);\r
- prvR = dstR; dstR = random(mCtr.y); }\r
- }\r
-\r
- int nBeats = 0;\r
- DParam pAmp, pRadius, pBounce;\r
-\r
- float t,amp,rad,bnc;\r
- float zTheta=0;\r
- ArrayList<rWave> waves = new ArrayList<rWave>(10);\r
-\r
- rAngle a1 = new rAngle(), a2 = new rAngle(),\r
- a3 = new rAngle(), a4 = new rAngle();\r
- xyz cPrev = new xyz(), cRand = new xyz(),\r
- cMid = new xyz(), V = new xyz(),\r
- Theta = new xyz(), TSin = new xyz(),\r
- TCos = new xyz(), cMidNorm = new xyz(),\r
- Pn = new xyz();\r
- float LastBeat=3, LastMeasure=3;\r
- int CurRandTempo = 1, CurRandTPat = 1;\r
-\r
- Pick pTimePattern, pTempoMult, pShape;\r
- int RandCube;\r
-\r
- Play(GLucose glucose) {\r
- super(glucose);\r
- pRadius = addParam("Rad" , .1 );\r
- pBounce = addParam("Bnc" , .2 );\r
- pAmp = addParam("Amp" , .2 );\r
- pTempoMult = addPick ("TMult" , 0 , 5 , new String[] {"1x", "2x", "4x", "8x", "16x", "Rand" } );\r
- pTimePattern= addPick ("TPat" , 6 , 7 , new String[] {"Bounce", "Sin", "Roll", "Quant", "Accel", "Deccel", "Slide", "Rand"} );\r
- pShape = addPick ("Shape" , 3 , 15 , new String[] {"Line", "Tap", "V", "RandV",\r
- "Pyramid", "Wings", "W2", "Clock",\r
- "Triangle", "Quad", "Sphere", "Cone",\r
- "Noise", "Wave", "?", "?"} );\r
- }\r
-\r
- public class rWave {\r
- float v0, a0, x0, t,damp,a;\r
- boolean bDone=false;\r
- final float len=8;\r
- rWave(float _x0, float _a0, float _v0, float _damp) { x0=_x0*len; a0=_a0; v0=_v0; t=0; damp = _damp; }\r
- void move(double deltaMs) {\r
- t += deltaMs*.001;\r
- if (t>4) bDone=true;\r
- }\r
- float val(float _x) {\r
- _x*=len;\r
- float dist = t*v0 - abs(_x-x0);\r
- if (dist<0) { a=1; return 0; }\r
- a = a0*exp(-dist*damp) * exp(-abs(_x-x0)/(.2*len)); // * max(0,1-t/dur)\r
- return -a*sin(dist);\r
- }\r
- }\r
-\r
- void StartPattern() { zTheta=0; }\r
- void StartRun(double deltaMs) {\r
- t = lx.tempo.rampf();\r
- amp = pAmp.Val();\r
- rad = pRadius.getValuef();\r
- bnc = pBounce.getValuef(); \r
- zTheta += deltaMs*(pSpin .Val()-.5)*.01;\r
-\r
- Theta .set(pRotX.Val()*PI*2, pRotY.Val()*PI*2, pRotZ.Val()*PI*2 + zTheta);\r
- TSin .set(sin(Theta.x), sin(Theta.y), sin(Theta.z));\r
- TCos .set(cos(Theta.x), cos(Theta.y), cos(Theta.z));\r
-\r
- if (t<LastMeasure) {\r
- if (random(3) < 1) { CurRandTempo = int(random(4)); if (CurRandTempo == 3) CurRandTempo = int(random(4)); }\r
- if (random(3) < 1) { CurRandTPat = pShape.Cur() > 6 ? 2+int(random(5)) : int(random(7)); }\r
- } LastMeasure = t;\r
- \r
- int nTempo = pTempoMult .Cur(); if (nTempo == 5) nTempo = CurRandTempo;\r
- int nTPat = pTimePattern.Cur(); if (nTPat == 7) nTPat = CurRandTPat ;\r
-\r
- switch (nTempo) {\r
- case 0: t = t; break;\r
- case 1: t = (t*2. )%1.; break;\r
- case 2: t = (t*4. )%1.; break;\r
- case 3: t = (t*8. )%1.; break;\r
- case 4: t = (t*16.)%1.; break;\r
- }\r
-\r
- int i=0; while (i< waves.size()) {\r
- rWave w = waves.get(i);\r
- w.move(deltaMs); if (w.bDone) waves.remove(i); else i++;\r
- }\r
-\r
- if ((t<LastBeat && !pKey.b) || DG.KeyPressed>-1) {\r
- waves.add(new rWave(\r
- pKey.b ? map(DG.KeyPressed,0,7,0,1) : random(1), // location\r
- bnc*10, // bounciness\r
- 7, // velocity\r
- 2*(1-amp))); // dampiness\r
- DG.KeyPressed=-1;\r
- if (waves.size() > 5) waves.remove(0);\r
- }\r
- \r
- if (t<LastBeat) {\r
- cPrev.set(cRand); cRand.setRand();\r
- a1.set(); a2.set(); a3.set(); a4.set();\r
- } LastBeat = t;\r
-\r
- switch (nTPat) {\r
- case 0: t = sin(PI*t); break; // bounce\r
- case 1: t = norm(sin(2*PI*(t+PI/2)),-1,1); break; // sin\r
- case 2: t = t; break; // roll\r
- case 3: t = constrain(int(t*8)/7.,0,1); break; // quant\r
- case 4: t = t*t*t; break; // accel\r
- case 5: t = sin(PI*t*.5); break; // deccel\r
- case 6: t = .5*(1-cos(PI*t)); break; // slide\r
- }\r
- \r
- cMid.set (cPrev); cMid.interpolate (t,cRand);\r
- cMidNorm.set (cMid); cMidNorm.setNorm();\r
- a1.move(); a2.move(); a3.move(); a4.move();\r
- }\r
-\r
- color CalcPoint(xyz Px) {\r
- if (Theta.x != 0) Px.RotateX(mCtr, TSin.x, TCos.x);\r
- if (Theta.y != 0) Px.RotateY(mCtr, TSin.y, TCos.y);\r
- if (Theta.z != 0) Px.RotateZ(mCtr, TSin.z, TCos.z);\r
- \r
- Pn.set(Px); Pn.setNorm();\r
-\r
- float mp = min(Pn.x, Pn.z);\r
- float yt = map(t,0,1,.5-bnc/2,.5+bnc/2);\r
- float r,d;\r
-\r
- switch (pShape.Cur()) {\r
- case 0: V.set(Pn.x, yt , Pn.z); break; // bouncing line\r
- case 1: V.set(Pn.x, map(cos(PI*t * Pn.x),-1,1,0,1) , Pn.z); break; // top tap\r
- case 2: V.set(Pn.x, bnc*map(Pn.x<.5?Pn.x:1-Pn.x,0,.5 ,0,t-.5)+.5, Pn.z); break; // V shape\r
- case 3: V.set(Pn.x, Pn.x < cMidNorm.x ? map(Pn.x,0,cMidNorm.x, .5,yt) :\r
- map(Pn.x,cMidNorm.x,1, yt,.5), Pn.z); break; // Random V shape\r
-\r
- case 4: V.set(Pn.x, .5*(Pn.x < cMidNorm.x ? map(Pn.x,0,cMidNorm.x, .5,yt) :\r
- map(Pn.x,cMidNorm.x,1, yt,.5)) +\r
- .5*(Pn.z < cMidNorm.z ? map(Pn.z,0,cMidNorm.z, .5,yt) :\r
- map(Pn.z,cMidNorm.z,1, yt,.5)), Pn.z); break; // Random Pyramid shape\r
- \r
- case 5: V.set(Pn.x, bnc*map((Pn.x-.5)*(Pn.x-.5),0,.25,0,t-.5)+.5, Pn.z); break; // wings\r
- case 6: V.set(Pn.x, bnc*map((mp -.5)*(mp -.5),0,.25,0,t-.5)+.5, Pn.z); break; // wings\r
-\r
- case 7: d = min(\r
- distToSeg(Px.x, Px.y, a1.getX(70),a1.getY(70), mCtr.x, mCtr.y),\r
- distToSeg(Px.x, Px.y, a2.getX(40),a2.getY(40), mCtr.x, mCtr.y));\r
- d = constrain(30*(rad*40-d),0,100);\r
- return color(0,max(0,150-d), d); // clock\r
-\r
- case 8: r = amp*200 * map(bnc,0,1,1,sin(PI*t));\r
- d = min(\r
- distToSeg(Px.x, Px.y, a1.getX(r),a1.getY(r), a2.getX(r),a2.getY(r)),\r
- distToSeg(Px.x, Px.y, a2.getX(r),a2.getY(r), a3.getX(r),a3.getY(r)),\r
- distToSeg(Px.x, Px.y, a3.getX(r),a3.getY(r), a1.getX(r),a1.getY(r)) // triangle\r
- );\r
- d = constrain(30*(rad*40-d),0,100);\r
- return color(0,max(0,150-d), d); // clock\r
-\r
- case 9: r = amp*200 * map(bnc,0,1,1,sin(PI*t));\r
- d = min(\r
- distToSeg(Px.x, Px.y, a1.getX(r),a1.getY(r), a2.getX(r),a2.getY(r)),\r
- distToSeg(Px.x, Px.y, a2.getX(r),a2.getY(r), a3.getX(r),a3.getY(r)),\r
- distToSeg(Px.x, Px.y, a3.getX(r),a3.getY(r), a4.getX(r),a4.getY(r)),\r
- distToSeg(Px.x, Px.y, a4.getX(r),a4.getY(r), a1.getX(r),a1.getY(r)) // quad\r
- );\r
- d = constrain(30*(rad*40-d),0,100);\r
- return color(0,max(0,150-d), d); // clock\r
-\r
- case 10:\r
- r = map(bnc,0,1,a1.r,amp*200*sin(PI*t));\r
- return color(0,0,c1c(.9+2*rad - dist(Px.x,Px.y,a1.getX(r),a1.getY(r))*.03) ); // sphere\r
-\r
- case 11:\r
- Px.z=mCtr.z; cMid.z=mCtr.z;\r
- return color(0,0,c1c(1 - CalcCone(Px,cMid,mCtr) * 0.02 > .5?1:0)); // cone\r
-\r
- case 12: return color(100 + noise(Pn.x,Pn.y,Pn.z + (NoiseMove+50000)/1000.)*200,\r
- 85,c1c(Pn.y < noise(Pn.x + NoiseMove/2000.,Pn.z)*(1+amp)-amp/2.-.1 ? 1 : 0)); // noise\r
-\r
- case 13: float y=0; for (rWave w : waves) y += .5*w.val(Pn.x);\r
- V.set(Pn.x, .7+y, Pn.z);\r
- break;\r
-\r
- default: return color(0,0,0);\r
- }\r
-\r
- return color(0,\r
- 150-c1c(1 - V.distance(Pn)/rad),\r
- c1c(1 - V.distance(Pn)/rad));\r
- }\r
-}\r
-//----------------------------------------------------------------------------------------------------------------------------------\r
-// 0 - TLB, L (b), BLB, B (l) // Fwd , Down, Back, Up\r
-// 4 - TLF, F (l), BLF, L (f) // Fwd , Down, Back, Up\r
-// 8 - TRF, R (f), BRF, F (r) // Back, Down, Fwd , Up\r
-// 12- TRB, B (r), BRB, R (b) // Back, Down, Fwd , Up\r
-// 1->7, 15->9\r
-\r
-class dBolt {\r
- dStrip v, h;\r
- int vpos, hpos;\r
- dBolt(dStrip _v, dStrip _h, int _vpos, int _hpos) {\r
- v=_v; h=_h; vpos=_vpos; hpos=_hpos;\r
- if (v.b0 == null) { v.b0=this; h.b0=this; } \r
- else { v.b1=this; h.b1=this; }\r
- }\r
-}\r
-\r
-class dVertex {\r
- dStrip s1 , s2 ;\r
- int dir1, dir2 ;\r
- dVertex(dStrip s, int d) {\r
- int _a = (s.iS%4==1)? (d==1? 5: 3) :\r
- (s.iS%4==3)? (d==1? 9:11) :\r
- (d==1) ? (s.Top()?4:12) : (s.Top()?12:4);\r
- dir1 = d * (s.isVert() ? -1 : 1);\r
- dir2 = d;\r
- s1 = DL_.DS[s.iCube() + ((s.iS+_a) % 16)];\r
- s2 = DL_.DS[d == 1 ? (s.idx == s.iFace()+3 ? s.idx-3 : s.idx+1):\r
- (s.idx == s.iFace() ? s.idx+3 : s.idx-1)];\r
- swapout(1 , 6);\r
- swapout(15,-6);\r
- }\r
- void swapout(int a, int b) {\r
- if (s1.iS == a) { s1 = DL_.DS[s1.idx + b]; dir1 = -dir1; }\r
- if (s2.iS == a) { s2 = DL_.DS[s2.idx + b]; dir2 = -dir2; }\r
- }\r
-\r
-}\r
-\r
-class dStrip { // THIS WAS SUCH A PAIN!\r
- int row, col, ci, idx, iS, axis; // 1-y, 2-left, 3-right\r
- Strip s; \r
- boolean bTop; // direction: top ccw, bottom cw.\r
-\r
- boolean Top (){ return axis!=1 && bTop ; }\r
- boolean Bottom(){ return axis!=1 && !bTop; }\r
- boolean isVert(){ return axis==1; }\r
- boolean isHorz(){ return axis!=1; }\r
- int iCube (){ return 16*floor(idx/16); }\r
- int iFace (){ return iCube() + 4*floor(iS/4); }\r
-\r
- void init(Strip _s, int _i, int _row, int _col) {\r
- idx = _i; row = _row; col = _col; s = _s;\r
- iS = idx%16; bTop = (iS%4==0);\r
- ci = s.points.get(0).index;\r
- DL_.DQ[col][row] = iCube();\r
- switch (iS) {\r
- case 4: case 6 : case 12: case 14: axis=2; break;\r
- case 0: case 2 : case 8 : case 10: axis=3; break;\r
- default: axis=1; break;\r
- }\r
- }\r
-\r
- void addBolts() {\r
- v0 = new dVertex(this, 1);\r
- v1 = new dVertex(this,-1);\r
-\r
-\r
- if (iS == 7 && col != 0 && row != 0) // left bottom\r
- new dBolt(this, DL_.GetStrip(row-1,col-1,(col % 2 == 1) ? 8 : 12), \r
- 4, (col % 2 == 1) ? 6 : 9); \r
-\r
- if (iS == 7 && col != 0 && row < MaxCubeHeight*2-2) // left top\r
- new dBolt(this, DL_.GetStrip(row+1,col-1,(col % 2 == 1) ? 10 : 14), \r
- 11, (col % 2 == 1) ? 9 : 6);\r
-\r
- if (iS == 9 && col < NumBackTowers-1 && row < MaxCubeHeight*2-2) // right top\r
- new dBolt(this, DL_.GetStrip(row+1,col+1,(col % 2 == 1) ? 6 : 2), \r
- 4, (col % 2 == 1) ? 6 : 9);\r
-\r
- if (iS == 9 && col < NumBackTowers-1 && row != 0) // right bottom\r
- new dBolt(this, DL_.GetStrip(row-1,col+1,(col % 2 == 1) ? 4 : 0), \r
- 11, (col % 2 == 1) ? 9 : 6);\r
- }\r
-\r
- dBolt b0, b1;\r
- dVertex v0, v1;\r
-}\r
-\r
-class dCursor {\r
- dStrip s, sNext;\r
- int nLast,pos,posNext,end; // 0 - 65535\r
- int dir; // 1 or -1\r
- color clr;\r
- \r
- dCursor(color _c) { clr=_c;}\r
-\r
- boolean isDone() { return pos==end; }\r
- void set(dStrip _s, int _dir) { \r
- s=_s; dir=_dir; pos = 0; end=65536; nLast=-1; sNext=null;\r
- }\r
-\r
- boolean MakeTurn(dBolt b) {\r
- int nEnd= (s.isVert() ? b.vpos : b.hpos) <<12;\r
- nEnd= (dir==1 ? nEnd : 65536-nEnd);\r
- if (nEnd < pos) return false;\r
- if (s.isVert()) { sNext = b.h; posNext = b.hpos<<12; end = nEnd; }\r
- else { sNext = b.v; posNext = b.vpos<<12; end = nEnd; }\r
- return true;\r
- }\r
-\r
- void PickNext() {\r
- if (sNext != null) {\r
- if (end == 65536) exit();\r
- end = 65536; \r
- pos = posNext;\r
- dir = randDir(); \r
- if (dir<0) pos = end-pos;\r
- s = sNext; sNext = null;\r
- nLast = -1;\r
- return;// could switch again!!\r
- } else {\r
- dVertex v = (dir == 1 ? s.v0 : s.v1);\r
- int r = floor(random(2));\r
- set(r==0 ? v.s1 : v.s2,r==0 ? v.dir1 : v.dir2);\r
- }\r
-\r
- // plan to turn the corner\r
- if (random(6)<1 && s.b0 != null && MakeTurn(s.b0)) return;\r
- if (random(6)<1 && s.b1 != null && MakeTurn(s.b1)) return;\r
- }\r
-}\r
-\r
-int randDir() { return round(random(1))*2-1; }\r
-\r
-class dLattice {\r
- int iTowerStrips=-1;\r
- dStrip[] DS = new dStrip[glucose.model.strips.size()];\r
- int[][] DQ = new int[NumBackTowers][MaxCubeHeight*2];\r
-\r
- int nStrips() { return iTowerStrips; }\r
- dStrip GetStrip (int row, int col, int off) { return DS[DQ[col][row]+off]; }\r
- dLattice() {\r
- DL_=this;\r
- int col = 0, row = -2, i=-1;\r
- for (Strip strip : glucose.model.strips ) { i++; \r
- if (i % 16 == 0) row+=2;\r
- if (row >= MaxCubeHeight*2-1) { col++; row = (col%2==1)?1:0; }\r
- if (col >= NumBackTowers) continue;\r
- iTowerStrips++ ;\r
- dStrip s = DS[iTowerStrips] = new dStrip();\r
- s.init(strip, iTowerStrips, row, col);\r
- }\r
-\r
- for (int j=0; j<iTowerStrips; j++) DS[j].addBolts();\r
- }\r
- dStrip rand() { return DS[floor(random(iTowerStrips))]; }\r
- void setRand(dCursor c) { c.set(rand(),randDir()); }\r
-}\r
-\r
-dLattice DL_;\r
-//----------------------------------------------------------------------------------------------------------------------------------\r
-class Worms extends SCPattern {\r
-\r
- int draw(dCursor c, int nAmount) {\r
- int nFrom = max(c.nLast+1,c.pos >> 12);\r
- int nTo = min(15,(c.pos+nAmount) >> 12); c.nLast=nTo;\r
- int nMv = min(nAmount, c.end-c.pos);\r
- c.pos += nMv;\r
- for (int i = nFrom; i <= nTo; i++) {\r
- int n = c.s.ci + (c.dir>0 ? i : 15-i);\r
- colors[n] = c.clr;\r
- }\r
- return nAmount - nMv;\r
- }\r
-\r
- float StripsPerSec = 6;\r
- float TrailTime = 1500;\r
- int Cursors = 40;\r
- dCursor cur[] = new dCursor[Cursors];\r
-\r
- Worms(GLucose glucose) { \r
- super(glucose); \r
- if (DL_ == null) DL_ = new dLattice();\r
- for (int i=0; i<Cursors; i++) { cur[i] = new dCursor(color(random(360),50+random(50),50+random(50))); DL_.setRand(cur[i]); }\r
- }\r
-\r
- void run(double deltaMs) {\r
- //Test Joints\r
- if (false) {\r
- for (int j=0; j<DL_.nStrips(); j++) {\r
- dStrip s =DL_.DS[j]; dBolt d = s.b0;\r
- if (d != null) {for (int i=0;i<16;i++) {\r
- if (s == d.v && i <= d.vpos) colors[d.v.ci+i] = color(0,0,30);\r
- if (s == d.h && i <= d.hpos) colors[d.h.ci+i] = color(0,0,30);\r
- }}\r
-\r
- d = s.b1; \r
- if (d != null) {for (int i=0;i<16;i++) {\r
- if (s == d.v && i >= d.vpos) colors[d.v.ci+i] = color(0,0,30);\r
- if (s == d.h && i >= d.hpos) colors[d.h.ci+i] = color(0,0,30);\r
- }}\r
- }\r
- } else {\r
- for (int i=0; i<Cursors; i++) {\r
- int nLeft = floor((float)deltaMs*.001*StripsPerSec * 65536);\r
- while(nLeft > 0) { \r
- nLeft = draw(cur[i], nLeft);\r
- if (cur[i].isDone()) cur[i].PickNext(); \r
- }\r
- }\r
-\r
- for (int i=0,s=model.points.size(); i<s; i++) {\r
- float b = brightness(colors[i]); \r
- color c = colors[i];\r
- if (b>0) colors[i] = color(hue(c), saturation(c), \r
- (float)(b-100*deltaMs/TrailTime));\r
- }\r
- }\r
- }\r
-}\r
-//----------------------------------------------------------------------------------------------------------------------------------\r
+//----------------------------------------------------------------------------------------------------------------------------------
+public class Pong extends DPat {
+ SinLFO x,y,z,dx,dy,dz;
+ float cRad; DParam pSize;
+ Pick pChoose;
+ xyz v = new xyz(), vMir = new xyz();
+
+ Pong(GLucose glucose) {
+ super(glucose);
+ cRad = mMax.x/10;
+ addModulator(dx = new SinLFO(6000, 500, 30000 )).trigger();
+ addModulator(dy = new SinLFO(3000, 500, 22472 )).trigger();
+ addModulator(dz = new SinLFO(1000, 500, 18420 )).trigger();
+ addModulator(x = new SinLFO(cRad, mMax.x - cRad, 0)).trigger(); x.modulateDurationBy(dx);
+ addModulator(y = new SinLFO(cRad, mMax.y - cRad, 0)).trigger(); y.modulateDurationBy(dy);
+ addModulator(z = new SinLFO(cRad, mMax.z - cRad, 0)).trigger(); z.modulateDurationBy(dz);
+ pSize = addParam ("Size" , 0.4 );
+ pChoose = addPick ("Animiation" , 0, 2, new String[] {"Pong", "Ball", "Cone"} );
+ }
+
+ void StartRun(double deltaMs) { cRad = mMax.x*pSize.Val()/6; }
+ color CalcPoint(xyz p) {
+ v.set(x.getValuef(), y.getValuef(), z.getValuef());
+ v.z=0;p.z=0;// ignore z dimension
+ switch(pChoose.Cur()) {
+ case 0: vMir.set(mMax); vMir.subtract(p);
+ return lx.hsb(0,0,c1c(1 - min(v.distance(p), v.distance(vMir))*.5/cRad)); // balls
+ case 1: return lx.hsb(0,0,c1c(1 - v.distance(p)*.5/cRad)); // ball
+ case 2: vMir.set(mMax.x/2,0,mMax.z/2);
+ return lx.hsb(0,0,c1c(1 - CalcCone(p,v,vMir) * max(.02,.45-pSize.Val()))); // spot
+ }
+ return lx.hsb(0,0,0);
+ }
+}
+//----------------------------------------------------------------------------------------------------------------------------------
+public class NDat {
+ float xz, yz, zz, hue, sat, speed, angle, den;
+ float xoff,yoff,zoff;
+ float sinAngle, cosAngle;
+ boolean isActive;
+ NDat () { isActive=false; }
+ boolean Active() { return isActive; }
+ void set (float _hue, float _sat, float _xz, float _yz, float _zz, float _den, float _speed, float _angle) {
+ isActive = true;
+ hue=_hue; sat=_sat; xz=_xz; yz=_yz; zz =_zz; den=_den; speed=_speed; angle=_angle;
+ xoff = random(100e3); yoff = random(100e3); zoff = random(100e3);
+ }
+}
+
+public class Noise extends DPat
+{
+ int CurAnim, iSymm;
+ int XSym=1,YSym=2,RadSym=3;
+ float zTime , zTheta=0, zSin, zCos, rtime, ttime, transAdd;
+ DParam pSpeed , pDensity;
+ Pick pChoose, pSymm;
+ int _ND = 4;
+ NDat N[] = new NDat[_ND];
+
+ Noise(GLucose glucose) {
+ super(glucose);
+ pSpeed = addParam("Fast" , .55);
+ pDensity = addParam("Dens" , .5);
+ pSymm = addPick("Symmetry" , 0, 3, new String[] {"None", "X", "Y", "Radial"} );
+ pChoose = addPick("Animation", 6, 7, new String[] {"Drip", "Cloud", "Rain", "Fire", "Machine", "Spark","VWave", "Wave"} );
+ for (int i=0; i<_ND; i++) N[i] = new NDat();
+ }
+
+ void StartPattern() { zTime = random(500); zTheta=0; rtime = 0; ttime = 0; transAdd=0; }
+ void StartRun(double deltaMs) {
+ zTime += deltaMs*(pSpeed.Val()-.5)*.002 ;
+ zTheta += deltaMs*(pSpin .Val()-.5)*.01 ;
+ rtime += deltaMs;
+ iSymm = pSymm.Cur();
+ transAdd = 1*(1 - constrain(rtime - ttime,0,1000)/1000);
+ zSin = sin(zTheta);
+ zCos = cos(zTheta);
+
+ if (pChoose.Cur() != CurAnim) {
+ CurAnim = pChoose.Cur(); ttime = rtime;
+ pSpin .reset(); zTheta = 0;
+ pDensity .reset(); pSpeed .reset();
+ for (int i=0; i<_ND; i++) { N[i].isActive = false; }
+
+ switch(CurAnim) {
+ // hue sat xz yz zz den mph angle
+ case 0: N[0].set(0 ,0 ,75 ,75 ,150,45 ,3 ,0 ); pSharp.set(1 ); break; // drip
+ case 1: N[0].set(0 ,0 ,100,100,200,45 ,3 ,180); pSharp.set(0 ); break; // clouds
+ case 2: N[0].set(0 ,0 ,2 ,400,2 ,20 ,3 ,0 ); pSharp.set(.5); break; // rain
+ case 3: N[0].set(40 ,1 ,100,100,200,10 ,1 ,180);
+ N[1].set(0 ,1 ,100,100,200,10 ,5 ,180); pSharp.set(0 ); break; // fire 1
+ case 4: N[0].set(0 ,1 ,40 ,40 ,40 ,15 ,2.5,180);
+ N[1].set(20 ,1 ,40 ,40 ,40 ,15 ,4 ,0 );
+ N[2].set(40 ,1 ,40 ,40 ,40 ,15 ,2 ,90 );
+ N[3].set(60 ,1 ,40 ,40 ,40 ,15 ,3 ,-90); pSharp.set(.5); break; // machine
+ case 5: N[0].set(0 ,1 ,400,100,2 ,15 ,3 ,90 );
+ N[1].set(20 ,1 ,400,100,2 ,15 ,2.5,0 );
+ N[2].set(40 ,1 ,100,100,2 ,15 ,2 ,180);
+ N[3].set(60 ,1 ,100,100,2 ,15 ,1.5,270); pSharp.set(.5); break; // spark
+ }
+
+ DG.UpdateLights();
+ }
+
+ for (int i=0; i<_ND; i++) if (N[i].Active()) {
+ N[i].sinAngle = sin(radians(N[i].angle));
+ N[i].cosAngle = cos(radians(N[i].angle));
+ }
+ }
+
+ color CalcPoint(xyz P) {
+ color c = 0;
+ P.RotateZ(mCtr, zSin, zCos);
+
+ if (CurAnim == 6 || CurAnim == 7) {
+ P.setNorm();
+ return lx.hsb(0,0, 100 * (
+ constrain(1-50*(1-pDensity.Val())*abs(P.y-sin(zTime*10 + P.x*(300))*.5 - .5),0,1) +
+ (CurAnim == 7 ? constrain(1-50*(1-pDensity.Val())*abs(P.x-sin(zTime*10 + P.y*(300))*.5 - .5),0,1) : 0))
+ );
+ }
+
+ if (iSymm == XSym && P.x > mMax.x/2) P.x = mMax.x-P.x;
+ if (iSymm == YSym && P.y > mMax.y/2) P.y = mMax.y-P.y;
+
+ for (int i=0;i<_ND; i++) if (N[i].Active()) {
+ NDat n = N[i];
+ float zx = zTime * n.speed * n.sinAngle,
+ zy = zTime * n.speed * n.cosAngle;
+
+ float b = (iSymm==RadSym ? noise(zTime*n.speed+n.xoff-Dist(P,mCtr)/n.xz)
+ : noise(P.x/n.xz+zx+n.xoff,P.y/n.yz+zy+n.yoff,P.z/n.zz+n.zoff))
+ *1.8;
+
+ b += n.den/100 -.4 + pDensity.Val() -1;
+ b += transAdd;
+ c = blendColor(c,color(n.hue,100*n.sat,c1c(b)),ADD);
+ }
+ return c;
+ }
+}
+//----------------------------------------------------------------------------------------------------------------------------------
+public class Play extends DPat
+{
+ public class rAngle {
+ float prvA, dstA, c;
+ float prvR, dstR, r;
+ float _cos, _sin, x, y;
+ float fixAngle (float a, float b) { return a<b ?
+ (abs(a-b) > abs(a+2*PI-b) ? a : a+2*PI) :
+ (abs(a-b) > abs(a-2*PI-b) ? a : a-2*PI) ; }
+ float getX(float r) { return mCtr.x + _cos*r; }
+ float getY(float r) { return mCtr.y + _sin*r; }
+ void move() { c = interp(t,prvA,dstA);
+ r = interp(t,prvR,dstR);
+ _cos = cos(c); _sin = sin(c);
+ x = getX(r); y = getY(r); }
+ void set() { prvA = dstA; dstA = random(2*PI); prvA = fixAngle(prvA, dstA);
+ prvR = dstR; dstR = random(mCtr.y); }
+ }
+
+ int nBeats = 0;
+ DParam pAmp, pRadius, pBounce;
+
+ float t,amp,rad,bnc;
+ float zTheta=0;
+ ArrayList<rWave> waves = new ArrayList<rWave>(10);
+
+ rAngle a1 = new rAngle(), a2 = new rAngle(),
+ a3 = new rAngle(), a4 = new rAngle();
+ xyz cPrev = new xyz(), cRand = new xyz(),
+ cMid = new xyz(), V = new xyz(),
+ Theta = new xyz(), TSin = new xyz(),
+ TCos = new xyz(), cMidNorm = new xyz(),
+ Pn = new xyz();
+ float LastBeat=3, LastMeasure=3;
+ int CurRandTempo = 1, CurRandTPat = 1;
+
+ Pick pTimePattern, pTempoMult, pShape;
+ int RandCube;
+
+ Play(GLucose glucose) {
+ super(glucose);
+ pRadius = addParam("Rad" , .1 );
+ pBounce = addParam("Bnc" , .2 );
+ pAmp = addParam("Amp" , .2 );
+ pTempoMult = addPick ("TMult" , 0 , 5 , new String[] {"1x", "2x", "4x", "8x", "16x", "Rand" } );
+ pTimePattern= addPick ("TPat" , 6 , 7 , new String[] {"Bounce", "Sin", "Roll", "Quant", "Accel", "Deccel", "Slide", "Rand"} );
+ pShape = addPick ("Shape" , 3 , 15 , new String[] {"Line", "Tap", "V", "RandV",
+ "Pyramid", "Wings", "W2", "Clock",
+ "Triangle", "Quad", "Sphere", "Cone",
+ "Noise", "Wave", "?", "?"} );
+ }
+
+ public class rWave {
+ float v0, a0, x0, t,damp,a;
+ boolean bDone=false;
+ final float len=8;
+ rWave(float _x0, float _a0, float _v0, float _damp) { x0=_x0*len; a0=_a0; v0=_v0; t=0; damp = _damp; }
+ void move(double deltaMs) {
+ t += deltaMs*.001;
+ if (t>4) bDone=true;
+ }
+ float val(float _x) {
+ _x*=len;
+ float dist = t*v0 - abs(_x-x0);
+ if (dist<0) { a=1; return 0; }
+ a = a0*exp(-dist*damp) * exp(-abs(_x-x0)/(.2*len)); // * max(0,1-t/dur)
+ return -a*sin(dist);
+ }
+ }
+
+ void StartPattern() { zTheta=0; }
+ void StartRun(double deltaMs) {
+ t = lx.tempo.rampf();
+ amp = pAmp.Val();
+ rad = pRadius.getValuef();
+ bnc = pBounce.getValuef();
+ zTheta += deltaMs*(pSpin .Val()-.5)*.01;
+
+ Theta .set(pRotX.Val()*PI*2, pRotY.Val()*PI*2, pRotZ.Val()*PI*2 + zTheta);
+ TSin .set(sin(Theta.x), sin(Theta.y), sin(Theta.z));
+ TCos .set(cos(Theta.x), cos(Theta.y), cos(Theta.z));
+
+ if (t<LastMeasure) {
+ if (random(3) < 1) { CurRandTempo = int(random(4)); if (CurRandTempo == 3) CurRandTempo = int(random(4)); }
+ if (random(3) < 1) { CurRandTPat = pShape.Cur() > 6 ? 2+int(random(5)) : int(random(7)); }
+ } LastMeasure = t;
+
+ int nTempo = pTempoMult .Cur(); if (nTempo == 5) nTempo = CurRandTempo;
+ int nTPat = pTimePattern.Cur(); if (nTPat == 7) nTPat = CurRandTPat ;
+
+ switch (nTempo) {
+ case 0: t = t; break;
+ case 1: t = (t*2. )%1.; break;
+ case 2: t = (t*4. )%1.; break;
+ case 3: t = (t*8. )%1.; break;
+ case 4: t = (t*16.)%1.; break;
+ }
+
+ int i=0; while (i< waves.size()) {
+ rWave w = waves.get(i);
+ w.move(deltaMs); if (w.bDone) waves.remove(i); else i++;
+ }
+
+ if ((t<LastBeat && !pKey.b) || DG.KeyPressed>-1) {
+ waves.add(new rWave(
+ pKey.b ? map(DG.KeyPressed,0,7,0,1) : random(1), // location
+ bnc*10, // bounciness
+ 7, // velocity
+ 2*(1-amp))); // dampiness
+ DG.KeyPressed=-1;
+ if (waves.size() > 5) waves.remove(0);
+ }
+
+ if (t<LastBeat) {
+ cPrev.set(cRand); cRand.setRand();
+ a1.set(); a2.set(); a3.set(); a4.set();
+ } LastBeat = t;
+
+ switch (nTPat) {
+ case 0: t = sin(PI*t); break; // bounce
+ case 1: t = norm(sin(2*PI*(t+PI/2)),-1,1); break; // sin
+ case 2: t = t; break; // roll
+ case 3: t = constrain(int(t*8)/7.,0,1); break; // quant
+ case 4: t = t*t*t; break; // accel
+ case 5: t = sin(PI*t*.5); break; // deccel
+ case 6: t = .5*(1-cos(PI*t)); break; // slide
+ }
+
+ cMid.set (cPrev); cMid.interpolate (t,cRand);
+ cMidNorm.set (cMid); cMidNorm.setNorm();
+ a1.move(); a2.move(); a3.move(); a4.move();
+ }
+
+ color CalcPoint(xyz Px) {
+ if (Theta.x != 0) Px.RotateX(mCtr, TSin.x, TCos.x);
+ if (Theta.y != 0) Px.RotateY(mCtr, TSin.y, TCos.y);
+ if (Theta.z != 0) Px.RotateZ(mCtr, TSin.z, TCos.z);
+
+ Pn.set(Px); Pn.setNorm();
+
+ float mp = min(Pn.x, Pn.z);
+ float yt = map(t,0,1,.5-bnc/2,.5+bnc/2);
+ float r,d;
+
+ switch (pShape.Cur()) {
+ case 0: V.set(Pn.x, yt , Pn.z); break; // bouncing line
+ case 1: V.set(Pn.x, map(cos(PI*t * Pn.x),-1,1,0,1) , Pn.z); break; // top tap
+ case 2: V.set(Pn.x, bnc*map(Pn.x<.5?Pn.x:1-Pn.x,0,.5 ,0,t-.5)+.5, Pn.z); break; // V shape
+ case 3: V.set(Pn.x, Pn.x < cMidNorm.x ? map(Pn.x,0,cMidNorm.x, .5,yt) :
+ map(Pn.x,cMidNorm.x,1, yt,.5), Pn.z); break; // Random V shape
+
+ case 4: V.set(Pn.x, .5*(Pn.x < cMidNorm.x ? map(Pn.x,0,cMidNorm.x, .5,yt) :
+ map(Pn.x,cMidNorm.x,1, yt,.5)) +
+ .5*(Pn.z < cMidNorm.z ? map(Pn.z,0,cMidNorm.z, .5,yt) :
+ map(Pn.z,cMidNorm.z,1, yt,.5)), Pn.z); break; // Random Pyramid shape
+
+ case 5: V.set(Pn.x, bnc*map((Pn.x-.5)*(Pn.x-.5),0,.25,0,t-.5)+.5, Pn.z); break; // wings
+ case 6: V.set(Pn.x, bnc*map((mp -.5)*(mp -.5),0,.25,0,t-.5)+.5, Pn.z); break; // wings
+
+ case 7: d = min(
+ distToSeg(Px.x, Px.y, a1.getX(70),a1.getY(70), mCtr.x, mCtr.y),
+ distToSeg(Px.x, Px.y, a2.getX(40),a2.getY(40), mCtr.x, mCtr.y));
+ d = constrain(30*(rad*40-d),0,100);
+ return lx.hsb(0,max(0,150-d), d); // clock
+
+ case 8: r = amp*200 * map(bnc,0,1,1,sin(PI*t));
+ d = min(
+ distToSeg(Px.x, Px.y, a1.getX(r),a1.getY(r), a2.getX(r),a2.getY(r)),
+ distToSeg(Px.x, Px.y, a2.getX(r),a2.getY(r), a3.getX(r),a3.getY(r)),
+ distToSeg(Px.x, Px.y, a3.getX(r),a3.getY(r), a1.getX(r),a1.getY(r)) // triangle
+ );
+ d = constrain(30*(rad*40-d),0,100);
+ return lx.hsb(0,max(0,150-d), d); // clock
+
+ case 9: r = amp*200 * map(bnc,0,1,1,sin(PI*t));
+ d = min(
+ distToSeg(Px.x, Px.y, a1.getX(r),a1.getY(r), a2.getX(r),a2.getY(r)),
+ distToSeg(Px.x, Px.y, a2.getX(r),a2.getY(r), a3.getX(r),a3.getY(r)),
+ distToSeg(Px.x, Px.y, a3.getX(r),a3.getY(r), a4.getX(r),a4.getY(r)),
+ distToSeg(Px.x, Px.y, a4.getX(r),a4.getY(r), a1.getX(r),a1.getY(r)) // quad
+ );
+ d = constrain(30*(rad*40-d),0,100);
+ return lx.hsb(0,max(0,150-d), d); // clock
+
+ case 10:
+ r = map(bnc,0,1,a1.r,amp*200*sin(PI*t));
+ return lx.hsb(0,0,c1c(.9+2*rad - dist(Px.x,Px.y,a1.getX(r),a1.getY(r))*.03) ); // sphere
+
+ case 11:
+ Px.z=mCtr.z; cMid.z=mCtr.z;
+ return lx.hsb(0,0,c1c(1 - CalcCone(Px,cMid,mCtr) * 0.02 > .5?1:0)); // cone
+
+ case 12: return lx.hsb(100 + noise(Pn.x,Pn.y,Pn.z + (NoiseMove+50000)/1000.)*200,
+ 85,c1c(Pn.y < noise(Pn.x + NoiseMove/2000.,Pn.z)*(1+amp)-amp/2.-.1 ? 1 : 0)); // noise
+
+ case 13: float y=0; for (rWave w : waves) y += .5*w.val(Pn.x);
+ V.set(Pn.x, .7+y, Pn.z);
+ break;
+
+ default: return lx.hsb(0,0,0);
+ }
+
+ return lx.hsb(0,
+ 150-c1c(1 - V.distance(Pn)/rad),
+ c1c(1 - V.distance(Pn)/rad));
+ }
+}
+//----------------------------------------------------------------------------------------------------------------------------------
+// 0 - TLB, L (b), BLB, B (l) // Fwd , Down, Back, Up
+// 4 - TLF, F (l), BLF, L (f) // Fwd , Down, Back, Up
+// 8 - TRF, R (f), BRF, F (r) // Back, Down, Fwd , Up
+// 12- TRB, B (r), BRB, R (b) // Back, Down, Fwd , Up
+// 1->7, 15->9
+
+int randDir() { return round(random(1))*2-1; }
+//----------------------------------------------------------------------------------------------------------------------------------
+boolean dDebug = true;
+class dCursor {
+ dVertex v, vNext;
+ int pos,posNext; // 0 - 65535
+ int stop; // 0-15
+ color clr;
+
+ dCursor(color _c) { clr=_c;}
+
+ boolean isDone() { return pos==stop<<12; }
+ void set(dVertex _v, int _pos) { pos = _pos; v = _v; vNext = null; stop=16; }
+
+ boolean Turn(dTurn t) {
+ if (t.pos0<<12 < pos) return false;
+ vNext = t.v;
+ stop = t.pos0;
+ posNext = t.pos1<<12;
+ if (randDir()<0) { vNext = t.v.opp; posNext = (16<<12)-posNext; }
+ return true;
+ }
+
+ void PickNext() {
+ if (vNext != null) { set(vNext, posNext); }
+ else { set(random(2) < 1 ? v.c0 : v.c1, 0); }
+ // plan to turn the corner
+ float r = random(3);
+ if (r<1 && v.t0 != null && Turn(v.t0)) return;
+ if (r<2 && v.t1 != null && Turn(v.t1)) return;
+ }
+ Point p1, p2; int i2;
+}
+
+//----------------------------------------------------------------------------------------------------------------------------------
+class Worms extends SCPattern {
+ float StripsPerSec = 10;
+ float TrailTime = 1000;
+ int Cursors = 25;
+ dCursor cur[] = new dCursor[Cursors];
+
+ int draw(dCursor c, int nAmount) {
+ int nFrom = (c.pos ) >> 12;
+ int nMv = min(nAmount, (c.stop<<12)-c.pos);
+ int nTo = min(15,(c.pos+nMv) >> 12);
+
+ if (dDebug) { c.p1 = c.v.getPoint(nFrom); float d = (c.p2 == null ? 0 : PointDist(c.p1,c.p2)); if (d>5) { println("too wide! quitting: " + d); exit(); }}
+ for (int i = nFrom; i <= nTo; i++) { colors[c.v.ci + c.v.dir*i ] = c.clr; }
+ if (c.v.same != null) for (int i = nFrom; i <= nTo; i++) { colors[c.v.same.ci + c.v.same.dir*i] = c.clr; }
+ if (dDebug) { c.p2 = c.v.getPoint(nTo); c.i2 = nTo; }
+
+ c.pos += nMv; return nAmount - nMv;
+ }
+
+ Worms(GLucose glucose) {
+ super(glucose);
+ if (DL_ == null) DL_ = new dLattice();
+ for (int i=0; i<Cursors; i++) { cur[i] = new dCursor(lx.hsb(135,100,100)); DL_.setRand(cur[i]); }
+ }
+
+ void run(double deltaMs) {
+ for (int i=0,s=model.points.size(); i<s; i++) {
+ color c = colors[i]; float b = brightness(c);
+ if (b>0) colors[i] = color(hue(c), saturation(c), (float)(b-100*deltaMs/TrailTime));
+ }
+
+ for (int i=0; i<Cursors; i++) {
+ int nLeft = floor((float)deltaMs*.001*StripsPerSec * 65536);
+ while(nLeft > 0) { nLeft = draw(cur[i], nLeft); if (cur[i].isDone()) cur[i].PickNext(); }
+ }
+ }
+}
+//----------------------------------------------------------------------------------------------------------------------------------
for(int i=0; i<s.points.size(); i++){
int index = s.points.get(i).index;
color c = colors[index];
- colors[index] = color((i*22.5), saturation(c), brightness(c));
+ colors[index] = lx.hsb((i*22.5), saturation(c), brightness(c));
}
}*/
}
//----------------------------------------------------------------------------------------------------------------------------------
public class xyz { float x,y,z;
xyz() {x=y=z=0;}
- xyz(Point p ) {x=p.fx ; y=p.fy; z=p.fz;}
+ xyz(Point p ) {x=p.x ; y=p.y; z=p.z;}
xyz(xyz p ) {set(p); }
xyz(float _x,float _y,float _z) {x=_x ; y=_y ; z=_z ;}
- void set(Point p ) {x=p.fx ; y=p.fy; z=p.fz;}
+ void set(Point p ) {x=p.x ; y=p.y; z=p.z;}
void set(xyz p ) {x=p.x ; y=p.y ; z=p.z ;}
void set(float _x,float _y,float _z) {x=_x ; y=_y ; z=_z ;}
void StartPattern() { }
void StartRun(double deltaMs) { }
- color CalcPoint(xyz p) { return color(0,0,0); }
+ color CalcPoint(xyz p) { return lx.hsb(0,0,0); }
boolean IsActive() { return this == DG.CurPat; }
boolean IsFocused() { return this == midiEngine.getFocusedDeck().getActivePattern(); }
void onInactive() { UpdateState(); }
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); }
- float s = saturation(cNew) + 100*(fSaturate*2-1);
- float b = brightness(cNew)/100.;
+ float s = lx.s(cNew) + 100*(fSaturate*2-1);
+ float b = lx.b(cNew)/100.;
if (pSharp.Val()>0) b = b < .5 ? pow(b,fSharp) : 1-pow(1-b,fSharp);
- if (DG._Trails()>0 && fQuant == 0) b = max(b, (float) (brightness(cOld)/100. - (1-DG._Trails()) * deltaMs/200.));
- if (DG.bSustain == true) b = max(b, (float) (brightness(cOld)/100.));
+ if (DG._Trails()>0 && fQuant == 0) b = max(b, (float) (lx.b(cOld)/100. - (1-DG._Trails()) * deltaMs/200.));
+ if (DG.bSustain == true) b = max(b, (float) (lx.b(cOld)/100.));
if (pInvert.b) { b = 1-b; s = 1-s; }
- colors[p.index] = color(
- (hue(cNew) + zSpinHue) % 360,
+ colors[p.index] = lx.hsb(
+ (lx.h(cNew) + zSpinHue) % 360,
s,
100 * b * DG._Level()
);
-// colors[p.index] = color(0,0, p.fx >= modmin.x && p.fy >= modmin.y && p.fz >= modmin.z &&
-// p.fx <= modmin.x+mMax.x && p.fy <= modmin.y+mMax.y && p.fz <= modmin.z+mMax.z ? 100 : 0);
+// colors[p.index] = lx.hsb(0,0, p.x >= modmin.x && p.y >= modmin.y && p.z >= modmin.z &&
+// p.x <= modmin.x+mMax.x && p.y <= modmin.y+mMax.y && p.z <= modmin.z+mMax.z ? 100 : 0);
}
}
}
-//----------------------------------------------------------------------------------------------------------------------------------
\ No newline at end of file
+//----------------------------------------------------------------------------------------------------------------------------------
+class dTurn {
+ dVertex v;
+ int pos0, pos1;
+ dTurn(int _pos0, dVertex _v, int _pos1) { v = _v; pos0 = _pos0; pos1 = _pos1; }
+}
+
+class dVertex {
+ dVertex c0, c1, opp, same;
+ dTurn t0, t1;
+ dStrip s;
+ int dir, ci;
+
+ dVertex(dStrip _s, Point _p) { s = _s; ci = _p.index; }
+ Point getPoint(int i) { return s.s.points.get(dir>0 ? i : 15-i); }
+ void setOpp(dVertex _opp) { opp = _opp; dir = (ci < opp.ci ? 1 : -1); }
+}
+
+class dStrip {
+ dVertex v0, v1;
+ int row, col;
+ Strip s;
+ dStrip(Strip _s, int _i, int _row, int _col) { s = _s; row = _row; col = _col; }
+}
+//----------------------------------------------------------------------------------------------------------------------------------
+float PointDist(Point p1, Point p2) { return dist(p1.x,p1.y,p1.z,p2.x,p2.y,p2.z); }
+
+class dLattice {
+ private int iTowerStrips=0;
+
+ dStrip[] DS = new dStrip[glucose.model.strips.size()];
+ int[][] DQ = new int[NumBackTowers][MaxCubeHeight*2];
+ dStrip GetStrip (int row, int col, int off) {
+ return (!btwn(off,0,15) || !btwn(row,0,MaxCubeHeight*2-1) || !btwn(col,0,NumBackTowers-1) || DQ[col][row]<0) ? null :
+ DS[DQ[col][row]+off];
+ }
+
+ void addTurn(dVertex v0, int pos0, dVertex v1, int pos1) { dTurn t = new dTurn(pos0, v1, pos1); if (v0.t0 == null) v0.t0=t; else v0.t1=t; }
+ void setRand(dCursor c) { c.set(DS[floor(random(iTowerStrips))].v0,0); }
+ float Dist2 (Strip s1, int pos1, Strip s2, int pos2) { return PointDist(s1.points.get(pos1), s2.points.get(pos2)); }
+ boolean SameSame (Strip s1, Strip s2) { return max(Dist2(s1, 0, s2, 0), Dist2(s1,15, s2,15)) < 5 ; }
+ boolean SameOpp (Strip s1, Strip s2) { return max(Dist2(s1, 0, s2,15), Dist2(s1,15, s2,0 )) < 5 ; }
+ boolean SameBar (Strip s1, Strip s2) { return SameSame(s1,s2) || SameOpp(s1,s2); }
+ void AddJoint (dVertex v1, dVertex v2) {
+ // should probably replace parallel but further with the new one
+ if (v1.c0 != null && SameBar(v2.s.s, v1.c0.s.s)) return;
+ if (v1.c1 != null && SameBar(v2.s.s, v1.c1.s.s)) return;
+ if (v1.c0 == null) v1.c0 = v2;
+ else if (v1.c1 == null) v1.c1 = v2;
+ }
+
+ dLattice() {
+ DL_=this;
+ for (int i=0;i<NumBackTowers;i++) for (int j=0;j<MaxCubeHeight*2;j++) DQ[i][j]=-1;
+
+ int col = 0, row = -2, i=-1;
+ for (Strip strip : glucose.model.strips ) { i++;
+ if (i % 16 == 0) row+=2;
+ if (row >= MaxCubeHeight*2-1) { col++; row = (col%2==1)?1:0; } // only include lattice parts!
+ iTowerStrips++;
+ dStrip s = DS[iTowerStrips-1] = new dStrip(strip, iTowerStrips-1, row, col);
+ s.v0 = new dVertex(s,strip.points.get(0 ));
+ s.v1 = new dVertex(s,strip.points.get(15));
+ s.v0.setOpp(s.v1); s.v1.setOpp(s.v0);
+ if (col < NumBackTowers) DQ[col][row] = 16*floor((iTowerStrips-1)/16);
+ }
+
+ for (int j=0; j<iTowerStrips; j++) { for (int k=j+1; k<iTowerStrips; k++) {
+ dStrip s1 = DS[j], s2 = DS[k];
+ int c=0;
+ if (SameSame(s1.s,s2.s)) { s1.v0.same = s2.v0; s1.v1.same = s2.v1;
+ s2.v0.same = s1.v0; s2.v1.same = s1.v1; continue; } // parallel
+ if (SameOpp (s1.s,s2.s)) { s1.v0.same = s2.v1; s1.v1.same = s2.v0;
+ s2.v0.same = s1.v1; s2.v1.same = s1.v0; continue; } // parallel
+ if (Dist2(s1.s, 0, s2.s, 0) < 5) { c++; AddJoint(s1.v1, s2.v0); AddJoint(s2.v1, s1.v0); }
+ if (Dist2(s1.s, 0, s2.s,15) < 5) { c++; AddJoint(s1.v1, s2.v1); AddJoint(s2.v0, s1.v0); }
+ if (Dist2(s1.s,15, s2.s, 0) < 5) { c++; AddJoint(s1.v0, s2.v0); AddJoint(s2.v1, s1.v1); }
+ if (Dist2(s1.s,15, s2.s,15) < 5) { c++; AddJoint(s1.v0, s2.v1); AddJoint(s2.v0, s1.v1); }
+ if (c>0) continue;
+
+ // Are they touching at all?
+ int pos1=0, pos2=0; float d = 100;
+
+ while (pos1 < 15 || pos2 < 15) {
+ float oldD = d;
+ if (pos1<15) { float d2 = Dist2(s1.s, pos1+1, s2.s, pos2+0); if (d2 < d) { d=d2; pos1++; } }
+ if (pos2<15) { float d2 = Dist2(s1.s, pos1+0, s2.s, pos2+1); if (d2 < d) { d=d2; pos2++; } }
+ if (d > 50 || oldD == d) break ;
+ }
+
+ if (d>5) continue;
+ addTurn(s1.v0, pos1, s2.v0, pos2); addTurn(s1.v1, 15-pos1, s2.v0, pos2);
+ addTurn(s2.v0, pos2, s1.v0, pos1); addTurn(s2.v1, 15-pos2, s1.v0, pos1);
+
+ }}
+ }
+}
+
+dLattice DL_;
+//----------------------------------------------------------------------------------------------------------------------------------
{
while(width()< g.position+1)
{
- graphicBuffer.add(color(0,0,0));
+ graphicBuffer.add(lx.hsb(0,0,0));
}
drawAll();
displayList.put(name , g);
{
while(width()< g.position + g.width())
{
- graphicBuffer.add(color(0,0,0));
+ graphicBuffer.add(lx.hsb(0,0,0));
}
if(g.changed)
{
{
for(int i = 0; i < len ;i++)
{
- graphicBuffer.add(color(0,255,255));
+ graphicBuffer.add(lx.hsb(0,255,255));
}
}
};
super();
for (int colorVal : colorSequence)
{
- graphicBuffer.add(color(colorVal, 255, 255));
+ graphicBuffer.add(lx.hsb(colorVal, 255, 255));
}
changed = true;
}
-color BLACK = color(0, 0, 0);
+color BLACK = #000000;
class Gimbal extends SCPattern {
+ pow(nearest_circle_z - c.z * ringExtendParam.getValuef(), 2));
float xy_distance = sqrt(c.x*c.x + c.y*c.y);
- return color(this.hue, 100, (1 - distance_to_circle / girth * fadeFromCoreParam.getValuef()) * 100);
+ return lx.hsb(this.hue, 100, (1 - distance_to_circle / girth * fadeFromCoreParam.getValuef()) * 100);
}
}
int stripe_count = 12;
float stripe_width = model.xMax / (float)stripe_count;
if (Math.floor((c.x) / stripe_width) % 2 == 0) {
- return color(hue, 100, 100);
+ return lx.hsb(hue, 100, 100);
} else {
- return color((hue + 90) % 360, 100, 100);
+ return lx.hsb((hue + 90) % 360, 100, 100);
}
/* OCTANTS
if ((isPositiveBit(c.x) + isPositiveBit(c.y) + isPositiveBit(c.z)) % 2 == 0) {
- return color(lx.getBaseHuef(), 100, 100);
+ return lx.hsb(lx.getBaseHuef(), 100, 100);
} else {
- return color(0, 0, 0);
+ return lx.hsb(0, 0, 0);
}
*/
}
float relative_b2 = b2 / (b1 + b2 + b3);
float relative_b3 = b3 / (b1 + b2 + b3);
- return color(
+ return lx.hsb(
(h1 * relative_b1 + h2 * relative_b1 + h3 * relative_b3) % 360,
s1 * relative_b1 + s2 * relative_b2 + s3 * relative_b3,
max(max(b1, b2), b3)
float v1 = sin_x > y_in_range ? (100 + 100*(y_in_range - sin_x)) : 0;
float hue_color = (lx.getBaseHuef() + hueScale.getValuef() * (abs(p.x-model.xMax/2.)*.3 + abs(p.y-model.yMax/2)*.9 + abs(p.z - model.zMax/2.))) % 360;
- colors[p.index] = color(hue_color, 70, v1);
+ colors[p.index] = lx.hsb(hue_color, 70, v1);
}
}
}
float v1 = max(0, 100 * (1 - 4*abs(sin_x - y_in_range)));
float hue_color = (lx.getBaseHuef() + hueScale.getValuef() * (abs(p.x-model.xMax/2.) + abs(p.y-model.yMax/2)*.2 + abs(p.z - model.zMax/2.)*.5)) % 360;
- color c = color(hue_color, 80, v1);
+ color c = lx.hsb(hue_color, 80, v1);
// Now draw the spheres
for (Sphere s : spheres) {
float sphere_color = (lx.getBaseHuef() - (1 - hueScale.getValuef()) * d/r * 45) % 360;
- c = blendColor(c, color((sphere_color + 270) % 360, 60, min(1, value) * 100), ADD);
+ c = blendColor(c, lx.hsb((sphere_color + 270) % 360, 60, min(1, value) * 100), ADD);
}
colors[p.index] = c;
}
+class MidiMusic extends SCPattern {
+
+ private final Map<Integer, LightUp> lightMap = new HashMap<Integer, LightUp>();
+ private final List<LightUp> allLights = new ArrayList<LightUp>();
+
+ private final Stack<LightUp> newLayers = new Stack<LightUp>();
+
+ MidiMusic(GLucose glucose) {
+ super(glucose);
+ }
+
+ class LightUp extends LXLayer {
+
+ private LinearEnvelope brt = new LinearEnvelope(0, 0, 0);
+ private Accelerator yPos = new Accelerator(0, 0, 0);
+ private float xPos;
+
+ LightUp() {
+ addModulator(brt);
+ addModulator(yPos);
+ }
+
+ boolean isAvailable() {
+ return brt.getValuef() <= 0;
+ }
+
+ void noteOn(Note note) {
+ xPos = lerp(0, model.xMax, constrain(0.5 + (note.getPitch() - 64) / 12., 0, 1));
+ yPos.setValue(lerp(20, model.yMax, note.getVelocity() / 127.));
+ brt.setRangeFromHereTo(lerp(40, 100, note.getVelocity() / 127.), 20).start();
+ }
+
+ void noteOff(Note note) {
+ yPos.setVelocity(0).setAcceleration(-380).start();
+ brt.setRangeFromHereTo(0, 1000).start();
+ }
+
+ public void run(double deltaMs, color[] colors) {
+ float bVal = brt.getValuef();
+ if (bVal <= 0) {
+ return;
+ }
+ float yVal = yPos.getValuef();
+ for (Point p : model.points) {
+ float b = max(0, bVal - 3*dist(p.x, p.y, xPos, yVal));
+ if (b > 0) {
+ colors[p.index] = blendColor(colors[p.index], lx.hsb(
+ (lx.getBaseHuef() + abs(p.x - model.cx) + abs(p.y - model.cy)) % 360,
+ 100,
+ b
+ ), ADD);
+ }
+ }
+ }
+ }
+
+ public synchronized boolean noteOn(Note note) {
+ if (note.getChannel() == 0) {
+ for (LightUp light : allLights) {
+ if (light.isAvailable()) {
+ light.noteOn(note);
+ lightMap.put(note.getPitch(), light);
+ return true;
+ }
+ }
+ LightUp newLight = new LightUp();
+ newLight.noteOn(note);
+ lightMap.put(note.getPitch(), newLight);
+ synchronized(newLayers) {
+ newLayers.push(newLight);
+ }
+ } else if (note.getChannel() == 1) {
+ }
+ return true;
+ }
+
+ public synchronized boolean noteOff(Note note) {
+ if (note.getChannel() == 0) {
+ LightUp light = lightMap.get(note.getPitch());
+ if (light != null) {
+ light.noteOff(note);
+ }
+ }
+ return true;
+ }
+
+ public synchronized void run(double deltaMs) {
+ setColors(#000000);
+ if (!newLayers.isEmpty()) {
+ synchronized(newLayers) {
+ while (!newLayers.isEmpty()) {
+ addLayer(newLayers.pop());
+ }
+ }
+ }
+ }
+}
+
+class Pulley extends SCPattern {
+
+ final int NUM_DIVISIONS = 16;
+ private final Accelerator[] gravity = new Accelerator[NUM_DIVISIONS];
+ private final Click[] delays = new Click[NUM_DIVISIONS];
+
+ private final Click reset = new Click(9000);
+ private boolean isRising = false;
+
+ private BasicParameter sz = new BasicParameter("SIZE", 0.5);
+ private BasicParameter beatAmount = new BasicParameter("BEAT", 0);
+
+ Pulley(GLucose glucose) {
+ super(glucose);
+ for (int i = 0; i < NUM_DIVISIONS; ++i) {
+ addModulator(gravity[i] = new Accelerator(0, 0, 0));
+ addModulator(delays[i] = new Click(0));
+ }
+ addModulator(reset).start();
+ addParameter(sz);
+ addParameter(beatAmount);
+ trigger();
+
+ }
+
+ private void trigger() {
+ isRising = !isRising;
+ int i = 0;
+ for (Accelerator g : gravity) {
+ if (isRising) {
+ g.setSpeed(random(20, 33), 0).start();
+ } else {
+ g.setVelocity(0).setAcceleration(-420);
+ delays[i].setDuration(random(0, 500)).trigger();
+ }
+ ++i;
+ }
+ }
+
+ public void run(double deltaMs) {
+ if (reset.click()) {
+ trigger();
+ }
+
+ if (isRising) {
+ // Fucking A, had to comment this all out because of that bizarre
+ // Processing bug where some simple loop takes an absurd amount of
+ // time, must be some pre-processor bug
+// for (Accelerator g : gravity) {
+// if (g.getValuef() > model.yMax) {
+// g.stop();
+// } else if (g.getValuef() > model.yMax*.55) {
+// if (g.getVelocityf() > 10) {
+// g.setAcceleration(-16);
+// } else {
+// g.setAcceleration(0);
+// }
+// }
+// }
+ } else {
+ int j = 0;
+ for (Click d : delays) {
+ if (d.click()) {
+ gravity[j].start();
+ d.stop();
+ }
+ ++j;
+ }
+ for (Accelerator g : gravity) {
+ if (g.getValuef() < 0) {
+ g.setValue(-g.getValuef());
+ g.setVelocity(-g.getVelocityf() * random(0.74, 0.84));
+ }
+ }
+ }
+
+ // A little silliness to test the grid API
+ for (int i = 0; i < 7; ++i) {
+ for (int j = 0; j < 8; ++j) {
+ int gi = (int) constrain(j * NUM_DIVISIONS / 8, 0, NUM_DIVISIONS-1);
+ float b = 1 - 4.*abs((6-i)/7. - gravity[gi].getValuef() / model.yMax);
+ midiEngine.grid.setState(i, j, (b < 0) ? 0 : 1);
+ }
+ }
+
+ float fPos = 1 - lx.tempo.rampf();
+ if (fPos < .2) {
+ fPos = .2 + 4 * (.2 - fPos);
+ }
+ float falloff = 100. / (3 + sz.getValuef() * 36 + fPos * beatAmount.getValuef()*48);
+ for (Point p : model.points) {
+ int gi = (int) constrain((p.x - model.xMin) * NUM_DIVISIONS / (model.xMax - model.xMin), 0, NUM_DIVISIONS-1);
+ colors[p.index] = lx.hsb(
+ (lx.getBaseHuef() + abs(p.x - model.cx)*.8 + p.y*.4) % 360,
+ constrain(130 - p.y*.8, 0, 100),
+ max(0, 100 - abs(p.y - gravity[gi].getValuef())*falloff)
+ );
+ }
+ }
+}
+
class ViolinWave extends SCPattern {
BasicParameter level = new BasicParameter("LVL", 0.45);
for (Point p : model.points) {
float b = 100 - pFalloff * (abs(p.x - x.getValuef()) + abs(p.y - y.getValuef()));
if (b > 0) {
- colors[p.index] = blendColor(colors[p.index], color(
+ colors[p.index] = blendColor(colors[p.index], lx.hsb(
lx.getBaseHuef(), 20, b
), ADD);
}
for (Point p : model.points) {
int ci = (int) lerp(0, centers.length-1, (p.x - model.xMin) / (model.xMax - model.xMin));
float rFactor = 1.0 - 0.9 * abs(p.x - model.cx) / (model.xMax - model.cx);
- colors[p.index] = color(
+ colors[p.index] = lx.hsb(
(lx.getBaseHuef() + abs(p.x - model.cx)) % 360,
min(100, 20 + 8*abs(p.y - centers[ci])),
constrain(edg*(val*rFactor - rng * abs(p.y-centers[ci])), 0, 100)
float d = sqrt((p.x-xv)*(p.x-xv) + (p.y-yv)*(p.y-yv) + .1*(p.z-zPos)*(p.z-zPos));
float b = constrain(130 - falloff*d, 0, 100);
if (b > 0) {
- colors[p.index] = blendColor(colors[p.index], color(
+ colors[p.index] = blendColor(colors[p.index], lx.hsb(
(lx.getBaseHuef() + p.y*.5 + abs(model.cx - p.x) * .5) % 360,
max(0, 100 - .45*(p.y - flrLevel)),
b
}
}
- public boolean noteOnReceived(Note note) {
+ public boolean noteOn(Note note) {
int pitch = (note.getPitch() + note.getChannel()) % NUM_BALLS;
balls[pitch].bounce(note.getVelocity());
return true;
for (Strip strip : model.strips) {
int i = 0;
for (Point p : strip.points) {
- colors[p.index] = color(
- (lx.getBaseHuef() + 360 - p.fx*.2 + p.fy * .3) % 360,
+ colors[p.index] = lx.hsb(
+ (lx.getBaseHuef() + 360 - p.x*.2 + p.y * .3) % 360,
constrain(.4 * min(abs(s - sVal1), abs(s - sVal2)), 20, 100),
max(0, 100 - fVal*abs(i - pVal*(strip.metrics.numPoints - 1)))
);
for (Strip strip : model.strips ) {
int i = 0;
for (Point p : strip.points) {
- float fV = max(-1, 1 - dist(p.fx/2., p.fy, fX.getValuef()/2., fY.getValuef()) / 64.);
- colors[p.index] = color(
- (lx.getBaseHuef() + 0.3 * abs(p.fx - hOffX.getValuef())) % 360,
+ float fV = max(-1, 1 - dist(p.x/2., p.y, fX.getValuef()/2., fY.getValuef()) / 64.);
+ colors[p.index] = lx.hsb(
+ (lx.getBaseHuef() + 0.3 * abs(p.x - hOffX.getValuef())) % 360,
constrain(80 + 40 * fV, 0, 100),
constrain(100 - (30 - fV * falloff.getValuef()) * modDist(i + (s*63)%61, offset.getValuef() * strip.metrics.numPoints, strip.metrics.numPoints), 0, 100)
);
float bleedf = 10 + bleed.getValuef() * 200.;
float xPos = (float) (-bleedf + progress * (model.xMax + bleedf));
for (Point p : model.points) {
- float d = (p.fx - xPos) / bleedf;
+ float d = (p.x - xPos) / bleedf;
if (d < 0) {
colors[p.index] = c2[p.index];
} else if (d > 1) {
float bassLevel = eq.getAverageLevel(0, 5);
for (Point p : model.points) {
- int avgIndex = (int) constrain(1 + abs(p.fx-model.xMax/2.)/(model.xMax/2.)*(eq.numBands-5), 0, eq.numBands-5);
+ int avgIndex = (int) constrain(1 + abs(p.x-model.xMax/2.)/(model.xMax/2.)*(eq.numBands-5), 0, eq.numBands-5);
float value = 0;
for (int i = avgIndex; i < avgIndex + 5; ++i) {
value += eq.getLevel(i);
}
value /= 5.;
- float b = constrain(8 * (value*model.yMax - abs(p.fy-model.yMax/2.)), 0, 100);
- colors[p.index] = color(
- (lx.getBaseHuef() + abs(p.fy - model.cy) + abs(p.fx - model.cx)) % 360,
- constrain(bassLevel*240 - .6*dist(p.fx, p.fy, model.cx, model.cy), 0, 100),
+ float b = constrain(8 * (value*model.yMax - abs(p.y-model.yMax/2.)), 0, 100);
+ colors[p.index] = lx.hsb(
+ (lx.getBaseHuef() + abs(p.y - model.cy) + abs(p.x - model.cx)) % 360,
+ constrain(bassLevel*240 - .6*dist(p.x, p.y, model.cx, model.cy), 0, 100),
b
);
}
float clrConst = 1.1 + clr.getValuef();
for (Point p : model.points) {
- float avgIndex = constrain(2 + p.fx / model.xMax * (eq.numBands-4), 0, eq.numBands-4);
+ float avgIndex = constrain(2 + p.x / model.xMax * (eq.numBands-4), 0, eq.numBands-4);
int avgFloor = (int) avgIndex;
float leftVal = eq.getLevel(avgFloor);
float value = lerp(smoothValue, chunkyValue, blockiness.getValuef());
- float b = constrain(edgeConst * (value*model.yMax - p.fy), 0, 100);
- colors[p.index] = color(
- (480 + lx.getBaseHuef() - min(clrConst*p.fy, 120)) % 360,
+ float b = constrain(edgeConst * (value*model.yMax - p.y), 0, 100);
+ colors[p.index] = lx.hsb(
+ (480 + lx.getBaseHuef() - min(clrConst*p.y, 120)) % 360,
100,
b
);
for (Point p : model.points) {
colors[p.index] = blendColor(
colors[p.index],
- color(huev, satv, constrain(brightv - falloffv*abs(boom.getValuef() - dist(p.fx, 2*p.fy, 3*p.fz, model.xMax/2, model.yMax, model.zMax*1.5)), 0, 100)),
+ lx.hsb(huev, satv, constrain(brightv - falloffv*abs(boom.getValuef() - dist(p.x, 2*p.y, 3*p.z, model.xMax/2, model.yMax, model.zMax*1.5)), 0, 100)),
ADD);
}
}
return base[index % base.length];
}
- public boolean noteOnReceived(Note note) {
+ public boolean noteOn(Note note) {
LinearEnvelope env = getEnvelope(note.getPitch());
env.setEndVal(min(1, env.getValuef() + (note.getVelocity() / 127.)), getAttackTime()).start();
return true;
}
- public boolean noteOffReceived(Note note) {
+ public boolean noteOff(Note note) {
getEnvelope(note.getPitch()).setEndVal(0, getReleaseTime()).start();
return true;
}
float levelf = level.getValuef();
for (Cube c : model.cubes) {
float v = max(getBase(i).getValuef() * levelf/4., getEnvelope(i++).getValuef());
- setColor(c, color(
+ setColor(c, lx.hsb(
(huef + 20*v + abs(c.cx-model.xMax/2.)*.3 + c.cy) % 360,
min(100, 120*v),
100*v
for (Point p : model.points) {
color c = 0;
- c = blendColor(c, color(
- (lx.getBaseHuef() + p.fx/10 + p.fy/3) % 360,
- constrain(140 - 1.1*abs(p.fx - model.xMax/2.), 0, 100),
- max(0, xlv - xwv*abs(p.fx - xv))
+ c = blendColor(c, lx.hsb(
+ (lx.getBaseHuef() + p.x/10 + p.y/3) % 360,
+ constrain(140 - 1.1*abs(p.x - model.xMax/2.), 0, 100),
+ max(0, xlv - xwv*abs(p.x - xv))
), ADD);
- c = blendColor(c, color(
- (lx.getBaseHuef() + 80 + p.fy/10) % 360,
- constrain(140 - 2.2*abs(p.fy - model.yMax/2.), 0, 100),
- max(0, ylv - ywv*abs(p.fy - yv))
+ c = blendColor(c, lx.hsb(
+ (lx.getBaseHuef() + 80 + p.y/10) % 360,
+ constrain(140 - 2.2*abs(p.y - model.yMax/2.), 0, 100),
+ max(0, ylv - ywv*abs(p.y - yv))
), ADD);
- c = blendColor(c, color(
- (lx.getBaseHuef() + 160 + p.fz / 10 + p.fy/2) % 360,
- constrain(140 - 2.2*abs(p.fz - model.zMax/2.), 0, 100),
- max(0, zlv - zwv*abs(p.fz - zv))
+ c = blendColor(c, lx.hsb(
+ (lx.getBaseHuef() + 160 + p.z / 10 + p.y/2) % 360,
+ constrain(140 - 2.2*abs(p.z - model.zMax/2.), 0, 100),
+ max(0, zlv - zwv*abs(p.z - zv))
), ADD);
colors[p.index] = c;
}
int i = 0;
float mv = m[si % m.length].getValuef();
for (Point p : strip.points) {
- colors[p.index] = color(
- (hv + p.fz + p.fy*hs.getValuef()) % 360,
- min(100, abs(p.fx - s.getValuef())/2.),
+ colors[p.index] = lx.hsb(
+ (hv + p.z + p.y*hs.getValuef()) % 360,
+ min(100, abs(p.x - s.getValuef())/2.),
max(0, 100 - mv/2. - mv * abs(i - (strip.metrics.length-1)/2.))
);
++i;
int i = 0;
for (Strip strip : model.strips) {
for (Point p : strip.points) {
- colors[p.index] = color(
- (huev + i*constrain(cv, 0, 2) + p.fz/2. + p.fx/4.) % 360,
- min(100, abs(p.fy-sv)),
+ colors[p.index] = lx.hsb(
+ (huev + i*constrain(cv, 0, 2) + p.z/2. + p.x/4.) % 360,
+ min(100, abs(p.y-sv)),
max(0, 100 - 50*abs((i%NUM) - mv))
);
}
float d = MAX_FLOAT;
for (Plane plane : planes) {
if (plane.denom != 0) {
- d = min(d, abs(plane.av*(p.fx-model.cx) + plane.bv*(p.fy-model.cy) + plane.cv) / plane.denom);
+ d = min(d, abs(plane.av*(p.x-model.cx) + plane.bv*(p.y-model.cy) + plane.cv) / plane.denom);
}
}
- colors[p.index] = color(
- (huev + abs(p.fx-model.cx)*.3 + p.fy*.8) % 360,
- max(0, 100 - .8*abs(p.fx - model.cx)),
+ colors[p.index] = lx.hsb(
+ (huev + abs(p.x-model.cx)*.3 + p.y*.8) % 360,
+ max(0, 100 - .8*abs(p.x - model.cx)),
constrain(140 - 10.*d, 0, 100)
);
}
float dv = d.getValuef();
float denom = sqrt(av*av + bv*bv + cv*cv);
for (Point p : model.points) {
- float d = abs(av*(p.fx-model.cx) + bv*(p.fy-model.cy) + cv*(p.fz-model.cz) + dv) / denom;
- colors[p.index] = color(
- (hv + abs(p.fx-model.cx)*.6 + abs(p.fy-model.cy)*.9 + abs(p.fz - model.cz)) % 360,
+ float d = abs(av*(p.x-model.cx) + bv*(p.y-model.cy) + cv*(p.z-model.cz) + dv) / denom;
+ colors[p.index] = lx.hsb(
+ (hv + abs(p.x-model.cx)*.6 + abs(p.y-model.cy)*.9 + abs(p.z - model.cz)) % 360,
constrain(110 - d*6, 0, 100),
constrain(130 - 7*d, 0, 100)
);
int i = (int) constrain((model.xMax - p.x) / model.xMax * FRAME_WIDTH, 0, FRAME_WIDTH-1);
int pos = (index + FRAME_WIDTH - i) % FRAME_WIDTH;
- colors[p.index] = color(
+ colors[p.index] = lx.hsb(
(360 + lx.getBaseHuef() + .8*abs(p.x-model.cx)) % 360,
100,
- constrain(9 * (bass[pos]*model.cy - abs(p.fy - model.cy)), 0, 100)
+ constrain(9 * (bass[pos]*model.cy - abs(p.y - model.cy)), 0, 100)
);
- colors[p.index] = blendColor(colors[p.index], color(
+ colors[p.index] = blendColor(colors[p.index], lx.hsb(
(400 + lx.getBaseHuef() + .5*abs(p.x-model.cx)) % 360,
60,
- constrain(5 * (treble[pos]*.6*model.cy - abs(p.fy - model.cy)), 0, 100)
+ constrain(5 * (treble[pos]*.6*model.cy - abs(p.y - model.cy)), 0, 100)
), ADD);
}
BasicParameter hueShift = new BasicParameter("HSHFT", 0);
BasicParameter sat = new BasicParameter("SAT", 1);
BasicParameter bright = new BasicParameter("BRT", 1);
+ float[] hsb = new float[3];
ColorFuckerEffect(GLucose glucose) {
super(glucose);
float hMod = hueShift.getValuef();
if (bMod < 1 || sMod < 1 || hMod > 0) {
for (int i = 0; i < colors.length; ++i) {
- colors[i] = color(
- (hue(colors[i]) + hueShift.getValuef()*360.) % 360,
- saturation(colors[i]) * sat.getValuef(),
- brightness(colors[i]) * bright.getValuef()
+ lx.RGBtoHSB(colors[i], hsb);
+ colors[i] = lx.hsb(
+ (360. * hsb[0] + hueShift.getValuef()*360.) % 360,
+ 100. * hsb[1] * sat.getValuef(),
+ 100. * hsb[2] * bright.getValuef()
);
}
}
float a = hv%250;
if (i%2 == 0) {
for (int b = 0; b < 70; b++) {
- colors[(i+b)%colors.length] = color(a+i%250, 100, b*a%100);
+ colors[(i+b)%colors.length] = lx.hsb(a+i%250, 100, b*a%100);
}
}
}
// For performance reasons, cut out points that are outside of
// the tube where the toroidal coil lives.
if (abs(myDist(p, axisPoint) - radius) > girth*.5f) {
- return color(0,0,0);
+ return lx.hsb(0,0,0);
}
// Find the appropriate point for the current rotation
// Soften edges by fading brightness.
float b = constrain(100*(1 - ((d-.5*girth)/(girth*.5))), 0, 100);
- return color((lx.getBaseHuef() + (360*(phase / TWO_PI)))%360, 80, b);
+ return lx.hsb((lx.getBaseHuef() + (360*(phase / TWO_PI)))%360, 80, b);
}
}
float t = axis.getTValue(pt) + spokePhase;
int spokeIndex = (int)floor((t - tMin + spokePeriod/2) / spokePeriod);
if (spokeIndex < 0 || spokeIndex >= basePairs.length) {
- return color(0,0,0);
+ return lx.hsb(0,0,0);
}
BasePairInfo basePair = basePairs[spokeIndex];
Line spokeLine = basePair.line;
float d = PVector.dist(pt, pointOnSpoke);
float b = (PVector.dist(pointOnSpoke, spokeLine.getPoint()) < spokeRadius) ? constrain(100*(1 - ((d-.5*spokeGirth)/(spokeGirth*.5))), 0, 100) : 0.f;
float phase = spokeLine.getTValue(pointOnSpoke) < 0 ? basePair.colorPhase1 : basePair.colorPhase2;
- return color((lx.getBaseHuef() + (360*(phase / TWO_PI)))%360, 80.f, b);
+ return lx.hsb((lx.getBaseHuef() + (360*(phase / TWO_PI)))%360, 80.f, b);
}
void run(double deltaMs) {
color spokeColor = calculateSpokeColor(pt);
if (!h1on) {
- h1c = color(0,0,0);
+ h1c = lx.hsb(0,0,0);
}
if (!h2on) {
- h2c = color(0,0,0);
+ h2c = lx.hsb(0,0,0);
}
if (!spokesOn) {
- spokeColor = color(0,0,0);
+ spokeColor = lx.hsb(0,0,0);
}
// The helices are positioned to not overlap. If that changes,
new CubeCurl(glucose),
// Slee
+ // new MidiMusic(glucose),
+ new Pulley(glucose),
new Swarm(glucose),
new ViolinWave(glucose),
new BouncyBalls(glucose),
new TestBassMapping(glucose),
new TestFloorMapping(glucose),
new TestSpeakerMapping(glucose),
+ new TestPerformancePattern(glucose),
// new TestHuePattern(glucose),
// new TestXPattern(glucose),
// new TestYPattern(glucose),
for (Strip strip : speaker.strips) {
float b = 100;
for (Point p : strip.points) {
- colors[p.index] = color(h % 360, 100, b);
+ colors[p.index] = lx.hsb(h % 360, 100, b);
b = max(0, b - 10);
}
h += 70;
for (int si : strips) {
float b = 100;
for (Point p : model.bassBox.strips.get(si).points) {
- colors[p.index] = color(h % 360, 100, b);
+ colors[p.index] = lx.hsb(h % 360, 100, b);
b = max(0, b - 10);
}
h += 70;
for (int si : strutIndices) {
float b = 100;
for (Point p : model.bassBox.struts.get(si).points) {
- colors[p.index] = color(h % 360, 100, b);
+ colors[p.index] = lx.hsb(h % 360, 100, b);
b = max(0, b - 10);
}
h += 50;
for (int fi : floorIndices) {
float b = 100;
for (Point p : model.boothFloor.strips.get(fi).points) {
- colors[p.index] = color(h, 100, b);
+ colors[p.index] = lx.hsb(h, 100, b);
b = max(0, b - 3);
}
h += 90;
}
}
+class TestPerformancePattern extends TestPattern {
+
+ final BasicParameter ops = new BasicParameter("OPS", 0);
+ final BasicParameter iter = new BasicParameter("ITER", 0);
+
+ TestPerformancePattern(GLucose glucose) {
+ super(glucose);
+ addParameter(ops);
+ addParameter(iter);
+ }
+
+ public void run(double deltaMs) {
+ float x = 1;
+ for (int j = 0; j < ops.getValuef() * 400000; ++j) {
+ x *= random(0, 1);
+ }
+
+ if (iter.getValuef() < 0.25) {
+ for (Point p : model.points) {
+ colors[p.index] = lx.hsb(
+ (p.x*.1 + p.y*.1) % 360,
+ 100,
+ 100
+ );
+ }
+ } else if (iter.getValuef() < 0.5) {
+ for (int i = 0; i < colors.length; ++i) {
+ colors[i] = lx.hsb(
+ (90 + model.px[i]*.1 + model.py[i]*.1) % 360,
+ 100,
+ 100
+ );
+ }
+ } else if (iter.getValuef() < 0.75) {
+ for (int i = 0; i < colors.length; ++i) {
+ colors[i] = lx.hsb(
+ (180 + model.p[3*i]*.1 + model.p[3*i+1]*.1) % 360,
+ 100,
+ 100
+ );
+ }
+ } else {
+ for (int i = 0; i < colors.length; ++i) {
+ colors[i] = lx.hsb(
+ (270 + model.x(i)*.1 + model.y(i)*.1) % 360,
+ 100,
+ 100
+ );
+ }
+ }
+ }
+}
+
class TestStripPattern extends TestPattern {
SinLFO d = new SinLFO(4, 40, 4000);
public void run(double deltaMs) {
for (Strip s : model.strips) {
for (Point p : s.points) {
- colors[p.index] = color(
+ colors[p.index] = lx.hsb(
lx.getBaseHuef(),
100,
max(0, 100 - d.getValuef()*dist(p.x, p.y, s.cx, s.cy))
// Access the core master hue via this method call
float hv = lx.getBaseHuef();
for (int i = 0; i < colors.length; ++i) {
- colors[i] = color(hv, 100, 100);
+ colors[i] = lx.hsb(hv, 100, 100);
}
}
}
// You can use abs() to determine the distance between two
// values. The further away this point is from an exact
// point, the more we decrease its brightness
- float bv = max(0, 100 - abs(p.fx - xPos.getValuef()));
- colors[p.index] = color(hv, 100, bv);
+ float bv = max(0, 100 - abs(p.x - xPos.getValuef()));
+ colors[p.index] = lx.hsb(hv, 100, bv);
}
}
}
public void run(double deltaMs) {
float hv = lx.getBaseHuef();
for (Point p : model.points) {
- float bv = max(0, 100 - abs(p.fy - yPos.getValuef()));
- colors[p.index] = color(hv, 100, bv);
+ float bv = max(0, 100 - abs(p.y - yPos.getValuef()));
+ colors[p.index] = lx.hsb(hv, 100, bv);
}
}
}
public void run(double deltaMs) {
float hv = lx.getBaseHuef();
for (Point p : model.points) {
- float bv = max(0, 100 - abs(p.fz - zPos.getValuef()));
- colors[p.index] = color(hv, 100, bv);
+ float bv = max(0, 100 - abs(p.z - zPos.getValuef()));
+ colors[p.index] = lx.hsb(hv, 100, bv);
}
}
}
int ti = 0;
for (Tower t : model.towers) {
for (Point p : t.points) {
- colors[p.index] = color(
+ colors[p.index] = lx.hsb(
lx.getBaseHuef(),
100,
max(0, 100 - 80*LXUtils.wrapdistf(ti, towerIndex.getValuef(), model.towers.size()))
float d = sqrt(c.x*c.x + c.y*c.y + c.z*c.z); // distance from origin
// d = abs(d-60) + max(0, abs(c.z) - 20); // life saver / ring thing
d = max(0, abs(c.y) - 10 + .1*abs(c.z) + .02*abs(c.x)); // plane / spear thing
- colors[c.index] = color(
+ colors[c.index] = lx.hsb(
(hv + .6*abs(c.x) + abs(c.z)) % 360,
100,
constrain(140 - 40*d, 0, 100)
for (Cube c : model.cubes) {
int i = 0;
for (Point p : c.points) {
- colors[p.index] = color(
+ colors[p.index] = lx.hsb(
lx.getBaseHuef(),
100,
max(0, 100 - 80.*abs(i - index.getValuef()))
}
public void run(double deltaMs) {
- color off = color(0, 0, 0);
+ color off = #000000;
color c = off;
color r = #FF0000;
color g = #00FF00;
for (Point p : model.points) {
float value = 0;
- color c = color(0, 0, 0);
+ color c = lx.hsb(0, 0, 0);
for (Sphere s : spheres) {
float d = sqrt(pow(p.x - s.x, 2) + pow(p.y - s.y, 2) + pow(p.z - s.z, 2));
float r = (s.radius); // * (sinLfoValue + 0.5));
value = max(0, 1 - max(0, d - r) / 10);
- c = blendColor(c, color(((s.hue + lfoValue) % 1) * 360, 100, min(1, value) * 100), ADD);
+ c = blendColor(c, lx.hsb(((s.hue + lfoValue) % 1) * 360, 100, min(1, value) * 100), ADD);
}
colors[p.index] = c;
}
float distanceTo(Point p) {
- return distanceTo(p.fx, p.fy, p.fz);
+ return distanceTo(p.x, p.y, p.z);
}
void add(Vector3 other, float multiplier) {
for (Point p : model.points) {
color c =
blendColor(
- color(210, 20, (float)Math.max(0, 1 - Math.pow((model.yMax - p.fy) / 10, 2)) * 50),
- color(220, 60, (float)Math.max(0, 1 - Math.pow((p.fy - model.yMin) / 10, 2)) * 100),
+ lx.hsb(210, 20, (float)Math.max(0, 1 - Math.pow((model.yMax - p.y) / 10, 2)) * 50),
+ lx.hsb(220, 60, (float)Math.max(0, 1 - Math.pow((p.y - model.yMin) / 10, 2)) * 100),
ADD);
for (Raindrop raindrop : raindrops) {
- if (p.fx >= (raindrop.p.x - raindrop.radius) && p.fx <= (raindrop.p.x + raindrop.radius) &&
- p.fy >= (raindrop.p.y - raindrop.radius) && p.fy <= (raindrop.p.y + raindrop.radius)) {
+ if (p.x >= (raindrop.p.x - raindrop.radius) && p.x <= (raindrop.p.x + raindrop.radius) &&
+ p.y >= (raindrop.p.y - raindrop.radius) && p.y <= (raindrop.p.y + raindrop.radius)) {
float d = raindrop.p.distanceTo(p) / raindrop.radius;
// float value = (float)Math.max(0, 1 - Math.pow(Math.min(0, d - raindrop.radius) / 5, 2));
if (d < 1) {
- c = blendColor(c, color(raindrop.hue, 80, (float)Math.pow(1 - d, 0.01) * 100), ADD);
+ c = blendColor(c, lx.hsb(raindrop.hue, 80, (float)Math.pow(1 - d, 0.01) * 100), ADD);
}
}
}
for (CubeFlash flash : flashes) {
float hue = (hueParameter.getValuef() + (hueVarianceParameter.getValuef() * flash.hue)) % 1.0;
- color c = color(hue * 360, saturationParameter.getValuef() * 100, (flash.value) * 100);
+ color c = lx.hsb(hue * 360, saturationParameter.getValuef() * 100, (flash.value) * 100);
for (Point p : flash.c.points) {
colors[p.index] = c;
}
color c = 0;
for (Plane plane : planes) {
- normalizedPoint.x = p.fx - plane.center.x;
- normalizedPoint.y = p.fy - plane.center.y;
- normalizedPoint.z = p.fz - plane.center.z;
+ normalizedPoint.x = p.x - plane.center.x;
+ normalizedPoint.y = p.y - plane.center.y;
+ normalizedPoint.z = p.z - plane.center.z;
float v = plane.rotation.rotatedY(normalizedPoint);
float d = abs(v);
final color planeColor;
if (d <= thickness) {
- planeColor = color(plane.hue, saturation, 100);
+ planeColor = lx.hsb(plane.hue, saturation, 100);
} else if (d <= thickness * 2) {
float value = 1 - ((d - thickness) / thickness);
- planeColor = color(plane.hue, saturation, value * 100);
+ planeColor = lx.hsb(plane.hue, saturation, value * 100);
} else {
planeColor = 0;
}
int value = 0;
for (Pinwheel pw : pinwheels) {
- value += (pw.isOnBlade(p.fx, p.fy - p.fz * zSlope) ? 1 : 0);
+ value += (pw.isOnBlade(p.x, p.y - p.z * zSlope) ? 1 : 0);
}
if (value == 1) {
values[i] = 1;
-// colors[p.index] = color(120, 0, 100);
+// colors[p.index] = lx.hsb(120, 0, 100);
} else {
values[i] = max(0, values[i] - fadeAmount);
//color c = colors[p.index];
- //colors[p.index] = color(max(0, hue(c) - 10), min(100, saturation(c) + 10), brightness(c) - 5 );
+ //colors[p.index] = lx.hsb(max(0, lx.h(c) - 10), min(100, lx.s(c) + 10), lx.b(c) - 5 );
}
if (random(1.0) >= derez) {
float v = values[i];
- colors[p.index] = color((360 + hue + pow(v, 2) * hueSpread) % 360, 30 + pow(1 - v, 0.25) * 60, v * 100);
+ colors[p.index] = lx.hsb((360 + hue + pow(v, 2) * hueSpread) % 360, 30 + pow(1 - v, 0.25) * 60, v * 100);
}
}
}
for (Strip s : model.strips) {
Vector3 v = new Vector3();
for (Point p : s.points) {
- v.add(p.fx, p.fy, p.fz);
+ v.add(p.x, p.y, p.z);
}
v.divide(s.points.size());
stripToCenter.put(s, v);
List<Strip> nearbyStrips = stripToNearbyStrips.get(s);
for (Point p : s.points) {
- Vector3 v = new Vector3(p.fx, p.fy, p.fz);
+ Vector3 v = new Vector3(p.x, p.y, p.z);
List<Point> neighbors = new ArrayList();
float closestPointDistance = 100000;
for (Point nsp : nearbyStrip.points) {
- float distance = v.distanceTo(nsp.fx, nsp.fy, nsp.fz);
+ float distance = v.distanceTo(nsp.x, nsp.y, nsp.z);
if (closestPoint == null || distance < closestPointDistance) {
closestPoint = nsp;
closestPointDistance = distance;
public void run(double deltaMs) {
for (Point p : model.points) {
color c = colors[p.index];
- colors[p.index] = color(hue(c), saturation(c), brightness(c) - 3);
+ colors[p.index] = lx.hsb(lx.h(c), lx.s(c), lx.b(c) - 3);
}
for (MovingPoint mp : movingPoints) {
mp.step();
- colors[mp.currentPoint.index] = blendColor(colors[mp.currentPoint.index], color(mp.hue, 10, 100), ADD);
+ colors[mp.currentPoint.index] = blendColor(colors[mp.currentPoint.index], lx.hsb(mp.hue, 10, 100), ADD);
}
}
}
public void run(double deltaMs) {
for (Point p : model.points) {
- float hv = sin(dist(p.fx + pos, p.fy, 128.0, 128.0) / 8.0)
- + sin(dist(p.fx, p.fy, 64.0, 64.0) / 8.0)
- + sin(dist(p.fx, p.fy + pos / 7, 192.0, 64.0) / 7.0)
- + sin(dist(p.fx, p.fz + pos, 192.0, 100.0) / 8.0);
+ float hv = sin(dist(p.x + pos, p.y, 128.0, 128.0) / 8.0)
+ + sin(dist(p.x, p.y, 64.0, 64.0) / 8.0)
+ + sin(dist(p.x, p.y + pos / 7, 192.0, 64.0) / 7.0)
+ + sin(dist(p.x, p.z + pos, 192.0, 100.0) / 8.0);
float bv = 100;
- colors[p.index] = color((hv+2)*50, satu, bv);
+ colors[p.index] = lx.hsb((hv+2)*50, satu, bv);
}
if (random(1.0)<glitch/20) {
pos=pos-int(random(10,30));
}
}
private color flameColor(float level) {
- if (level<=0) return color(0,0,0);
+ if (level<=0) return lx.hsb(0,0,0);
float br=min(100,sqrt(level)*15);
- return color(level/1.7,100,br);
+ return lx.hsb(level/1.7,100,br);
}
public void run(double deltaMs) {
for (int x=10;x<xm-10;x++) {
}
for (Point p : model.points) {
- int x = max(0,(int(p.fx)+int(p.fz))%xm);
- int y = constrain(ym-int(p.fy),0,ym-1);
+ int x = max(0,(int(p.x)+int(p.z))%xm);
+ int y = constrain(ym-int(p.y),0,ym-1);
colors[p.index] = flameColor(intensity[x][y]);
}
}
for (Strip strip : model.strips) {
for (int i=0;i<numOsc;i++) {
float avgdist=0.0;
- avgdist = dist(strip.points.get(8).fx,strip.points.get(8).fy,strip.points.get(8).fz,fX[i].getValuef(),fY[i].getValuef(),fZ[i].getValuef());
+ avgdist = dist(strip.points.get(8).x,strip.points.get(8).y,strip.points.get(8).z,fX[i].getValuef(),fY[i].getValuef(),fZ[i].getValuef());
boolean on = avgdist<30;
float hv = (lx.getBaseHuef()+colorOffset[i])%360;
float br = max(0,100-avgdist*4);
for (Point p : strip.points) {
if (on && br>bright[p.index]) {
- colors[p.index] = color(hv,sat[i].getValuef(),br);
+ colors[p.index] = lx.hsb(hv,sat[i].getValuef(),br);
bright[p.index] = br;
}
}
Strip s = c.strips.get(j);
if (j%4!=0 && j%4!=2) {
for (Point p : s.points) {
- int seq = int(p.fy*avgSize/model.yMax+pos.getValuef()+sin(p.fx+p.fz)*2)%avgSize;
+ int seq = int(p.y*avgSize/model.yMax+pos.getValuef()+sin(p.x+p.z)*2)%avgSize;
seq=min(abs(seq-(avgSize/2)),avgSize-1);
- colors[p.index] = color(200,max(0,100-abs(p.fx-col1.getValuef())/2),lightVals[seq]);
+ colors[p.index] = lx.hsb(200,max(0,100-abs(p.x-col1.getValuef())/2),lightVals[seq]);
}
}
}
for (Point p : s.points) {
float dx, dz;
if (i%32 < 16) {
- dx = p.fx - (s.cx+xosc.getValuef());
- dz = p.fz - (s.cz+zosc.getValuef());
+ dx = p.x - (s.cx+xosc.getValuef());
+ dz = p.z - (s.cz+zosc.getValuef());
} else {
- dx = p.fx - (s.cx+zosc.getValuef());
- dz = p.fz - (s.cz+xosc.getValuef());
+ dx = p.x - (s.cx+zosc.getValuef());
+ dz = p.z - (s.cz+xosc.getValuef());
}
//println(dx);
- float a1=max(0,100-abs(p.fx-col1.getValuef()));
- float a2=max(0,100-abs(p.fx-col2.getValuef()));
+ float a1=max(0,100-abs(p.x-col1.getValuef()));
+ float a2=max(0,100-abs(p.x-col2.getValuef()));
float sat = max(a1,a2);
float h = (359*a1+200*a2) / (a1+a2);
- colors[p.index] = color(h,sat,100-abs(dx*5)-abs(dz*5));
+ colors[p.index] = lx.hsb(h,sat,100-abs(dx*5)-abs(dz*5));
}
}
}
Strip s = c.strips.get(j);
if (j%4!=0 && j%4!=2) {
for (Point p : s.points) {
- float dis = (abs(p.fx-model.xMax/2)+pos.getValuef())%model.xMax/2;
+ float dis = (abs(p.x-model.xMax/2)+pos.getValuef())%model.xMax/2;
int seq = int((dis*avgSize*2)/model.xMax);
if (seq>avgSize) seq=avgSize-seq;
seq=constrain(seq,0,avgSize-1);
- float br=max(0, lightVals[seq]-p.fy);
- colors[p.index] = color((dis*avgSize*65)/model.xMax,90,br);
+ float br=max(0, lightVals[seq]-p.y);
+ colors[p.index] = lx.hsb((dis*avgSize*65)/model.xMax,90,br);
}
}
}
MappingTool mappingTool;
PandaDriver[] pandaBoards;
MidiEngine midiEngine;
+GridController gridController;
// Display configuration mode
boolean mappingMode = false;
boolean uiOn = true;
LXPattern restoreToPattern = null;
PImage logo;
+float[] hsb = new float[3];
// Handles to UI objects
UIContext[] overlays;
}
return rightPatterns;
}
-
void logTime(String evt) {
int now = millis();
lx.enableKeyboardTempo();
logTime("Built GLucose engine");
- // MIDI devices
- midiEngine = new MidiEngine();
- logTime("Setup MIDI devices");
-
// Set the patterns
Engine engine = lx.engine;
engine.setPatterns(patterns = _leftPatterns(glucose));
logTime("Built transitions");
glucose.lx.addEffects(effects(glucose));
logTime("Built effects");
-
+
+ // MIDI devices
+ midiEngine = new MidiEngine();
+ logTime("Setup MIDI devices");
+
// Build output driver
PandaMapping[] pandaMappings = buildPandaList();
pandaBoards = new PandaDriver[pandaMappings.length];
void draw() {
// Draws the simulation and the 2D UI overlay
background(40);
- color[] colors = glucose.getColors();
+ color[] simulationColors;
+ color[] sendColors;
+ simulationColors = sendColors = glucose.getColors();
String displayMode = uiCrossfader.getDisplayMode();
if (displayMode == "A") {
- colors = lx.engine.getDeck(0).getColors();
+ simulationColors = lx.engine.getDeck(0).getColors();
} else if (displayMode == "B") {
- colors = lx.engine.getDeck(1).getColors();
+ simulationColors = lx.engine.getDeck(1).getColors();
}
if (debugMode) {
- debugUI.maskColors(colors);
+ debugUI.maskColors(simulationColors);
+ debugUI.maskColors(sendColors);
}
camera(
strokeWeight(2);
beginShape(POINTS);
for (Point p : glucose.model.points) {
- stroke(colors[p.index]);
- vertex(p.fx, p.fy, p.fz);
+ stroke(simulationColors[p.index]);
+ vertex(p.x, p.y, p.z);
}
endShape();
// 2D Overlay UI
drawUI();
- // Send output colors
- color[] sendColors = glucose.getColors();
- if (debugMode) {
- debugUI.maskColors(sendColors);
- }
-
// Gamma correction here. Apply a cubic to the brightness
// for better representation of dynamic range
for (int i = 0; i < sendColors.length; ++i) {
- float b = brightness(sendColors[i]) / 100.f;
- sendColors[i] = color(
- hue(sendColors[i]),
- saturation(sendColors[i]),
- (b*b*b) * 100.
- );
+ lx.RGBtoHSB(sendColors[i], hsb);
+ float b = hsb[2];
+ sendColors[i] = lx.hsb(360.*hsb[0], 100.*hsb[1], 100.*(b*b*b));
}
// TODO(mcslee): move into GLucose engine
}
}
break;
+ case 't':
+ if (!midiEngine.isQwertyEnabled()) {
+ lx.engine.setThreaded(!lx.engine.isThreaded());
+ }
+ break;
case 'p':
for (PandaDriver p : pandaBoards) {
p.toggle();
}
}
-void mouseWheel(int delta) {delta*=20;
+void mouseWheel(int delta) {
boolean wheeled = false;
for (UIContext context : overlays) {
wheeled |= context.mouseWheel(mouseX, mouseY, delta);
class MidiEngine {
+ public final GridController grid;
private final List<MidiEngineListener> listeners = new ArrayList<MidiEngineListener>();
private final List<SCMidiInput> midiControllers = new ArrayList<SCMidiInput>();
private int activeDeckIndex = 0;
public MidiEngine() {
-
- midiControllers.add(midiQwertyKeys = new SCMidiInput(SCMidiInput.KEYS));
- midiControllers.add(midiQwertyAPC = new SCMidiInput(SCMidiInput.APC));
+ grid = new GridController(this);
+ midiControllers.add(midiQwertyKeys = new VirtualKeyMidiInput(this, VirtualKeyMidiInput.KEYS));
+ midiControllers.add(midiQwertyAPC = new VirtualKeyMidiInput(this, VirtualKeyMidiInput.APC));
for (MidiInputDevice device : RWMidi.getInputDevices()) {
if (device.getName().contains("APC")) {
- midiControllers.add(new APC40MidiInput(device).setEnabled(true));
+ midiControllers.add(new APC40MidiInput(this, device).setEnabled(true));
} else if (device.getName().contains("SLIDER/KNOB KORG")) {
- midiControllers.add(new KorgNanoKontrolMidiInput(device).setEnabled(true));
+ midiControllers.add(new KorgNanoKontrolMidiInput(this, device).setEnabled(true));
} else {
- boolean enabled = device.getName().contains("KEYBOARD KORG");
- midiControllers.add(new SCMidiInput(device).setEnabled(enabled));
+ boolean enabled = device.getName().contains("KEYBOARD KORG") || device.getName().contains("Bus 1 Apple");
+ midiControllers.add(new GenericDeviceMidiInput(this, device).setEnabled(enabled));
+ }
+ }
+ for (MidiOutputDevice device : RWMidi.getOutputDevices()) {
+ if (device.getName().contains("APC")) {
+ new APC40MidiOutput(this, device);
}
}
}
return this.midiControllers;
}
+ public Engine.Deck getFocusedDeck() {
+ return lx.engine.getDeck(activeDeckIndex);
+ }
+
+ public SCPattern getFocusedPattern() {
+ return (SCPattern) getFocusedDeck().getActivePattern();
+ }
+
public MidiEngine setFocusedDeck(int deckIndex) {
if (this.activeDeckIndex != deckIndex) {
this.activeDeckIndex = deckIndex;
return this;
}
- public Engine.Deck getFocusedDeck() {
- return lx.engine.getDeck(activeDeckIndex);
- }
-
public boolean isQwertyEnabled() {
return midiQwertyKeys.isEnabled() || midiQwertyAPC.isEnabled();
}
public void onEnabled(SCMidiInput controller, boolean enabled);
}
-public class SCMidiInput extends AbstractScrollItem {
+public abstract class SCMidiInput extends AbstractScrollItem {
- public static final int MIDI = 0;
- public static final int KEYS = 1;
- public static final int APC = 2;
-
- private boolean enabled = false;
+ protected boolean enabled = false;
private final String name;
- private final int mode;
- private int octaveShift = 0;
-
- class NoteMeta {
- int channel;
- int number;
- NoteMeta(int channel, int number) {
- this.channel = channel;
- this.number = number;
- }
- }
- final Map<Character, NoteMeta> keyToNote = new HashMap<Character, NoteMeta>();
+ protected final MidiEngine midiEngine;
final List<SCMidiInputListener> listeners = new ArrayList<SCMidiInputListener>();
+ protected SCMidiInput(MidiEngine midiEngine, String name) {
+ this.midiEngine = midiEngine;
+ this.name = name;
+ }
+
public SCMidiInput addListener(SCMidiInputListener l) {
listeners.add(l);
return this;
return this;
}
- SCMidiInput(MidiInputDevice d) {
- mode = MIDI;
- d.createInput(this);
- name = d.getName().replace("Unknown vendor","");
+ public String getLabel() {
+ return name;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public boolean isSelected() {
+ return enabled;
+ }
+
+ public void onMousePressed() {
+ setEnabled(!enabled);
+ }
+
+ public SCMidiInput setEnabled(boolean enabled) {
+ if (enabled != this.enabled) {
+ this.enabled = enabled;
+ for (SCMidiInputListener l : listeners) {
+ l.onEnabled(this, enabled);
+ }
+ }
+ return this;
+ }
+
+ private boolean logMidi() {
+ return (uiMidi != null) && uiMidi.logMidi();
+ }
+
+ final void programChangeReceived(ProgramChange pc) {
+ if (!enabled) {
+ return;
+ }
+ if (logMidi()) {
+ println(getLabel() + " :: Program Change :: " + pc.getNumber());
+ }
+ handleProgramChange(pc);
+ }
+
+ final void controllerChangeReceived(rwmidi.Controller cc) {
+ if (!enabled) {
+ return;
+ }
+ if (logMidi()) {
+ println(getLabel() + " :: Controller :: " + cc.getChannel() + " :: " + cc.getCC() + ":" + cc.getValue());
+ }
+ if (!handleGridControllerChange(cc)) {
+ if (!midiEngine.getFocusedPattern().controllerChange(cc)) {
+ handleControllerChange(cc);
+ }
+ }
+ }
+
+ final void noteOnReceived(Note note) {
+ if (!enabled) {
+ return;
+ }
+ if (logMidi()) {
+ println(getLabel() + " :: Note On :: " + note.getChannel() + ":" + note.getPitch() + ":" + note.getVelocity());
+ }
+ if (!handleGridNoteOn(note)) {
+ if (!midiEngine.getFocusedPattern().noteOn(note)) {
+ handleNoteOn(note);
+ }
+ }
+ }
+
+ final void noteOffReceived(Note note) {
+ if (!enabled) {
+ return;
+ }
+ if (logMidi()) {
+ println(getLabel() + " :: Note Off :: " + note.getChannel() + ":" + note.getPitch() + ":" + note.getVelocity());
+ }
+ if (!handleGridNoteOff(note)) {
+ if (!midiEngine.getFocusedPattern().noteOff(note)) {
+ handleNoteOff(note);
+ }
+ }
}
- SCMidiInput(int mode) {
+ // Subclasses may implement these to map top-level functionality
+ protected boolean handleGridNoteOn(Note note) { return false; }
+ protected boolean handleGridNoteOff(Note note) { return false; }
+ protected boolean handleGridControllerChange(rwmidi.Controller cc) { return false; }
+ protected void handleProgramChange(ProgramChange pc) {}
+ protected void handleControllerChange(rwmidi.Controller cc) {}
+ protected void handleNoteOn(Note note) {}
+ protected void handleNoteOff(Note note) {}
+}
+
+public class VirtualKeyMidiInput extends SCMidiInput {
+
+ public static final int KEYS = 1;
+ public static final int APC = 2;
+
+ private final int mode;
+
+ private int octaveShift = 0;
+
+ class NoteMeta {
+ int channel;
+ int number;
+ NoteMeta(int channel, int number) {
+ this.channel = channel;
+ this.number = number;
+ }
+ }
+
+ final Map<Character, NoteMeta> keyToNote = new HashMap<Character, NoteMeta>();
+
+ VirtualKeyMidiInput(MidiEngine midiEngine, int mode) {
+ super(midiEngine, "QWERTY (" + (mode == APC ? "APC" : "Key") + " Mode)");
this.mode = mode;
- switch (mode) {
- case APC:
- name = "QWERTY (APC Mode)";
+ if (mode == APC) {
mapAPC();
- break;
- default:
- case KEYS:
- name = "QWERTY (Key Mode)";
+ } else {
mapKeys();
- break;
}
+ registerKeyEvent(this);
}
private void mapAPC() {
mapNote('v', 3, 56);
mapNote('b', 4, 56);
mapNote('n', 5, 56);
- registerKeyEvent(this);
}
private void mapKeys() {
mapNote('k', 1, note++);
mapNote('o', 1, note++);
mapNote('l', 1, note++);
- registerKeyEvent(this);
}
void mapNote(char ch, int channel, int number) {
keyToNote.put(ch, new NoteMeta(channel, number));
}
-
- public String getLabel() {
- return name;
- }
-
+
public void keyEvent(KeyEvent e) {
if (!enabled) {
return;
}
}
}
+}
- public boolean isEnabled() {
- return enabled;
- }
-
- public boolean isSelected() {
- return enabled;
- }
-
- public void onMousePressed() {
- setEnabled(!enabled);
- }
-
- public SCMidiInput setEnabled(boolean enabled) {
- if (enabled != this.enabled) {
- this.enabled = enabled;
- for (SCMidiInputListener l : listeners) {
- l.onEnabled(this, enabled);
- }
- }
- return this;
+public class GenericDeviceMidiInput extends SCMidiInput {
+ GenericDeviceMidiInput(MidiEngine midiEngine, MidiInputDevice d) {
+ super(midiEngine, d.getName().replace("Unknown vendor",""));
+ d.createInput(this);
}
+}
- protected SCPattern getFocusedPattern() {
- return (SCPattern) midiEngine.getFocusedDeck().getActivePattern();
- }
+public class APC40MidiInput extends GenericDeviceMidiInput {
- private boolean logMidi() {
- return (uiMidi != null) && uiMidi.logMidi();
+ private boolean shiftOn = false;
+ private LXEffect releaseEffect = null;
+
+ APC40MidiInput(MidiEngine midiEngine, MidiInputDevice d) {
+ super(midiEngine, d);
}
- final void programChangeReceived(ProgramChange pc) {
- if (!enabled) {
- return;
- }
- if (logMidi()) {
- println(getLabel() + " :: Program Change :: " + pc.getNumber());
+ private class GridPosition {
+ public final int row, col;
+ GridPosition(int r, int c) {
+ row = r;
+ col = c;
}
- handleProgramChange(pc);
}
-
- final void controllerChangeReceived(rwmidi.Controller cc) {
- if (!enabled) {
- return;
- }
- if (logMidi()) {
- println(getLabel() + " :: Controller :: " + cc.getCC() + ":" + cc.getValue());
- }
- if (!getFocusedPattern().controllerChangeReceived(cc)) {
- handleControllerChange(cc);
+
+ private GridPosition getGridPosition(Note note) {
+ int channel = note.getChannel();
+ int pitch = note.getPitch();
+ if (channel < 8) {
+ if (pitch >= 53 && pitch <=57) return new GridPosition(pitch-53, channel);
+ else if (pitch == 52) return new GridPosition(5, channel);
}
+ return null;
}
- final void noteOnReceived(Note note) {
- if (!enabled) {
- return;
- }
- if (logMidi()) {
- println(getLabel() + " :: Note On :: " + note.getChannel() + ":" + note.getPitch() + ":" + note.getVelocity());
- }
- if (!getFocusedPattern().noteOnReceived(note)) {
- handleNoteOn(note);
+ protected boolean handleGridNoteOn(Note note) {
+ GridPosition p = getGridPosition(note);
+ if (p != null) {
+ return midiEngine.grid.gridPressed(p.row, p.col);
}
+ return false;
}
- final void noteOffReceived(Note note) {
- if (!enabled) {
- return;
- }
- if (logMidi()) {
- println(getLabel() + " :: Note Off :: " + note.getChannel() + ":" + note.getPitch() + ":" + note.getVelocity());
- }
- if (!getFocusedPattern().noteOffReceived(note)) {
- handleNoteOff(note);
+ protected boolean handleGridNoteOff(Note note) {
+ GridPosition p = getGridPosition(note);
+ if (p != null) {
+ return midiEngine.grid.gridReleased(p.row, p.col);
}
- }
-
- // Subclasses may implement these to map top-level functionality
- protected void handleProgramChange(ProgramChange pc) {
- }
- protected void handleControllerChange(rwmidi.Controller cc) {
- }
- protected void handleNoteOn(Note note) {
- }
- protected void handleNoteOff(Note note) {
- }
-}
-
-public class APC40MidiInput extends SCMidiInput {
-
- private boolean shiftOn = false;
- private LXEffect releaseEffect = null;
-
- APC40MidiInput(MidiInputDevice d) {
- super(d);
+ return false;
}
protected void handleControllerChange(rwmidi.Controller cc) {
parameterIndex = 8 + (number-16);
}
if (parameterIndex >= 0) {
- List<LXParameter> parameters = getFocusedPattern().getParameters();
+ List<LXParameter> parameters = midiEngine.getFocusedPattern().getParameters();
if (parameterIndex < parameters.size()) {
parameters.get(parameterIndex).setValue(cc.getValue() / 127.);
}
}
}
-
+ private long tap1 = 0;
- private double Tap1 = 0;
- private double getNow() { return millis() + 1000*second() + 60*1000*minute() + 3600*1000*hour(); }
- private boolean dbtwn (double a,double b,double c) { return a >= b && a <= c; }
+ private boolean lbtwn(long a, long b, long c) {
+ return a >= b && a <= c;
+ }
protected void handleNoteOn(Note note) {
- int nPitch = note.getPitch(), nChan = note.getChannel();
+ int nPitch = note.getPitch(), nChan = note.getChannel();
switch (nPitch) {
- case 82: EFF_boom .trigger(); break; // BOOM!
- case 83: EFF_flash .trigger(); break; // Flash
-
- case 90: lx.tempo.trigger(); Tap1 = getNow(); break; // dan's dirty tapping mechanism
+ case 82: // scene 1
+ EFF_boom.trigger();
+ break;
+
+ case 83: // scene 2
+ EFF_flash.trigger();
+ break;
+
+ case 90:
+ // dan's dirty tapping mechanism
+ lx.tempo.trigger();
+ tap1 = millis();
+ break;
case 91: // play
- case 95: // bank
+ case 97: // left bank
midiEngine.setFocusedDeck(0);
break;
case 93: // rec
- case 94: // right bank
+ case 96: // right bank
midiEngine.setFocusedDeck(1);
break;
- case 96: // up bank
+ case 94: // up bank
if (shiftOn) {
- glucose.incrementSelectedEffectBy(1);
+ glucose.incrementSelectedEffectBy(-1);
} else {
- midiEngine.getFocusedDeck().goNext();
+ midiEngine.getFocusedDeck().goPrev();
}
break;
- case 97: // down bank
+ case 95: // down bank
if (shiftOn) {
- glucose.incrementSelectedEffectBy(-1);
+ glucose.incrementSelectedEffectBy(1);
} else {
- midiEngine.getFocusedDeck().goPrev();
+ midiEngine.getFocusedDeck().goNext();
}
break;
lx.tempo.setBpm(lx.tempo.bpm() - (shiftOn ? 1 : .1));
break;
- case 62: // Detail View
+ case 62: // Detail View / red 5
releaseEffect = glucose.getSelectedEffect();
if (releaseEffect.isMomentary()) {
releaseEffect.enable();
}
break;
- case 63: // rec quantize
+ case 63: // rec quantize / red 6
glucose.getSelectedEffect().disable();
break;
}
}
protected void handleNoteOff(Note note) {
- int nPitch = note.getPitch(), nChan = note.getChannel();
+ int nPitch = note.getPitch(), nChan = note.getChannel();
switch (nPitch) {
- case 90:
- if (dbtwn(getNow() - Tap1,5000,300*1000)) { // hackish tapping mechanism
- double bpm = 32.*60000./(getNow()-Tap1);
- while (bpm < 20) bpm*=2;
- while (bpm > 40) bpm/=2;
- lx.tempo.setBpm(bpm); lx.tempo.trigger(); Tap1=0; println("Tap Set - " + bpm + " bpm");
- }
- break;
-
+ case 90: // SEND C
+ long tapDelta = millis() - tap1;
+ if (lbtwn(tapDelta,5000,300*1000)) { // hackish tapping mechanism
+ double bpm = 32.*60000./(tapDelta);
+ while (bpm < 20) bpm*=2;
+ while (bpm > 40) bpm/=2;
+ lx.tempo.setBpm(bpm);
+ lx.tempo.trigger();
+ tap1 = 0;
+ println("Tap Set - " + bpm + " bpm");
+ }
+ break;
- case 63: // rec quantize
+ case 63: // rec quantize / RED 6
if (releaseEffect != null) {
if (releaseEffect.isMomentary()) {
releaseEffect.disable();
case 98: // shift
shiftOn = false;
- break;
+ break;
}
}
}
-class KorgNanoKontrolMidiInput extends SCMidiInput {
+class KorgNanoKontrolMidiInput extends GenericDeviceMidiInput {
- KorgNanoKontrolMidiInput(MidiInputDevice d) {
- super(d);
+ KorgNanoKontrolMidiInput(MidiEngine midiEngine, MidiInputDevice d) {
+ super(midiEngine, d);
}
protected void handleControllerChange(rwmidi.Controller cc) {
int number = cc.getCC();
if (number >= 16 && number <= 23) {
int parameterIndex = number - 16;
- List<LXParameter> parameters = getFocusedPattern().getParameters();
+ List<LXParameter> parameters = midiEngine.getFocusedPattern().getParameters();
if (parameterIndex < parameters.size()) {
parameters.get(parameterIndex).setValue(cc.getValue() / 127.);
}
}
}
+class APC40MidiOutput implements LXParameter.Listener, GridOutput {
+
+ private final MidiEngine midiEngine;
+ private final MidiOutput output;
+ private LXPattern focusedPattern = null;
+ private LXEffect focusedEffect = null;
+
+ APC40MidiOutput(MidiEngine midiEngine, MidiOutputDevice device) {
+ this.midiEngine = midiEngine;
+ output = device.createOutput();
+ midiEngine.addListener(new MidiEngineListener() {
+ public void onFocusedDeck(int deckIndex) {
+ resetPatternParameters();
+ }
+ });
+ glucose.addEffectListener(new GLucose.EffectListener() {
+ public void effectSelected(LXEffect effect) {
+ resetEffectParameters();
+ }
+ });
+ Engine.Listener deckListener = new Engine.AbstractListener() {
+ public void patternDidChange(Engine.Deck deck, LXPattern pattern) {
+ resetPatternParameters();
+ }
+ };
+ for (Engine.Deck d : lx.engine.getDecks()) {
+ d.addListener(deckListener);
+ }
+ resetParameters();
+ midiEngine.grid.addOutput(this);
+ }
+
+ private void resetParameters() {
+ resetPatternParameters();
+ resetEffectParameters();
+ }
+
+ private void resetPatternParameters() {
+ LXPattern newPattern = midiEngine.getFocusedDeck().getActivePattern();
+ if (newPattern == focusedPattern) {
+ return;
+ }
+ if (focusedPattern != null) {
+ for (LXParameter p : focusedPattern.getParameters()) {
+ ((LXListenableParameter) p).removeListener(this);
+ }
+ }
+ focusedPattern = newPattern;
+ int i = 0;
+ for (LXParameter p : focusedPattern.getParameters()) {
+ ((LXListenableParameter) p).addListener(this);
+ sendKnob(i++, p);
+ }
+ while (i < 12) {
+ sendKnob(i++, 0);
+ }
+ for (int row = 0; row < 7; ++row) {
+ for (int col = 0; col < 8; ++col) {
+ setGridState(row, col, 0);
+ }
+ }
+ }
+
+ private void resetEffectParameters() {
+ LXEffect newEffect = glucose.getSelectedEffect();
+ if (newEffect == focusedEffect) {
+ return;
+ }
+ if (focusedEffect != null) {
+ for (LXParameter p : focusedPattern.getParameters()) {
+ ((LXListenableParameter) p).removeListener(this);
+ }
+ }
+ focusedEffect = newEffect;
+ int i = 0;
+ for (LXParameter p : focusedEffect.getParameters()) {
+ ((LXListenableParameter) p).addListener(this);
+ sendKnob(12 + i++, p);
+ }
+ while (i < 4) {
+ sendKnob(12 + i++, 0);
+ }
+ }
+
+ private void sendKnob(int i, LXParameter p) {
+ sendKnob(i, (int) (p.getValuef() * 127.));
+ }
+
+ private void sendKnob(int i, int value) {
+ if (i < 8) {
+ output.sendController(0, 48+i, value);
+ } else if (i < 16) {
+ output.sendController(0, 8+i, value);
+ }
+ }
+
+ public void onParameterChanged(LXParameter parameter) {
+ int i = 0;
+ for (LXParameter p : focusedPattern.getParameters()) {
+ if (p == parameter) {
+ sendKnob(i, p);
+ break;
+ }
+ ++i;
+ }
+ i = 12;
+ for (LXParameter p : focusedEffect.getParameters()) {
+ if (p == parameter) {
+ sendKnob(i, p);
+ break;
+ }
+ ++i;
+ }
+ }
+
+ public void setGridState(int row, int col, int state) {
+ if (col < 8) {
+ if (row < 5) output.sendNoteOn(col, 53+row, state);
+ else if (row == 6) output.sendNoteOn(col, 52, state);
+ }
+ }
+}
+
+interface GridOutput {
+ public static final int OFF = 0;
+ public static final int GREEN = 1;
+ public static final int GREEN_BLINK = 2;
+ public static final int RED = 3;
+ public static final int RED_BLINK = 4;
+ public static final int YELLOW = 5;
+ public static final int YELLOW_BLINK = 6;
+ public static final int ON = 127;
+
+ public void setGridState(int row, int col, int state);
+}
+
+class GridController {
+ private final List<GridOutput> outputs = new ArrayList<GridOutput>();
+
+ private final MidiEngine midiEngine;
+
+ GridController(MidiEngine midiEngine) {
+ this.midiEngine = midiEngine;
+ }
+
+ public void addOutput(GridOutput output) {
+ outputs.add(output);
+ }
+
+ public boolean gridPressed(int row, int col) {
+ return midiEngine.getFocusedPattern().gridPressed(row, col);
+ }
+
+ public boolean gridReleased(int row, int col) {
+ return midiEngine.getFocusedPattern().gridReleased(row, col);
+ }
+
+ public void setState(int row, int col, int state) {
+ for (GridOutput g : outputs) {
+ g.setGridState(row, col, state);
+ }
+ }
+}
+
towerList.add(new Tower(tower));
}
- return new Model(towerList, cubes, bassBox, speakers);
+ return new Model(towerList, cubes, bassBox, speakers);
}
/**
itemColor = #707070;
}
float factor = even ? .92 : 1.08;
- itemColor = color(hue(itemColor), saturation(itemColor), min(100, factor*brightness(itemColor)));
+ itemColor = lx.scaleBrightness(itemColor, factor);
pg.noStroke();
pg.fill(itemColor);
}
if (hasScroll) {
pg.noStroke();
- pg.fill(color(0, 0, 100, 15));
+ pg.fill(0x26ffffff);
pg.rect(w-12, 0, 12, h);
pg.fill(#333333);
pg.rect(w-12, scrollYStart, 12, scrollYHeight);