X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=_PandaDriver.pde;fp=_PandaDriver.pde;h=0000000000000000000000000000000000000000;hb=e037f60f518373c3bb952f79a2ae66950e55a52f;hp=26ac3d74c49aedfdb306290417044f9119ec7baf;hpb=344908672b7cfe1efba03f739ef945601dae1b8e;p=SugarCubes.git diff --git a/_PandaDriver.pde b/_PandaDriver.pde deleted file mode 100644 index 26ac3d7..0000000 --- a/_PandaDriver.pde +++ /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(); - } - } -}