Lots of code cleanup, removed Panda code, all grizzly, cleaning up mapping
[SugarCubes.git] / _PandaDriver.pde
diff --git a/_PandaDriver.pde b/_PandaDriver.pde
deleted file mode 100644 (file)
index 26ac3d7..0000000
+++ /dev/null
@@ -1,438 +0,0 @@
-import netP5.*;
-import oscP5.*;
-
-
-/**
- *     DOUBLE BLACK DIAMOND        DOUBLE BLACK DIAMOND
- *
- *         //\\   //\\                 //\\   //\\  
- *        ///\\\ ///\\\               ///\\\ ///\\\
- *        \\\/// \\\///               \\\/// \\\///
- *         \\//   \\//                 \\//   \\//
- *
- *        EXPERTS ONLY!!              EXPERTS ONLY!!
- *
- * This class implements the output function to the Panda Boards. It
- * will be moved into GLucose once stabilized.
- */
-public static class PandaDriver {
-  
-  interface Listener {
-    public void onToggle(boolean enabled);
-  }
-  
-  private Listener listener = null;
-  
-  // IP address
-  public final String ip;
-
-  public PandaMapping pm;
-  
-  private final static int PORT = 779;
-  
-  private final DatagramSocket socket;
-  
-  // Address to send to
-  private final NetAddress address;
-  
-  // Whether board output is enabled
-  private boolean enabled = false;
-
-  // Frame count for Grizzlies
-  private int frameNum = 1;
-  
-  // OSC message
-  private final OscMessage message;
-
-  // List of point indices that get sent to this board
-  private final int[] points;
-    
-  // Packet data
-  private final byte[] packet = new byte[4*280]; // magic number, our UDP packet size
-
-  private static final int NO_POINT = -1;
-
-  private Model _model;
-
-  ////////////////////////////////////////////////////////////////
-  //
-  // READ THIS RIGHT NOW BEFORE YOU MODIFY THE BELOW!!!!!!!!!!!!!
-  // READ THIS RIGHT NOW BEFORE YOU MODIFY THE BELOW!!!!!!!!!!!!!
-  // READ THIS RIGHT NOW BEFORE YOU MODIFY THE BELOW!!!!!!!!!!!!!
-  //
-  // The mappings below indicate the physical order of strips
-  // connected to a pandaboard channel. The strip numbers are a
-  // reflection of how the model is built.
-  //
-  // For ANYTHING in the model which is a rectangular prism,
-  // which means Cubes, the BassBox, and each Speaker, the
-  // strips are numbered incrementally by face. The first
-  // face is always the FRONT, which you are looking at.
-  // The next face is the RIGHT, then the BACK, then the LEFT.
-  //
-  // For every face, the strips are ordered numerically moving
-  // clockwise from the the TOP LEFT.
-  //
-  // So, for a cube:
-  //
-  //  Strip 0: front face, top strip, left to right
-  //  Strip 1: front face, right strip, top to bottom
-  //  Strip 2: front face, bottom strip, right to left
-  //  Strip 3: front face, left strip, bottom to top
-  //
-  //  Strip 4: right face, top strip, left to right
-  //  ... and so on
-  //  Strip 14: left face, bottom strip, right to left
-  //  Strip 15: left face, left strip, bottom to top
-  //
-  ////////////////////////////////////////////////////////////////
-  
-  private final static int FORWARD = -1;
-  private final static int BACKWARD = -2;
-
-  /**
-   * These constant arrays indicate the order in which the strips of a cube
-   * are wired. There are four different options, depending on which bottom
-   * corner of the cube the data wire comes in.
-   */
-  private final static int[][] CUBE_STRIP_ORDERINGS = new int[][] {
-//    {  2,  1,  0,  3, 13, 12, 15, 14,  4,  7,  6,  5, 11, 10,  9,  8 }, // FRONT_LEFT
-//    {  6,  5,  4,  7,  1,  0,  3,  2,  8, 11, 10,  9, 15, 14, 13, 12 }, // FRONT_RIGHT
-//    { 14, 13, 12, 15,  9,  8, 11, 10,  0,  3,  2,  1,  7,  6,  5,  4 }, // REAR_LEFT
-//    { 10,  9,  8, 11,  5,  4,  7,  6, 12, 15, 14, 13,  3,  2,  1,  0 }, // REAR_RIGHT
-
-
-    {  2,  1,  0,  3, 13, 12, 15, 14,  4,  7,  6,  5, 11, 10,  9,  8 }, // FRONT_LEFT
-    {  6,  5,  4,  7,  1,  0,  3,  2,  8, 11, 10,  9, 15, 14, 13, 12 }, // FRONT_RIGHT
-    { 14, 13, 12, 15,  9,  8, 11, 10,  0,  3,  2,  1,  7,  6,  5,  4 }, // REAR_LEFT
-    {  9,  8, 11,  5,  4,  7,  6, 10, 14,  2,  1,  0,  3, 13, 12, 15 }, // REAR_RIGHT
-
-  };
-  
-  private final static int[][] BASS_STRIP_ORDERING = {
-    // front face, counterclockwise from bottom front left
-    {2, BACKWARD /* if this strip has extra pixels, you can add them here */ /*, 4 */ }, 
-    {1, BACKWARD /* if this strip is short some pixels, substract them here */ /*, -3 */ },
-    {0, BACKWARD },
-    {3, BACKWARD },
-    
-    // left face, counterclockwise from bottom front left
-    {13, BACKWARD },
-    {12, BACKWARD },
-    {15, BACKWARD },
-    {14, BACKWARD },
-
-    // back face, counterclockwise from bottom rear left
-    {9, BACKWARD },
-    {8, BACKWARD },
-    {11, BACKWARD },
-    {10, BACKWARD },
-
-    // right face, counterclockwise from bottom rear right
-    {5, BACKWARD },
-    {4, BACKWARD },
-    {7, BACKWARD },
-    {6, BACKWARD },
-  };
-
-  private final static int[][] STRUT_STRIP_ORDERING = {
-    {6, BACKWARD},
-    {5, FORWARD},
-    {4, BACKWARD},
-    {3, FORWARD},
-    {2, BACKWARD},
-    {1, FORWARD},
-    {0, BACKWARD},
-    {7, FORWARD},    
-  };
-  
-  private final static int[][] FLOOR_STRIP_ORDERING = {
-    {0, FORWARD},
-    {1, FORWARD},
-    {2, FORWARD},
-    {3, BACKWARD},
-  };
-  
-  // The speakers are currently configured to be wired the same
-  // as cubes with Wiring.FRONT_LEFT. If this needs to be changed,
-  // remove this null assignment and change the below to have mappings
-  // for the LEFT and RIGHT speaker
-  private final static int[][][] SPEAKER_STRIP_ORDERING = {
-    // Left speaker
-    { 
-      // Front face, counter-clockwise from bottom left
-      {2, BACKWARD },
-      {1, BACKWARD },
-      {0, BACKWARD },
-      {3, BACKWARD },
-    },
-    // Right speaker
-    {
-      // Front face, counter-clockwise from bottom left
-      {2, BACKWARD },
-      {1, BACKWARD },
-      {0, BACKWARD },
-      {3, BACKWARD },
-    }
-  };
-
-  public PandaDriver(String ip) {
-    this.ip = ip;
-    
-    // Initialize our OSC output stuff
-    address = new NetAddress(ip, 779);
-    message = new OscMessage("/shady/pointbuffer");
-    
-    try {
-      socket = new DatagramSocket();
-    } catch (Exception x) {
-      throw new RuntimeException(x);
-    }
-    
-    // Build the array of points, initialize all to nothing
-    points = new int[PandaMapping.PIXELS_PER_BOARD];
-    for (int i = 0; i < points.length; ++i) {
-      points[i] = NO_POINT;
-    }
-  }
-    
-  public PandaDriver(String ip, Model model, PandaMapping _pm) {
-    this(ip);
-    pm = _pm;
-    _model = model;
-    // Ok, we are initialized, time to build the array if points in order to
-    // send out. We start at the head of our point buffer, and work our way
-    // down. This is the order in which points will be sent down the wire.
-    int ci = -1;
-    
-    // Iterate through all our channelq s
-    for (ChannelMapping channel : pm.channelList) {
-      ++ci;
-      int pi = ci * ChannelMapping.PIXELS_PER_CHANNEL;
-      
-      switch (channel.mode) {
-
-        case ChannelMapping.MODE_CUBES:
-          // We have a list of cubes per channel
-          for (int rawCubeIndex : channel.objectIndices) {
-            if (rawCubeIndex < 0) {
-              // No cube here, skip ahead in the buffer
-              pi += Cube.POINTS_PER_CUBE;
-            } else {
-              // The cube exists, check which way it is wired to
-              // figure out the order of strips.
-              Cube cube = model.getCubeByRawIndex(rawCubeIndex);
-              int stripOrderIndex = 0;
-              switch (cube.wiring) {
-                case FRONT_LEFT: stripOrderIndex = 0; break;
-                case FRONT_RIGHT: stripOrderIndex = 1; break;
-                case REAR_LEFT: stripOrderIndex = 2; break;
-                case REAR_RIGHT: stripOrderIndex = 3; break;
-              }
-              
-              // TODO(mcslee): clean up, ordering always consistent now
-              stripOrderIndex = 2;
-              
-              // Iterate through all the strips on the cube and add the points
-              for (int stripIndex : CUBE_STRIP_ORDERINGS[stripOrderIndex]) {
-                // We go backwards here... in the model strips go clockwise, but
-                // the physical wires are run counter-clockwise
-                pi = mapStrip(cube.strips.get(stripIndex), BACKWARD, points, pi);
-              }
-            }
-          }
-          break;
-          
-        case ChannelMapping.MODE_BASS:
-          for (int[] config : BASS_STRIP_ORDERING) {
-            pi = mapStrip(model.bassBox.strips.get(config[0]), config[1], points, pi);
-            if (config.length >= 3) pi += config[2];            
-          }
-          break;
-          
-        case ChannelMapping.MODE_STRUTS_AND_FLOOR:
-          for (int[] config : STRUT_STRIP_ORDERING) {
-            pi = mapStrip(model.bassBox.struts.get(config[0]), config[1], points, pi);
-            if (config.length >= 3) pi += config[2];
-          }     
-          for (int[] config : FLOOR_STRIP_ORDERING) {
-            pi = mapStrip(model.boothFloor.strips.get(config[0]), config[1], points, pi);
-            if (config.length >= 3) pi += config[2];
-          }
-          break;
-          
-        case ChannelMapping.MODE_SPEAKER:
-          int [][] speakerStripOrdering;
-          if (SPEAKER_STRIP_ORDERING == null) {
-            // Copy the cube strip ordering
-            int[] frontLeftCubeWiring = CUBE_STRIP_ORDERINGS[0];
-            speakerStripOrdering = new int[frontLeftCubeWiring.length][];
-            for (int i = 0; i < frontLeftCubeWiring.length; ++i) {
-              speakerStripOrdering[i] = new int[] { frontLeftCubeWiring[0], BACKWARD }; 
-            }
-          } else {
-            speakerStripOrdering = SPEAKER_STRIP_ORDERING[channel.objectIndices[0]];
-          }
-          for (int[] config : speakerStripOrdering) {
-            Speaker speaker = model.speakers.get(channel.objectIndices[0]);
-            pi = mapStrip(speaker.strips.get(config[0]), config[1], points, pi);
-            if (config.length >= 3) pi += config[2];            
-          }
-          break;
-          
-        case ChannelMapping.MODE_NULL:
-          // No problem, nothing on this channel!
-          break;
-          
-        default:
-          throw new RuntimeException("Invalid/unhandled channel mapping mode: " + channel.mode);
-      }
-
-    }
-  }
-  
-  private int mapStrip(Strip s, int direction, int[] points, int pi) {
-    return mapStrip(s, direction, points, pi, s.points.size());
-  }
-  
-  private int mapStrip(Strip s, int direction, int[] points, int pi, int len) {
-    if (direction == FORWARD) {
-      int i = 0;
-      for (LXPoint p : s.points) {
-        points[pi++] = p.index;
-        if (++i >= len) {
-          break;
-        }
-      }
-    } else if (direction == BACKWARD) {
-      for (int i = len-1; i >= 0; --i) {
-        points[pi++] = s.points.get(i).index;
-      }
-    } else {
-      throw new RuntimeException("Unidentified strip mapping direction: " + direction);
-    }
-    return pi;
-  }
-
-  public PandaDriver setListener(Listener listener) {
-    this.listener = listener;
-    return this;
-  }
-
-  public void setEnabled(boolean enabled) {
-    if (this.enabled != enabled) {
-      this.enabled = enabled;
-      println("PandaBoard/" + ip + ": " + (enabled ? "ON" : "OFF"));
-      if (listener != null) {
-        listener.onToggle(enabled);
-      }
-    }
-  }
-  
-  public boolean isEnabled() {
-    return this.enabled;
-  }
-
-  public void disable() {
-    setEnabled(false);
-  }
-  
-  public void enable() {
-    setEnabled(true);
-  }
-
-  public void toggle() {
-    setEnabled(!enabled);
-  }
-
-  private final int[] GRIZZLY_STRIP_ORDERING = new int[] {  9,  8, 11,  5,  4,  7,  6, 10, 14,  2,  1,  0,  3, 13, 12, 15 };
-
-  public final void send(int[] colors) {
-    if (!enabled) {
-      return;
-    }
-    frameNum++;
-    int len = 0;
-    int packetNum = 0;
-    for (ChannelMapping channel : pm.channelList) {
-      for (int rawCubeIndex : channel.objectIndices) {
-        if (rawCubeIndex > 0) {
-          Cube cube = _model.getCubeByRawIndex(rawCubeIndex);
-          
-          // TODO(mcslee): clean this up, precompute paths
-          for (int stripIndex : GRIZZLY_STRIP_ORDERING) {
-            Strip strip = cube.strips.get(stripIndex);
-            int stripLen = ((stripIndex == 9) || (stripIndex == 16)) ? 15 : 16;
-            for (int i = stripLen-1; i >= 0; --i) {
-              int c = colors[strip.points.get(i).index];
-              byte r = (byte) ((c >> 16) & 0xFF);
-              byte g = (byte) ((c >> 8) & 0xFF);
-              byte b = (byte) ((c) & 0xFF);
-              packet[len++] = (byte) 0; // alpha channel, unused but makes for 4-byte alignment
-              packet[len++] = (byte) r;
-              packet[len++] = (byte) g;
-              packet[len++] = (byte) b;
-            }
-          }
-          
-//          for (LXPoint p : cube.points) {
-//            int c = (p.index < 0) ? 0 : colors[p.index];
-//            byte r = (byte) ((c >> 16) & 0xFF);
-//            byte g = (byte) ((c >> 8) & 0xFF);
-//            byte b = (byte) ((c) & 0xFF);
-//            packet[len++] = (byte) 0; // alpha channel, unused but makes for 4-byte alignment
-//            packet[len++] = (byte) r;
-//            packet[len++] = (byte) g;
-//            packet[len++] = (byte) b;
-//          }
-        }
-      }
-      // println("Packet number: " + packetNum);
-      sendPacket(frameNum, packetNum++);
-      len = 0;
-    }
-    // for (int index : points) {
-    //   int c = (index < 0) ? 0 : colors[index];
-    //   byte r = (byte) ((c >> 16) & 0xFF);
-    //   byte g = (byte) ((c >> 8) & 0xFF);
-    //   byte b = (byte) ((c) & 0xFF);
-    //   packet[len++] = 0; // alpha channel, unused but makes for 4-byte alignment
-    //   packet[len++] = r;
-    //   packet[len++] = g;
-    //   packet[len++] = b;
-
-    //   // Flush once packet is full buffer size
-    //   if (len >= packet.length) {
-    //     sendPacket(packetNum++);
-    //     len = 0;
-    //   }
-    // }
-
-    // // Flush any remaining data
-    // if (len > 0) {
-    //   sendPacket(packetNum++);
-    // }
-  }
-  
-
-  private void sendPacket(int frameNum, int packetNum) {
-    // println("Sending frame #" + frameNum + ", channel # " + packetNum);
-    message.clearArguments();
-    message.add(frameNum);
-    message.add(0xDEADBEEF);
-    message.add(packetNum);
-    message.add(0xFEEDBEEF);
-    message.add(packet.length);
-    message.add(packet);
-    message.add(0xBEFFFFEB);
-
-    try {
-      // OscP5.flush(message, address); // new DatagramSocket every time, no thanks
-      byte[] bytes = message.getBytes();
-      DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address.inetaddress(), PORT);
-      socket.send(packet);
-    } catch (Exception x) {
-      x.printStackTrace();
-    }
-  }
-}