X-Git-Url: https://git.piment-noir.org/?p=SugarCubes.git;a=blobdiff_plain;f=_Internals.pde;h=100607a97d4cecee33689184b736ed26efbee064;hp=7eb5f938a11f976c9baccc3771dd029115b3494c;hb=dde759833df1c0190d9d3a982a90c0a4f8d76a26;hpb=e037f60f518373c3bb952f79a2ae66950e55a52f diff --git a/_Internals.pde b/_Internals.pde index 7eb5f93..100607a 100644 --- a/_Internals.pde +++ b/_Internals.pde @@ -14,9 +14,9 @@ */ import glucose.*; -import glucose.model.*; import heronarts.lx.*; import heronarts.lx.effect.*; +import heronarts.lx.model.*; import heronarts.lx.modulator.*; import heronarts.lx.parameter.*; import heronarts.lx.pattern.*; @@ -30,13 +30,16 @@ import ddf.minim.analysis.*; import processing.opengl.*; import rwmidi.*; import java.lang.reflect.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; final int VIEWPORT_WIDTH = 900; final int VIEWPORT_HEIGHT = 700; // 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_WIDTH = 192; +final float TRAILER_DEPTH = 192; final float TRAILER_HEIGHT = 33; int targetFramerate = 60; @@ -74,23 +77,23 @@ UISpeed uiSpeed; * Engine construction and initialization. */ -LXTransition _transition(GLucose glucose) { - return new DissolveTransition(glucose.lx).setDuration(1000); +LXTransition _transition(LX lx) { + return new DissolveTransition(lx).setDuration(1000); } -LXPattern[] _leftPatterns(GLucose glucose) { - LXPattern[] patterns = patterns(glucose); +LXPattern[] _leftPatterns(LX lx) { + LXPattern[] patterns = patterns(lx); for (LXPattern p : patterns) { - p.setTransition(_transition(glucose)); + p.setTransition(_transition(lx)); } return patterns; } -LXPattern[] _rightPatterns(GLucose glucose) { - LXPattern[] patterns = _leftPatterns(glucose); +LXPattern[] _rightPatterns(LX lx) { + LXPattern[] patterns = _leftPatterns(lx); LXPattern[] rightPatterns = new LXPattern[patterns.length+1]; int i = 0; - rightPatterns[i++] = new BlankPattern(glucose).setTransition(_transition(glucose)); + rightPatterns[i++] = new BlankPattern(lx).setTransition(_transition(lx)); for (LXPattern p : patterns) { rightPatterns[i++] = p; } @@ -134,10 +137,10 @@ void setup() { // Set the patterns LXEngine engine = lx.engine; - engine.setPatterns(patterns = _leftPatterns(glucose)); - engine.addDeck(_rightPatterns(glucose)); + engine.setPatterns(patterns = _leftPatterns(lx)); + engine.addDeck(_rightPatterns(lx)); logTime("Built patterns"); - glucose.setTransitions(transitions(glucose)); + glucose.setTransitions(transitions(lx)); logTime("Built transitions"); glucose.lx.addEffects(_effectsArray(effects = new Effects())); logTime("Built effects"); @@ -163,13 +166,13 @@ void setup() { logTime("Built Grizzly Outputs"); // Mapping tools - mappingTool = new MappingTool(glucose); + mappingTool = new MappingTool(lx); // Build overlay UI UILayer[] layers = new UILayer[] { // Camera layer new UICameraLayer(lx.ui) - .setCenter(TRAILER_WIDTH/2., glucose.model.yMax/2, TRAILER_DEPTH/2.) + .setCenter(model.cx, model.cy, model.cz) .setRadius(290).addComponent(new UICubesLayer()), // Left controls @@ -205,6 +208,94 @@ void setup() { println("Hit the 'o' key to toggle live output"); } +public SCPattern getPattern() { + return (SCPattern) lx.getPattern(); +} + +/** + * Subclass of LXPattern specific to sugar cubes. These patterns + * get access to the glucose state and geometry, and have some + * little helpers for interacting with the model. + */ +public static abstract class SCPattern extends LXPattern { + + protected SCPattern(LX lx) { + super(lx); + } + + /** + * Reset this pattern to its default state. + */ + public final void reset() { + for (LXParameter parameter : getParameters()) { + parameter.reset(); + } + onReset(); + } + + /** + * Subclasses may override to add additional reset functionality. + */ + protected /*abstract*/ void onReset() {} + + /** + * Invoked by the engine when a grid controller button press occurs + * + * @param row Row index on the gird + * @param col Column index on the grid + * @return True if the event was consumed, false otherwise + */ + public boolean gridPressed(int row, int col) { + return false; + } + + /** + * Invoked by the engine when a grid controller button release occurs + * + * @param row Row index on the gird + * @param col Column index on the grid + * @return True if the event was consumed, false otherwise + */ + public boolean gridReleased(int row, int col) { + return false; + } + + /** + * Invoked by engine when this pattern is focused an a midi note is received. + * + * @param note + * @return True if the pattern has consumed this note, false if the top-level + * may handle it + */ + public boolean noteOn(rwmidi.Note note) { + return false; + } + + /** + * Invoked by engine when this pattern is focused an a midi note off is received. + * + * @param note + * @return True if the pattern has consumed this note, false if the top-level + * may handle it + */ + public boolean noteOff(rwmidi.Note note) { + return false; + } + + /** + * Invoked by engine when this pattern is focused an a controller is received + * + * @param note + * @return True if the pattern has consumed this controller, false if the top-level + * may handle it + */ + public boolean controllerChange(rwmidi.Controller controller) { + return false; + } +} + +long simulationNanos = 0; + /** * Core render loop and drawing functionality. */ @@ -231,8 +322,8 @@ void draw() { // TODO(mcslee): fix long drawNanos = System.nanoTime() - drawStart; - - long simulationNanos = 0, uiNanos = 0; + long uiNanos = 0; + if (diagnosticsOn) { drawDiagnostics(drawNanos, simulationNanos, uiNanos, gammaNanos); } @@ -252,14 +343,91 @@ class UICubesLayer extends UICameraComponent { if (simulationOn) { drawSimulation(simulationColors); } - long simulationNanos = System.nanoTime() - simulationStart; + simulationNanos = System.nanoTime() - simulationStart; camera(); javax.media.opengl.GL gl = ((PGraphicsOpenGL)g).beginGL(); gl.glClear(javax.media.opengl.GL.GL_DEPTH_BUFFER_BIT); ((PGraphicsOpenGL)g).endGL(); strokeWeight(1); - } + } + + void drawSimulation(color[] simulationColors) { + translate(0, 30, 0); + + noStroke(); + fill(#141414); + drawBox(0, -TRAILER_HEIGHT, 0, 0, 0, 0, TRAILER_WIDTH, TRAILER_HEIGHT, TRAILER_DEPTH, TRAILER_HEIGHT/2.); + fill(#070707); + stroke(#222222); + beginShape(); + vertex(0, 0, 0); + vertex(TRAILER_WIDTH, 0, 0); + vertex(TRAILER_WIDTH, 0, TRAILER_DEPTH); + vertex(0, 0, TRAILER_DEPTH); + endShape(); + + // Draw the logo on the front of platform + pushMatrix(); + translate(0, 0, -1); + float s = .07; + scale(s, -s, s); + image(logo, TRAILER_WIDTH/2/s-logo.width/2, TRAILER_HEIGHT/2/s-logo.height/2-2/s); + popMatrix(); + + noStroke(); + for (Cube c : model.cubes) { + drawCube(c); + } + + noFill(); + strokeWeight(2); + beginShape(POINTS); + for (LXPoint p : model.points) { + stroke(simulationColors[p.index]); + vertex(p.x, p.y, p.z); + } + endShape(); + } + + void drawCube(Cube c) { + float in = .15; + noStroke(); + fill(#393939); + drawBox(c.x+in, c.y+in, c.z+in, c.rx, c.ry, c.rz, Cube.EDGE_WIDTH-in*2, Cube.EDGE_HEIGHT-in*2, Cube.EDGE_WIDTH-in*2, Cube.CHANNEL_WIDTH-in); + } + + void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) { + pushMatrix(); + translate(x, y, z); + rotate(rx / 180. * PI, -1, 0, 0); + rotate(ry / 180. * PI, 0, -1, 0); + rotate(rz / 180. * PI, 0, 0, -1); + for (int i = 0; i < 4; ++i) { + float wid = (i % 2 == 0) ? xd : zd; + + beginShape(); + vertex(0, 0); + vertex(wid, 0); + vertex(wid, yd); + vertex(wid - sw, yd); + vertex(wid - sw, sw); + vertex(0, sw); + endShape(); + beginShape(); + vertex(0, sw); + vertex(0, yd); + vertex(wid - sw, yd); + vertex(wid - sw, yd - sw); + vertex(sw, yd - sw); + vertex(sw, sw); + endShape(); + + translate(wid, 0, 0); + rotate(HALF_PI, 0, -1, 0); + } + popMatrix(); + } } void drawDiagnostics(long drawNanos, long simulationNanos, long uiNanos, long gammaNanos) { @@ -319,159 +487,6 @@ void drawDiagnostics(long drawNanos, long simulationNanos, long uiNanos, long ga } } -void drawSimulation(color[] simulationColors) { - translate(0, 40, 0); - - noStroke(); - fill(#141414); - drawBox(0, -TRAILER_HEIGHT, 0, 0, 0, 0, TRAILER_WIDTH, TRAILER_HEIGHT, TRAILER_DEPTH, TRAILER_HEIGHT/2.); - fill(#070707); - stroke(#222222); - beginShape(); - vertex(0, 0, 0); - vertex(TRAILER_WIDTH, 0, 0); - vertex(TRAILER_WIDTH, 0, TRAILER_DEPTH); - vertex(0, 0, TRAILER_DEPTH); - endShape(); - - // Draw the logo on the front of platform - pushMatrix(); - translate(0, 0, -1); - float s = .07; - scale(s, -s, s); - image(logo, TRAILER_WIDTH/2/s-logo.width/2, TRAILER_HEIGHT/2/s-logo.height/2-2/s); - popMatrix(); - - noStroke(); - if (glucose.model.bassBox.exists) { - drawBassBox(glucose.model.bassBox, false); - } - for (Speaker speaker : glucose.model.speakers) { - drawSpeaker(speaker); - } - for (Cube c : glucose.model.cubes) { - drawCube(c); - } - - noFill(); - strokeWeight(2); - beginShape(POINTS); - for (LXPoint p : glucose.model.points) { - stroke(simulationColors[p.index]); - vertex(p.x, p.y, p.z); - } - endShape(); -} - -void drawBassBox(BassBox b, boolean hasSub) { - - float in = .15; - - if (hasSub) { - noStroke(); - fill(#191919); - pushMatrix(); - translate(b.x + BassBox.EDGE_WIDTH/2., b.y + BassBox.EDGE_HEIGHT/2, b.z + BassBox.EDGE_DEPTH/2.); - box(BassBox.EDGE_WIDTH-20*in, BassBox.EDGE_HEIGHT-20*in, BassBox.EDGE_DEPTH-20*in); - popMatrix(); - } - - noStroke(); - fill(#393939); - drawBox(b.x+in, b.y+in, b.z+in, 0, 0, 0, BassBox.EDGE_WIDTH-in*2, BassBox.EDGE_HEIGHT-in*2, BassBox.EDGE_DEPTH-in*2, Cube.CHANNEL_WIDTH-in); - - pushMatrix(); - translate(b.x+(Cube.CHANNEL_WIDTH-in)/2., b.y + BassBox.EDGE_HEIGHT-in, b.z + BassBox.EDGE_DEPTH/2.); - float lastOffset = 0; - for (float offset : BoothFloor.STRIP_OFFSETS) { - translate(offset - lastOffset, 0, 0); - box(Cube.CHANNEL_WIDTH-in, 0, BassBox.EDGE_DEPTH - 2*in); - lastOffset = offset; - } - popMatrix(); - - pushMatrix(); - translate(b.x + (Cube.CHANNEL_WIDTH-in)/2., b.y + BassBox.EDGE_HEIGHT/2., b.z + in); - for (int j = 0; j < 2; ++j) { - pushMatrix(); - for (int i = 0; i < BassBox.NUM_FRONT_STRUTS; ++i) { - translate(BassBox.FRONT_STRUT_SPACING, 0, 0); - box(Cube.CHANNEL_WIDTH-in, BassBox.EDGE_HEIGHT - in*2, 0); - } - popMatrix(); - translate(0, 0, BassBox.EDGE_DEPTH - 2*in); - } - popMatrix(); - - pushMatrix(); - translate(b.x + in, b.y + BassBox.EDGE_HEIGHT/2., b.z + BassBox.SIDE_STRUT_SPACING + (Cube.CHANNEL_WIDTH-in)/2.); - box(0, BassBox.EDGE_HEIGHT - in*2, Cube.CHANNEL_WIDTH-in); - translate(BassBox.EDGE_WIDTH-2*in, 0, 0); - box(0, BassBox.EDGE_HEIGHT - in*2, Cube.CHANNEL_WIDTH-in); - popMatrix(); - -} - -void drawCube(Cube c) { - float in = .15; - noStroke(); - fill(#393939); - drawBox(c.x+in, c.y+in, c.z+in, c.rx, c.ry, c.rz, Cube.EDGE_WIDTH-in*2, Cube.EDGE_HEIGHT-in*2, Cube.EDGE_WIDTH-in*2, Cube.CHANNEL_WIDTH-in); -} - -void drawSpeaker(Speaker s) { - float in = .15; - - noStroke(); - fill(#191919); - pushMatrix(); - translate(s.x, s.y, s.z); - rotate(s.ry / 180. * PI, 0, -1, 0); - translate(Speaker.EDGE_WIDTH/2., Speaker.EDGE_HEIGHT/2., Speaker.EDGE_DEPTH/2.); - box(Speaker.EDGE_WIDTH-20*in, Speaker.EDGE_HEIGHT-20*in, Speaker.EDGE_DEPTH-20*in); - translate(0, Speaker.EDGE_HEIGHT/2. + Speaker.EDGE_HEIGHT*.8/2, 0); - - fill(#222222); - box(Speaker.EDGE_WIDTH*.6, Speaker.EDGE_HEIGHT*.8, Speaker.EDGE_DEPTH*.75); - popMatrix(); - - noStroke(); - fill(#393939); - drawBox(s.x+in, s.y+in, s.z+in, 0, s.ry, 0, Speaker.EDGE_WIDTH-in*2, Speaker.EDGE_HEIGHT-in*2, Speaker.EDGE_DEPTH-in*2, Cube.CHANNEL_WIDTH-in); -} - -void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) { - pushMatrix(); - translate(x, y, z); - rotate(rx / 180. * PI, -1, 0, 0); - rotate(ry / 180. * PI, 0, -1, 0); - rotate(rz / 180. * PI, 0, 0, -1); - for (int i = 0; i < 4; ++i) { - float wid = (i % 2 == 0) ? xd : zd; - - beginShape(); - vertex(0, 0); - vertex(wid, 0); - vertex(wid, yd); - vertex(wid - sw, yd); - vertex(wid - sw, sw); - vertex(0, sw); - endShape(); - beginShape(); - vertex(0, sw); - vertex(0, yd); - vertex(wid - sw, yd); - vertex(wid - sw, yd - sw); - vertex(sw, yd - sw); - vertex(sw, sw); - endShape(); - - translate(wid, 0, 0); - rotate(HALF_PI, 0, -1, 0); - } - popMatrix(); -} - void drawFPS() { // Always draw FPS meter fill(#555555);