Commit ff62ae5c authored by Philip Levis's avatar Philip Levis
Browse files

Merge branch 'dev/pal' of code.stanford.edu:plevis/ee185 into dev/pal

parents e9aaf2a4 fdbbb1ef
class UIFlightDisplay extends UI3dComponent implements GeometryConstants {
final float[] VBAR_OFFSETS;
final float[] HBAR_OFFSETS;
final float[] BACK_WALL_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++) {
xPos += GeometryConstants.FRONT_WINDOW_VBAR_SPACINGS[i];
VBAR_OFFSETS[i] = xPos;
}
HBAR_OFFSETS = new float[GeometryConstants.FRONT_WINDOW_HBAR_SPACINGS.length];
float yPos = 0.0;
for (int i = 0; i < GeometryConstants.FRONT_WINDOW_HBAR_SPACINGS.length; i++) {
yPos += GeometryConstants.FRONT_WINDOW_HBAR_SPACINGS[i];
HBAR_OFFSETS[i] = yPos;
}
BACK_WALL_OFFSETS = new float[GeometryConstants.BACK_WALL_SPACINGS.length];
yPos = 0;
for (int i = 0; i < GeometryConstants.BACK_WALL_SPACINGS.length; i++) {
yPos += GeometryConstants.BACK_WALL_SPACINGS[i];
BACK_WALL_OFFSETS[i] = yPos;
}
}
protected void onDraw(UI ui, PGraphics pg) {
pg.pushMatrix();
// I'd like the bottom left corner of the stairwell to be 0, 0, 0
// and then just set the camera to a good spot, but this does not
// seem to work with the preview window. So, instead, translate
// the whole model so that 0, 0, 0 is at a good spot.
drawBuilding(pg);
drawFlyers(pg);
pg.popMatrix();
}
private void drawFlyers(PGraphics pg) {
computeFlyerLightsAndWings();
// We draw each flyer by first computing a geometric
// transformation (matrix) for its position and orientation,
// 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();
pg.fill(c);
pg.pushMatrix();
float x = flyer.getX();
float y = flyer.getY();
float z = flyer.getZ();
pg.translate(x, y, z);
// rotateY(-flyer.getRotation() * (float)Math.PI / 180);
// rotateZ(-flyer.getTilt() * (float)Math.PI / 180);
drawFlyer(pg, flyer);
pg.popMatrix();
}
}
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
pg.noStroke();
// top plate
pg.fill(#a0a0a0);
pg.beginShape();
pg.vertex(0, 0, 0);
pg.vertex(3.33f, 0, 4.04f);
pg.vertex(26.26, 0, 0);
pg.vertex(3.33f, 0, -4.04f);
pg.endShape(CLOSE);
// Left wing
LightSamplePoint[] leftLights = flyer.getLeftWing().getLightPoints();
pg.fill(leftLights[0].getColor()); // Just use point 0 for the wing for now
pg.beginShape();
pg.vertex(4.01, 0, 4.96);
pg.vertex(9.12, 0, 11.17);
pg.vertex(26.74, 0, 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
pg.beginShape();
pg.vertex(4.01, 0, -4.96);
pg.vertex(9.12, 0, -11.17);
pg.vertex(26.74, 0, -0.987);
pg.endShape(CLOSE);
// Body shell
LightSamplePoint light = flyer.getBodyLightPoint();
pg.fill(light.getColor());
pg.beginShape();
pg.vertex(0, 0, 0);
pg.vertex(3.33f, 0, 4.04f);
pg.vertex(5.29f, -4.39f, 0);
pg.endShape(CLOSE);
pg.beginShape();
pg.vertex(0, 0, 0);
pg.vertex(3.33f, 0, -4.04f);
pg.vertex(5.29f, -4.39f, 0);
pg.endShape(CLOSE);
pg.beginShape();
pg.vertex(26.26, 0, 0);
pg.vertex(3.33f, 0, 4.04f);
pg.vertex(5.29f, -4.39f, 0);
pg.endShape(CLOSE);
pg.beginShape();
pg.vertex(26.26, 0, 0);
pg.vertex(3.33f, 0, -4.04f);
pg.vertex(5.29f, -4.39f, 0);
pg.endShape(CLOSE);
}
private void computeFlyerLightsAndWings() {
//Wing[] wings = (Wing[]) model.getAllWings().toArray();
for (LightSamplePoint l: model.getLightsOfAllWings()) {
//l.setColor(LXColor.RED);
}
for (LightSamplePoint l: model.getLightsOfAllBodies()) {
//l.setColor(LXColor.BLUE);
}
for (LXAbstractChannel channel: pengine.getChannels()) {
/* if (channel.hasLights()) {
channel.getFaderTransition().blend(lights, channel.getLights(), 1);
} */
// Motion is just last writer wins.
/*
if (channel.hasMotion()) {
channel.setWings(wings);
}
*/
}
flyerHighlighter.highlight();
}
private void drawBuilding(PGraphics pg) {
drawWalls(pg);
drawCeiling(pg);
drawStairs(pg);
}
private void drawCylinder(PGraphics pg, float r, float h) {
int sides = 36;
float angle = 360 / sides;
// draw top shape
beginShape();
for (int i = 0; i < sides; i++) {
float x = cos( radians( i * angle ) ) * r;
float y = sin( radians( i * angle ) ) * r;
vertex( x, y, 0 );
}
endShape(CLOSE);
// draw bottom shape
beginShape();
for (int i = 0; i < sides; i++) {
float x = cos( radians( i * angle ) ) * r;
float y = sin( radians( i * angle ) ) * r;
vertex( x, y, h );
}
endShape(CLOSE);
// draw body
beginShape(TRIANGLE_STRIP);
for (int i = 0; i < sides + 1; i++) {
float x = cos( radians( i * angle ) ) * r;
float y = sin( radians( i * angle ) ) * r;
vertex( x, y, h);
vertex( x, y, 0);
}
endShape(CLOSE);
}
private void drawCeilingPipe(PGraphics pg, float x0, float z0, float x1, float z1) {
pg.noStroke();
pg.fill(#c0c0c0);
pg.pushMatrix();
float y0 = FRONT_WINDOW_NADIR_HEIGHT + GeometryConstants.FRONT_WINDOW_BAR_WIDTH / 2.0f;
float y1 = FRONT_WINDOW_NADIR_HEIGHT + GeometryConstants.FRONT_WINDOW_BAR_WIDTH / 2.0f;
float xAngle = atan((x1 - x0)/(z1 - z0));
float length = sqrt((x1 - x0) * (x1 - x0) + (z1 - z0) * (z1 - z0));
pg.translate(x0, y0, z0);
pg.rotateY(xAngle);
drawCylinder(pg, 0.5f * GeometryConstants.FEET, length);
pg.popMatrix();
}
private void drawCeiling(PGraphics pg) {
// Because the back wall is at a 45 degree angle to the front window,
// the X and Z displacement is the same. -pal
// Draw straight pipes
for (int i = 0; i < BACK_WALL_OFFSETS.length; i++) {
float backWallOffset = BACK_WALL_OFFSETS[i] * 0.707;
// Straight pipe across
drawCeilingPipe(pg,
VBAR_OFFSETS[i * 2], 0.0,
backWallOffset, backWallOffset);
if (i == 1 || i == 2) {
float nextFX = VBAR_OFFSETS[2 * (i + 1)];
float nextFZ = 0.0f;
float nextBX = BACK_WALL_OFFSETS[i + 1] * 0.707;
float nextBZ = BACK_WALL_OFFSETS[i + 1] * 0.707;
float midpointX = nextFX + ((nextBX - nextFX) / 2.0);
float midpointZ = nextFZ + ((nextBZ - nextFZ)/ 2.0f);
System.out.println("Drawing v pipe");
System.out.println("StartX: " + VBAR_OFFSETS[i * 2]);
System.out.println("StartZ: " + 0);
System.out.println("NextX: " + nextFX);
System.out.println("NextZ: " + nextFZ);
System.out.println("BackX: " + nextBX);
System.out.println("BackZ: " + nextBZ);
System.out.println("MidX: " + midpointX);
System.out.println("MidZ: " + midpointZ);
// Two pipes of the V that meet at next one
drawCeilingPipe(pg,
VBAR_OFFSETS[i * 2], 0.0,
midpointX, midpointZ);
drawCeilingPipe(pg,
midpointX, midpointZ,
backWallOffset, backWallOffset);
}
}
}
private void drawStairFlight(PGraphics pg, float yOffset, boolean up) {
pg.fill(#202020);
pg.pushMatrix();
pg.translate(0, yOffset, 0);
if (up) {
pg.pushMatrix();
pg.translate(-168.0f + 126.0f * sin(PI/8f),
0,
32.0f + 126f * cos(PI/8f));
pg.rotateY(PI/8f);
pg.beginShape();
pg.vertex(0, 0, 0);
pg.vertex(0, 90f, 186f);
// This 128 is a hacked constant. I got sick of trying
// to do the triginometry. -pal
pg.vertex(0, 90f, 186f + 128f);
pg.vertex(69f, 90f, 186f);
pg.vertex(69f, 0, 0);
pg.endShape(CLOSE);
pg.popMatrix();
} else {
pg.pushMatrix();
pg.translate(168.0f - 126.0f * sin(PI/8f),
0,
32.0f + 126f * cos(PI/8f));
pg.rotateY(-PI/8f);
pg.beginShape();
pg.vertex(0, 0, 0);
pg.vertex(0, -90f, 186f);
// This 128 is a hacked constant. I got sick of trying
// to do the triginometry. -pal
pg.vertex(0, -90f, 186f + 128f);
pg.vertex(-69f, -90f, 186f);
pg.vertex(-69f, 0, 0);
pg.endShape(CLOSE);
pg.popMatrix();
}
pg.popMatrix();
}
private void drawPlatform(PGraphics pg, float yOffset) {
pg.fill(#202020);
pg.pushMatrix();
pg.translate(0, yOffset, 0);
pg.beginShape();
pg.vertex(126.0f, 0, 0.0f);
pg.vertex(126.0f, 0, 32.0f);
pg.vertex(168.0f, 0, 32.0f);
pg.vertex(168.0f - 126.0f * sin(PI/8f),
0,
32.0f + 126f * cos(PI/8f));
pg.vertex(168.0f - 126.0f * sin(PI/8f) - 69f * sin(5f / 8f * PI),
0,
32f + 126f * cos(PI/8f) + 69f * cos(5f / 8f * PI));
pg.vertex(168.0f - 126.0f * sin(PI/8f) - 69f * sin(5f / 8f * PI) + 21f * sin(PI/8f),
0,
32f + 126f * cos(PI/8f) + 69f * cos(5f / 8f * PI) - 21f * cos(PI/8f));
pg.vertex(-168.0f + 126.0f * sin(PI/8f) + 69f * sin(5f / 8f * PI) - 21f * sin(PI/8f),
0,
32f + 126f * cos(PI/8f) + 69f * cos(5f / 8f * PI) - 21f * cos(PI/8f));
pg.vertex(-168.0f + 126.0f * sin(PI/8f) + 69f * sin(5f / 8f * PI),
0,
32f + 126f * cos(PI/8f) + 69f * cos(5f / 8f * PI));
pg.vertex(-168.0f + 126.0f * sin(PI/8),
0,
32.0f + 126f * cos(PI/8));
pg.vertex(-168.0f, 0, 32.0f);
pg.vertex(-126.0f, 0, 32.0f);
pg.vertex(-126.0f, 0, 0.0f);
pg.endShape(CLOSE);
pg.popMatrix();
}
private void drawStairs(PGraphics pg) {
pg.pushMatrix();
// Translate to the midpoint of the center wall that
// the stair platforms are on; this is halfway between
// the end of the front wall (WIDTH) and the end of the back wall
// (0.707 * WIDTH) -pal
pg.translate(FRONT_WINDOW_WIDTH * (1f + 0.707) / 2f,
0f,
FRONT_WINDOW_WIDTH * (0.707) / 2f);
// The stairwell is 45 degrees; this means the mid angle from the
// center of the stair wall -22.5 degrees from along the X axis,
// so -(PI/4 + P/16)
pg.rotateY(- 5.0f/8.0f * PI);
drawPlatform(pg, 0f);
drawPlatform(pg, 180f);
drawPlatform(pg, 360f);
drawStairFlight(pg, 0, true);
drawStairFlight(pg, 180f, false);
drawStairFlight(pg, 180f, true);
drawStairFlight(pg, 360f, false);
pg.popMatrix();
}
private void drawWalls(PGraphics pg) {
pg.fill(#c0c0c0);
pg.stroke(#202020);
// Vertical bars: need a polygon not a rectangle
// because their top has an angle with the roof.
for (int i = 0; i < VBAR_OFFSETS.length; i++) {
float offset = VBAR_OFFSETS[i];
float center = FRONT_WINDOW_VBAR_HEIGHTS[i];
pg.beginShape();
pg.vertex(offset, 0.0);
pg.vertex(offset + FRONT_WINDOW_BAR_WIDTH, 0);
pg.vertex(offset + FRONT_WINDOW_BAR_WIDTH, center);
pg.vertex(offset, center);
pg.endShape(CLOSE);
}
// Horizontal bars
for (float offset: HBAR_OFFSETS) {
pg.rect(0,
offset,
FRONT_WINDOW_WIDTH,
FRONT_WINDOW_BAR_WIDTH);
}
//Top roof edge bar
pg.beginShape();
pg.vertex(0, FRONT_WINDOW_CORNER_HEIGHT, 0);
for (int i = 0; i < VBAR_OFFSETS.length; i++) {
pg.vertex(VBAR_OFFSETS[i] + FRONT_WINDOW_BAR_WIDTH, FRONT_WINDOW_VBAR_HEIGHTS[i], 0);
}
for (int i = VBAR_OFFSETS.length - 1; i >= 0; i--) {
pg.vertex(VBAR_OFFSETS[i] + FRONT_WINDOW_TOP_WIDTH, FRONT_WINDOW_VBAR_HEIGHTS[i] + FRONT_WINDOW_TOP_WIDTH, 0);
}
pg.vertex(0, FRONT_WINDOW_CORNER_HEIGHT + FRONT_WINDOW_TOP_WIDTH, 0);
pg.endShape(CLOSE);
// Bottom floor: 45 degree angle means back corner is at sqrt(2)
pg.beginShape();
pg.fill(#808080);
pg.vertex(0, -2, 0);
pg.vertex(FRONT_WINDOW_WIDTH, -2, 0);
pg.vertex(FRONT_WINDOW_WIDTH * 0.707, -2, FRONT_WINDOW_WIDTH * 0.707);
pg.endShape(CLOSE);
// Back wall: 45 degree angle means far corner is at sqrt(2)
pg.fill(#f0f0f0);
pg.beginShape();
pg.vertex(0, 0, 0);
pg.vertex(0, FRONT_WINDOW_CORNER_HEIGHT, 0);
pg.vertex(FRONT_WINDOW_WIDTH * 0.707,
FRONT_WINDOW_CORNER_HEIGHT,
FRONT_WINDOW_CORNER_HEIGHT * 0.707);
pg.vertex(FRONT_WINDOW_WIDTH * 0.707,
0,
FRONT_WINDOW_CORNER_HEIGHT * 0.707);
pg.endShape(CLOSE);
}
}
class UIFlyerConfiguration extends UIWindow {
final static int WIDTH = 140;
final static int HEIGHT = 360;
......@@ -612,12 +208,12 @@ class UIFlyerConfiguration extends UIWindow {
flyerHighlighter.reloadModel();
}
};
String[] yOptions = {"1".intern(), "2".intern(), "3".intern(), "4".intern(), "5".intern(), "6".intern()};
String[] yOptions = {"1".intern(), "2".intern(), "3".intern(), "4".intern(), "5".intern()};
yToggle.setOptions(yOptions);
}
private void makePositionSlider() {
BoundedParameter pos = new BoundedParameter("Position", 0, -1, 1);
BoundedParameter pos = new BoundedParameter("Position", 0, 0, 1);
this.positionSlider = new UISlider(0, 0, 0, 16) {
public void onParameterChanged(LXParameter parameter) {
flyerHighlighter.getConfig().faceConfig().position = parameter.getValuef();
......@@ -629,7 +225,7 @@ class UIFlyerConfiguration extends UIWindow {
private void makeMountingSlider() {
BoundedParameter mount = new BoundedParameter("Mount", 0, -1, 1);
BoundedParameter mount = new BoundedParameter("Mount", 0, 0, 1);
this.mountPointSlider = new UISlider(0, 0, 0, 16) {
public void onParameterChanged(LXParameter parameter) {
flyerHighlighter.getConfig().faceConfig().mountPoint = parameter.getValuef();
......@@ -646,7 +242,7 @@ class UIFlyerConfiguration extends UIWindow {
flyerHighlighter.reloadModel();
}
};
String[] pipeOptions = {"1".intern(), "2".intern(), "3".intern(), "4".intern(), "5".intern(), "6".intern(), "7".intern()};
String[] pipeOptions = {"0".intern(), "1".intern(), "2".intern(), "3".intern(), "4".intern(), "5".intern(), "6".intern(), "7".intern()};
pipeToggle.setOptions(pipeOptions);
}
......
class UIFlightDisplay extends UI3dComponent implements GeometryConstants {
final float[] VBAR_OFFSETS;
final float[] HBAR_OFFSETS;
final float[] BACK_WALL_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++) {
xPos += GeometryConstants.FRONT_WINDOW_VBAR_SPACINGS[i];
VBAR_OFFSETS[i] = xPos;
}
HBAR_OFFSETS = new float[GeometryConstants.FRONT_WINDOW_HBAR_SPACINGS.length];
float yPos = 0.0;
for (int i = 0; i < GeometryConstants.FRONT_WINDOW_HBAR_SPACINGS.length; i++) {
yPos += GeometryConstants.FRONT_WINDOW_HBAR_SPACINGS[i];
HBAR_OFFSETS[i] = yPos;
}
BACK_WALL_OFFSETS = new float[GeometryConstants.BACK_WALL_SPACINGS.length];
yPos = 0;
for (int i = 0; i < GeometryConstants.BACK_WALL_SPACINGS.length; i++) {
yPos += GeometryConstants.BACK_WALL_SPACINGS[i];
BACK_WALL_OFFSETS[i] = yPos;
}
}
protected void onDraw(UI ui, PGraphics pg) {
pg.pushMatrix();
// I'd like the bottom left corner of the stairwell to be 0, 0, 0
// and then just set the camera to a good spot, but this does not
// seem to work with the preview window. So, instead, translate
// the whole model so that 0, 0, 0 is at a good spot.
drawBuilding(pg);
drawFlyers(pg);
pg.popMatrix();
}
private void drawFlyers(PGraphics pg) {
computeFlyerLightsAndWings();
// We draw each flyer by first computing a geometric
// transformation (matrix) for its position and orientation,
// 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();
pg.fill(c);
pg.pushMatrix();
float x = flyer.getX();
float y = flyer.getY();
float z = flyer.getZ();
pg.translate(x, y, z);
rotateY(-flyer.getRotation() * (float)Math.PI / 180);
rotateZ(-flyer.getTilt() * (float)Math.PI / 180);
drawFlyer(pg, flyer);
pg.popMatrix();
}
}
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
pg.translate(-10f, 0, 0);
pg.noStroke();
// top plate
pg.fill(#a0a0a0);
pg.beginShape();
pg.vertex(0, 0, 0);
pg.vertex(3.33f, 0, 4.04f);
pg.vertex(26.26, 0, 0);
pg.vertex(3.33f, 0, -4.04f);
pg.endShape(CLOSE);
// Left wing
LightSamplePoint[] leftLights = flyer.getLeftWing().getLightPoints();
pg.fill(leftLights[0].getColor()); // Just use point 0 for the wing for now
pg.beginShape();
pg.vertex(4.01, 0, 4.96);
pg.vertex(9.12, 0, 11.17);
pg.vertex(26.74, 0, 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
pg.beginShape();
pg.vertex(4.01, 0, -4.96);
pg.vertex(9.12, 0, -11.17);
pg.vertex(26.74, 0, -0.987);
pg.endShape(CLOSE);
// Body shell
LightSamplePoint light = flyer.getBodyLightPoint();
pg.fill(light.getColor());
pg.beginShape();
pg.vertex(0, 0, 0);
pg.vertex(3.33f, 0, 4.04f);
pg.vertex(5.29f, -4.39f, 0);
pg.endShape(CLOSE);
pg.beginShape();
pg.vertex(0, 0, 0);
pg.vertex(3.33f, 0, -4.04f);
pg.vertex(5.29f, -4.39f, 0);
pg.endShape(CLOSE);
pg.beginShape();
pg.vertex(26.26, 0, 0);
pg.vertex(3.33f, 0, 4.04f);
pg.vertex(5.29f, -4.39f, 0);
pg.endShape(CLOSE);
pg.beginShape();
pg.vertex(26.26, 0, 0);
pg.vertex(3.33f, 0, -4.04f);
pg.vertex(5.29f, -4.39f, 0);
pg.endShape(CLOSE);
}
private void computeFlyerLightsAndWings() {
//Wing[] wings = (Wing[]) model.getAllWings().toArray();
for (LightSamplePoint l: model.getLightsOfAllWings()) {
//l.setColor(LXColor.RED);
}
for (LightSamplePoint l: model.getLightsOfAllBodies()) {
//l.setColor(LXColor.BLUE);
}
for (LXAbstractChannel channel: pengine.getChannels()) {
/* if (channel.hasLights()) {
channel.getFaderTransition().blend(lights, channel.getLights(), 1);
} */
// Motion is just last writer wins.
/*
if (channel.hasMotion()) {
channel.setWings(wings);
}
*/
}
flyerHighlighter.highlight();
}
private void drawBuilding(PGraphics pg) {
drawWalls(pg);