public class Sphere { int M, N; // mesh dimension final int X = 0, Y = 1, Z = 2, U = 3, V = 4; ImageBuffer imgBuf; double[][][] txtBuf; double mesh[][][]; double[] center = {0, 0, 0}; Material material; double[][] color = {{0.2,0.6,0.2},{0.2,0.6,0.2},{0.2,0.6,0.2}}; public Sphere(int m, int n) { M = m; N = n; mesh = new double[M][N][5]; fillMesh(); } public void printMesh() { System.out.print("\n"); for (int i = 0; i < mesh.length; i++) { System.out.print("\n"); for (int j=0; j < mesh[i].length; j++) System.out.print("{" + mesh[i][j][X] + ", " + mesh[i][j][Y] + ", " + mesh[i][j][Z] + "}"); } System.out.print("\n"); } public void reset() { center[0] = 0; center[1] = 0; center[2] = 0; setImageBuffer(null); setTextureBuffer(null); fillMesh(); }; public void setTextureBuffer(double[][][] textureBuffer) { txtBuf = textureBuffer; } public void setImageBuffer(ImageBuffer imageBuffer) { imgBuf = imageBuffer; } public void setMaterial(Material m) { material = m.copy(); } public void bufferTo(double[][] zBuffer, double[][][] frameBuffer, Light[] lights, double focalLength) { //System.out.println("Center is {" + center[0] + ", " + center[1] + ", " + center[2] + "}"); // Go over all vertices and make triangles for (int i = 0; i < M - 1; i++) for (int j = 0; j < N - 1; j++) { //System.out.println("vertices for tri1: { {" + mesh[i][j][0] + ", " + mesh[i][j][1] + ", " + mesh[i][j][2] + "}, {" + mesh[i+1][j][0] + ", " + mesh[i+1][j][1] + ", " + mesh[i+1][j][2] + "}, {" + mesh[i+1][j+1][0] + ", " + mesh[i+1][j+1][1] + ", " + mesh[i+1][j+1][2] + "} }"); //for (int k = 0; k < mesh[i][j].length; k++) { //System.out.println("point["+ i + "][" + j + "][" + k + "] = " + mesh[i][j][k]); //} Triangle triangle1 = makeTriangle(mesh[i][j], mesh[i+1][j], mesh[i+1][j+1]); //System.out.println("vertices for tri2: { {" + mesh[i][j][0] + ", " + mesh[i][j][1] + ", " + mesh[i][j][2] + "}, {" + mesh[i+1][j+1][0] + ", " + mesh[i+1][j+1][1] + ", " + mesh[i+1][j+1][2] + "}, {" + mesh[i][j+1][0] + ", " + mesh[i][j+1][1] + ", " + mesh[i][j+1][2] + "} }"); Triangle triangle2 = makeTriangle(mesh[i][j], mesh[i+1][j+1], mesh[i][j+1]); triangle1.perspectiveTransform(focalLength); //System.out.println("perspective Transformed"); //triangle1.print(); triangle2.perspectiveTransform(focalLength); triangle1.viewportTransform(zBuffer.length, zBuffer[0].length); //System.out.println("viewport Transformed"); //triangle1.print(); triangle2.viewportTransform(zBuffer.length, zBuffer[0].length); //System.out.println("PRE calculateColors()"); //triangle1.printColors(); triangle1.calculateColors(lights); triangle2.calculateColors(lights); //System.out.println("POST calculateColors()"); //triangle1.printColors(); //triangle1.setPointColors(color); //triangle2.setPointColors(color); //System.out.println("buffer triangle 1"); triangle1.bufferTo(zBuffer, frameBuffer); //System.out.println("buffer triangle 2"); triangle2.bufferTo(zBuffer, frameBuffer); } } private Triangle makeTriangle(double[] p0, double[] p1, double[] p2) { double[][] vertices = { {p0[0], p0[1], p0[2]}, {p1[0], p1[1], p1[2]}, {p2[0], p2[1], p2[2]} }; double[][] normals = { {p0[0] - center[0], p0[1] - center[1], p0[2] - center[2] }, {p1[0] - center[0], p1[1] - center[1], p1[2] - center[2] }, {p2[0] - center[0], p2[1] - center[1], p2[2] - center[2] } }; double[][] uv = { // do 1 - V so image is not upside down {p0[U], 1 - p0[V]}, {p1[U], 1 - p1[V]}, {p2[U], 1 - p2[V]} }; Triangle triangle = new Triangle(); //System.out.println("vertices for tri: { {" + p0[0] + ", " + p0[1] + ", " + p0[2] + "}, {" + p1[0] + ", " + p1[1] + ", " + p1[2] + "}, {" + p2[0] + ", " + p2[1] + ", " + p2[2] + "} }"); //System.out.println("normals for tri: { {" + normals[0][0] + ", " + normals[0][1] + ", " + normals[0][2] + "}, {" + normals[1][0] + ", " + normals[1][1] + ", " + normals[1][2] + "}, {" + normals[2][0] + ", " + normals[2][1] + ", " + normals[2][2] + "} }"); triangle.setVertices(vertices); triangle.setNormals(normals); triangle.setUV(uv); triangle.setImageBuffer(imgBuf); triangle.setTextureBuffer(txtBuf); triangle.setAmbientColor(material.getAmbientColor()); triangle.setDiffuseColor(material.getDiffuseColor()); triangle.setSpecularColor(material.getSpecularColor()); triangle.setSpecularPower(material.specularPower); return triangle; } public void transformedBy(Matrix3D t) { double[][][] transformed = new double[M][N][5]; double[] point = new double[3]; double[] newCenter; for (int i = 0; i < transformed.length; i++) for (int j = 0; j < transformed[i].length; j++) { point = t.transform(mesh[i][j]); transformed[i][j][X] = point[X]; transformed[i][j][Y] = point[Y]; transformed[i][j][Z] = point[Z]; transformed[i][j][U] = i / (M - 1.0); transformed[i][j][V] = j / (N - 1.0); } newCenter = t.transform(center); center = newCenter; mesh = transformed; } private void fillMesh() { for (int i = 0; i < M; i++) { //System.out.println(); for (int j = 0; j < N; j++) { double u = i / (M - 1.0); double v = j / (N - 1.0); mesh[i][j][X] = x(u, v); mesh[i][j][Y] = y(u, v); mesh[i][j][Z] = z(u, v); mesh[i][j][U] = u; mesh[i][j][V] = v; //System.out.print("{" + mesh[i][j][X] + ", " + mesh[i][j][Y] + ", " + mesh[i][j][Z] + ", " + mesh[i][j][U] + ", " + mesh[i][j][V] + "} "); //System.out.print("{" + mesh[i][j][U] + ", " + mesh[i][j][V] + "} "); } //System.out.println(); } } private double x(double u, double v) { return ( Math.cos(2 * Math.PI * u) * Math.cos(Math.PI * v - (Math.PI / 2))); } private double y(double u, double v) { return (Math.sin(Math.PI * v - (Math.PI / 2))); } private double z(double u, double v) { return ( -1 * Math.sin(2 * Math.PI * u) * Math.cos(Math.PI * v - (Math.PI / 2))); } }