From: Ben Morrow Date: Sun, 18 Aug 2013 04:12:59 +0000 (-0700) Subject: Merge branch 'master' of github.com:sugarcubes/SugarCubes into BenMorrow X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=63642201449513f71cc4ad77c610f4990c83b8a0;hp=3b85aef48bc63012831ae3f47405a299b1139e87;p=SugarCubes.git Merge branch 'master' of github.com:sugarcubes/SugarCubes into BenMorrow --- diff --git a/MarkSlee.pde b/MarkSlee.pde index 1ecb640..7b1b86b 100644 --- a/MarkSlee.pde +++ b/MarkSlee.pde @@ -499,10 +499,10 @@ class AskewPlanes extends SCPattern { private final SinLFO a; private final SinLFO b; private final SinLFO c; - float av; - float bv; - float cv; - float denom; + float av = 1; + float bv = 1; + float cv = 1; + float denom = 0.1; Plane(int i) { addModulator(a = new SinLFO(-1, 1, 4000 + 1029*i)).trigger(); @@ -528,25 +528,33 @@ class AskewPlanes extends SCPattern { planes[i] = new Plane(i); } } - - private final float denoms[] = new float[NUM_PLANES]; public void run(int deltaMs) { float huev = lx.getBaseHuef(); - int i = 0; - for (Plane p : planes) { - p.run(deltaMs); - } + + // This is super fucking bizarre. But if this is a for loop, the framerate + // tanks to like 30FPS, instead of 60. Call them manually and it works fine. + // Doesn't make ANY sense... there must be some weird side effect going on + // with the Processing internals perhaps? +// for (Plane plane : planes) { +// plane.run(deltaMs); +// } + planes[0].run(deltaMs); + planes[1].run(deltaMs); + planes[2].run(deltaMs); + for (Point p : model.points) { - float d = MAX_FLOAT; - for (Plane plane : planes) { - d = min(d, abs(plane.av*(p.fx-model.xMax/2.) + plane.bv*(p.fy-model.yMax/2.) + plane.cv) / plane.denom); - } - colors[p.index] = color( - (lx.getBaseHuef() + abs(p.fx-model.xMax/2.)*.3 + p.fy*.8) % 360, - max(0, 100 - .8*abs(p.fx - model.xMax/2.)), - constrain(140 - 10.*d, 0, 100) - ); + float d = MAX_FLOAT; + for (Plane plane : planes) { + if (plane.denom != 0) { + d = min(d, abs(plane.av*(p.fx-model.cx) + plane.bv*(p.fy-model.cy) + plane.cv) / plane.denom); + } + } + colors[p.index] = color( + (huev + abs(p.fx-model.cx)*.3 + p.fy*.8) % 360, + max(0, 100 - .8*abs(p.fx - model.cx)), + constrain(140 - 10.*d, 0, 100) + ); } } } @@ -574,9 +582,9 @@ class ShiftingPlane extends SCPattern { float dv = d.getValuef(); float denom = sqrt(av*av + bv*bv + cv*cv); for (Point p : model.points) { - float d = abs(av*(p.fx-model.xMax/2.) + bv*(p.fy-model.yMax/2.) + cv*(p.fz-model.zMax/2.) + dv) / denom; + float d = abs(av*(p.fx-model.cx) + bv*(p.fy-model.cy) + cv*(p.fz-model.cz) + dv) / denom; colors[p.index] = color( - (hv + abs(p.fx-model.xMax/2.)*.6 + abs(p.fy-model.yMax/2)*.9 + abs(p.fz - model.zMax/2.)) % 360, + (hv + abs(p.fx-model.cx)*.6 + abs(p.fy-model.cy)*.9 + abs(p.fz - model.cz)) % 360, constrain(110 - d*6, 0, 100), constrain(130 - 7*d, 0, 100) ); diff --git a/TestPatterns.pde b/TestPatterns.pde index 38ea229..14572a2 100644 --- a/TestPatterns.pde +++ b/TestPatterns.pde @@ -1,8 +1,15 @@ +abstract class TestPattern extends SCPattern { + public TestPattern(GLucose glucose) { + super(glucose); + setEligible(false); + } +} + /** * Simplest demonstration of using the rotating master hue. * All pixels are full-on the same color. */ -class TestHuePattern extends SCPattern { +class TestHuePattern extends TestPattern { public TestHuePattern(GLucose glucose) { super(glucose); } @@ -19,7 +26,7 @@ class TestHuePattern extends SCPattern { /** * Test of a wave moving across the X axis. */ -class TestXPattern extends SCPattern { +class TestXPattern extends TestPattern { private final SinLFO xPos = new SinLFO(0, model.xMax, 4000); public TestXPattern(GLucose glucose) { super(glucose); @@ -41,7 +48,7 @@ class TestXPattern extends SCPattern { /** * Test of a wave on the Y axis. */ -class TestYPattern extends SCPattern { +class TestYPattern extends TestPattern { private final SinLFO yPos = new SinLFO(0, model.yMax, 4000); public TestYPattern(GLucose glucose) { super(glucose); @@ -59,7 +66,7 @@ class TestYPattern extends SCPattern { /** * Test of a wave on the Z axis. */ -class TestZPattern extends SCPattern { +class TestZPattern extends TestPattern { private final SinLFO zPos = new SinLFO(0, model.zMax, 4000); public TestZPattern(GLucose glucose) { super(glucose); @@ -77,7 +84,7 @@ class TestZPattern extends SCPattern { /** * This shows how to iterate over towers, enumerated in the model. */ -class TestTowerPattern extends SCPattern { +class TestTowerPattern extends TestPattern { private final SawLFO towerIndex = new SawLFO(0, model.towers.size(), 1000*model.towers.size()); public TestTowerPattern(GLucose glucose) { @@ -119,7 +126,7 @@ class TestTowerPattern extends SCPattern { * of sparse, non-uniformly spaced pixels. Mutating the structure would move * things to a space where there are no pixels in 99% of the cases. */ -class TestProjectionPattern extends SCPattern { +class TestProjectionPattern extends TestPattern { private final Projection projection; private final SawLFO angle = new SawLFO(0, TWO_PI, 9000); @@ -161,7 +168,7 @@ class TestProjectionPattern extends SCPattern { } } -class TestCubePattern extends SCPattern { +class TestCubePattern extends TestPattern { private SawLFO index = new SawLFO(0, Cube.POINTS_PER_CUBE, Cube.POINTS_PER_CUBE*60); @@ -185,7 +192,7 @@ class TestCubePattern extends SCPattern { } } -class MappingTool extends SCPattern { +class MappingTool extends TestPattern { private int cubeIndex = 0; private int stripIndex = 0; diff --git a/_Mappings.pde b/_Mappings.pde index b049bf7..967048f 100644 --- a/_Mappings.pde +++ b/_Mappings.pde @@ -38,149 +38,153 @@ public Model buildModel() { // y-axis. // // The cubes automatically increment their y-position by Cube.EDGE_HEIGHT. + + final float STACKED_RELATIVE = 1; + final float STACKED_REL_SPIN = 2; + TowerMapping[] mapping = new TowerMapping[] { new TowerMapping(0, 0, 0, new float[][] { - {0, 0}, - {5, -10, 20}, - {0, -6}, - {-5, -2, -20}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 5, -10, 20}, + {STACKED_RELATIVE, 0, -6}, + {STACKED_RELATIVE, -5, -2, -20}, }), new TowerMapping(Cube.EDGE_WIDTH + 2, 0, 0, new float[][] { - {0, 0}, - {0, 5, 10}, - {0, 2, 20}, - {0, 0, 30}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 0, 5, 10}, + {STACKED_RELATIVE, 0, 2, 20}, + {STACKED_RELATIVE, 0, 0, 30}, }), // Back Cubes behind DJ platform (in order of increasing x) new TowerMapping(50, 5, BASS_DEPTH, new float[][] { - {0, 0}, - {2, 0, 20}, - {-2, 10}, - {-5, 15, -20}, - {-2, 13}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 2, 0, 20}, + {STACKED_RELATIVE, -2, 10}, + {STACKED_RELATIVE, -5, 15, -20}, + {STACKED_RELATIVE, -2, 13}, }), new TowerMapping(79, 5, BASS_DEPTH, new float[][] { - {0, 0}, - {2, 0, 20}, - {4, 10}, - {2, 15, -20}, - {0, 13}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 2, 0, 20}, + {STACKED_RELATIVE, 4, 10}, + {STACKED_RELATIVE, 2, 15, -20}, + {STACKED_RELATIVE, 0, 13}, }), new TowerMapping(107, 5, BASS_DEPTH, new float[][] { - {0, 0}, - {4, 0, 20}, - {6, 10}, - {3, 15, -20}, - // {8, 13}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 4, 0, 20}, + {STACKED_RELATIVE, 6, 10}, + {STACKED_RELATIVE, 3, 15, -20}, + // {STACKED_RELATIVE, 8, 13}, }), new TowerMapping(133, 5, BASS_DEPTH, new float[][] { - {0, 0}, - {-2, 0, 20}, - {0, 10}, - {2, 15, -20}, - // {4, 13} + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, -2, 0, 20}, + {STACKED_RELATIVE, 0, 10}, + {STACKED_RELATIVE, 2, 15, -20}, + // {STACKED_RELATIVE, 4, 13} }), new TowerMapping(165, 5, BASS_DEPTH, new float[][] { - {0, 0}, - {-1, 20}, - {2, 10}, - {-2, 15, -20}, - {3, 13}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, -1, 20}, + {STACKED_RELATIVE, 2, 10}, + {STACKED_RELATIVE, -2, 15, -20}, + {STACKED_RELATIVE, 3, 13}, }), // front DJ cubes new TowerMapping((TRAILER_WIDTH - BASS_WIDTH)/2, BASS_HEIGHT, 10, new float[][] { - {0, 0}, - {0, -10, 20}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 0, -10, 20}, }), new TowerMapping((TRAILER_WIDTH - BASS_WIDTH)/2 + Cube.EDGE_HEIGHT, BASS_HEIGHT, 10, new float[][] { - {3, 0}, - {2, -10, 20}, + {STACKED_RELATIVE, 3, 0}, + {STACKED_RELATIVE, 2, -10, 20}, }), new TowerMapping((TRAILER_WIDTH - BASS_WIDTH)/2 + 2*Cube.EDGE_HEIGHT + 5, BASS_HEIGHT, 10, new float[][] { - {0, 0}, - {1, 0, 10}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 1, 0, 10}, }), new TowerMapping((TRAILER_WIDTH - BASS_WIDTH)/2 + 3*Cube.EDGE_HEIGHT + 9, BASS_HEIGHT, 10, new float[][] { - {0, 0}, - {-1, 0}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, -1, 0}, }), new TowerMapping((TRAILER_WIDTH - BASS_WIDTH)/2 + 4*Cube.EDGE_HEIGHT + 15, BASS_HEIGHT, 10, new float[][] { - {0, 0}, - {-1, 0}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, -1, 0}, }), // left dj cubes new TowerMapping((TRAILER_WIDTH - BASS_WIDTH)/2, BASS_HEIGHT, Cube.EDGE_HEIGHT + 2, new float[][] { - {0, 0}, - {0, 2, 20}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 0, 2, 20}, }), new TowerMapping((TRAILER_WIDTH - BASS_WIDTH)/2, BASS_HEIGHT, 2*Cube.EDGE_HEIGHT + 4, new float[][] { - {0, 0}, - {0, 2, 20}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 0, 2, 20}, }), // right dj cubes new TowerMapping((TRAILER_WIDTH - BASS_WIDTH)/2 + 4*Cube.EDGE_HEIGHT + 15, BASS_HEIGHT, Cube.EDGE_HEIGHT + 2, new float[][] { - {0, 0}, - {0, 2, 20}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 0, 2, 20}, }), new TowerMapping((TRAILER_WIDTH - BASS_WIDTH)/2 + 4*Cube.EDGE_HEIGHT + 15, BASS_HEIGHT, 2*Cube.EDGE_HEIGHT + 4, new float[][] { - {0, 0}, - {0, 2, 20}, + {STACKED_RELATIVE, 0, 0}, + {STACKED_RELATIVE, 0, 2, 20}, }), new TowerMapping(200, 0, 0, new float[][] { - {0, 10}, - {5, 0, 20}, - {0, 4}, - {-5, 8, -20}, - {0, 3}, + {STACKED_RELATIVE, 0, 10}, + {STACKED_RELATIVE, 5, 0, 20}, + {STACKED_RELATIVE, 0, 4}, + {STACKED_RELATIVE, -5, 8, -20}, + {STACKED_RELATIVE, 0, 3}, }), new TowerMapping(0, 0, Cube.EDGE_HEIGHT + 10, new float[][] { - {10, 0, 40}, - {3, -2, 20}, - {0, 0, 40}, - {0, 0, 60}, - {0, 0, 40}, + {STACKED_RELATIVE, 10, 0, 40}, + {STACKED_RELATIVE, 3, -2, 20}, + {STACKED_RELATIVE, 0, 0, 40}, + {STACKED_RELATIVE, 0, 0, 60}, + {STACKED_RELATIVE, 0, 0, 40}, }), new TowerMapping(20, 0, 2*Cube.EDGE_HEIGHT + 18, new float[][] { - {0, 0, 40}, - {10, 0, 20}, - {5, 0, 40}, - {10, 0, 60}, - {12, 0, 40}, + {STACKED_RELATIVE, 0, 0, 40}, + {STACKED_RELATIVE, 10, 0, 20}, + {STACKED_RELATIVE, 5, 0, 40}, + {STACKED_RELATIVE, 10, 0, 60}, + {STACKED_RELATIVE, 12, 0, 40}, }), new TowerMapping(210, 0, Cube.EDGE_HEIGHT + 15, new float[][] { - {0, 0, 40}, - {5, 0, 20}, - {8, 0, 40}, - {3, 0, 60}, - {0, 0, 40}, + {STACKED_RELATIVE, 0, 0, 40}, + {STACKED_RELATIVE, 5, 0, 20}, + {STACKED_RELATIVE, 8, 0, 40}, + {STACKED_RELATIVE, 3, 0, 60}, + {STACKED_RELATIVE, 0, 0, 40}, }), new TowerMapping(210, 0, 2*Cube.EDGE_HEIGHT + 25, new float[][] { - {0, 0, 40}, - {5, 0, 20}, - {2, 0, 40}, - {5, 0, 60}, - {0, 0, 40}, + {STACKED_RELATIVE, 0, 0, 40}, + {STACKED_RELATIVE, 5, 0, 20}, + {STACKED_RELATIVE, 2, 0, 40}, + {STACKED_RELATIVE, 5, 0, 60}, + {STACKED_RELATIVE, 0, 0, 40}, }), }; @@ -189,16 +193,25 @@ public Model buildModel() { ArrayList tower; Cube[] cubes = new Cube[79]; int cubeIndex = 1; - float x, y, z, ry; + float tx, ty, tz, px, pz, ny, dx, dz, ry; for (TowerMapping tm : mapping) { tower = new ArrayList(); - x = tm.x; - y = tm.y; - z = tm.z; + px = tx = tm.x; + ny = ty = tm.y; + pz = tz = tm.z; + int ti = 0; for (float[] cp : tm.cubePositions) { - ry = (cp.length >= 3) ? cp[2] : 0; - tower.add(cubes[cubeIndex++] = new Cube(x + cp[0], y, z + cp[1], 0, ry, 0)); - y += Cube.EDGE_HEIGHT; + float mode = cp[0]; + if (mode == STACKED_RELATIVE) { + dx = cp[1]; + dz = cp[2]; + ry = (cp.length >= 4) ? cp[3] : 0; + tower.add(cubes[cubeIndex++] = new Cube(px = tx + dx, ny, pz = tz + dz, 0, ry, 0)); + ny += Cube.EDGE_HEIGHT; + } else if (mode == STACKED_REL_SPIN) { + // Same as above but the front left of this cube is actually its back right for wiring + // TODO(mcslee): implement this + } } towerList.add(new Tower(tower)); } diff --git a/_Overlay.pde b/_Overlay.pde index 29e2353..a02aa12 100644 --- a/_Overlay.pde +++ b/_Overlay.pde @@ -33,6 +33,7 @@ abstract class OverlayUI { protected final int scrollWidth = 14; protected final color lightBlue = #666699; protected final color lightGreen = #669966; + protected final int toggleButtonSize = 10; private PImage logo; @@ -45,6 +46,8 @@ abstract class OverlayUI { protected final int pandaHeight = 13; protected final int pandaTop = height-16; + protected int eligibleLeft; + protected OverlayUI() { leftPos = width - w; leftTextPos = leftPos + 4; @@ -110,6 +113,17 @@ abstract class OverlayUI { return drawObjectList(yPos, title, items, names, stateMethod, sz, 0); } + protected void drawToggleButton(float x, float y, boolean eligible, color textColor) { + noFill(); + stroke(textColor); + rect(x, y, toggleButtonSize, toggleButtonSize); + if (eligible) { + noStroke(); + fill(textColor); + rect(x + 2, y + 2, toggleButtonSize - 4, toggleButtonSize - 4); + } + } + protected int drawObjectList(int yPos, String title, Object[] items, String[] names, Method stateMethod, int scrollLength, int scrollPos) { noStroke(); fill(titleColor); @@ -117,6 +131,7 @@ abstract class OverlayUI { textAlign(LEFT); text(title, leftTextPos, yPos += lineHeight); if (items != null) { + boolean hasScroll = (scrollPos > 0) || (scrollLength < items.length); textFont(itemFont); color textColor; boolean even = true; @@ -143,12 +158,18 @@ abstract class OverlayUI { fill(even ? #666666 : #777777); break; } + noStroke(); rect(leftPos, yPos+6, w, lineHeight); fill(textColor); text(names[i], leftTextPos, yPos += lineHeight); + if (lx.isAutoTransitionEnabled() && items[i] instanceof LXPattern) { + boolean eligible = ((LXPattern)items[i]).isEligible(); + eligibleLeft = leftPos + w - (hasScroll ? scrollWidth : 0) - 15; + drawToggleButton(eligibleLeft, yPos-8, eligible, textColor); + } even = !even; } - if ((scrollPos > 0) || (scrollLength < items.length)) { + if (hasScroll) { int yHere = yPos+6; noStroke(); fill(color(0, 0, 0, 50)); @@ -214,6 +235,9 @@ class ControlUI extends OverlayUI { private int firstEffectY; private int firstEffectKnobY; + private int autoRotateX; + private int autoRotateY; + private final int PATTERN_LIST_LENGTH = 8; private int patternScrollPos = 0; @@ -240,6 +264,11 @@ class ControlUI extends OverlayUI { public void draw() { drawLogoAndBackground(); int yPos = 0; + autoRotateX = leftPos + w - 29; + autoRotateY = yPos + 12; + drawToggleButton(autoRotateX, autoRotateY, lx.isAutoTransitionEnabled(), #999999); + fill(lx.isAutoTransitionEnabled() ? #222222: #999999); + text("A", autoRotateX + 2, autoRotateY + 9); firstPatternY = yPos + lineHeight + 6; yPos = drawObjectList(yPos, "PATTERN", patterns, patternNames, patternStateMethod, PATTERN_LIST_LENGTH, patternScrollPos); yPos += controlSpacing; @@ -396,6 +425,20 @@ class ControlUI extends OverlayUI { return; } + if ((mouseX >= autoRotateX) && + (mouseX < autoRotateX + toggleButtonSize) && + (mouseY >= autoRotateY) && + (mouseY < autoRotateY + toggleButtonSize)) { + if (lx.isAutoTransitionEnabled()) { + lx.disableAutoTransition(); + println("Auto pattern transition disabled"); + } else { + lx.enableAutoTransition(60000); + println("Auto pattern transition enabled"); + } + return; + } + if (mouseY > tempoY) { if (mouseY - tempoY < tempoHeight) { lx.tempo.tap(); @@ -430,7 +473,11 @@ class ControlUI extends OverlayUI { } else { int patternIndex = objectClickIndex(firstPatternY); if (patternIndex < patterns.length) { - lx.goIndex(patternIndex + patternScrollPos); + if (lx.isAutoTransitionEnabled() && (mouseX > eligibleLeft)) { + patterns[patternIndex + patternScrollPos].toggleEligible(); + } else { + lx.goIndex(patternIndex + patternScrollPos); + } } } } diff --git a/code/GLucose.jar b/code/GLucose.jar index 3525e18..04bf1fa 100644 Binary files a/code/GLucose.jar and b/code/GLucose.jar differ