From: Mark Slee Date: Wed, 12 Jun 2013 02:18:44 +0000 (-0700) Subject: Add mappings for panda board UI and PandaDriver class X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=e73ef85d13e1f4787bbf2705d294791d268d95b1;p=SugarCubes.git Add mappings for panda board UI and PandaDriver class --- diff --git a/_Internals.pde b/_Internals.pde index a103f13..30e410d 100644 --- a/_Internals.pde +++ b/_Internals.pde @@ -29,7 +29,6 @@ import heronarts.lx.transition.*; import ddf.minim.*; import ddf.minim.analysis.*; import processing.opengl.*; -import java.lang.reflect.*; import rwmidi.*; final int VIEWPORT_WIDTH = 900; @@ -43,6 +42,11 @@ LXPattern[] patterns; LXTransition[] transitions; LXEffect[] effects; OverlayUI ui; +OscP5 osc; +PandaDriver pandaFront; +PandaDriver pandaRear; + +boolean pandaBoardsEnabled = false; void setup() { startMillis = lastMillis = millis(); @@ -66,6 +70,14 @@ void setup() { logTime("Built effects"); transitions = transitions(glucose); logTime("Built transitions"); + + // Build output driver + int[][] frontChannels = glucose.mapping.buildFrontChannelList(); + int[][] rearChannels = glucose.mapping.buildRearChannelList(); + int[][] flippedRGB = glucose.mapping.buildFlippedRGBList(); + pandaFront = new PandaDriver(new NetAddress("192.168.1.28", 9001), glucose.model, frontChannels, flippedRGB); + pandaRear = new PandaDriver(new NetAddress("192.168.1.29", 9001), glucose.model, rearChannels, flippedRGB); + logTime("Build PandaDriver"); // Build overlay UI ui = new OverlayUI(); @@ -76,6 +88,7 @@ void setup() { logTime("Setup MIDI devices"); println("Total setup: " + (millis() - startMillis) + "ms"); + println("Hit the 'p' key to toggle Panda Board output"); } void logTime(String evt) { @@ -87,6 +100,13 @@ void logTime(String evt) { void draw() { // The glucose engine deals with the core simulation here, we don't need // to do anything specific. This method just needs to exist. + + // TODO(mcslee): move into GLucose engine + if (pandaBoardsEnabled) { + color[] colors = glucose.getColors(); + pandaFront.send(colors); + pandaRear.send(colors); + } } void drawUI() { @@ -102,6 +122,10 @@ boolean uiOn = true; boolean knobsOn = true; void keyPressed() { switch (key) { + case 'p': + pandaBoardsEnabled = !pandaBoardsEnabled; + println("PandaBoard Output: " + (pandaBoardsEnabled ? "ON" : "OFF")); + break; case 'u': uiOn = !uiOn; break; diff --git a/_Mappings.pde b/_Mappings.pde index 8137050..fd581e5 100644 --- a/_Mappings.pde +++ b/_Mappings.pde @@ -97,5 +97,162 @@ class SCMapping implements GLucose.Mapping { cubes[78] = new Cube(20, 140, 80, 0, 0, 0, false, 0, 3); return cubes; } + + public int[][] buildFrontChannelList() { + return new int[][] { + { + 1, 57, 56, 55, 0 // Pandaboard A, structural channel 1 + } + , + { + 30, 31, 32, 17, 3 // Pandaboard B, structural channel 2 + } + , + { + 20, 21, 15, 19, 0 // Pandaboard C, structural channel 3 + } + , + { + 69, 75, 74, 76, 73 // Pandaboard D, structural channel 4 + } + , + { + 16, 2, 5, 0, 0 // Pandaboard E, structural channel 5 + } + , + { + 48, 47, 37, 29, 0 // Pandaboard F, structural channel 6 (is there a 5th?) + } + , + { + 68, 63, 62, 78, 45 // Pandaboard G, structural channel 7, left top front side + } + , + { + 18, 6, 7, 0, 0 // Pandaboard H, structural channel 8 + } + }; + } + + public int[][] buildRearChannelList() { + return new int[][] { + { + 22, 8, 14, 28, 0 // Pandaboard A, structural channel 9 + } + , + { + 36, 34, 40, 52, 66 // Pandaboard B, structural channel 10 + } + , + { + 65, 61, 60, 54, 51 // Pandaboard C, structural channel 11 + } + , + { + 35, 25, 11, 10, 24 // Pandaboard D, structural channel 12 + } + , + { + 23, 9, 13, 27, 12 // Pandaboard E, structural channel 13, missing taillight? + } + , + { + 64, 75, 72, 49, 50 // Pandaboard F, structural channel 14, right top backside + } + , + { + 77, 39, 46, 33, 26 // Pandaboard G, structural channel 15 + } + , + { + 44, 53, 42, 43, 41 // Pandaboard H, structural channel 16, last cube busted? + } + }; + } + + public int[][] buildFlippedRGBList() { + // syntax is {cube #, strip #, strip #, . . . } + return new int[][] { + { + 22, 4, 8 + } + , + { + 50, 1, 3 + } + , + { + 7, 1, 2, 11 + } + , + { + 49, 1 + } + , + { + 39, 1 + } + , + { + 41, 1 + } + , + { + 26, 3, 5 + } + , + { + 64, 1 + } + , + { + 32, 2 + } + , + { + 20, 6, 7 + } + , + { + 19, 1, 2 + } + , + { + 15, 6, 8 + } + , + { + 29, 3, 10 + } + , + { + 68, 4, 9 + } + , + { + 18, 12 + } + , + { + 6, 2, 4 + } + , + { + 78, 11 + } + , + { + 56, 2 + } + , + { + 57, 3 + } + , + { + 74, 6, 7 + } + }; + } } diff --git a/_Overlay.pde b/_Overlay.pde index c08e185..acf8505 100644 --- a/_Overlay.pde +++ b/_Overlay.pde @@ -1,3 +1,5 @@ +import java.lang.reflect.*; + /** * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND * diff --git a/_PandaDriver.pde b/_PandaDriver.pde new file mode 100644 index 0000000..7fd45c0 --- /dev/null +++ b/_PandaDriver.pde @@ -0,0 +1,128 @@ +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 class PandaDriver { + + // Address to send to + private final NetAddress address; + + // OSC message + private final OscMessage message; + + // List of point indices on the board + private final List points; + + // Bit for flipped status of each point index + private final boolean[] flipped; + + // Packet data + private final byte[] packet = new byte[4*352]; // TODO: de-magic-number + + public PandaDriver(NetAddress address, Model model, int[][] channelList, int[][] flippedList) { + this.address = address; + message = new OscMessage("/shady/pointbuffer"); + points = buildMappedList(model, channelList); + flipped = buildFlippedList(model, flippedList); + } + + private ArrayList buildMappedList(Model model, int[][] channelList) { + ArrayList points = new ArrayList(); + for (int[] channel : channelList) { + for (int cubeNumber : channel) { + if (cubeNumber == 0) { + for (int i = 0; i < (Cube.CLIPS_PER_CUBE*Clip.STRIPS_PER_CLIP*Strip.POINTS_PER_STRIP); ++i) { + points.add(0); + } + } else { + Cube cube = model.getCubeByRawIndex(cubeNumber); + if (cube == null) { + throw new RuntimeException("Non-zero, non-existing cube specified in channel mapping (" + cubeNumber + ")"); + } + for (Point p : cube.points) { + points.add(p.index); + } + } + } + } + return points; + } + + private boolean[] buildFlippedList(Model model, int[][] flippedRGBList) { + boolean[] flipped = new boolean[model.points.size()]; + for (int i = 0; i < flipped.length; ++i) { + flipped[i] = false; + } + for (int[] cubeInfo : flippedRGBList) { + int cubeNumber = cubeInfo[0]; + Cube cube = model.getCubeByRawIndex(cubeNumber); + if (cube == null) { + throw new RuntimeException("Non-existing cube specified in flipped RGB mapping (" + cubeNumber + ")"); + } else { + for (int i = 1; i < cubeInfo.length; ++i) { + int stripIndex = cubeInfo[i]; + for (Point p : cube.strips.get(stripIndex-1).points) { + flipped[p.index] = true; + } + } + } + } + return flipped; + } + + public final void send(int[] colors) { + int len = 0; + int packetNum = 0; + for (int index : points) { + int c = colors[index]; + byte r = (byte) ((c >> 16) & 0xFF); + byte g = (byte) ((c >> 8) & 0xFF); + byte b = (byte) ((c) & 0xFF); + if (flipped[index]) { + byte tmp = r; + r = g; + g = tmp; + } + packet[len++] = 0; + packet[len++] = r; + packet[len++] = g; + packet[len++] = b; + + // Flush once packet is full buffer size + if (len >= packet.length) { + sendPacket(packetNum++, len); + len = 0; + } + } + + // Flush any remaining data + if (len > 0) { + sendPacket(packetNum++, len); + } + } + + private void sendPacket(int packetNum, int len) { + message.clearArguments(); + message.add(packetNum); + message.add(len); + message.add(packet); + try { + OscP5.flush(message, address); + } catch (Exception x) { + x.printStackTrace(); + } + } +} + diff --git a/code/GLucose.jar b/code/GLucose.jar index 321f2a0..7b7d1bd 100644 Binary files a/code/GLucose.jar and b/code/GLucose.jar differ diff --git a/code/oscP5.jar b/code/oscP5.jar new file mode 100644 index 0000000..24c6756 Binary files /dev/null and b/code/oscP5.jar differ