import java.awt.*; public class DrawMesh extends PixApplet { int w, h; // width/height of applet window int M = 30, N = 30; int mouseX =0, mouseY = 0, phi = 0, theta = 0; double focalLength = -3; ImageBuffer imageBuffer; boolean damageFlag; boolean editTexture = false; int numShapes = 3; int numTextures = 3; int shapeNum = 0; int textureNum = 0; int editedPoint = -16; final double[] bgColor = {0.3, 0.3, 0.3}; double[][] zBuffer; double[][][] frameBuffer; double[][][] textureBuffer; double[][] gx = { { -1.0, -0.5, 0.5, 1.0}, { -1.0, -0.5, 0.5, 1.0}, { -1.0, -0.5, 0.5, 1.0}, { -1.0, -0.5, 0.5, 1.0} }; double[][] gy = { { 1.0, 1.0, 1.0, 1.0}, { 0.5, 0.5, 0.5, 0.5}, { -0.5, -0.5, -0.5, -0.5}, { -1.0, -1.0, -1.0, -1.0} }; double[][] gz = { { -0.0, 0.0, -0.0, 0.0}, { -0.0, 0.0, -0.0, 0.0}, { -0.0, 0.0, -0.0, 0.0}, { -0.0, 0.0, -0.0, 0.0} }; Light light1 = new Light( 1, 1, 2, 0.6, 0.6, 0.1); Light light2 = new Light(-1, -1, 1, 0.2, 1.0, 0.4); Light light3 = new Light( 0, 0, 1, 0.5, 0.2, 1.0); Light[] lights = {light1};// , light2, light3}; Material sphereMaterial1= new Material(0.3, 0.3, 0.6, 0.2, 0.2, 0.3, 0.4, 0.4, 1.0, 4); Material sphereMaterial2= new Material(0.6, 0.3, 0.3, 0.3, 0.2, 0.2, 1.0, 0.4, 0.4, 4); Material tubeMaterial = new Material(0.3, 0.6, 0.3, 0.3, 0.4, 0.3, 0.4, 1.0, 0.4, 4); Material cubeMaterial = new Material(0.6, 0.6, 0.6, 0.2, 0.2, 0.2, 1.0, 1.0, 1.0, 4); Material patchMaterial = new Material(0.4, 0.8, 0.5, 0.2, 0.6, 0.3, 1.0, 1.0, 1.0, 4); Material blankMaterial = new Material(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 4); Material whiteMaterial = new Material(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 4); Material redMaterial = new Material(1.0, 0.0, 0.0, 0.8, 0.4, 0.4, 0.0, 0.0, 0.0, 4); Material earthMaterial = new Material(0.3, 0.6, 0.6, 0.2, 0.4, 0.4, 0.1, 0.2, 0.3, 2); //Material sphereMaterial1= new Material(0.3, 0.3, 0.6, 0.2, 0.2, 0.3, 0.2, 0.2, 0.8, 2); //Material sphereMaterial2= new Material(0.6, 0.3, 0.3, 0.3, 0.2, 0.2, 0.8, 0.1, 0.1, 1.5); //Material tubeMaterial = new Material(0.3, 0.6, 0.3, 0.3, 0.4, 0.3, 0.2, 0.8, 0.0, 2); //Material cubeMaterial = new Material(0.6, 0.6, 0.6, 0.2, 0.2, 0.2, 0.8, 0.8, 0.0, 2); SplinePatch patch = new SplinePatch(M, N, gx, gy, gz); Sphere sphere1 = new Sphere(M, N); Sphere sphere2 = new Sphere(M, N); Cube cube1 = new Cube(); Disc disc1 = new Disc(M); Tube tube = new Tube(M); Cylinder cylinder = new Cylinder(M); MatrixStack stack = new MatrixStack(); Matrix3D t = new Matrix3D(); public void init() { super.init(); w = bounds().width; // FIND OUT HOW BIG THE APPLET WINDOW IS h = bounds().height; zBuffer = new double[w][h]; frameBuffer = new double[w][h][3]; textureBuffer = new double[w][h][3]; clearTexture(); Triangle.switchTexture(false); String urlName = getParameter("image"); imageBuffer = new ImageBuffer(urlName, this); System.out.println("w, h: " + imageBuffer.width + ", " + imageBuffer.height); } public void setPix(int frame) { if (damageFlag) { damage = true; } System.out.println("drawmesh: frame " + frame); if (!editTexture) display3D(); else displayTexture(); // display frame buffer int n = 0; for (int j = 0 ; j < H ; j++) // LOOP OVER IMAGE ROWS for (int i = 0 ; i < W ; i++) { // LOOP OVER IMAGE COLUMNS pix[n++] = pack(Math.max(0,Math.min(255,(int)(255 * frameBuffer[i][j][0]))), Math.max(0,Math.min(255,(int)(255 * frameBuffer[i][j][1]))), Math.max(0,Math.min(255,(int)(255 * frameBuffer[i][j][2])))); } } private void displayTexture(){ //copy texturebuffer to framebuffer for (int i = 0; i < frameBuffer.length; i++) { for (int j = 0; j < frameBuffer[i].length; j++) { frameBuffer[i][j][0] = textureBuffer[i][j][0]; frameBuffer[i][j][1] = textureBuffer[i][j][1]; frameBuffer[i][j][2] = textureBuffer[i][j][2]; } } } private void display3D() { // set the framebuffer to bgcolor for (int i = 0; i < frameBuffer.length; i++) { for (int j = 0; j < frameBuffer[i].length; j++) { frameBuffer[i][j][0] = bgColor[0]; frameBuffer[i][j][1] = bgColor[1]; frameBuffer[i][j][2] = bgColor[2]; zBuffer[i][j] = Double.MIN_VALUE; } } push(); t.translate(0, 0, -3); t.rotateX(phi * Math.PI / 180); t.rotateY(theta * Math.PI / 180); push(); // AFFECT ALL ITEMS IN WORLD if (shapeNum == 0) { sphere1.reset(); if (textureNum == 1) sphere1.setImageBuffer(imageBuffer); else if (textureNum == 2) sphere1.setTextureBuffer(textureBuffer); sphere1.setMaterial(earthMaterial); sphere1.transformedBy(t); sphere1.bufferTo(zBuffer, frameBuffer, lights, focalLength); } else if (shapeNum == 1) { if (editedPoint >= 0) { push(); int row = editedPoint / 4; int col = editedPoint % 4; t.translate(gx[row][col], gy[row][col], gz[row][col]); t.scale(0.08, 0.08, 0.08); sphere1.reset(); sphere1.setMaterial(redMaterial); sphere1.transformedBy(t); sphere1.bufferTo(zBuffer, frameBuffer, lights, focalLength); pop(); } patch.setGX(gx); patch.setGY(gy); patch.setGZ(gz); patch.reset(); if (textureNum == 1) patch.setImageBuffer(imageBuffer); else if (textureNum == 2) patch.setTextureBuffer(textureBuffer); patch.setMaterial(blankMaterial); patch.transformedBy(t); patch.bufferTo(zBuffer, frameBuffer, lights, focalLength); } else if (shapeNum == 2) { tube.reset(); if (textureNum == 1) tube.setImageBuffer(imageBuffer); else if (textureNum == 2) tube.setTextureBuffer(textureBuffer); tube.setMaterial(blankMaterial); tube.transformedBy(t); tube.bufferTo(zBuffer, frameBuffer, lights, focalLength); } pop(); pop(); } private void push() { stack.push(); t = stack.get(); } private void pop() { stack.pop(); t = stack.get(); } private void clearTexture() { for (int i = 0; i < textureBuffer.length; i++) for (int j = 0; j < textureBuffer[i].length; j++) for (int k = 0; k < 3; k++) textureBuffer[i][j][k] = 1; } public boolean mouseDown(Event e, int x, int y) { if (!editTexture) { mouseX = x; mouseY = y; } else { textureBuffer[x][y][0] = 0; textureBuffer[x][y][1] = 0; textureBuffer[x][y][2] = 0; } return true; } public boolean mouseDrag(Event e, int x, int y) { if (!editTexture) { theta = theta + x - mouseX; phi = phi + y - mouseY; mouseX = x; mouseY = y; damage = true; } else { textureBuffer[x][y][0] = 0; textureBuffer[x][y][1] = 0; textureBuffer[x][y][2] = 0; } return true; } public void editNextPoint() { if (editedPoint >= 0) { editedPoint++; editedPoint = editedPoint % 16; System.out.println("edited point is " + editedPoint ); damage = true; } } public void movePoint(int axis, double scale) { if (editedPoint >= 0) { System.out.println("axis: " + axis + "; scale: " + scale); int row = editedPoint / 4; int col = editedPoint % 4; double adjustment = 0.1; adjustment *= scale; if (axis == 0) gx[row][col] += adjustment; else if (axis == 1) gy[row][col] += adjustment; else if (axis == 2) gz[row][col] += adjustment; damage = true; } } public boolean keyDown(Event e, int key) { System.out.println("key is " + key); switch (key) { case ' ': editNextPoint(); break; case '+': movePoint(2, 1); break; case '-': movePoint(2, -1); break; case 1004: //UP movePoint(1, 1); break; case 1005: //DOWN movePoint(1, -1); break; case 1006: //LEF movePoint(0, -1); break; case 1007: // Right movePoint(0, 1); break; case 't': textureNum++; textureNum = textureNum % numTextures; if (textureNum > 0) Triangle.switchTexture(true); else Triangle.switchTexture(false); damageFlag = true; break; case 'f': focalLength--; damageFlag = true; break; case 'g': if (focalLength < -1) { focalLength++; damageFlag = true; } break; case 's': shapeNum++; shapeNum = shapeNum % numShapes; damageFlag = true; break; case 'e': if (editedPoint < 0) editedPoint += 16; else editedPoint -= 16; break; case 'd': editTexture = editTexture ? false : true; damageFlag = true; break; case 'c': if (editTexture) clearTexture(); break; case '0': Triangle.setTextureRepeat(Triangle.textureRepeatLength * 10); damageFlag = true; break; case '1': Triangle.setTextureRepeat(1); damageFlag = true; break; case '2': Triangle.setTextureRepeat(2); damageFlag = true; break; case '3': Triangle.setTextureRepeat(3); damageFlag = true; break; case '4': Triangle.setTextureRepeat(4); damageFlag = true; break; case '5': Triangle.setTextureRepeat(5); damageFlag = true; break; case '6': Triangle.setTextureRepeat(6); damageFlag = true; break; case '7': Triangle.setTextureRepeat(7); damageFlag = true; break; case '8': Triangle.setTextureRepeat(8); damageFlag = true; break; case '9': Triangle.setTextureRepeat(9); damageFlag = true; break; } return true; } }