Model is now in processing, not glucose
authorMark Slee <mcslee@gmail.com>
Tue, 25 Feb 2014 20:46:56 +0000 (12:46 -0800)
committerMark Slee <mcslee@gmail.com>
Tue, 25 Feb 2014 20:46:56 +0000 (12:46 -0800)
DanUtil.pde
SugarCubes.pde
TestPatterns.pde
_Grizzly.pde
_Internals.pde
_Mappings.pde
_Model.pde [new file with mode: 0644]
_UIImplementation.pde
code/GLucose.jar
code/oscP5.jar [deleted file]

index 382cf975c8a36740b4f15079783f657a52e720f1..78dc6d717c4c5b2d9535ea0cc3e8e3c39768c8fe 100644 (file)
@@ -287,7 +287,7 @@ class dLattice {
        dPixel getClosest(PVector p) {
                dVertex v = null; int pos=0; float d = 500;
 
-               for (Strip s : glucose.model.strips) {
+               for (Strip s : model.strips) {
                        float nd = pd2(s.points.get(0),p.x,p.y,p.z); if (nd < d) { v=v0(s); d=nd; pos=0; }
                        if (nd > 30) continue;
                        for (int k=0; k<=15; k++) {
@@ -300,13 +300,13 @@ class dLattice {
        dLattice() {
                lattice=this;
 
-               for (Strip s  : glucose.model.strips) {
+               for (Strip s  : model.strips) {
                        dVertex vrtx0 = new dVertex(s,s.points.get(0 )); s.obj1=vrtx0;
                        dVertex vrtx1 = new dVertex(s,s.points.get(15)); s.obj2=vrtx1;
                        vrtx0.setOpp(vrtx1); vrtx1.setOpp(vrtx0);
                }
 
-               for (Strip s1 : glucose.model.strips) { for (Strip s2 : glucose.model.strips) {
+               for (Strip s1 : model.strips) { for (Strip s2 : model.strips) {
                        if (s1.points.get(0).index < s2.points.get(0).index) continue;
                        int c=0;
                        if (sameSame(s1,s2))    {       v0(s1).same = v0(s2); v1(s1).same = v1(s2);
index ff85065f00b8519e045ab2025606a0d76aa09d6d..5fe3c7bb5f412a83a63e07129e44a0ec35dcca09 100644 (file)
@@ -15,8 +15,8 @@
  *
  * Welcome to the Sugar Cubes! This Processing sketch is a fun place to build
  * animations, effects, and interactions for the platform. Most of the icky
- * code guts are embedded in the GLucose library extension. If you're an
- * artist, you shouldn't need to worry about any of that.
+ * code guts are embedded in the HeronLX library, or files prefixed with
+ * an underscore. If you're an artist, you shouldn't need to worry about that.
  *
  * Below, you will find definitions of the Patterns, Effects, and Interactions.
  * If you're an artist, create a new tab in the Processing environment with
@@ -31,7 +31,7 @@ LXPattern[] patterns(GLucose glucose) {
      
     // Slee
     // new Cathedrals(glucose),
-     new Swarm(glucose),
+    new Swarm(glucose),
     new MidiMusic(glucose),
     new Pulley(glucose),
     
@@ -51,8 +51,8 @@ LXPattern[] patterns(GLucose glucose) {
     new CubeEQ(glucose).setEligible(false),
     new PianoKeyPattern(glucose).setEligible(false),
 
-       // AntonK
-       new AKPong(glucose),
+    // AntonK
+    new AKPong(glucose),
 
     // DanH
     new Noise(glucose),
@@ -65,7 +65,7 @@ LXPattern[] patterns(GLucose glucose) {
     
     // Alex G
      
-     // Tim
+    // Tim
     new TimMetronome(glucose),
     new TimPlanes(glucose),
     new TimPinwheels(glucose),
@@ -99,8 +99,6 @@ LXPattern[] patterns(GLucose glucose) {
     new Swim(glucose),
     new Balance(glucose),
     
-
-    
     // Ben
     // new Sandbox(glucose),
     new TowerParams(glucose),
@@ -108,7 +106,7 @@ LXPattern[] patterns(GLucose glucose) {
     new GranimTestPattern2(glucose),
     
     // Shaheen
-    //new HelixPattern(glucose).setEligible(false),
+    // new HelixPattern(glucose).setEligible(false),
     
     // Sam
     new JazzRainbow(glucose),
@@ -123,9 +121,6 @@ LXPattern[] patterns(GLucose glucose) {
     new TestTowerPattern(glucose),
     new TestProjectionPattern(glucose),
     new TestStripPattern(glucose),
-    new TestBassMapping(glucose),
-    new TestFloorMapping(glucose),
-    new TestSpeakerMapping(glucose),    
     // new TestHuePattern(glucose),
     // new TestXPattern(glucose),
     // new TestYPattern(glucose),
@@ -144,8 +139,8 @@ LXTransition[] transitions(GLucose glucose) {
     new SwipeTransition(glucose),
     new FadeTransition(lx),
 //  new SubtractTransition(glucose),   // similar to multiply - dh
-//  new BurnTransition(glucose),               // similar to multiply - dh
-//  new ScreenTransition(glucose),             // same as add -dh
+//  new BurnTransition(glucose),       // similar to multiply - dh
+//  new ScreenTransition(glucose),     // same as add -dh
 //  new SoftLightTransition(glucose),  // same as overlay -dh
   };
 }
index d76aeda5bab22d702deb81a54d92659ed35adca9..106cb16143fda10e848665e8fcd638dd52fa6e04 100644 (file)
@@ -15,75 +15,6 @@ abstract class TestPattern extends SCPattern {
   }
 }
 
-class TestSpeakerMapping extends TestPattern {
-  TestSpeakerMapping(GLucose glucose) {
-    super(glucose);
-  }
-  
-  public void run(double deltaMs) {
-    int h = 0;
-    for (Speaker speaker : model.speakers) {
-      for (Strip strip : speaker.strips) {
-        float b = 100;
-        for (LXPoint p : strip.points) {
-          colors[p.index] = lx.hsb(h % 360, 100, b);
-          b = max(0, b - 10);
-        }
-        h += 70;
-      }
-    }
-  }
-
-}
-
-class TestBassMapping extends TestPattern {
-  TestBassMapping(GLucose glucose) {
-    super(glucose);
-  }
-  
-  public void run(double deltaMs) {
-    int[] strips = { 2, 1, 0, 3, 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6 };
-    int h = 0;
-    for (int si : strips) {
-      float b = 100;
-      for (LXPoint p : model.bassBox.strips.get(si).points) {
-        colors[p.index] = lx.hsb(h % 360, 100, b);
-        b = max(0, b - 10);
-      }
-      h += 70;
-    }
-  }
-}
-
-class TestFloorMapping extends TestPattern {
-  TestFloorMapping(GLucose glucose) {
-    super(glucose);
-  }
-
-  public void run(double deltaMs) {
-    int[] strutIndices = {6, 5, 4, 3, 2, 1, 0, 7};
-    int h = 0;
-    for (int si : strutIndices) {
-      float b = 100;
-      for (LXPoint p : model.bassBox.struts.get(si).points) {
-        colors[p.index] = lx.hsb(h % 360, 100, b);
-        b = max(0, b - 10);
-      }
-      h += 50;
-    }
-    int[] floorIndices = {0, 1, 2, 3};
-    h = 0;
-    for (int fi : floorIndices) {
-      float b = 100;
-      for (LXPoint p : model.boothFloor.strips.get(fi).points) {
-        colors[p.index] = lx.hsb(h, 100, b);
-        b = max(0, b - 3);
-      }
-      h += 90;
-    }
-  }
-}
-
 class TestStripPattern extends TestPattern {
   
   SinLFO d = new SinLFO(4, 40, 4000);
index f376fab8cd7d5c8a9048129d297d042c6267b981..25d390f07fba7d653039521539f7dabd395a2ca4 100644 (file)
@@ -8,9 +8,8 @@
  *
  *        EXPERTS ONLY!!              EXPERTS ONLY!!
  *
- * If you are an artist, you may ignore this file! It just sets
- * up the framework to run the patterns. Should not need modification
- * for general animation work.
+ * If you are an artist, you may ignore this file! It contains
+ * the code to drive grizzly board outputs.
  */
 
 GrizzlyOutput[] buildGrizzlies() throws SocketException, UnknownHostException {
@@ -22,13 +21,17 @@ GrizzlyOutput[] buildGrizzlies() throws SocketException, UnknownHostException {
   };
 }
 
+/**
+ * Grizzly Output, sends packets to one grizzly board with a fixed IP and a number
+ * of channels.
+ */
 class GrizzlyOutput extends LXDatagramOutput {
 
   public final String ipAddress;
   
   private int frameNumber = 0;
   
-  GrizzlyOutput(LX lx, String ipAddress, int ... cubeIndices) throws UnknownHostException, SocketException {
+  public GrizzlyOutput(LX lx, String ipAddress, int ... cubeIndices) throws UnknownHostException, SocketException {
     super(lx);
     this.ipAddress = ipAddress;
     int channelNum = 0;
@@ -51,6 +54,9 @@ class GrizzlyOutput extends LXDatagramOutput {
   }
 }
 
+/**
+ * Datagram to a Grizzlyboard. A simple fixed OSC packet.
+ */
 static class GrizzlyDatagram extends LXDatagram {
   
   private static byte[] oscString(String s) {
index 6e985f123e9129f3c95794c13326879dd114f46d..1b313ccbad5620ec1f16e71e283874ba3b8125d5 100644 (file)
@@ -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,6 +30,9 @@ 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;
@@ -287,14 +290,14 @@ class UICubesLayer extends UICameraComponent {
     popMatrix();
     
     noStroke();
-    for (Cube c : glucose.model.cubes) {
+    for (Cube c : model.cubes) {
       drawCube(c);
     }
   
     noFill();
     strokeWeight(2);
     beginShape(POINTS);
-    for (LXPoint p : glucose.model.points) {
+    for (LXPoint p : model.points) {
       stroke(simulationColors[p.index]);
       vertex(p.x, p.y, p.z);
     }
index 53ff88924b7a0848d8ea57176121da344987d8a0..b7b6a86d483279fa9fbcc1973f9b089b297ee39d 100644 (file)
@@ -43,7 +43,7 @@ public Model buildModel() {
   // "raw object index" is serialized by running through towermapping and then individual cube mapping below.
   //  We can do better than this.  The raw object index should be obvious from the code-- looking through the
   //  rendered simulation and counting through cubes in mapping mode is grossly inefficient. 
-  
+
   List<Tower> towers = new ArrayList<Tower>();
   Cube[] cubes = new Cube[200];
   int cubeIndex = 1;
@@ -72,6 +72,5 @@ public Model buildModel() {
     towers.add(new Tower(tower));
   }
 
-  return new Model(towers, cubes, BassBox.noBassBox(), new ArrayList<Speaker>());
+  return new Model(towers, cubes);
 }
-
diff --git a/_Model.pde b/_Model.pde
new file mode 100644 (file)
index 0000000..3376246
--- /dev/null
@@ -0,0 +1,365 @@
+/**
+ *     DOUBLE BLACK DIAMOND        DOUBLE BLACK DIAMOND
+ *
+ *         //\\   //\\                 //\\   //\\  
+ *        ///\\\ ///\\\               ///\\\ ///\\\
+ *        \\\/// \\\///               \\\/// \\\///
+ *         \\//   \\//                 \\//   \\//
+ *
+ *        EXPERTS ONLY!!              EXPERTS ONLY!!
+ *
+ * Contains the model definitions for the cube structures.
+ */
+
+/**
+ * Top-level model of the entire sculpture. This contains a list of
+ * every cube on the sculpture, which forms a hierarchy of faces, strips
+ * and points.
+ */
+public static class Model extends LXModel {
+
+  public final List<Tower> towers;
+  public final List<Cube> cubes;
+  public final List<Face> faces;
+  public final List<Strip> strips;
+
+  private final Cube[] _cubes;
+
+  public Model(List<Tower> towerList, Cube[] cubeArr) {
+    super(new Fixture(cubeArr));
+    Fixture fixture = (Fixture) this.fixtures.get(0);
+
+    _cubes = cubeArr;
+
+    // Make unmodifiable accessors to the model data
+    List<Cube> cubeList = new ArrayList<Cube>();
+    List<Face> faceList = new ArrayList<Face>();
+    List<Strip> stripList = new ArrayList<Strip>();
+    for (Cube cube : _cubes) {
+      if (cube != null) {
+        cubeList.add(cube);
+        for (Face face : cube.faces) {
+          faceList.add(face);
+          for (Strip strip : face.strips) {
+            stripList.add(strip);
+          }
+        }
+      }
+    }
+
+    this.towers = Collections.unmodifiableList(towerList);
+    this.cubes = Collections.unmodifiableList(cubeList);
+    this.faces = Collections.unmodifiableList(faceList);
+    this.strips = Collections.unmodifiableList(stripList);
+  }
+
+  private static class Fixture extends LXAbstractFixture {
+
+    private Fixture(Cube[] cubeArr) {
+      for (Cube cube : cubeArr) {
+        if (cube != null) {
+          for (LXPoint point : cube.points) {
+            this.points.add(point);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * TODO(mcslee): figure out better solution
+   * 
+   * @param index
+   * @return
+   */
+  public Cube getCubeByRawIndex(int index) {
+    return _cubes[index];
+  }
+}
+
+/**
+ * Model of a set of cubes stacked in a tower
+ */
+public static class Tower extends LXModel {
+  /**
+   * Immutable list of cubes
+   */
+  public final List<Cube> cubes;
+
+  /**
+   * Immutable list of faces
+   */
+  public final List<Face> faces;
+
+  /**
+        * Immutable list of strips
+        */
+  public final List<Strip> strips;
+
+  /**
+   * Constructs a tower model from these cubes
+   * 
+   * @param cubes Array of cubes
+   */
+  public Tower(List<Cube> cubes) {
+    super(cubes.toArray(new Cube[] {}));
+
+    List<Cube> cubeList = new ArrayList<Cube>();
+    List<Face> faceList = new ArrayList<Face>();
+    List<Strip> stripList = new ArrayList<Strip>();
+
+    for (Cube cube : cubes) {
+      cubeList.add(cube);
+      for (Face face : cube.faces) {
+        faceList.add(face);
+        for (Strip strip : face.strips) {
+          stripList.add(strip);
+        }
+      }
+    }
+    this.cubes = Collections.unmodifiableList(cubeList);
+    this.faces = Collections.unmodifiableList(faceList);
+    this.strips = Collections.unmodifiableList(stripList);
+  }
+}
+
+/**
+ * Model of a single cube, which has an orientation and position on the
+ * car. The position is specified in x,y,z coordinates with rotation. The
+ * x axis is left->right, y is bottom->top, and z is front->back.
+ * 
+ * A cube's x,y,z position is specified as the left, bottom, front corner.
+ * 
+ * Dimensions are all specified in real-world inches.
+ */
+public static class Cube extends LXModel {
+
+  public final static int FACES_PER_CUBE = 4;  
+  public static final int POINTS_PER_STRIP = 16;
+
+  public final static int STRIPS_PER_CUBE = FACES_PER_CUBE*Face.STRIPS_PER_FACE;
+  public final static int POINTS_PER_CUBE = STRIPS_PER_CUBE*POINTS_PER_STRIP;
+  public final static int POINTS_PER_FACE = Face.STRIPS_PER_FACE*POINTS_PER_STRIP;
+
+  public final static float EDGE_HEIGHT = 21.75f;
+  public final static float EDGE_WIDTH = 24.625f;
+  public final static float CHANNEL_WIDTH = 1.5f;
+
+  public final static Face.Metrics FACE_METRICS = new Face.Metrics(
+    new Strip.Metrics(EDGE_WIDTH, POINTS_PER_STRIP), 
+    new Strip.Metrics(EDGE_HEIGHT, POINTS_PER_STRIP)
+  );
+
+  /**
+   * Immutable list of all cube faces
+   */
+  public final List<Face> faces;
+
+  /**
+   * Immutable list of all strips
+   */
+  public final List<Strip> strips;
+
+  /**
+   * Front left corner x coordinate 
+   */
+  public final float x;
+
+  /**
+   * Front left corner y coordinate 
+   */
+  public final float y;
+
+  /**
+   * Front left corner z coordinate 
+   */
+  public final float z;
+
+  /**
+   * Rotation about the x-axis 
+   */
+  public final float rx;
+
+  /**
+   * Rotation about the y-axis 
+   */
+  public final float ry;
+
+  /**
+   * Rotation about the z-axis 
+   */
+  public final float rz;
+
+  public Cube(double x, double y, double z, double rx, double ry, double rz) {
+    this((float) x, (float) y, (float) z, (float) rx, (float) ry, (float) rz);
+  }
+
+  public Cube(float x, float y, float z, float rx, float ry, float rz) {
+    super(new Fixture(x, y, z, rx, ry, rz));
+    Fixture fixture = (Fixture) this.fixtures.get(0);
+
+    while (rx < 0) rx += 360;
+    while (ry < 0) ry += 360;
+    while (rz < 0) rz += 360;
+    rx = rx % 360;
+    ry = ry % 360;
+    rz = rz % 360;
+
+    this.x = x; 
+    this.y = y;
+    this.z = z;
+    this.rx = rx;
+    this.ry = ry;
+    this.rz = rz;
+
+    this.faces = Collections.unmodifiableList(fixture.faces);
+    this.strips = Collections.unmodifiableList(fixture.strips);
+  }
+
+  private static class Fixture extends LXAbstractFixture {
+
+    private final List<Face> faces = new ArrayList<Face>();
+    private final List<Strip> strips = new ArrayList<Strip>();
+
+    private Fixture(float x, float y, float z, float rx, float ry, float rz) {
+      LXTransform t = new LXTransform();
+      t.translate(x, y, z);
+      t.rotateX(rx * PI / 180.);
+      t.rotateY(ry * PI / 180.);
+      t.rotateZ(rz * PI / 180.);               
+
+      for (int i = 0; i < FACES_PER_CUBE; i++) {
+        Face face = new Face(FACE_METRICS, (ry + 90*i) % 360, t);
+        this.faces.add(face);
+        for (Strip s : face.strips) {
+          this.strips.add(s);
+        }
+        for (LXPoint p : face.points) {
+          this.points.add(p);
+        }
+        t.translate(EDGE_WIDTH, 0, 0);
+        t.rotateY(HALF_PI);
+      }
+    }
+  }
+}
+
+/**
+ * A face is a component of a cube. It is comprised of four strips forming
+ * the lights on this side of a cube. A whole cube is formed by four faces.
+ */
+public static class Face extends LXModel {
+
+  public final static int STRIPS_PER_FACE = 4;
+
+  public static class Metrics {
+    final Strip.Metrics horizontal;
+    final Strip.Metrics vertical;
+
+    public Metrics(Strip.Metrics horizontal, Strip.Metrics vertical) {
+      this.horizontal = horizontal;
+      this.vertical = vertical;
+    }
+  }
+
+  /**
+   * Immutable list of strips
+   */
+  public final List<Strip> strips;
+
+  /**
+   * Rotation of the face about the y-axis
+   */
+  public final float ry;
+
+  Face(Metrics metrics, float ry, LXTransform transform) {
+    super(new Fixture(metrics, ry, transform));
+    Fixture fixture = (Fixture) this.fixtures.get(0);
+    this.ry = ry;
+    this.strips = Collections.unmodifiableList(fixture.strips);
+  }
+
+  private static class Fixture extends LXAbstractFixture {
+
+    private final List<Strip> strips = new ArrayList<Strip>();
+
+    private Fixture(Metrics metrics, float ry, LXTransform transform) {
+      transform.push();
+      transform.translate(0, metrics.vertical.length, 0);
+      for (int i = 0; i < STRIPS_PER_FACE; i++) {
+        boolean isHorizontal = (i % 2 == 0);
+        Strip.Metrics stripMetrics = isHorizontal ? metrics.horizontal : metrics.vertical;
+        Strip strip = new Strip(stripMetrics, ry, transform, isHorizontal);
+        this.strips.add(strip);
+        transform.translate(isHorizontal ? metrics.horizontal.length : metrics.vertical.length, 0, 0);
+        transform.rotateZ(HALF_PI);
+        for (LXPoint p : strip.points) {
+          this.points.add(p);
+        }
+      }
+      transform.pop();
+    }
+  }
+}
+
+/**
+ * A strip is a linear run of points along a single edge of one cube.
+ */
+public static class Strip extends LXModel {
+
+  public static final float POINT_SPACING = 18.625f / 15.f;
+
+  public static class Metrics {
+
+    public final float length;
+    public final int numPoints;
+
+    public Metrics(float length, int numPoints) {
+      this.length = length;
+      this.numPoints = numPoints;
+    }
+  }
+
+  public final Metrics metrics;
+
+  /**
+   * Whether this is a horizontal strip
+   */
+  public final boolean isHorizontal;
+
+  /**
+   * Rotation about the y axis
+   */
+  public final float ry;
+
+  public Object obj1 = null, obj2 = null;
+
+  Strip(Metrics metrics, float ry, List<LXPoint> points, boolean isHorizontal) {
+    super(points);
+    this.isHorizontal = isHorizontal;
+    this.metrics = metrics;            
+    this.ry = ry;
+  }
+
+  Strip(Metrics metrics, float ry, LXTransform transform, boolean isHorizontal) {
+    super(new Fixture(metrics, ry, transform));
+    this.metrics = metrics;
+    this.isHorizontal = isHorizontal;
+    this.ry = ry;
+  }
+
+  private static class Fixture extends LXAbstractFixture {
+    private Fixture(Metrics metrics, float ry, LXTransform transform) {
+      float offset = (metrics.length - (metrics.numPoints - 1) * POINT_SPACING) / 2.f;
+      transform.push();
+      transform.translate(offset, -Cube.CHANNEL_WIDTH/2.f, 0);
+      for (int i = 0; i < metrics.numPoints; i++) {
+        LXPoint point = new LXPoint(transform.x(), transform.y(), transform.z());
+        this.points.add(point);
+        transform.translate(POINT_SPACING, 0, 0);
+      }
+      transform.pop();
+    }
+  }
+}
+
index c749ad4b891e72f12ed00c87e992ba96f2d4c827..ac8d6aa6276043be7d49224d0c8a7cfd965ac85c 100644 (file)
@@ -282,7 +282,7 @@ class UIMapping extends UIWindow {
       protected void onValueChange(int value) {
         mappingTool.setCube(value-1);
       }
-    }).setRange(1, glucose.model.cubes.size()).addToContainer(this);
+    }).setRange(1, model.cubes.size()).addToContainer(this);
     yp += 24;
     
     yp += 10;
index e8290f8ec97e2fba2ab1795de64dffa8cb8b84d2..c7c05bd85190eedbd65f10a137fe08ba00d04d55 100755 (executable)
Binary files a/code/GLucose.jar and b/code/GLucose.jar differ
diff --git a/code/oscP5.jar b/code/oscP5.jar
deleted file mode 100755 (executable)
index 24c6756..0000000
Binary files a/code/oscP5.jar and /dev/null differ