import damkjer.ocd.*; import ddf.sds.*; int currCube; CompositeMesh cubed; color cubeColor; Mesh smoothCubed; CatmullClark sds; Camera cam; boolean drawSmoothCubed = false; boolean drawWireFrame = true; static final int SCALE = 0; static final int ROTX = 1; static final int ROTY = 2; static final int ROTZ = 3; int mode = SCALE; /** * Hold down the LEFT mouse button and move the mouse to rotate around the currently selected (red) cube.
* Hold down the RIGHT mouse button and move the mouse up and down to zoom in and out on the currently selected cube.
* Press t to toggle between the cube mesh and the subdivided mesh.
* Press w to toggle the wireframe cubes on and off. * Press d to move to the previous cube in the structure, press f to move to the next.
* Note: the order of traversal will be the order in which they were created and NOT necessarily the order in which they appear.
*
* When adding a cube, it will be added next to the indicated side of the currently selected cube. * 8 is +Y, 2 is -Y, 4 is -X, 6 is +X, 9 is -Z, 3 is +Z.
* The newly added cube will become the currently selected cube.
*
* Use the arrow keys to move the currently selected cube along the X and Y axes, * use the o and l keys to move along the Z axis.
* Note that the camera will remain aimed at the cube as you move it.
* The [ and ] keys to change the currently selected cube's scale or rotation, depending on the current mode.
* ] increases the scale or rotates by a positive angle, [ decreses scale or rotates by a negative angle.
* z switches to scaling mode, x switches to X-rotation mode, c switches to Y-rotation mode, * and v switches to Z-rotation mode.
* The current mode is always displayed in the upper right hand corner of the applet. */ void setup() { size(800, 600, P3D); cubeColor = color(0, 128, 255); Mesh cube = MeshMaker.makeCube(10, cubeColor); cubed = new CompositeMesh(cube); currCube = 0; sds = new CatmullClark(); cam = new Camera(this, 20, -70, 160, 0, 0, 0); resubdivide(); textFont(createFont("Arial", 20)); } void draw() { background(0); noStroke(); lights(); cam.feed(); // coord axes stroke(0, 255, 0, 128); fill(0, 255, 0, 128); line(-200, 0, 0, 200, 0, 0); line(0, -200, 0, 0, 200, 0); line(0, 0, -200, 0, 0, 200); text("+X", 100, 0, 0); text("-X", -100, 0, 0); text("+Y", 0, -100, 0); text("-Y", 0, 100, 0); text("+Z", 0, 0, 100); text("-Z", 0, 0, -100); noStroke(); if ( drawSmoothCubed && smoothCubed != null ) { smoothCubed.draw(this); } else { cubed.draw(this); } for(int i = 0; drawWireFrame && i < cubed.numMesh(); i++) { if ( currCube == i ) cubed.getMesh(i).drawWireFrame(this, color(255, 0, 0)); else cubed.getMesh(i).drawWireFrame(this, color(255)); } // reset the camera and perspective for text overlay camera(); perspective(); hint(DISABLE_DEPTH_TEST); fill(160); text("Editing Mode: " + modeString(), 10, 30); text("Use '[' to decrement, ']' to increment.", 10, 60); noHint(DISABLE_DEPTH_TEST); } String modeString() { switch(mode) { case SCALE: return "Scale"; case ROTX: return "Rotate X"; case ROTY: return "Rotate Y"; case ROTZ: return "Rotate Z"; } return "?????"; } void mouseDragged() { if ( mouseButton == LEFT ) { cam.tumble(radians(mouseX - pmouseX), radians(mouseY - pmouseY)); } if ( mouseButton == RIGHT ) { cam.zoom(radians(mouseY - pmouseY)/2); } } void keyPressed() { if ( keyCode == RIGHT ) { cubed.getMesh(currCube).translate(5, 0, 0); resubdivide(); } if ( keyCode == LEFT ) { cubed.getMesh(currCube).translate(-5, 0, 0); resubdivide(); } if ( keyCode == UP ) { cubed.getMesh(currCube).translate(0, -5, 0); resubdivide(); } if ( keyCode == DOWN ) { cubed.getMesh(currCube).translate(0, 5, 0); resubdivide(); } if ( key == 'o' ) { cubed.getMesh(currCube).translate(0, 0, 5); resubdivide(); } if ( key == 'l' ) { cubed.getMesh(currCube).translate(0, 0, -5); resubdivide(); } if ( key == ']' ) { Mesh m = cubed.getMesh(currCube); switch (mode) { case SCALE: m.scale(1.2); break; case ROTX: m.rotateX(0.1); break; case ROTY: m.rotateY(0.1); break; case ROTZ: m.rotateZ(0.1); break; } resubdivide(); } if ( key == '[' ) { Mesh m = cubed.getMesh(currCube); switch (mode) { case SCALE: m.scale(0.8); break; case ROTX: m.rotateX(-0.1); break; case ROTY: m.rotateY(-0.1); break; case ROTZ: m.rotateZ(-0.1); break; } resubdivide(); } } void keyReleased() { if ( key == 'z' ) { mode = SCALE; println("Now in scaling mode."); } if ( key == 'x' ) { mode = ROTX; println("Now in X-rotation mode."); } if ( key == 'c' ) { mode = ROTY; println("Now in Y-rotation mode."); } if ( key == 'v' ) { mode = ROTZ; println("Now in Z-rotation mode."); } if ( key == 'f' ) { currCube += 1; currCube %= cubed.numMesh(); Mesh c = cubed.getMesh(currCube); cam.aim(c.center.x, c.center.y, c.center.z); } if ( key == 'd' ) { currCube -= 1; if ( currCube < 0 ) currCube = cubed.numMesh()-1; Mesh c = cubed.getMesh(currCube); cam.aim(c.center.x, c.center.y, c.center.z); } if ( key == 'w' ) { drawWireFrame = !drawWireFrame; } if ( key == 't' ) { drawSmoothCubed = !drawSmoothCubed; } if ( key == '2' ) { Mesh newCube = MeshMaker.makeCube(10, cubeColor); Mesh cCube = cubed.getMesh(currCube); newCube.translate(cCube.center.x, cCube.center.y + cCube.scale + 20, cCube.center.z); if ( cubed.addMesh(newCube, cCube) ) { resubdivide(); aimCam(); } } if ( key == '8' ) { Mesh newCube = MeshMaker.makeCube(10, cubeColor); Mesh cCube = cubed.getMesh(currCube); newCube.translate(cCube.center.x, cCube.center.y - cCube.scale - 20, cCube.center.z); if ( cubed.addMesh(newCube, cCube) ) { resubdivide(); aimCam(); } } if ( key == '6' ) { Mesh newCube = MeshMaker.makeCube(10, cubeColor); Mesh cCube = cubed.getMesh(currCube); newCube.translate(cCube.center.x + cCube.scale + 20, cCube.center.y, cCube.center.z); if ( cubed.addMesh(newCube, cCube) ) { resubdivide(); aimCam(); } } if ( key == '4' ) { Mesh newCube = MeshMaker.makeCube(10, cubeColor); Mesh cCube = cubed.getMesh(currCube); newCube.translate(cCube.center.x - cCube.scale - 20, cCube.center.y, cCube.center.z); if ( cubed.addMesh(newCube, cCube) ) { resubdivide(); aimCam(); } } if ( key == '9' ) { Mesh newCube = MeshMaker.makeCube(10, cubeColor); Mesh cCube = cubed.getMesh(currCube); newCube.translate(cCube.center.x, cCube.center.y, cCube.center.z - cCube.scale - 20); if ( cubed.addMesh(newCube, cCube) ) { resubdivide(); aimCam(); } } if ( key == '3' ) { Mesh newCube = MeshMaker.makeCube(10, cubeColor); Mesh cCube = cubed.getMesh(currCube); newCube.translate(cCube.center.x, cCube.center.y, cCube.center.z + cCube.scale + 20); if ( cubed.addMesh(newCube, cCube) ) { resubdivide(); aimCam(); } } } void aimCam() { currCube = cubed.numMesh() - 1; Mesh c = cubed.getMesh(currCube); cam.aim(c.center.x, c.center.y, c.center.z); } void resubdivide() { Mesh c = cubed.getMesh(currCube); cam.aim(c.center.x, c.center.y, c.center.z); cubed.mixDown(); smoothCubed = sds.subdivide(cubed, 3); }