Few tiny cleanups
[SugarCubes.git] / _Internals.pde
index 1b313ccbad5620ec1f16e71e283874ba3b8125d5..b593f3ef07b9c4aa7db088430348d3da9c653ae7 100644 (file)
@@ -13,7 +13,6 @@
  * for general animation work.
  */
 
-import glucose.*;
 import heronarts.lx.*;
 import heronarts.lx.effect.*;
 import heronarts.lx.model.*;
@@ -34,23 +33,28 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-final int VIEWPORT_WIDTH = 900;
-final int VIEWPORT_HEIGHT = 700;
+static final int VIEWPORT_WIDTH = 900;
+static final int VIEWPORT_HEIGHT = 700;
+
+static final int LEFT_DECK = 0;
+static final int RIGHT_DECK = 1;
 
 // The trailer is measured from the outside of the black metal (but not including the higher welded part on the front)
-final float TRAILER_WIDTH = 192;
-final float TRAILER_DEPTH = 192;
-final float TRAILER_HEIGHT = 33;
+static final float TRAILER_WIDTH = 192;
+static final float TRAILER_DEPTH = 192;
+static final float TRAILER_HEIGHT = 33;
 
 int targetFramerate = 60;
 int startMillis, lastMillis;
 
 // Core engine variables
-GLucose glucose;
 LX lx;
 Model model;
 LXPattern[] patterns;
+LXTransition[] transitions;
 Effects effects;
+LXEffect[] effectsArr;
+DiscreteParameter selectedEffect;
 MappingTool mappingTool;
 GrizzlyOutput[] grizzlies;
 PresetManager presetManager;
@@ -77,23 +81,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;
   }
@@ -111,7 +115,11 @@ LXEffect[] _effectsArray(Effects effects) {
     } catch (IllegalAccessException iax) {}
   }
   return effectList.toArray(new LXEffect[]{});
-} 
+}
+
+LXEffect getSelectedEffect() {
+  return effectsArr[selectedEffect.getValuei()];
+}
 
 void logTime(String evt) {
   int now = millis();
@@ -129,20 +137,29 @@ void setup() {
   // hint(ENABLE_OPENGL_4X_SMOOTH); // no discernable improvement?
   logTime("Created viewport");
 
-  // Create the GLucose engine to run the cubes
-  glucose = new GLucose(this, model = buildModel());
-  lx = glucose.lx;
+  // Create the model
+  model = buildModel();
+  logTime("Built Model");
+  
+  // LX engine
+  lx = new LX(this, model);
   lx.enableKeyboardTempo();
-  logTime("Built GLucose engine");
+  logTime("Built LX engine");
     
   // Set the patterns
   LXEngine engine = lx.engine;
-  engine.setPatterns(patterns = _leftPatterns(glucose));
-  engine.addDeck(_rightPatterns(glucose));
+  engine.setPatterns(patterns = _leftPatterns(lx));
+  engine.addDeck(_rightPatterns(lx));
   logTime("Built patterns");
-  glucose.setTransitions(transitions(glucose));
+
+  // Transitions
+  transitions = transitions(lx);
+  lx.engine.getDeck(RIGHT_DECK).setFaderTransition(transitions[0]);
   logTime("Built transitions");
-  glucose.lx.addEffects(_effectsArray(effects = new Effects()));
+  
+  // Effects
+  lx.addEffects(effectsArr = _effectsArray(effects = new Effects()));
+  selectedEffect = new DiscreteParameter("EFFECT", effectsArr.length);
   logTime("Built effects");
 
   // Preset manager
@@ -164,9 +181,10 @@ void setup() {
     x.printStackTrace();
   }
   logTime("Built Grizzly Outputs");
-  
-  // Mapping tools
-  mappingTool = new MappingTool(glucose);
+
+  // Mapping tool
+  mappingTool = new MappingTool(lx);
+  logTime("Built Mapping Tool");
   
   // Build overlay UI
   UILayer[] layers = new UILayer[] {
@@ -176,14 +194,14 @@ void setup() {
       .setRadius(290).addComponent(new UICubesLayer()),
     
     // Left controls
-    uiPatternA = new UIPatternDeck(lx.ui, lx.engine.getDeck(GLucose.LEFT_DECK), "PATTERN A", 4, 4, 140, 324),
+    uiPatternA = new UIPatternDeck(lx.ui, lx.engine.getDeck(LEFT_DECK), "PATTERN A", 4, 4, 140, 324),
     new UIBlendMode(4, 332, 140, 86),
     new UIEffects(4, 422, 140, 144),
     new UITempo(4, 570, 140, 50),
     uiSpeed = new UISpeed(4, 624, 140, 50),
         
     // Right controls
-    new UIPatternDeck(lx.ui, lx.engine.getDeck(GLucose.RIGHT_DECK), "PATTERN B", width-144, 4, 140, 324),
+    new UIPatternDeck(lx.ui, lx.engine.getDeck(RIGHT_DECK), "PATTERN B", width-144, 4, 140, 324),
     uiMidi = new UIMidi(midiEngine, width-144, 332, 140, 158),
     new UIOutput(grizzlies, width-144, 494, 140, 106),
     
@@ -208,6 +226,92 @@ 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 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;
 
 /**
@@ -220,7 +324,7 @@ void draw() {
   background(40);
   
   // Send colors
-  color[] sendColors = glucose.getColors();  
+  color[] sendColors = lx.getColors();  
   long gammaStart = System.nanoTime();
   // Gamma correction here. Apply a cubic to the brightness
   // for better representation of dynamic range
@@ -243,107 +347,6 @@ void draw() {
   }  
 }
 
-class UICubesLayer extends UICameraComponent {
-  void onDraw(UI ui) {
-    color[] simulationColors = glucose.getColors();
-    String displayMode = uiCrossfader.getDisplayMode();
-    if (displayMode == "A") {
-      simulationColors = lx.engine.getDeck(GLucose.LEFT_DECK).getColors();
-    } else if (displayMode == "B") {
-      simulationColors = lx.engine.getDeck(GLucose.RIGHT_DECK).getColors();
-    }
-
-    long simulationStart = System.nanoTime();
-    if (simulationOn) {
-      drawSimulation(simulationColors);
-    }
-    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) {
   float ws = 4 / 1000000.;
   int thirtyfps = 1000000000 / 30;