Commit | Line | Data |
---|---|---|
1ecdb44a MS |
1 | /** |
2 | * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND | |
3 | * | |
4 | * //\\ //\\ //\\ //\\ | |
5 | * ///\\\ ///\\\ ///\\\ ///\\\ | |
6 | * \\\/// \\\/// \\\/// \\\/// | |
7 | * \\// \\// \\// \\// | |
8 | * | |
9 | * EXPERTS ONLY!! EXPERTS ONLY!! | |
10 | * | |
186bc4d3 | 11 | * This file implements the mapping functions needed to lay out the physical |
1ecdb44a MS |
12 | * cubes and the output ports on the panda board. It should only be modified |
13 | * when physical changes or tuning is being done to the structure. | |
14 | */ | |
45f43cc2 | 15 | |
f0cc0ba5 MS |
16 | public Model buildModel() { |
17 | ||
46fc29d4 | 18 | |
f0cc0ba5 MS |
19 | // Shorthand helpers for specifying wiring more quickly |
20 | final Cube.Wiring WFL = Cube.Wiring.FRONT_LEFT; | |
21 | final Cube.Wiring WFR = Cube.Wiring.FRONT_RIGHT; | |
22 | final Cube.Wiring WRL = Cube.Wiring.REAR_LEFT; | |
23 | final Cube.Wiring WRR = Cube.Wiring.REAR_RIGHT; | |
95c50032 | 24 | |
a3ccf23a | 25 | // Utility value if you need the height of a cube shorthand |
95c50032 | 26 | final float CH = Cube.EDGE_HEIGHT; |
ae579223 | 27 | |
a3ccf23a | 28 | // Positions for the bass box |
ae579223 MS |
29 | final float BBY = BassBox.EDGE_HEIGHT + BoothFloor.PLEXI_WIDTH; |
30 | final float BBX = 56; | |
31 | final float BBZ = 2; | |
32 | ||
46fc29d4 | 33 | |
46fc29d4 MS |
34 | // The model is represented as an array of towers. The cubes in the tower |
35 | // are represenented relatively. Each tower has an x, y, z reference position, | |
36 | // which is typically the base cube's bottom left corner. | |
37 | // | |
38 | // Following that is an array of floats. A 2-d array contains an x-offset | |
f0cc0ba5 MS |
39 | // and a z-offset from the previous reference position. Typically the first cube |
40 | // will just be {0, 0}. Each successive cube uses the position of the previous | |
41 | // cube as its reference. | |
46fc29d4 MS |
42 | // |
43 | // A 3-d array contains an x-offset, a z-offset, and a rotation about the | |
44 | // y-axis. | |
45 | // | |
46 | // The cubes automatically increment their y-position by Cube.EDGE_HEIGHT. | |
e27a8652 AG |
47 | |
48 | // To-Do: (Mark Slee, Alex Green, or Ben Morrow): The Cube # is determined by the order in this list. "raw object index" is serialized by running through towermapping and then individual cube mapping below. | |
49 | // 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. | |
f0cc0ba5 | 50 | TowerMapping[] towerCubes = new TowerMapping[] { |
46fc29d4 | 51 | |
e28f168c AG |
52 | |
53 | ||
54 | //back left cubes: temp Channel 1 | |
55 | new TowerMapping(0, Cube.EDGE_HEIGHT, 72, new CubeMapping[] { | |
e27a8652 AG |
56 | new CubeMapping(0, 14, -45 , WRL), // #1 |
57 | new CubeMapping(18, -12, -20, WFL), //#2 | |
58 | new CubeMapping(5, 9, 45, WRR), //#3 | |
e28f168c AG |
59 | |
60 | ||
61 | }), | |
62 | //back left cube tower: Channel 2 | |
63 | new TowerMapping(0, Cube.EDGE_HEIGHT, 70, new CubeMapping[] { | |
e27a8652 | 64 | new CubeMapping(18, -2.5, 45, WRL), //#4 |
e28f168c AG |
65 | new CubeMapping(15, -6, 45, WFR), |
66 | new CubeMapping(-6 , 7, 5, WRR), | |
67 | new CubeMapping(18, 11, -5, WFL) | |
68 | ||
69 | }), | |
70 | ||
71 | //second from left back tower: Channel 3 | |
72 | new TowerMapping(31, Cube.EDGE_HEIGHT, 73.5, new CubeMapping[] { | |
73 | new CubeMapping( 12.5, 5.5 , 10 , WRR), | |
74 | new CubeMapping( 16.5, 2.5 , 30, WRR), | |
75 | new CubeMapping( 16.5, 3, 10, WRR), | |
76 | new CubeMapping(.5, 4.5, -10 , WFL) | |
77 | } ), | |
78 | ||
79 | //center tower, Channel 4 | |
80 | new TowerMapping(106, Cube.EDGE_HEIGHT, 84, new CubeMapping[] { | |
81 | new CubeMapping( -3.5, -2, 10, WFL), | |
82 | new CubeMapping( -11, 5, 30, WFR), | |
83 | new CubeMapping( 13.5, 2, 15, WRR), | |
84 | new CubeMapping(20.75, -4, 35 , WRL) | |
85 | } ), | |
86 | ||
87 | //second from back right tower, Channel 5 | |
88 | ||
89 | new TowerMapping(160, Cube.EDGE_HEIGHT, 78, new CubeMapping[] { | |
90 | new CubeMapping( -31.5, -.5 , 5 , WFR), | |
91 | new CubeMapping( 7, -.5, 60, WRL), | |
92 | new CubeMapping( -5.5, -3, 0, WFR), | |
93 | new CubeMapping(22 , 2 , 30 , WRL) | |
94 | }), | |
95 | ||
96 | ||
97 | //back right cubes: temp Channel 6 | |
98 | new TowerMapping(201, Cube.EDGE_HEIGHT, 72, new CubeMapping[] { | |
99 | new CubeMapping(7.5, 6, 25, WRL), | |
100 | new CubeMapping(-4.5, -0.5, 18, WFR), | |
101 | new CubeMapping(8.5, .5, 30, WRL), | |
102 | new CubeMapping(-7, -14, 10, WFR) | |
103 | ||
104 | }), | |
105 | ||
106 | ||
107 | ||
108 | ||
109 | ||
110 | //tower to the right of BASS BOX | |
111 | new TowerMapping (192, Cube.EDGE_HEIGHT, 40, new CubeMapping[] { | |
112 | new CubeMapping(-6, 4, -10, WRL), | |
113 | new CubeMapping(5 ,5 , 5, WFR ), | |
114 | new CubeMapping(-2, .5 , -3, WFL), | |
115 | new CubeMapping(-10, 5.5 , -20, WRR ) | |
116 | }), | |
117 | ||
118 | //end right tower in middle, right of previous tower | |
e27a8652 AG |
119 | //new TowerMapping (214, Cube.EDGE_HEIGHT, 37, new CubeMapping[] { |
120 | //new CubeMapping(10,0 , 50, WRR), | |
121 | //new CubeMapping(5 ,5 , 65, WFL) | |
122 | //}), | |
e28f168c AG |
123 | // // DJ booth, from back left to back right |
124 | ||
125 | new TowerMapping(BBX, BBY, BBZ, new CubeMapping[] { | |
126 | new CubeMapping(3, 28, 3, WFL), | |
127 | new CubeMapping(-2, 11.5, 10, WFR), | |
128 | new CubeMapping(10.5, 4.5, 40, WFR) | |
129 | ||
130 | ||
131 | }), | |
132 | ||
133 | ||
134 | ||
ae579223 MS |
135 | new TowerMapping(BBX, BBY, BBZ, new CubeMapping[] { |
136 | new CubeMapping(-7.25, 7.5, -25, WFR), | |
137 | new CubeMapping(7.5, -15.75, 12, WRL), | |
e28f168c AG |
138 | |
139 | ||
ae579223 MS |
140 | }), |
141 | new TowerMapping(BBX, BBY, BBZ, new CubeMapping[] { | |
142 | new CubeMapping(19.625, 5.375, -22, WFR), | |
143 | new CubeMapping(8, -14.5, 10, WRR), | |
144 | }), | |
145 | new TowerMapping(BBX, BBY, BBZ, new CubeMapping[] { | |
146 | new CubeMapping(48, 4.75, -35, WRL), | |
147 | new CubeMapping(8, -15, 10, WRR), | |
148 | }), | |
149 | new TowerMapping(BBX, BBY, BBZ, new CubeMapping[] { | |
150 | new CubeMapping(78.75, 3.75, -28, WRR), | |
151 | new CubeMapping(8, -15, 10, WRR), | |
46fc29d4 | 152 | }), |
e28f168c AG |
153 | |
154 | // next two are right DJ channel | |
155 | ||
156 | new TowerMapping(BBX, BBY, BBZ, new CubeMapping[] { | |
157 | new CubeMapping(105, 20.5, 20, WRR), | |
158 | new CubeMapping(6, -6, 30, WFR), | |
159 | }), | |
160 | ||
161 | new TowerMapping(BBX, BBY, BBZ, new CubeMapping[] { | |
ae579223 MS |
162 | new CubeMapping(104.75, 0, -27, WRL), |
163 | new CubeMapping(8, -15, 10, WFL), | |
164 | }), | |
46fc29d4 | 165 | |
e28f168c | 166 | |
46fc29d4 | 167 | }; |
f0cc0ba5 MS |
168 | |
169 | // Single cubes can be constructed directly here if you need them | |
170 | Cube[] singleCubes = new Cube[] { | |
e28f168c AG |
171 | //back left channel behind speaker |
172 | new Cube(15, int( Cube.EDGE_HEIGHT), 39, 0, 10, 0, WRL), | |
173 | new Cube(-6, int(Cube.EDGE_HEIGHT), 47, 0, 20, 0, WFR), | |
174 | new Cube(0, int(2*Cube.EDGE_HEIGHT), 46, 0, 40, 0, WRR), | |
175 | ||
176 | // Top left Channel Above DJ booth | |
177 | new Cube(33, int(4.5*Cube.EDGE_HEIGHT ), 28, 0, 10, 0, WRR), | |
e27a8652 AG |
178 | //new Cube(35, int(5*Cube.EDGE_HEIGHT ), 52, 0, 10, 0, WRR), |
179 | //new Cube(56, int(5*Cube.EDGE_HEIGHT ), 69, 0, 10, 0, WFL), | |
180 | //new Cube(76, int(5*Cube.EDGE_HEIGHT ), 61, 0, -45, 0, WRL), | |
e28f168c AG |
181 | |
182 | //next channel to the right, same height | |
e27a8652 AG |
183 | //new Cube(85, int(5*Cube.EDGE_HEIGHT ), 77, 0, 20, 0, WRL), |
184 | //new Cube(92, int(6*Cube.EDGE_HEIGHT ), 63, 0,20, 0, WRR), | |
185 | //new Cube(86, int(6*Cube.EDGE_HEIGHT ), 47, 0, -45, 0, WRL), | |
186 | //new Cube(123, int(6*Cube.EDGE_HEIGHT ), 31, 0, 20, 0, WFR), | |
e28f168c AG |
187 | |
188 | // next channel to right, same height | |
e27a8652 AG |
189 | //new Cube(111, int(5*Cube.EDGE_HEIGHT ), 79, 0, 30, 0, WRL), |
190 | //new Cube(125, int(6*Cube.EDGE_HEIGHT ), 76, 0,27, 0, WRL), | |
191 | //new Cube(144, int(5*Cube.EDGE_HEIGHT ), 44, 0, 45, 0, WRR), | |
192 | //new Cube(134, int(5*Cube.EDGE_HEIGHT ), 42, 0, 45, 0, WRL), | |
e28f168c AG |
193 | |
194 | //next channel to right | |
195 | new Cube(185, int(4*Cube.EDGE_HEIGHT ), 73, 0, -45, 0, WRR), | |
e27a8652 AG |
196 | //new Cube(170, int(5*Cube.EDGE_HEIGHT ), 58, 0,40, 0, WRL), |
197 | //new Cube(158, int(6*Cube.EDGE_HEIGHT ), 34, 0, 40, 0, WFR), | |
198 | //new Cube(130, int(6*Cube.EDGE_HEIGHT ), 10, 0, -5, 30, WRL), | |
e28f168c AG |
199 | |
200 | //next channel highest to the right | |
e27a8652 AG |
201 | //new Cube(203, int(5*Cube.EDGE_HEIGHT ), 55, 0, 35, 0, WRR), |
202 | //new Cube(174, int(5*Cube.EDGE_HEIGHT ), 32, 0,35, 0, WFR), | |
203 | //new Cube(178, int(6.5*Cube.EDGE_HEIGHT ), 16, 0, 20 , 30, WRL), | |
204 | //new Cube(212, int(6.5*Cube.EDGE_HEIGHT ), 23, 0, 20 ,30, WRR), | |
e28f168c AG |
205 | |
206 | //last channel | |
e27a8652 AG |
207 | //new Cube(204, int(5*Cube.EDGE_HEIGHT ), 28, 0, 25, 0, WFR), |
208 | ///new Cube(185, int(6*Cube.EDGE_HEIGHT ), 38, 0,40, 0, WRR), | |
e28f168c | 209 | |
e27a8652 AG |
210 | //new cubes above DJ deck |
211 | ||
212 | new Cube(BBX + 78.5, BBY + 2*Cube.EDGE_HEIGHT, BBZ, 0, 10, 0, WRR), | |
213 | new Cube(BBX + 49.5, BBY + 2*Cube.EDGE_HEIGHT, BBZ - 7, 0, 10, 0, WRR), | |
214 | new Cube(BBX + 13, BBY + 2*Cube.EDGE_HEIGHT, BBZ + 11, 0, -30, 0, WRL), | |
215 | new Cube(BBX - 15, BBY + 2*Cube.EDGE_HEIGHT, BBZ + 30, 0, -35, 0, WRR), | |
216 | ||
217 | // new cubes above DJ deck at crazy angles | |
218 | new Cube(BBX - 5, BBY + 3*Cube.EDGE_HEIGHT, BBZ + 15.5, 0, -15, 0, WRL), | |
219 | new Cube(BBX + 27, BBY + 3*Cube.EDGE_HEIGHT, BBZ + 12.5, 0, -18, -15, WRR), | |
220 | new Cube(BBX + 59, BBY + 3*Cube.EDGE_HEIGHT + 4, BBZ + 12.5, -12, 10, -10, WRL), | |
221 | new Cube(BBX + 93, BBY + 3*Cube.EDGE_HEIGHT + 7, BBZ + 20.5, -15, 20, -35, WRR), | |
222 | ||
223 | //new cubes on right side of DJ deck | |
224 | new Cube(161, BBY + 2*Cube.EDGE_HEIGHT, 15, 0, -40, 0, WFR), | |
225 | new Cube(161, BBY + 3*Cube.EDGE_HEIGHT, 24, 0, -30, 0, WFL), | |
226 | new Cube(165, BBY + 4*Cube.EDGE_HEIGHT, 41, 0, 5, 0, WFR), | |
227 | ||
228 | //new cubes top back left | |
229 | new Cube(BBX + 32, 5*Cube.EDGE_HEIGHT, BBZ + BassBox.EDGE_DEPTH + 7, 0, -25, 0, WFR), | |
230 | new Cube(BBX + 5.5, 5*Cube.EDGE_HEIGHT, BBZ + BassBox.EDGE_DEPTH +7, 0, -25, 0, WFL), | |
231 | new Cube(BBX - 23, 5*Cube.EDGE_HEIGHT, BBZ + BassBox.EDGE_DEPTH + 11, 0, -25, 0, WFL), | |
232 | new Cube(BBX - 33, 5*Cube.EDGE_HEIGHT + 8, BBZ +BassBox.EDGE_DEPTH- 29, 0, 10, 0, WFL), | |
233 | ||
234 | //on top of previous channel | |
235 | new Cube(BBX + 22, 6*Cube.EDGE_HEIGHT, BBZ + BassBox.EDGE_DEPTH , 0, 5, 0, WRL), | |
236 | new Cube(BBX + 27, 6*Cube.EDGE_HEIGHT - 13, BBZ + BassBox.EDGE_DEPTH- 25, 0, 3, -20, WRR), | |
237 | new Cube(BBX +5, 6*Cube.EDGE_HEIGHT - 13, BBZ + BassBox.EDGE_DEPTH -27, 0, 5, -15, WRL), | |
238 | new Cube(BBX - 11, 6*Cube.EDGE_HEIGHT -1.5, BBZ +BassBox.EDGE_DEPTH - 11, 0, 30, 0, WRR), | |
239 | ||
240 | //top center | |
241 | new Cube(BBX +37, 6*Cube.EDGE_HEIGHT, BBZ + BassBox.EDGE_DEPTH +13 , 0, 15, 0, WRR), | |
242 | new Cube(BBX + 64, 6*Cube.EDGE_HEIGHT, BBZ + BassBox.EDGE_DEPTH + 25, 0, 15, 0, WFR), | |
243 | new Cube(BBX + 64, 6*Cube.EDGE_HEIGHT - 3, BBZ + BassBox.EDGE_DEPTH -4 , 0, 0, -30, WRL), | |
244 | new Cube(BBX + 87.5, 6*Cube.EDGE_HEIGHT + 13, BBZ +BassBox.EDGE_DEPTH - 10, 0, 0, 0, WRL), | |
245 | ||
246 | //top right | |
247 | new Cube(BBX + 76, 107.5, BBZ + BassBox.EDGE_DEPTH + 23, 0, -40, 0, WRR), | |
248 | new Cube(BBX + 98, 129, BBZ + BassBox.EDGE_DEPTH - 5, 0, 10, 0, WRR), | |
249 | new Cube(BBX + 104, 107.5, BBZ + BassBox.EDGE_DEPTH + 17, 0, -35, 0, WRR), | |
250 | new Cube(BBX + 129, 107.5, BBZ +BassBox.EDGE_DEPTH +10, 0, -35, 0, WFL), | |
251 | ||
252 | new Cube(179, 4*Cube.EDGE_HEIGHT, BBZ + BassBox.EDGE_DEPTH + 14,0, -20, 0 , WFR) | |
253 | ||
f0cc0ba5 MS |
254 | // new Cube(x, y, z, rx, ry, rz, wiring), |
255 | }; | |
256 | ||
257 | // The bass box! | |
e28f168c AG |
258 | //BassBox bassBox = new BassBox(BBX, 0, BBZ); |
259 | //test for Alex, should be commented out | |
260 | ||
f0cc0ba5 | 261 | // The speakers! |
e28f168c | 262 | //List<Speaker> speakers = Arrays.asList(new Speaker[] { |
a3ccf23a | 263 | // each speaker parameter is x, y, z, rotation, the left speaker comes first |
e28f168c AG |
264 | // new Speaker(-12, 6, 0, 15), |
265 | // new Speaker(TRAILER_WIDTH - Speaker.EDGE_WIDTH + 8, 6, 3, -15) | |
266 | // }); | |
f0cc0ba5 | 267 | |
a3ccf23a MS |
268 | ////////////////////////////////////////////////////////////////////// |
269 | // BENEATH HERE SHOULD NOT REQUIRE ANY MODIFICATION!!!! // | |
270 | ////////////////////////////////////////////////////////////////////// | |
271 | ||
f0cc0ba5 | 272 | // These guts just convert the shorthand mappings into usable objects |
46fc29d4 MS |
273 | ArrayList<Tower> towerList = new ArrayList<Tower>(); |
274 | ArrayList<Cube> tower; | |
f0cc0ba5 | 275 | Cube[] cubes = new Cube[80]; |
46fc29d4 | 276 | int cubeIndex = 1; |
f0cc0ba5 MS |
277 | float px, pz, ny; |
278 | for (TowerMapping tm : towerCubes) { | |
279 | px = tm.x; | |
280 | ny = tm.y; | |
281 | pz = tm.z; | |
46fc29d4 | 282 | tower = new ArrayList<Cube>(); |
f0cc0ba5 MS |
283 | for (CubeMapping cm : tm.cubeMappings) { |
284 | tower.add(cubes[cubeIndex++] = new Cube(px = px + cm.dx, ny, pz = pz + cm.dz, 0, cm.ry, 0, cm.wiring)); | |
285 | ny += Cube.EDGE_HEIGHT; | |
46fc29d4 MS |
286 | } |
287 | towerList.add(new Tower(tower)); | |
288 | } | |
f0cc0ba5 MS |
289 | for (Cube cube : singleCubes) { |
290 | cubes[cubeIndex++] = cube; | |
291 | } | |
e76480d4 | 292 | |
e28f168c | 293 | return new Model(towerList, cubes, null, null); |
186bc4d3 | 294 | } |
e73ef85d | 295 | |
a3ccf23a MS |
296 | /** |
297 | * This function maps the panda boards. We have an array of them, each has | |
298 | * an IP address and a list of channels. | |
299 | */ | |
186bc4d3 | 300 | public PandaMapping[] buildPandaList() { |
1d75c8a9 MS |
301 | final int LEFT_SPEAKER = 0; |
302 | final int RIGHT_SPEAKER = 1; | |
303 | ||
186bc4d3 MS |
304 | return new PandaMapping[] { |
305 | new PandaMapping( | |
e28f168c AG |
306 | // 8 maps to: 3, 4, 7, 8, 13, 14, 15, 16. So if it's J4, |
307 | "10.200.1.30", new ChannelMapping[] { | |
e27a8652 AG |
308 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 20, 21, 22, 23}), //30 J3 * |
309 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 24, 25, 26, 27}), //30 J4 //ORIG * | |
310 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 16, 17, 18, 19}), //30 J7 * | |
311 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 39,40,41,42 }), //30 J8 * | |
312 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 37, 38, 36, 35}), //30 J13 | |
313 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 48,49,50,51}), //30 J14 | |
314 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 52,53,54,55 }), // 30 J15 | |
315 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 56, 57, 58, 75}), // 30 J16 | |
186bc4d3 | 316 | }), |
e28f168c AG |
317 | new PandaMapping( |
318 | "10.200.1.29", new ChannelMapping[] { | |
e27a8652 AG |
319 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 59,60,61,62}), //29 J3 |
320 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 63, 64, 65, 66}), //29 J4 | |
321 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 67, 68, 69, 70 }), // 29 J7 | |
322 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 71,72,73,74 }), //29 J8 //XXX | |
e28f168c | 323 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 17, 18, 19, 20 }), //29 J13 //XX //bassbox |
e27a8652 AG |
324 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1,1,1}), //29 J14 |
325 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 37, 38, 39, 35}), //29 J15 | |
e28f168c AG |
326 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 16, 17,18,19 }), //29 J16 |
327 | }), | |
186bc4d3 | 328 | new PandaMapping( |
29674806 | 329 | "10.200.1.28", new ChannelMapping[] { |
e27a8652 AG |
330 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1,1,1}), //28 J3 |
331 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1,1,1,1}), //28 J4 | |
332 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 1, 1, 1, 1 }), //28 J7 | |
e28f168c AG |
333 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 13, 14 , 15, 16 }), //28 J8 |
334 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 8,9,10,11 }), //28 J13 | |
e27a8652 | 335 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 33,34,32,31}), //28 J14 |
e28f168c | 336 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 12, 13, 14, 15 }), //28 J15 |
e27a8652 | 337 | new ChannelMapping(ChannelMapping.MODE_CUBES, new int[] { 28, 29, 30, 1}), //28 J16 |
e28f168c AG |
338 | }), |
339 | }; | |
340 | ||
45f43cc2 | 341 | } |
e73ef85d | 342 | |
e28f168c AG |
343 | |
344 | ||
f0cc0ba5 MS |
345 | class TowerMapping { |
346 | public final float x, y, z; | |
347 | public final CubeMapping[] cubeMappings; | |
348 | ||
349 | TowerMapping(float x, float y, float z, CubeMapping[] cubeMappings) { | |
350 | this.x = x; | |
351 | this.y = y; | |
352 | this.z = z; | |
353 | this.cubeMappings = cubeMappings; | |
354 | } | |
355 | } | |
356 | ||
357 | class CubeMapping { | |
358 | public final float dx, dz, ry; | |
359 | public final Cube.Wiring wiring; | |
360 | ||
361 | CubeMapping(float dx, float dz, Cube.Wiring wiring) { | |
362 | this(dx, dz, 0, wiring); | |
363 | } | |
364 | ||
365 | CubeMapping(float dx, float dz, float ry) { | |
366 | this(dz, dz, ry, Cube.Wiring.FRONT_LEFT); | |
367 | } | |
368 | ||
369 | CubeMapping(float dx, float dz, float ry, Cube.Wiring wiring) { | |
370 | this.dx = dx; | |
371 | this.dz = dz; | |
372 | this.ry = ry; | |
373 | this.wiring = wiring; | |
374 | } | |
375 | } | |
376 | ||
a922e963 MS |
377 | /** |
378 | * Each panda board has an IP address and a fixed number of channels. The channels | |
379 | * each have a fixed number of pixels on them. Whether or not that many physical | |
380 | * pixels are connected to the channel, we still send it that much data. | |
381 | */ | |
45f43cc2 MS |
382 | class PandaMapping { |
383 | ||
045b432d | 384 | // How many channels are on the panda board |
e28f168c | 385 | public final static int CHANNELS_PER_BOARD = 8; |
045b432d | 386 | |
44b8de9c | 387 | // How many total pixels on the whole board |
84086fa3 | 388 | public final static int PIXELS_PER_BOARD = ChannelMapping.PIXELS_PER_CHANNEL * CHANNELS_PER_BOARD; |
44b8de9c | 389 | |
45f43cc2 | 390 | final String ip; |
84086fa3 | 391 | final ChannelMapping[] channelList = new ChannelMapping[CHANNELS_PER_BOARD]; |
45f43cc2 | 392 | |
84086fa3 | 393 | PandaMapping(String ip, ChannelMapping[] rawChannelList) { |
45f43cc2 | 394 | this.ip = ip; |
a922e963 MS |
395 | |
396 | // Ensure our array is the right length and has all valid items in it | |
84086fa3 MS |
397 | for (int i = 0; i < channelList.length; ++i) { |
398 | channelList[i] = (i < rawChannelList.length) ? rawChannelList[i] : new ChannelMapping(); | |
a922e963 MS |
399 | if (channelList[i] == null) { |
400 | channelList[i] = new ChannelMapping(); | |
401 | } | |
045b432d | 402 | } |
e73ef85d | 403 | } |
1ecdb44a MS |
404 | } |
405 | ||
a922e963 | 406 | /** |
e27a8652 | 407 | * Each channel on a pandaboard can be mapped in a number of modes. The typical is |
a922e963 MS |
408 | * to a series of connected cubes, but we also have special mappings for the bass box, |
409 | * the speaker enclosures, and the DJ booth floor. | |
410 | * | |
411 | * This class is just the mapping meta-data. It sanitizes the input to make sure | |
412 | * that the cubes and objects being referenced actually exist in the model. | |
413 | * | |
414 | * The logic for how to encode the pixels is contained in the PandaDriver. | |
415 | */ | |
84086fa3 MS |
416 | class ChannelMapping { |
417 | ||
418 | // How many cubes per channel xc_PB is configured for | |
419 | public final static int CUBES_PER_CHANNEL = 4; | |
45f43cc2 | 420 | |
84086fa3 MS |
421 | // How many total pixels on each channel |
422 | public final static int PIXELS_PER_CHANNEL = Cube.POINTS_PER_CUBE * CUBES_PER_CHANNEL; | |
423 | ||
424 | public static final int MODE_NULL = 0; | |
425 | public static final int MODE_CUBES = 1; | |
426 | public static final int MODE_BASS = 2; | |
427 | public static final int MODE_SPEAKER = 3; | |
1d75c8a9 | 428 | public static final int MODE_STRUTS_AND_FLOOR = 4; |
84086fa3 MS |
429 | public static final int MODE_INVALID = 5; |
430 | ||
431 | public static final int NO_OBJECT = -1; | |
432 | ||
433 | final int mode; | |
434 | final int[] objectIndices = new int[CUBES_PER_CHANNEL]; | |
435 | ||
436 | ChannelMapping() { | |
437 | this(MODE_NULL); | |
438 | } | |
439 | ||
440 | ChannelMapping(int mode) { | |
441 | this(mode, new int[]{}); | |
442 | } | |
443 | ||
444 | ChannelMapping(int mode, int rawObjectIndex) { | |
445 | this(mode, new int[]{ rawObjectIndex }); | |
446 | } | |
447 | ||
448 | ChannelMapping(int mode, int[] rawObjectIndices) { | |
449 | if (mode < 0 || mode >= MODE_INVALID) { | |
450 | throw new RuntimeException("Invalid channel mapping mode: " + mode); | |
451 | } | |
452 | if (mode == MODE_SPEAKER) { | |
453 | if (rawObjectIndices.length != 1) { | |
454 | throw new RuntimeException("Speaker channel mapping mode must specify one speaker index"); | |
455 | } | |
456 | int speakerIndex = rawObjectIndices[0]; | |
457 | if (speakerIndex < 0 || speakerIndex >= glucose.model.speakers.size()) { | |
e28f168c | 458 | //throw new RuntimeException("Invalid speaker channel mapping: " + speakerIndex); |
84086fa3 | 459 | } |
1d75c8a9 | 460 | } else if ((mode == MODE_STRUTS_AND_FLOOR) || (mode == MODE_BASS) || (mode == MODE_NULL)) { |
84086fa3 | 461 | if (rawObjectIndices.length > 0) { |
e28f168c | 462 | //throw new RuntimeException("Bass/floor/null mappings cannot specify object indices"); |
84086fa3 MS |
463 | } |
464 | } else if (mode == MODE_CUBES) { | |
465 | for (int rawCubeIndex : rawObjectIndices) { | |
466 | if (glucose.model.getCubeByRawIndex(rawCubeIndex) == null) { | |
467 | throw new RuntimeException("Non-existing cube specified in cube mapping: " + rawCubeIndex); | |
468 | } | |
469 | } | |
470 | } | |
471 | ||
472 | this.mode = mode; | |
473 | for (int i = 0; i < objectIndices.length; ++i) { | |
474 | objectIndices[i] = (i < rawObjectIndices.length) ? rawObjectIndices[i] : NO_OBJECT; | |
475 | } | |
476 | } | |
477 | } |