Commit | Line | Data |
---|---|---|
e73ef85d MS |
1 | import netP5.*; |
2 | import oscP5.*; | |
3 | ||
4 | /** | |
5 | * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND | |
6 | * | |
7 | * //\\ //\\ //\\ //\\ | |
8 | * ///\\\ ///\\\ ///\\\ ///\\\ | |
9 | * \\\/// \\\/// \\\/// \\\/// | |
10 | * \\// \\// \\// \\// | |
11 | * | |
12 | * EXPERTS ONLY!! EXPERTS ONLY!! | |
13 | * | |
14 | * This class implements the output function to the Panda Boards. It | |
15 | * will be moved into GLucose once stabilized. | |
16 | */ | |
17 | public class PandaDriver { | |
18 | ||
79ae8245 MS |
19 | // IP address |
20 | public final String ip; | |
21 | ||
e73ef85d MS |
22 | // Address to send to |
23 | private final NetAddress address; | |
24 | ||
79ae8245 MS |
25 | // Whether board output is enabled |
26 | private boolean enabled = false; | |
27 | ||
e73ef85d MS |
28 | // OSC message |
29 | private final OscMessage message; | |
30 | ||
31 | // List of point indices on the board | |
e4d0d812 | 32 | private final int[] points; |
44b8de9c | 33 | |
e73ef85d | 34 | // Packet data |
b0071f51 | 35 | private final byte[] packet = new byte[4*352]; // TODO: de-magic-number, UDP related? |
e73ef85d | 36 | |
84086fa3 MS |
37 | private static final int NO_POINT = -1; |
38 | ||
44b8de9c | 39 | public PandaDriver(String ip) { |
79ae8245 MS |
40 | this.ip = ip; |
41 | this.address = new NetAddress(ip, 9001); | |
e73ef85d | 42 | message = new OscMessage("/shady/pointbuffer"); |
44b8de9c MS |
43 | points = new int[PandaMapping.PIXELS_PER_BOARD]; |
44 | for (int i = 0; i < points.length; ++i) { | |
45 | points[i] = 0; | |
46 | } | |
47 | } | |
48 | ||
49 | public PandaDriver(String ip, int[] pointList) { | |
50 | this(ip); | |
51 | for (int i = 0; i < pointList.length && i < points.length; ++i) { | |
52 | this.points[i] = pointList[i]; | |
e4d0d812 | 53 | } |
e73ef85d | 54 | } |
44b8de9c MS |
55 | |
56 | public PandaDriver(String ip, Model model, PandaMapping pm) { | |
57 | this(ip); | |
58 | buildPointList(model, pm); | |
59 | } | |
79ae8245 MS |
60 | |
61 | public void toggle() { | |
62 | enabled = !enabled; | |
045b432d | 63 | println("PandaBoard/" + ip + ": " + (enabled ? "ON" : "OFF")); |
79ae8245 | 64 | } |
e73ef85d | 65 | |
44b8de9c | 66 | private void buildPointList(Model model, PandaMapping pm) { |
68dcffde MS |
67 | final int[][] stripOrderings = new int[][] { |
68 | { 2, 1, 0, 3, 13, 12, 15, 14, 4, 7, 6, 5, 11, 10, 9, 8 }, // FRONT_LEFT | |
69 | { 6, 5, 4, 7, 1, 0, 3, 2, 8, 11, 10, 9, 15, 14, 13, 12 }, // FRONT_RIGHT | |
70 | { 14, 13, 12, 15, 9, 8, 11, 10, 0, 3, 2, 1, 7, 6, 5, 4 }, // REAR_LEFT | |
71 | { 10, 9, 8, 11, 5, 4, 7, 6, 12, 15, 14, 13, 3, 2, 1, 0 }, // REAR_RIGHT | |
72 | }; | |
73 | ||
44b8de9c | 74 | int pi = 0; |
84086fa3 MS |
75 | for (ChannelMapping channel : pm.channelList) { |
76 | switch (channel.mode) { | |
77 | case ChannelMapping.MODE_CUBES: | |
78 | for (int rawCubeIndex : channel.objectIndices) { | |
79 | if (rawCubeIndex < 0) { | |
80 | for (int i = 0; i < Cube.POINTS_PER_CUBE; ++i) { | |
81 | points[pi++] = NO_POINT; | |
82 | } | |
83 | } else { | |
84 | Cube cube = model.getCubeByRawIndex(rawCubeIndex); | |
85 | int stripOrderIndex = 0; | |
86 | switch (cube.wiring) { | |
87 | case FRONT_LEFT: stripOrderIndex = 0; break; | |
88 | case FRONT_RIGHT: stripOrderIndex = 1; break; | |
89 | case REAR_LEFT: stripOrderIndex = 2; break; | |
90 | case REAR_RIGHT: stripOrderIndex = 3; break; | |
91 | } | |
92 | for (int stripIndex : stripOrderings[stripOrderIndex]) { | |
93 | Strip s = cube.strips.get(stripIndex); | |
94 | for (int j = s.points.size() - 1; j >= 0; --j) { | |
95 | points[pi++] = s.points.get(j).index; | |
96 | } | |
97 | } | |
98 | } | |
e73ef85d | 99 | } |
84086fa3 MS |
100 | break; |
101 | ||
102 | case ChannelMapping.MODE_BASS: | |
103 | // TODO(mapping): figure out how these strips are wired | |
104 | for (int i = 0; i < ChannelMapping.PIXELS_PER_CHANNEL; ++i) { | |
105 | points[pi++] = NO_POINT; | |
e73ef85d | 106 | } |
84086fa3 MS |
107 | break; |
108 | ||
109 | case ChannelMapping.MODE_FLOOR: | |
110 | // TODO(mapping): figure out how these strips are wired | |
111 | for (int i = 0; i < ChannelMapping.PIXELS_PER_CHANNEL; ++i) { | |
112 | points[pi++] = NO_POINT; | |
68dcffde | 113 | } |
84086fa3 MS |
114 | break; |
115 | ||
116 | case ChannelMapping.MODE_SPEAKER: | |
117 | // TODO(mapping): figure out how these strips are wired | |
118 | for (int i = 0; i < ChannelMapping.PIXELS_PER_CHANNEL; ++i) { | |
119 | points[pi++] = NO_POINT; | |
120 | } | |
121 | break; | |
122 | ||
123 | case ChannelMapping.MODE_NULL: | |
124 | for (int i = 0; i < ChannelMapping.PIXELS_PER_CHANNEL; ++i) { | |
125 | points[pi++] = NO_POINT; | |
e73ef85d | 126 | } |
84086fa3 MS |
127 | break; |
128 | ||
129 | default: | |
130 | throw new RuntimeException("Invalid/unhandled channel mapping mode: " + channel.mode); | |
e73ef85d MS |
131 | } |
132 | } | |
e73ef85d MS |
133 | } |
134 | ||
e73ef85d | 135 | public final void send(int[] colors) { |
79ae8245 MS |
136 | if (!enabled) { |
137 | return; | |
138 | } | |
e73ef85d MS |
139 | int len = 0; |
140 | int packetNum = 0; | |
141 | for (int index : points) { | |
84086fa3 | 142 | int c = (index < 0) ? 0 : colors[index]; |
e73ef85d MS |
143 | byte r = (byte) ((c >> 16) & 0xFF); |
144 | byte g = (byte) ((c >> 8) & 0xFF); | |
145 | byte b = (byte) ((c) & 0xFF); | |
e73ef85d MS |
146 | packet[len++] = 0; |
147 | packet[len++] = r; | |
148 | packet[len++] = g; | |
149 | packet[len++] = b; | |
150 | ||
151 | // Flush once packet is full buffer size | |
152 | if (len >= packet.length) { | |
f584b5eb | 153 | sendPacket(packetNum++); |
e73ef85d MS |
154 | len = 0; |
155 | } | |
156 | } | |
157 | ||
158 | // Flush any remaining data | |
159 | if (len > 0) { | |
f584b5eb | 160 | sendPacket(packetNum++); |
e73ef85d MS |
161 | } |
162 | } | |
163 | ||
f584b5eb | 164 | private void sendPacket(int packetNum) { |
e73ef85d MS |
165 | message.clearArguments(); |
166 | message.add(packetNum); | |
f584b5eb | 167 | message.add(packet.length); |
e73ef85d MS |
168 | message.add(packet); |
169 | try { | |
bfff6bc2 | 170 | OscP5.flush(message, address); |
e73ef85d MS |
171 | } catch (Exception x) { |
172 | x.printStackTrace(); | |
173 | } | |
174 | } | |
175 | } | |
176 |