final int VIEWPORT_WIDTH = 900;
final int VIEWPORT_HEIGHT = 700;
+// The trailer is measured from the outside of the black metal (but not including the higher welded part on the front)
final float TRAILER_WIDTH = 240;
final float TRAILER_DEPTH = 97;
final float TRAILER_HEIGHT = 33;
-final float BASS_WIDTH = 124;
-final float BASS_HEIGHT = 31.5;
-final float BASS_DEPTH = 66;
-final float BASS_X = (TRAILER_WIDTH - BASS_WIDTH) / 2.;
-final float BASS_Z = (TRAILER_DEPTH - BASS_DEPTH) / 2.;
-
int targetFramerate = 60;
int startMillis, lastMillis;
OverlayUI ui;
ControlUI controlUI;
MappingUI mappingUI;
-PandaDriver pandaFront;
-PandaDriver pandaRear;
+PandaDriver[] pandaBoards;
boolean mappingMode = false;
-
-boolean pandaBoardsEnabled = false;
-
boolean debugMode = false;
DebugUI debugUI;
logTime("Created viewport");
// Create the GLucose engine to run the cubes
- glucose = new GLucose(this, new SCMapping());
+ glucose = new GLucose(this, buildModel());
lx = glucose.lx;
lx.enableKeyboardTempo();
logTime("Built GLucose engine");
logTime("Built transitions");
// Build output driver
- int[][] frontChannels = glucose.mapping.buildFrontChannelList();
- int[][] rearChannels = glucose.mapping.buildRearChannelList();
- mappingTool = new MappingTool(glucose, frontChannels, rearChannels);
- pandaFront = new PandaDriver(new NetAddress("192.168.1.28", 9001), glucose.model, frontChannels);
- pandaRear = new PandaDriver(new NetAddress("192.168.1.29", 9001), glucose.model, rearChannels);
- logTime("Build PandaDriver");
+ PandaMapping[] pandaMappings = buildPandaList();
+ pandaBoards = new PandaDriver[pandaMappings.length];
+ int pbi = 0;
+ for (PandaMapping pm : pandaMappings) {
+ pandaBoards[pbi++] = new PandaDriver(pm.ip, glucose.model, pm);
+ }
+ mappingTool = new MappingTool(glucose, pandaMappings);
+ logTime("Built PandaDriver");
// Build overlay UI
ui = controlUI = new ControlUI();
mappingUI = new MappingUI(mappingTool);
- debugUI = new DebugUI(frontChannels, rearChannels);
+ debugUI = new DebugUI(pandaMappings);
logTime("Built overlay UI");
// MIDI devices
mouseWheel(mwe.getWheelRotation());
}});
-
println("Total setup: " + (millis() - startMillis) + "ms");
println("Hit the 'p' key to toggle Panda Board output");
}
+boolean[] noteState = new boolean[16];
+
void controllerChangeReceived(rwmidi.Controller cc) {
if (debugMode) {
println("CC: " + cc.toString());
}
+ //println(cc.getInput().getName());
+ int c = cc.getCC();
+ if(c==1){
+ for(int i=0; i<16; i++){
+ if(noteState[i] && i<8) { LXParameter p = glucose.patternKnobs.get(i); p.setValue(cc.getValue()/127.0); }
+ else if(noteState[i] && i<16) { try { LXParameter p = gparams.get(i-8); p.setValue(cc.getValue()/127.0); } catch(Exception e) {} }
+ }
+ }
+ if(c==2){
+ for(int i=0; i<16; i++){
+ //sif(noteState[i] && i<8) { println( gplay.Sliders ); }
+ //else if(noteState[i] && i<16) { try { LXParameter p = gparams.get(i-8); p.setValue(cc.getValue()/127.0); } catch(Exception e) {} }
+ }
+ }
+
+
+ //if(c>=16 || c<16+8){
+ // LXParameter p = gparams.get(c-16);
+ // p.setValue(c/127.0);
+ //}
}
+
void noteOnReceived(Note note) {
if (debugMode) {
println("Note On: " + note.toString());
}
+ int pitch = note.getPitch();
+ if(pitch>=36 && pitch <36+16){
+ noteState[pitch-36]=true;
+ }
}
void noteOffReceived(Note note) {
if (debugMode) {
println("Note Off: " + note.toString());
}
+ int pitch = note.getPitch();
+ if(pitch>=36 && pitch <36+16){
+ noteState[pitch-36]=false;
+ }
}
+
void logTime(String evt) {
int now = millis();
println(evt + ": " + (now - lastMillis) + "ms");
endShape();
noStroke();
- fill(#292929);
- drawBox(BASS_X, 0, BASS_Z, 0, 0, 0, BASS_WIDTH, BASS_HEIGHT, BASS_DEPTH, Cube.CHANNEL_WIDTH);
+ drawBassBox(glucose.model.bassBox);
+ for (Speaker s : glucose.model.speakers) {
+ drawSpeaker(s);
+ }
for (Cube c : glucose.model.cubes) {
drawCube(c);
}
for (Point p : glucose.model.points) {
stroke(colors[p.index]);
vertex(p.fx, p.fy, p.fz);
- // println(p.fx + ":" + p.fy + ":" + p.fz);
}
endShape();
debugUI.draw();
}
+ // Gamma correction here. Apply a cubic to the brightness
+ // for better representation of dynamic range
+ for (int i = 0; i < colors.length; ++i) {
+ float b = brightness(colors[i]) / 100.f;
+ colors[i] = color(
+ hue(colors[i]),
+ saturation(colors[i]),
+ (b*b*b) * 100.
+ );
+ }
+
// TODO(mcslee): move into GLucose engine
- if (pandaBoardsEnabled) {
- pandaFront.send(colors);
- // pandaRear.send(colors);
+ for (PandaDriver p : pandaBoards) {
+ p.send(colors);
}
}
+void drawBassBox(BassBox b) {
+ /*
+ float in = .15;
+
+ noStroke();
+ fill(#191919);
+ pushMatrix();
+ translate(b.x + BassBox.EDGE_WIDTH/2., b.y + BassBox.EDGE_HEIGHT/2, b.z + BassBox.EDGE_DEPTH/2.);
+ box(BassBox.EDGE_WIDTH-20*in, BassBox.EDGE_HEIGHT-20*in, BassBox.EDGE_DEPTH-20*in);
+ popMatrix();
+
+ noStroke();
+ fill(#393939);
+ drawBox(b.x+in, b.y+in, b.z+in, 0, 0, 0, BassBox.EDGE_WIDTH-in*2, BassBox.EDGE_HEIGHT-in*2, BassBox.EDGE_DEPTH-in*2, Cube.CHANNEL_WIDTH-in);
+
+ pushMatrix();
+ translate(b.x+(Cube.CHANNEL_WIDTH-in)/2., b.y + BassBox.EDGE_HEIGHT-in, b.z + BassBox.EDGE_DEPTH/2.);
+ float lastOffset = 0;
+ for (float offset : BoothFloor.STRIP_OFFSETS) {
+ translate(offset - lastOffset, 0, 0);
+ box(Cube.CHANNEL_WIDTH-in, 0, BassBox.EDGE_DEPTH - 2*in);
+ lastOffset = offset;
+ }
+ popMatrix();
+
+ pushMatrix();
+ translate(b.x + (Cube.CHANNEL_WIDTH-in)/2., b.y + BassBox.EDGE_HEIGHT/2., b.z + in);
+ for (int j = 0; j < 2; ++j) {
+ pushMatrix();
+ for (int i = 0; i < BassBox.NUM_FRONT_STRUTS; ++i) {
+ translate(BassBox.FRONT_STRUT_SPACING, 0, 0);
+ box(Cube.CHANNEL_WIDTH-in, BassBox.EDGE_HEIGHT - in*2, 0);
+ }
+ popMatrix();
+ translate(0, 0, BassBox.EDGE_DEPTH - 2*in);
+ }
+ popMatrix();
+
+ pushMatrix();
+ translate(b.x + in, b.y + BassBox.EDGE_HEIGHT/2., b.z + BassBox.SIDE_STRUT_SPACING + (Cube.CHANNEL_WIDTH-in)/2.);
+ box(0, BassBox.EDGE_HEIGHT - in*2, Cube.CHANNEL_WIDTH-in);
+ translate(BassBox.EDGE_WIDTH-2*in, 0, 0);
+ box(0, BassBox.EDGE_HEIGHT - in*2, Cube.CHANNEL_WIDTH-in);
+ popMatrix();*/
+
+}
+
void drawCube(Cube c) {
float in = .15;
+ noStroke();
+ fill(#393939);
drawBox(c.x+in, c.y+in, c.z+in, c.rx, c.ry, c.rz, Cube.EDGE_WIDTH-in*2, Cube.EDGE_HEIGHT-in*2, Cube.EDGE_WIDTH-in*2, Cube.CHANNEL_WIDTH-in);
}
+void drawSpeaker(Speaker s) {
+ float in = .15;
+
+ noStroke();
+ fill(#191919);
+ pushMatrix();
+ translate(s.x, s.y, s.z);
+ rotate(s.ry / 180. * PI, 0, -1, 0);
+ translate(Speaker.EDGE_WIDTH/2., Speaker.EDGE_HEIGHT/2., Speaker.EDGE_DEPTH/2.);
+ box(Speaker.EDGE_WIDTH-20*in, Speaker.EDGE_HEIGHT-20*in, Speaker.EDGE_DEPTH-20*in);
+ translate(0, Speaker.EDGE_HEIGHT/2. + Speaker.EDGE_HEIGHT*.8/2, 0);
+
+ fill(#222222);
+ box(Speaker.EDGE_WIDTH*.6, Speaker.EDGE_HEIGHT*.8, Speaker.EDGE_DEPTH*.75);
+ popMatrix();
+
+ noStroke();
+ fill(#393939);
+ drawBox(s.x+in, s.y+in, s.z+in, 0, s.ry, 0, Speaker.EDGE_WIDTH-in*2, Speaker.EDGE_HEIGHT-in*2, Speaker.EDGE_DEPTH-in*2, Cube.CHANNEL_WIDTH-in);
+}
+
+
void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) {
pushMatrix();
translate(x, y, z);
ui.drawHelpTip();
}
ui.drawFPS();
+ ui.drawDanText();
}
boolean uiOn = true;
int restoreToIndex = -1;
+boolean doDual = false;
void keyPressed() {
if (mappingMode) {
mappingTool.keyPressed();
}
switch (key) {
+ case 'w':
+ doDual = !doDual;
+ break;
case '-':
case '_':
frameRate(--targetFramerate);
}
break;
case 'p':
- pandaBoardsEnabled = !pandaBoardsEnabled;
- println("PandaBoard Output: " + (pandaBoardsEnabled ? "ON" : "OFF"));
+ for (PandaDriver p : pandaBoards) {
+ p.toggle();
+ }
break;
case 'u':
uiOn = !uiOn;
}
int mx, my;
-
void mousePressed() {
- if (mouseX > ui.leftPos) {
- ui.mousePressed();
- } else {
+ ui.mousePressed();
+ if (mouseX < ui.leftPos) {
if (debugMode) {
debugUI.mousePressed();
}
}
void mouseReleased() {
- if (mouseX > ui.leftPos) {
- ui.mouseReleased();
- }
+ ui.mouseReleased();
}
void mouseWheel(int delta) {
eyeZ = midZ + eyeR*cos(eyeA);
}
}
-