From 51d0d59a585389dffc7281cd5c64bde8a2632e16 Mon Sep 17 00:00:00 2001 From: Mark Slee Date: Tue, 6 Aug 2013 15:27:07 -0700 Subject: [PATCH] Add rendering of cube frames, trailer, etc. --- _Internals.pde | 71 ++++++++++++++++++++++++++++++++++++++++------- _Mappings.pde | 39 ++++++++++++++++++++++---- code/GLucose.jar | Bin 19179 -> 19334 bytes 3 files changed, 95 insertions(+), 15 deletions(-) diff --git a/_Internals.pde b/_Internals.pde index 88ea2e0..f81e6b2 100644 --- a/_Internals.pde +++ b/_Internals.pde @@ -34,7 +34,7 @@ import rwmidi.*; final int VIEWPORT_WIDTH = 900; final int VIEWPORT_HEIGHT = 700; -int targetFramerate = 45; +int targetFramerate = 60; int startMillis, lastMillis; GLucose glucose; @@ -58,6 +58,8 @@ DebugUI debugUI; // Camera variables float eyeR, eyeA, eyeX, eyeY, eyeZ, midX, midY, midZ; +final float FEET = 12; + void setup() { startMillis = lastMillis = millis(); @@ -154,22 +156,34 @@ void draw() { if (debugMode) { debugUI.maskColors(colors); } - + camera( eyeX, eyeY, eyeZ, midX, midY, midZ, 0, -1, 0 ); - stroke(#333333); - fill(#292929); - float yFloor = -2; + + float trailerWidth = 20*FEET; + float trailerDepth = 8*FEET; + float trailerHeight = 2*FEET; + noStroke(); + fill(#141414); + drawBox(0, -trailerHeight, 0, 0, 0, 0, trailerWidth, trailerHeight, trailerDepth, trailerHeight/2.); + fill(#070707); + stroke(#222222); beginShape(); - vertex(0, yFloor, 0); - vertex(glucose.model.xMax, yFloor, 0); - vertex(glucose.model.xMax, yFloor, glucose.model.zMax); - vertex(0, yFloor, glucose.model.zMax); - endShape(CLOSE); + vertex(0, 0, 0); + vertex(trailerWidth, 0, 0); + vertex(trailerWidth, 0, trailerDepth); + vertex(0, 0, trailerDepth); + endShape(); + noStroke(); + fill(#292929); + for (Cube c : glucose.model.cubes) { + drawCube(c); + } + noFill(); strokeWeight(2); beginShape(POINTS); @@ -182,6 +196,7 @@ void draw() { // 2D Overlay camera(); + noLights(); javax.media.opengl.GL gl= ((PGraphicsOpenGL)g).beginGL(); gl.glClear(javax.media.opengl.GL.GL_DEPTH_BUFFER_BIT); ((PGraphicsOpenGL)g).endGL(); @@ -199,6 +214,42 @@ void draw() { } } +void drawCube(Cube c) { + drawBox(c.x, c.y, c.z, c.rx, c.ry, c.rz, Cube.EDGE_WIDTH, Cube.EDGE_HEIGHT, Cube.EDGE_WIDTH, Strip.CHANNEL_WIDTH); +} + +void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) { + pushMatrix(); + translate(x, y, z); + rotate(rx, 1, 0, 0); + rotate(ry / 180. * PI, 0, -1, 0); + rotate(rz, 0, 0, 1); + for (int i = 0; i < 4; ++i) { + float wid = (i % 2 == 0) ? xd : zd; + + beginShape(); + vertex(0, 0); + vertex(wid, 0); + vertex(wid, yd); + vertex(wid - sw, yd); + vertex(wid - sw, sw); + vertex(0, sw); + endShape(); + beginShape(); + vertex(0, sw); + vertex(0, yd); + vertex(wid - sw, yd); + vertex(wid - sw, yd - sw); + vertex(sw, yd - sw); + vertex(sw, sw); + endShape(); + + translate(wid, 0, 0); + rotate(HALF_PI, 0, -1, 0); + } + popMatrix(); +} + void drawUI() { if (uiOn) { ui.draw(); diff --git a/_Mappings.pde b/_Mappings.pde index 4db2330..2aa4b14 100644 --- a/_Mappings.pde +++ b/_Mappings.pde @@ -26,11 +26,40 @@ class SCMapping implements GLucose.Mapping { cubes[cubeIndex++] = new Cube(0, 2*Cube.EDGE_HEIGHT, -6, 0, 0, 0); cubes[cubeIndex++] = new Cube(-5, 3*Cube.EDGE_HEIGHT, -2, 0, -20, 0); - cubes[cubeIndex++] = new Cube(40, 0, 20, 0, 0, 0); - cubes[cubeIndex++] = new Cube(45, Cube.EDGE_HEIGHT, 10, 0, 20, 0); - cubes[cubeIndex++] = new Cube(40, 2*Cube.EDGE_HEIGHT, 14, 0, 0, 0); - cubes[cubeIndex++] = new Cube(35, 3*Cube.EDGE_HEIGHT, 18, 0, -20, 0); - cubes[cubeIndex++] = new Cube(40, 4*Cube.EDGE_HEIGHT, 13, 0, 0, 0); + cubes[cubeIndex++] = new Cube(40, 5, 20, 0, 0, 0); + cubes[cubeIndex++] = new Cube(45, 5+Cube.EDGE_HEIGHT, 10, 0, 20, 0); + cubes[cubeIndex++] = new Cube(40, 5+2*Cube.EDGE_HEIGHT, 14, 0, 0, 0); + cubes[cubeIndex++] = new Cube(35, 5+3*Cube.EDGE_HEIGHT, 18, 0, -20, 0); + cubes[cubeIndex++] = new Cube(40, 5+4*Cube.EDGE_HEIGHT, 13, 0, 0, 0); + + cubes[cubeIndex++] = new Cube(80, 0, 10, 0, 0, 0); + cubes[cubeIndex++] = new Cube(85, Cube.EDGE_HEIGHT, 0, 0, 20, 0); + cubes[cubeIndex++] = new Cube(80, 2*Cube.EDGE_HEIGHT, 4, 0, 0, 0); + cubes[cubeIndex++] = new Cube(75, 3*Cube.EDGE_HEIGHT, 8, 0, -20, 0); + cubes[cubeIndex++] = new Cube(80, 4*Cube.EDGE_HEIGHT, 3, 0, 0, 0); + + cubes[cubeIndex++] = new Cube(120, 10, 10, 0, 0, 0); + cubes[cubeIndex++] = new Cube(125, 10+Cube.EDGE_HEIGHT, 0, 0, 20, 0); + cubes[cubeIndex++] = new Cube(120, 10+2*Cube.EDGE_HEIGHT, 4, 0, 0, 0); + cubes[cubeIndex++] = new Cube(115, 10+3*Cube.EDGE_HEIGHT, 8, 0, -20, 0); + cubes[cubeIndex++] = new Cube(120, 10+4*Cube.EDGE_HEIGHT, 3, 0, 0, 0); + + cubes[cubeIndex++] = new Cube(160, 0, 30, 0, 0, 0); + cubes[cubeIndex++] = new Cube(165, Cube.EDGE_HEIGHT, 20, 0, 20, 0); + cubes[cubeIndex++] = new Cube(160, 2*Cube.EDGE_HEIGHT, 24, 0, 0, 0); + cubes[cubeIndex++] = new Cube(155, 3*Cube.EDGE_HEIGHT, 28, 0, -20, 0); + cubes[cubeIndex++] = new Cube(160, 4*Cube.EDGE_HEIGHT, 23, 0, 0, 0); + + cubes[cubeIndex++] = new Cube(200, 0, 10, 0, 0, 0); + cubes[cubeIndex++] = new Cube(205, Cube.EDGE_HEIGHT, 0, 0, 20, 0); + cubes[cubeIndex++] = new Cube(200, 2*Cube.EDGE_HEIGHT, 4, 0, 0, 0); + cubes[cubeIndex++] = new Cube(195, 3*Cube.EDGE_HEIGHT, 8, 0, -20, 0); + cubes[cubeIndex++] = new Cube(200, 4*Cube.EDGE_HEIGHT, 3, 0, 0, 0); + + cubes[cubeIndex++] = new Cube(200, 0, 10, 0, 0, 0); + cubes[cubeIndex++] = new Cube(205, Cube.EDGE_HEIGHT, 0, 0, 20, 0); + cubes[cubeIndex++] = new Cube(200, 2*Cube.EDGE_HEIGHT, 4, 0, 0, 0); + cubes[cubeIndex++] = new Cube(195, 3*Cube.EDGE_HEIGHT, 8, 0, -20, 0); if (true) { diff --git a/code/GLucose.jar b/code/GLucose.jar index 52e651b0a1aa363dabb0eccfc7b829acb4adbaf1..19d2e1677ea881ba6630d5fe97bcb835f40c85b4 100644 GIT binary patch delta 4668 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 a{<$|@lL0&{gS3)?A}2J-2?Vffp#K5QdshGe delta 4564 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 -- 2.34.1