Commit | Line | Data |
---|---|---|
e28f168c AG |
1 | //---------------------------------------------------------------------------------------------------------------------------------- |
2 | static MidiOutput midiout; | |
3 | int nNumRows = 5, nNumCols = 8; | |
4 | float xdMax,ydMax,zdMax; | |
5 | String DanTextLine1 = "", DanTextLine2 = ""; | |
6 | ||
7 | boolean btwn (int a,int b,int c) { return a >= b && a <= c; } | |
8 | boolean btwn (double a,double b,double c) { return a >= b && a <= c; } | |
9 | ||
10 | public class Pick { | |
11 | Pick (String label, int _Def, int _Max) { NumPicks=_Max; Default = _Def; tag=label; } | |
12 | int Cur() { return (CurRow-StartRow)*nNumCols + CurCol; } | |
13 | int NumPicks, Default, CurRow, CurCol, StartRow, EndRow; | |
14 | String tag; | |
15 | } | |
16 | //---------------------------------------------------------------------------------------------------------------------------------- | |
17 | public class _DhP extends BasicParameter { | |
18 | double dflt; | |
19 | _DhP (String label, double value) { super(label,value); dflt=value; } | |
20 | void Set (double value) { super.updateValue(value); } | |
21 | void reset () { super.updateValue(dflt); } | |
22 | float Val () { return getValuef(); } | |
23 | boolean ZeroOrOne () { return Val()==0 || Val() == 1; } | |
24 | } | |
25 | ||
26 | public class IndexNums { | |
27 | int point ;//, cube , tower , face , strip ; | |
28 | int nPoints ;//, nCubes, nTowers, nFaces, nStrips ; | |
29 | // boolean isHoriz; | |
30 | void reset() { point=0;}//cube=tower=face=strip=0; } | |
31 | } | |
32 | IndexNums iCur = new IndexNums(); | |
33 | //---------------------------------------------------------------------------------------------------------------------------------- | |
34 | public class xyz { float x,y,z; | |
35 | xyz() {x=y=z=0;} | |
36 | xyz(Point p ) {x=p.fx ; y=p.fy; z=p.fz;} | |
37 | xyz(float _x,float _y,float _z) {x=_x ; y=_y ; z=_z ;} | |
38 | void set(float _x,float _y,float _z) {x=_x ; y=_y ; z=_z ;} | |
39 | float distance(xyz b) {return dist(x,y,z,b.x,b.y,b.z); } | |
40 | float dot (xyz b) {return x*b.x + y*b.y + z*b.z; } | |
41 | xyz minus (xyz b) {return new xyz(x-b.x,y-b.y,z-b.z); } | |
42 | xyz plus (xyz b) {return new xyz(x+b.x,y+b.y,z+b.z); } | |
43 | xyz plus (float b) {return new xyz(x+b ,y+b ,z+b ); } | |
44 | xyz over (xyz b) {return new xyz(x/b.x,y/b.y,z/b.z); } | |
45 | xyz times (float b) {return new xyz(x*b ,y*b ,z*b ); } | |
46 | ||
47 | xyz RotateX (xyz o, float a) { return new xyz ( x, | |
48 | cos(a)*(y-o.y) - sin(a)*(z-o.z) + o.y, | |
49 | sin(a)*(y-o.y) + cos(a)*(z-o.z) + o.z); } | |
50 | ||
51 | xyz RotateY (xyz o, float a) { return new xyz ( cos(a)*(x-o.x) - sin(a)*(z-o.z) + o.x, | |
52 | y, | |
53 | sin(a)*(x-o.x) + cos(a)*(z-o.z) + o.z); } | |
54 | ||
55 | xyz RotateZ (xyz o, float a) { return new xyz ( cos(a)*(x-o.x) - sin(a)*(y-o.y) + o.x, | |
56 | sin(a)*(x-o.x) + cos(a)*(y-o.y) + o.y, | |
57 | z ); } | |
58 | ||
59 | xyz setRand () { return new xyz ( random(xdMax), random(ydMax), random(zdMax)); } | |
60 | xyz setNorm () { return new xyz ( x / xdMax, y / ydMax, z / zdMax); } | |
61 | ||
62 | float interp (float a, float b, float c) { return (1-a)*b + a*c; } | |
63 | xyz interpolate(float i, xyz d) { return new xyz ( interp(i,x,d.x), interp(i,y,d.y), interp(i,z,d.z)); } | |
64 | } | |
65 | //---------------------------------------------------------------------------------------------------------------------------------- | |
66 | public class DPat extends SCPattern | |
67 | { | |
68 | float zSpinHue; | |
69 | xyz xyzdMax, xyz0, xyzMid, xyzHalf; | |
70 | PFont itemFont = createFont("Lucida Grande", 11); | |
71 | ArrayList picklist = new ArrayList(); | |
72 | ArrayList paramlist = new ArrayList(); | |
73 | int nMaxRow = 0; | |
74 | boolean bIsActive = false; | |
75 | float NoiseMove = random(10000); | |
76 | ||
77 | float Dist (xyz a, xyz b) { return dist(a.x,a.y,a.z,b.x,b.y,b.z); } | |
78 | int c1c (float a) { return int(100*constrain(a,0,1)); } | |
79 | int mapRow (int a) { return btwn(a,53,57) ? a-53 : a; } | |
80 | int unmapRow (int a) { return btwn(a,0 , 4) ? a+53 : a; } | |
81 | void SetLight (int row, int col, int clr){ if (midiout != null) midiout.sendNoteOn(col, unmapRow(row), clr); } | |
82 | void keypad (int row, int col) { println(row + " " + col); } | |
d626bc9b | 83 | void onInactive() { bIsActive=false; DanTextLine1 = ""; DanTextLine2 = ""; uiDebugText.setText(""); } |
e28f168c AG |
84 | void onActive () { bIsActive=true; |
85 | zSpinHue = 0; | |
86 | for (int i=0; i<paramlist.size(); i++) ((_DhP)paramlist.get(i)).reset(); | |
87 | while (lx.tempo.bpm() > 40) lx.tempo.setBpm(lx.tempo.bpm()/2); | |
88 | UpdateLights(); | |
89 | } | |
34327c96 | 90 | void StartRun(double deltaMs) { } |
e28f168c AG |
91 | color CalcPoint(xyz p) { return color(0,0,0); } |
92 | float CalcCone (xyz v1, xyz v2, xyz c) { | |
93 | return degrees( acos ( v1.minus(c).dot(v2.minus(c)) / (sqrt(v1.minus(c).dot(v1.minus(c))) * sqrt(v2.minus(c).dot(v2.minus(c))) ) )); | |
94 | } | |
95 | ||
96 | void AddDanText() { | |
97 | DanTextLine1 = "APC40: "; | |
98 | for (int i=0; i<picklist.size() ; i++) { Pick P = (Pick)picklist.get(i); DanTextLine1 += P.tag + ": " + P.Cur() + " "; } | |
99 | DanTextLine1 += " X-Symm: " + (_XSym ? "ON" : "OFF") + " "; | |
100 | DanTextLine1 += " Y-Symm: " + (_YSym ? "ON" : "OFF") + " "; | |
101 | DanTextLine1 += " Z-Symm: " + (_ZSym ? "ON" : "OFF") + " "; | |
102 | DanTextLine1 += " Rad-Sym: " + (_RadSym ? "ON" : "OFF") + " "; | |
103 | // DanTextLine1 += " Horiz: " + (_Horiz ? "ON" : "OFF") + " "; | |
104 | // DanTextLine1 += " Vert: " + (_Vert ? "ON" : "OFF") + " "; | |
105 | ||
106 | DanTextLine2 = "SLIDERS: "; | |
107 | for (int i=0; i<8; i++) if (SliderText[i] != "") { DanTextLine2 += SliderText[i] + ": " + Sliders[i] + " "; } | |
d626bc9b MS |
108 | |
109 | uiDebugText.setText(DanTextLine1, DanTextLine2); | |
e28f168c AG |
110 | } |
111 | ||
34327c96 | 112 | void run(double deltaMs) { |
e28f168c AG |
113 | NoiseMove += deltaMs; |
114 | xdMax = model.xMax; | |
115 | ydMax = model.yMax; | |
116 | zdMax = model.zMax; | |
117 | xyzdMax = new xyz(xdMax,ydMax,zdMax); | |
118 | xyzMid = new xyz(xdMax/2, ydMax/2, zdMax/2); | |
119 | StartRun (deltaMs); | |
120 | zSpinHue += s_SpinHue ()*deltaMs*.05; | |
121 | float fSharp = 1/(1.01-pSharp.Val()); | |
122 | AddDanText(); | |
123 | iCur.reset(); iCur.nPoints = model.points.size(); | |
124 | // iCur.nTowers = model.towers.size(); iCur.nCubes = model.cubes .size(); | |
125 | // iCur.nFaces = model.faces .size(); iCur.nStrips = model.strips.size(); | |
126 | ||
127 | // for (Tower t : model.towers) { iCur.tower++; | |
128 | // for (Cube c : t.cubes) { iCur.cube ++; | |
129 | // for (Face f : c.faces) { iCur.face ++; | |
130 | // for (Strip s : f.strips) { iCur.strip++; iCur.isHoriz= (iCur.strip % 2 == 1 || iCur.strip < 5) ? true : false; | |
131 | for (Point p : model.points) { iCur.point++; | |
132 | xyz P = new xyz(p); | |
133 | ||
134 | if (s_Spark () > 0) P.y += s_Spark () * (noise(P.x,P.y+NoiseMove/30 ,P.z)*ydMax - ydMax/2.); | |
135 | if (s_Wiggle() > 0) P.y += s_Wiggle() * (noise(P.x/(xdMax*.3)-NoiseMove/1500.) - .5) * (ydMax/2.); | |
136 | ||
137 | color cOld = colors[p.index]; | |
138 | color cNew = CalcPoint(P); | |
139 | ||
140 | // if (_Horiz && !iCur.isHoriz) { colors[p.index] = 0; continue; } | |
141 | // if (_Vert && iCur.isHoriz) { colors[p.index] = 0; continue; } | |
142 | if (_XSym) cNew = blendColor(cNew, CalcPoint(new xyz(xdMax-P.x,P.y,P.z)), ADD); | |
143 | if (_YSym) cNew = blendColor(cNew, CalcPoint(new xyz(P.x,ydMax-P.y,P.z)), ADD); | |
144 | if (_ZSym) cNew = blendColor(cNew, CalcPoint(new xyz(P.x,P.y,zdMax-P.z)), ADD); | |
145 | ||
146 | float b = brightness(cNew)/100.; | |
147 | b = b < .5 ? pow(b,fSharp) : 1-pow(1-b,fSharp); | |
148 | ||
149 | float modhue = s_ModHue ()>0 ? s_ModHue ()*360:0; | |
150 | ||
151 | float noizhue = s_NoiseHue()>0 ? s_NoiseHue()*360*noise( P.x/(xdMax*.3)+NoiseMove/3000., | |
152 | P.y/(ydMax*.3)+NoiseMove/4000., | |
153 | P.z/(zdMax*.3)+NoiseMove/5000.) : 0; | |
154 | ||
155 | cNew = color( (hue(cNew) + modhue + zSpinHue - noizhue) % 360, | |
156 | saturation(cNew) + 100*s_Saturate(), | |
34327c96 | 157 | 100 * (s_Trails()==0 ? b : max(b, (float) (brightness(cOld)/100. - (1-s_Trails()) * deltaMs/200.))) |
e28f168c AG |
158 | * (s_Dim ()==0 ? 1 : 1-s_Dim()) |
159 | ); | |
160 | ||
161 | colors[p.index] = cNew; | |
162 | } | |
163 | // }}}} | |
164 | } | |
165 | ||
166 | void controllerChangeReceived(rwmidi.Controller cc) { | |
167 | if (cc.getCC() == 7 && btwn(cc.getChannel(),0,7)) Sliders[cc.getChannel()] = 1.*cc.getValue()/127.; | |
168 | } | |
169 | ||
170 | public float Sliders[] = new float[] {0,0,0,0,0,0,0,0}; | |
171 | String SliderText[]= new String[] {"Trails", "Dim", "Saturate", "SpinHue", "Hue", "NoiseHue", "Spark", "Wiggle"}; | |
172 | float s_Trails () { return Sliders[0]; } | |
173 | float s_Dim () { return Sliders[1]; } | |
174 | float s_Saturate () { return Sliders[2]; } | |
175 | float s_SpinHue () { return Sliders[3]; } | |
176 | float s_ModHue () { return Sliders[4]; } | |
177 | float s_NoiseHue () { return Sliders[5]; } | |
178 | float s_Spark () { return Sliders[6]; } | |
179 | float s_Wiggle () { return Sliders[7]; } | |
180 | _DhP pSharp; | |
181 | ||
182 | DPat(GLucose glucose) { | |
183 | super(glucose); | |
184 | xyzHalf = new xyz(.5,.5,.5); | |
185 | xyz0 = new xyz(0,0,0); | |
186 | pSharp = addParam("Shrp", 0); | |
187 | ||
a8d55ade | 188 | // for (MidiInputDevice input : RWMidi.getInputDevices ()) { if (input.toString().contains("APC")) input .createInput (this);} |
e28f168c AG |
189 | for (MidiOutputDevice output : RWMidi.getOutputDevices()) { |
190 | if (midiout == null && output.toString().contains("APC")) midiout = output.createOutput(); | |
191 | } | |
192 | } | |
193 | ||
194 | void UpdateLights() { | |
195 | for (int i=0; i<nNumRows ; i++) for (int j=0; j<nNumCols; j++) SetLight(i, j, 0); | |
196 | for (int i=0; i<picklist.size() ; i++) { | |
197 | Pick P = (Pick)picklist.get(i); SetLight(P.CurRow, P.CurCol, 3); | |
198 | } | |
199 | SetLight(82, 0, _XSym ? 3 : 0); | |
200 | SetLight(83, 0, _YSym ? 3 : 0); | |
201 | SetLight(84, 0, _ZSym ? 3 : 0); | |
202 | SetLight(85, 0, _RadSym ? 3 : 0); | |
203 | // SetLight(86, 0, _Horiz ? 3 : 0); | |
204 | // SetLight(87, 0, _Vert ? 3 : 0); | |
205 | } | |
206 | ||
207 | Pick GetPick(int row, int col) { | |
208 | for (int i=0; i<picklist.size(); i++) { Pick P = (Pick)picklist.get(i); | |
209 | if (!btwn(row,P.StartRow,P.EndRow) ) continue; | |
210 | if (!btwn(col,0,nNumCols-1) ) continue; | |
211 | if (!btwn((row-P.StartRow)*nNumCols + col,0,P.NumPicks-1) ) continue; | |
212 | return P; | |
213 | } | |
214 | return null; | |
215 | } | |
216 | ||
217 | double Tap1 = 0; | |
218 | double getNow() { return millis() + 1000*second() + 60*1000*minute() + 3600*1000*hour(); } | |
219 | ||
220 | void noteOffReceived(Note note) { if (!bIsActive) return; | |
221 | int row = mapRow(note.getPitch()), col = note.getChannel(); | |
222 | ||
223 | if (row == 50 && col == 0 && btwn(getNow() - Tap1,5000,300*1000)) { // hackish tapping mechanism | |
224 | double bpm = 32.*60000./(getNow()-Tap1); | |
225 | while (bpm < 20) bpm*=2; | |
226 | while (bpm > 40) bpm/=2; | |
227 | lx.tempo.setBpm(bpm); lx.tempo.trigger(); Tap1=0; println("Tap Set - " + bpm + " bpm"); | |
228 | } | |
229 | ||
230 | UpdateLights(); | |
231 | } | |
232 | ||
233 | boolean _XSym=false, _YSym=false, _ZSym=false, _RadSym=false; //, _Horiz=false, _Vert=false; | |
234 | ||
235 | void noteOnReceived (Note note) { if (!bIsActive) return; | |
236 | int row = mapRow(note.getPitch()), col = note.getChannel(); | |
237 | Pick P = GetPick(row,col); | |
238 | if (P != null) { P.CurRow=row; P.CurCol=col; } | |
239 | else if (row == 50 && col == 0) { lx.tempo.trigger(); Tap1 = getNow(); } | |
240 | else if (row == 82 && col == 0) _XSym = !_XSym ; | |
241 | else if (row == 83 && col == 0) _YSym = !_YSym ; | |
242 | else if (row == 84 && col == 0) _ZSym = !_ZSym ; | |
243 | else if (row == 85 && col == 0) _RadSym = !_RadSym ; | |
244 | else keypad(row, col) ; | |
245 | } | |
246 | ||
247 | _DhP addParam(String label, double value) { | |
248 | _DhP P = new _DhP(label, value); | |
249 | super.addParameter(P); | |
250 | paramlist.add(P); return P; | |
251 | } | |
252 | ||
253 | Pick addPick(String name, int def, int nmax) { | |
254 | Pick P = new Pick(name, def, nmax); | |
255 | P.StartRow = nMaxRow; | |
256 | P.EndRow = P.StartRow + int((nmax-1) / nNumCols); | |
257 | nMaxRow = P.EndRow + 1; | |
258 | P.CurCol = def % nNumCols; | |
259 | P.CurRow = P.StartRow + def/nNumCols; | |
260 | picklist.add(P); | |
261 | return P; | |
262 | } | |
263 | } | |
d626bc9b | 264 | //---------------------------------------------------------------------------------------------------------------------------------- |