Commit a2b909f1 authored by Ashley Chen's avatar Ashley Chen
Browse files

updated the models to be subclasses of LXModel and LXPoint, integrate with the...

updated the models to be subclasses of LXModel and LXPoint, integrate with the UI, wrote a test pattern

Merge branch 'dev/engine-ashley' into 'master'

Dev/engine ashley

See merge request !15
parent 59bf3682
import heronarts.lx.*;
import heronarts.lx.audio.*;
import heronarts.lx.color.LXColor;
import heronarts.lx.effect.*;
import heronarts.lx.model.*;
import heronarts.lx.output.*;
import heronarts.lx.parameter.*;
import heronarts.lx.pattern.*;
import heronarts.lx.studio.LXStudio;
import heronarts.lx.transform.*;
import heronarts.lx.modulator.*;
......@@ -46,14 +48,12 @@ UI3dContext viewContext;
FlyerHighlighter flyerHighlighter;
class ProcessingEngine extends FlightEngine {
ProcessingEngine(String projectPath, FlightModel model, LXStudio lx) {
super(projectPath, model, lx);
}
}
// Derived from Mark Slee's LXStudioApp example
private static final String WINDOW_TITLE = "FLIGHT Graphical UI";
private static int WIDTH = 1280;
......@@ -67,17 +67,17 @@ void settings() {
// Starts wings as Red and bodies as Blue, why not.
void initializeModel() {
model = new Model(flyerConfigurations).getFlightModel();
List<LightSamplePoint> wingLights = model.getLightsOfAllWings();
for (LightSamplePoint light: wingLights) {
light.setColor(LXColor.hsb(0, 0.5, 0.8));
}
List<LightSamplePoint> bodyLights = model.getLightsOfAllBodies();
for (LightSamplePoint light: bodyLights) {
light.setColor(LXColor.hsb(0.7, 0.5, 0.8));
}
model = new Model(flyerConfigurations).getFlightModel();
List<LightSamplePoint> wingLights = model.getAllWingsLights();
for (LightSamplePoint light: wingLights) {
light.setColor(LXColor.hsb(0, 0.5, 0.8));
}
List<LightSamplePoint> bodyLights = model.getAllBodyLights();
for (LightSamplePoint light: bodyLights) {
light.setColor(LXColor.hsb(0.7, 0.5, 0.8));
}
}
......@@ -87,75 +87,73 @@ void setup() {
IO io = new IO(sketchPath());
flyerConfigurations = io.loadConfigFile(Config.FLYER_CONFIG_FILE);
initializeModel();
lx = new LXStudio(this, model);
lx = new LXStudio(this, model);
}
void initializeUI(LXStudio lx, LXStudio.UI ui) {
pengine = new ProcessingEngine(sketchPath(), model, lx);
lx.engine.setThreaded(true);
lx.engine.addLoopTask(new FadeTest(lx));
lx.engine.addLoopTask(new BlackPinkTest(lx));
}
public void onUIReady(LXStudio lx, LXStudio.UI ui) {
System.out.println("Creating UI.");
FlightGui.this.flyerHighlighter = new FlyerHighlighter(lx, flyerConfigurations);
lx.addEffect(flyerHighlighter);
configureUI(ui);
System.out.println("Creating UI.");
FlightGui.this.flyerHighlighter = new FlyerHighlighter(lx, flyerConfigurations);
lx.addEffect(flyerHighlighter);
configureUI(ui);
}
void configureUI(LXStudio.UI ui) {
// Don't want all of the standard LXStudio stuff.
ui.bottomTray.setVisible(false);
ui.contentPicker.setVisible(false);
ui.helpBar.setVisible(false);
ui.leftPane.setVisible(false);
ui.preview.setVisible(false);
ui.rightPane.setVisible(false);
// Set up the camera view the UI uses to display the FLIGHT
// installation.
viewContext = new UI3dContext(ui) {
protected void beforeDraw(LXStudio.UI ui, PGraphics pg) {
//hint(ENABLE_DEPTH_TEST);
}
protected void afterDraw(LXStudio.UI ui, PGraphics pg) {
//hint(DISABLE_DEPTH_TEST);
}
};
// Configure the camera to rotate around a center point that's
// in the middle of the front window and 15 feet inside.
// Also set some camera angle constants so things look OK. Something
// more principled would be great. -pal
viewContext.setRadius(75*GeometryConstants.FEET);
viewContext.setCenter(GeometryConstants.FRONT_WINDOW_WIDTH / 2,
GeometryConstants.FRONT_WINDOW_CORNER_HEIGHT / 2,
15 * GeometryConstants.FEET);
viewContext.setTheta((float)(30.0 * Math.PI / 180.0));
viewContext.setPhi((float) (10.0 * Math.PI / 180.0));
viewContext.setCameraVelocity(10000.0);
viewContext.setCameraAcceleration(10000.0);
viewContext.setInteractionMode(UI3dContext.InteractionMode.ZOOM);
viewContext.addComponent(new UIFlightDisplay());
// Adds the control panel for selecting and moving Flyers
ui.addLayer(viewContext);
ui.addLayer(new UIFlyerConfiguration(ui));
// Don't want all of the standard LXStudio stuff.
ui.bottomTray.setVisible(false);
ui.contentPicker.setVisible(false);
ui.helpBar.setVisible(false);
ui.leftPane.setVisible(false);
ui.preview.setVisible(false);
ui.rightPane.setVisible(false);
// Set up the camera view the UI uses to display the FLIGHT
// installation.
viewContext = new UI3dContext(ui) {
protected void beforeDraw(LXStudio.UI ui, PGraphics pg) {
//hint(ENABLE_DEPTH_TEST);
}
protected void afterDraw(LXStudio.UI ui, PGraphics pg) {
//hint(DISABLE_DEPTH_TEST);
}
};
// Configure the camera to rotate around a center point that's
// in the middle of the front window and 15 feet inside.
// Also set some camera angle constants so things look OK. Something
// more principled would be great. -pal
viewContext.setRadius(75*GeometryConstants.FEET);
viewContext.setCenter(GeometryConstants.FRONT_WINDOW_WIDTH / 2,
GeometryConstants.FRONT_WINDOW_CORNER_HEIGHT / 2,
15 * GeometryConstants.FEET);
viewContext.setTheta((float)(30.0 * Math.PI / 180.0));
viewContext.setPhi((float) (10.0 * Math.PI / 180.0));
viewContext.setCameraVelocity(10000.0);
viewContext.setCameraAcceleration(10000.0);
viewContext.setInteractionMode(UI3dContext.InteractionMode.ZOOM);
viewContext.addComponent(new UIFlightDisplay());
// Adds the control panel for selecting and moving Flyers
ui.addLayer(viewContext);
ui.addLayer(new UIFlyerConfiguration(ui));
}
@Override
public void draw() {
//background(#222222);
// The actual model and such are drawn in their own
// draw methods, e.g. UIFlightDisplay.onDraw.
//background(#222222);
// The actual model and such are drawn in their own
// draw methods, e.g. UIFlightDisplay.onDraw.
}
void keyPressed() {
switch (key) {
case 'a':
System.out.println("Pressed a");
break;
case 'a':
System.out.println("Pressed a");
break;
}
}
import java.util.List;
class UIFlightDisplay extends UI3dComponent implements GeometryConstants {
final float[] VBAR_OFFSETS;
final float[] HBAR_OFFSETS;
UIFlightDisplay() {
super();
VBAR_OFFSETS = new float[GeometryConstants.FRONT_WINDOW_VBAR_SPACINGS.length];
float xPos = 0.0;
for (int i = 0; i < GeometryConstants.FRONT_WINDOW_VBAR_SPACINGS.length; i++) {
......@@ -20,7 +22,7 @@ class UIFlightDisplay extends UI3dComponent implements GeometryConstants {
HBAR_OFFSETS[i] = yPos;
}
}
protected void onDraw(UI ui, PGraphics pg) {
pg.lights();
pg.pointLight(0, 0, 80, model.cx, GeometryConstants.Y_ROOM/2, -10*GeometryConstants.FEET);
......@@ -36,7 +38,7 @@ class UIFlightDisplay extends UI3dComponent implements GeometryConstants {
// drawing it, then popping the tranformation. This allows the
// draw code to just operate in a normalized coordinate space. -pal
for (Flyer flyer : model.getFlyers()) {
int c = flyer.getBodyLightPoint().getColor();
int c = ((LightSamplePoint) flyer.getBodyLightPoint()).getColor();
pg.fill(c);
pg.pushMatrix();
......@@ -54,7 +56,7 @@ class UIFlightDisplay extends UI3dComponent implements GeometryConstants {
private void drawFlyer(PGraphics pg, Flyer flyer) {
// All of these values are in inches, taken from
// FRACTAL_FLYER/drawings/body-dimensions-for-ui-graphics.pdf
// top plate
pg.fill(#a0a0a0);
pg.beginShape();
......@@ -65,25 +67,27 @@ class UIFlightDisplay extends UI3dComponent implements GeometryConstants {
pg.endShape(CLOSE);
// Left wing
LightSamplePoint[] leftLights = flyer.getLeftWing().getLightPoints();
pg.fill(leftLights[0].getColor()); // Just use point 0 for the wing for now
List<LightSamplePoint> leftLights = model.getFlyerLeftWingLights(flyer.getIndex());
fill(leftLights.get(0).getColor()); // Just use point 0 for the wing for now
float leftSkew = model.getFlyerLeftWing(flyer.getIndex()).getSkew() / 9 - 10;
pg.beginShape();
pg.vertex(4.01, 0, 4.96);
pg.vertex(9.12, 0, 11.17);
pg.vertex(26.74, 0, 0.987);
pg.vertex(4.01, leftSkew, 4.96);
pg.vertex(9.12, leftSkew, 11.17);
pg.vertex(26.74, leftSkew, 0.987);
pg.endShape(CLOSE);
// Right wing
LightSamplePoint[] rightLights = flyer.getRightWing().getLightPoints();
pg.fill(rightLights[0].getColor()); // Just use point 0 for the wing for now
List<LightSamplePoint> rightLights = model.getFlyerRightWingLights(flyer.getIndex());
fill(rightLights.get(0).getColor()); // Just use point 0 for the wing for now
float rightSkew = model.getFlyerRightWing(flyer.getIndex()).getSkew() / 9 - 10;
pg.beginShape();
pg.vertex(4.01, 0, -4.96);
pg.vertex(9.12, 0, -11.17);
pg.vertex(26.74, 0, -0.987);
pg.vertex(4.01, rightSkew, -4.96);
pg.vertex(9.12, rightSkew, -11.17);
pg.vertex(26.74, rightSkew, -0.987);
pg.endShape(CLOSE);
// Body shell
LightSamplePoint light = flyer.getBodyLightPoint();
LightSamplePoint light = model.getFlyerBodyLight(flyer.getIndex());
pg.fill(light.getColor());
pg.beginShape();
......@@ -113,14 +117,14 @@ class UIFlightDisplay extends UI3dComponent implements GeometryConstants {
private void computeFlyerLightsAndWings() {
//Wing[] wings = (Wing[]) model.getAllWings().toArray();
for (LightSamplePoint l: model.getLightsOfAllWings()) {
for (LightSamplePoint l: model.getAllWingsLights()) {
//l.setColor(LXColor.RED);
}
for (LightSamplePoint l: model.getLightsOfAllBodies()) {
for (LightSamplePoint l: model.getAllBodyLights()) {
//l.setColor(LXColor.BLUE);
}
for (LXAbstractChannel channel: pengine.getChannels()) {
/* if (channel.hasLights()) {
channel.getFaderTransition().blend(lights, channel.getLights(), 1);
......@@ -189,7 +193,7 @@ class UIFlightDisplay extends UI3dComponent implements GeometryConstants {
pg.endShape(CLOSE);
}
}
class UIFlyerConfiguration extends UIWindow {
......@@ -206,7 +210,7 @@ class UIFlyerConfiguration extends UIWindow {
private UIToggleSet pipeToggle; // Ceiling: which pipe
private UISlider mountPointSlider; // Ceiling: were on pipe
private UIToggleSet faceToggle;
private UILabel name;
private UILabel text;
......@@ -223,7 +227,7 @@ class UIFlyerConfiguration extends UIWindow {
pipeToggle.setVisible(false);
positionSlider.setVisible(false);
mountPointSlider.setVisible(false);
if (face.equals("C")) {
pipeToggle.setVisible(true);
mountPointSlider.setVisible(true);
......@@ -237,15 +241,15 @@ class UIFlyerConfiguration extends UIWindow {
} else {
System.err.println("Unrecognized face: " + face + "; disable all controls.");
}
}
UIFlyerConfiguration(UI ui) {
super(ui, "LAYOUT TOOL",
BORDER, FlightGui.this.height - (HEIGHT + BORDER),
WIDTH, HEIGHT);
makeEnableButton();
makeFlyerSelect();
makeFaceToggle();
......@@ -257,17 +261,17 @@ class UIFlyerConfiguration extends UIWindow {
makeMountingSlider();
// makeSaveButton();
name = new UILabel(0, 0, 0, 16);
name.setLabel("?");
text = new UILabel(0, 0, 0, 16);
text.setLabel("?");
float yPos = TITLE_LABEL_HEIGHT;
yPos += ROW_HEIGHT;
yPos = labelRow(yPos, "FLYER #", flyerSelect);
yPos = labelRow(yPos, "NAME", name);
yPos = labelRow(yPos, "TEXT", text);
......@@ -278,7 +282,7 @@ class UIFlyerConfiguration extends UIWindow {
yPos = labelRow(yPos, "POS", positionSlider);
yPos = labelRow(yPos, "PIPE", pipeToggle);
yPos = labelRow(yPos, "MOUNT", mountPointSlider);
new UIButton(4, yPos, this.width-8, 20) {
void onToggle(boolean active) {
if (active) {
......@@ -291,10 +295,10 @@ class UIFlyerConfiguration extends UIWindow {
}
}
}.setMomentary(true).setLabel("Save Changes").addToContainer(this);
setFlyer();
}
private void makeEnableButton() {
this.enableButton = new UIButton(4, TITLE_LABEL_HEIGHT, width-8, 20) {
public void onToggle(boolean enabled) {
......@@ -325,7 +329,7 @@ class UIFlyerConfiguration extends UIWindow {
};
flyerHighlighter.flyerIndex.addListener(selectListener);
}
private void makeFaceToggle() {
this.faceToggle = new UIToggleSet() {
protected void onToggle(String value) {
......@@ -334,7 +338,7 @@ class UIFlyerConfiguration extends UIWindow {
flyerHighlighter.reloadModel();
}
};
// We have to convert to intern() because of a bug in ToggleSet
// that compares with == rather than .equals(); if you don't
// use .intern(), then strings don't match. -pal
......@@ -345,7 +349,7 @@ class UIFlyerConfiguration extends UIWindow {
}
this.faceToggle.setOptions(options);
}
private void makeHangLengthSlider() {
BoundedParameter hang = new BoundedParameter("Hang", 0, 8 * GeometryConstants.FEET);
this.hangDistanceSlider = new UISlider(0, 0, 0, 16) {
......@@ -356,7 +360,7 @@ class UIFlyerConfiguration extends UIWindow {
};
this.hangDistanceSlider.setParameter(hang);
}
private void makeXSlider() {
BoundedParameter x = new BoundedParameter("X", 0, GeometryConstants.FRONT_WINDOW_WIDTH);
this.xSlider = new UISlider(0, 0, 0, 16) {
......@@ -390,7 +394,7 @@ class UIFlyerConfiguration extends UIWindow {
this.positionSlider.setParameter(pos);
}
private void makeMountingSlider() {
BoundedParameter mount = new BoundedParameter("Mount", 0, -1, 1);
this.mountPointSlider = new UISlider(0, 0, 0, 16) {
......@@ -401,7 +405,7 @@ class UIFlyerConfiguration extends UIWindow {
};
this.mountPointSlider.setParameter(mount);
}
private void makePipeToggle() {
this.pipeToggle = new UIToggleSet() {
protected void onToggle(String str) {
......@@ -412,7 +416,7 @@ class UIFlyerConfiguration extends UIWindow {
String[] pipeOptions = {"1".intern(), "2".intern(), "3".intern(), "4".intern(), "5".intern(), "6".intern(), "7".intern()};
pipeToggle.setOptions(pipeOptions);
}
float labelRow(float yPos, String label, UI2dComponent obj) {
new UILabel(4, yPos, 50, 20)
.setLabel(label)
......@@ -424,7 +428,7 @@ class UIFlyerConfiguration extends UIWindow {
yPos += ROW_HEIGHT;
return yPos;
}
void setFlyer() {
FlyerConfig config = flyerConfigurations[flyerHighlighter.flyerIndex.getValuei()];
xSlider.getParameter().setValue(config.faceConfig().x);
......@@ -435,4 +439,3 @@ class UIFlyerConfiguration extends UIWindow {
text.setLabel(config.metadata().text);
}
}
File mode changed from 100644 to 100755
......@@ -3,5 +3,4 @@ final class Config {
public static final String FLYER_CONFIG_FILE = "data/flyers.json";
public static final String OUTPUT_NAMES_FILE = "data/outputs.json";
public static final String[] FACE_NAMES = {"C", "F", "I", "E"};
}
import java.util.List;
interface Flight extends GeometryConstants {
/*
* The naming scheme for the pattern getter functions are as follows:
* get [required]
* all flyers or one flyer (All vs Flyer) [required]
* part specifier if applicable (LeftWing(s), RightWing(s), Wings, Body) [optional]
* light specifier if applicable (PositionIndexed) [optional]
* Light/Lights
*/
abstract interface Flight extends GeometryConstants {
/**
* for movement pattern
* pattern getters for all flyers
*/
List<Wing> getLeftWings();
List<Wing> getRightWings();
/* ------------- all flyers, motion ------------- */
List<Wing> getAllWings();
List<Wing> getAllLeftWings();
List<Wing> getAllRightWings();
/**
* for light pattern
*/
List<LightSamplePoint> getLightsOfLeftWings();
List<LightSamplePoint> getLightsOfRightWings();
List<LightSamplePoint> getLightsOfAllWings();
List<LightSamplePoint> getHeadLightOfLeftWings();
List<LightSamplePoint> getHeadLightOfRightWings();
/* ------------- all flyers, lights ------------- */
List<LightSamplePoint> getAllLights();
List<LightSamplePoint> getHeadLightOfAllWings();
List<LightSamplePoint> getAllBodyLights();
List<LightSamplePoint> getAllWingsLights();
List<LightSamplePoint> getAllWingsPositionIndexedLights(int positionIndex); // head
List<LightSamplePoint> getSideLightOfLeftWings();
// left wings
List<LightSamplePoint> getAllLeftWingLights();
List<LightSamplePoint> getAllLeftWingPositionIndexedLights(int positionIndex);
List<LightSamplePoint> getSideLightOfRightWings();
// right wings
List<LightSamplePoint> getAllRightWingLights();
List<LightSamplePoint> getAllRightWingPositionIndexedLights(int positionIndex);
List<LightSamplePoint> getSideLightOfAllWings();
List<LightSamplePoint> getTailLightOfLeftWings();
/**
* pattern getters for individual flyers
*/
/* ------------- one flyer, motion ------------- */
Wing getFlyerLeftWing(int flyerIndex);
Wing getFlyerRightWing(int flyerIndex);
List<Wing> getFlyerWings(int flyerIndex);
List<LightSamplePoint> getTailLightOfRightWings();
/* ------------- one flyer, lights ------------- */
List<LightSamplePoint> getFlyerLights(int flyerIndex);
List<LightSamplePoint> getTailLightOfAllWings();
LightSamplePoint getFlyerBodyLight(int flyerIndex);
List<LightSamplePoint> getFlyerWingsLights(int flyerIndex);
List<LightSamplePoint> getFlyerWingsPositionIndexedLights(int flyerIndex, int positionIndex);
List<LightSamplePoint> getLightsOfAllBodies();
List<LightSamplePoint> getFlyerLeftWingLights(int flyerIndex);
LightSamplePoint getFlyerLeftWingPositionIndexedLights(int flyerIndex, int positionIndex);
List<LightSamplePoint> getAllLights();
List<LightSamplePoint> getFlyerRightWingLights(int flyerIndex);
LightSamplePoint getFlyerRightWingPositionIndexedLights(int flyerIndex, int positionIndex);
FlyerConfig[] getFlyerConfigs();
/**
* flyer config getters
*/
Flyer getFlyer(int i);
Flyer[] getFlyers();
/**
* This defines the positions of the flyers, which are
* index,
* x (left to right), y (front to back), z (bottom to top),
* rotation in degrees, and tilt (3 options)
*/
/**
* This defines the positions of the flyers, which are
* index,
* x (left to right), y (front to back), z (bottom to top),
* rotation in degrees, and tilt (3 options)
*/
FlyerConfig[] getFlyerConfigs();
List<Flyer> getFlyers();
}
\ No newline at end of file
interface Flyer extends GeometryConstants {
public final static int PIXELS_PER_BODY =
LightSamplePoint.LightCorners.BODY.numPixels;
import java.util.List;
public final static int PIXELS_PER_FLYER =
NUM_WINGS_PER_FLYER *
(LightSamplePoint.LightCorners.HEAD.numPixels +
LightSamplePoint.LightCorners.SIDE.numPixels +
LightSamplePoint.LightCorners.TAIL.numPixels) +
import heronarts.lx.model.LXModel;
import heronarts.lx.model.LXPoint;
abstract interface Flyer extends GeometryConstants {
public final static int PIXELS_PER_BODY =
LightSamplePoint.LightCorners.BODY.numPixels;
int getIndex();
......@@ -21,16 +19,18 @@ interface Flyer extends GeometryConstants {
float getTilt();
Wing[] getWings();
LXModel[] getWings();
Wing getLeftWing();
Wing getRightWing();
LightSamplePoint getBodyLightPoint();
LightSamplePoint[] getLightPoints();
LXPoint getBodyLightPoint();
List<? extends LXPoint> getLightPoints();
FlyerConfig getConfig();
}
class FlyerConfig {
......@@ -49,6 +49,7 @@ class FlyerConfig {
float mountPoint;
float hangDistance;
@Override
public String toString() {
String s = "Face: \"" + face + "\"\n";
s += "x: " + x + "\n";
......@@ -59,7 +60,7 @@ class FlyerConfig {
s += "hangDistance: " + hangDistance + "\n";
return s;
}
}
static class FlyerMetadata {
......@@ -69,6 +70,7 @@ class FlyerConfig {