/** Reallocates and resets all matrices */ public void resetMatrices() { /* Store material for a particular accessed face */ Material faceMaterial = new Material(); int n = scene.getNumFaces(); for (int j = 0; j < 3; j++) { F[j] = new FlexCompRowMatrix(n, n); B[j] = new DenseVector(n); E[j] = new DenseVector(n); // make the matrix the identity... for (int i = 0; i < n; i++) { F[j].set(i, i, 1); /* TODO! Emission for each face /* Initialize face/patch based on whether luminous * if lit, set E to diffuse lighting for each colour * (since surface radiance == diffuse material properties) */ faceMaterial = scene.getObject().getFaceMaterial(i); /* If lit patch, initialize to amount of light based on diffuse parameter */ if (faceMaterial.emission) { E[j].add(i, faceMaterial.kd[j]); // Set light for each colour for each face } } } }
/** * We want to draw the scene using a display list to make it fast when using the IDENT style * (i.e., avoid recomputing all the face colours) * * @param drawable * @param style */ private void draw(GLAutoDrawable drawable, DrawStyle style) { GL gl = drawable.getGL(); if (listID != -1) { gl.glCallList(listID); } else { listID = gl.glGenLists(1); gl.glNewList(listID, GL.GL_COMPILE_AND_EXECUTE); scene.draw(drawable, style); gl.glEndList(); } }
/** * Collects Form Factor and possibly fist bounce Emission data. Note that if you call collect * twice, the form factors will be increased! (i.e., only want to call collect once per hemicube * draw... not collect on draw, unless you simply want to see sparsity) * * @param which * @param collectF * @param collectE */ private void collectData(int which) { /* Find material for the specified face */ Material faceMaterial = scene.getObject().getFaceMaterial(which); for (int i = 0; i < divisions * divisions * 12; i++) { byte r = pixelData[i * 4 + 0]; byte g = pixelData[i * 4 + 1]; byte b = pixelData[i * 4 + 2]; int id = ObjectScene.colourBytesToInt(r, g, b); if (id > 0 && id < scene.getNumFaces()) { // TODO -- Part 2 - Collecting FFs! /* Collect form factors for each face based on * diffuse material (kd), weight (data) */ F[0].add(which, id, -faceMaterial.kd[0] * data[i]); F[1].add(which, id, -faceMaterial.kd[1] * data[i]); F[2].add(which, id, -faceMaterial.kd[2] * data[i]); } } }
/** * Draws the five sides of the hemicube into the provided drawable * * @param drawable * @param which * @param near * @param far * @param bCollect */ public void drawHemiCube( GLAutoDrawable drawable, int which, double near, double far, boolean bCollect) { // TODO - PART 1 - DRAW HEMICUBE! GL gl = drawable.getGL(); GLU glu = new GLU(); /* Return the face based on which parameter */ int[] vertices = scene.getObject().getFace(which); /* Find the center of the face */ /* Center of the face is the average of the three vertices */ /* Using returned list of vertex indices, find the vertices * corresponding to a particular face */ Vertex v1 = scene.getObject().vertexList.get(vertices[0]); Vertex v2 = scene.getObject().vertexList.get(vertices[1]); Vertex v3 = scene.getObject().vertexList.get(vertices[2]); /* Locate center of face */ /* Average of three vertices */ Point3d centerPoint = new Point3d(); centerPoint = new Point3d(v1.p); centerPoint.add(v2.p); centerPoint.add(v3.p); centerPoint.scale(0.33333); /* Set up camera frame */ /* --- Surface normal --- */ /* Declare points of vertex for face */ Point3d p1 = new Point3d(v1.p); Point3d p2 = new Point3d(v2.p); Point3d p3 = new Point3d(v3.p); /* Declare vector u as p2-p1 */ Point3d uVec = new Point3d(p2); uVec.sub(p1); Vector3d u = new Vector3d(uVec); /* Declare vector v as p3-p1 */ Point3d vVec = new Point3d(p3); vVec.sub(p1); Vector3d v = new Vector3d(vVec); /* Make normal vector */ Vector3d norm = new Vector3d(); norm.cross(u, v); /* --- Vectors Orthonormal to Normal --- */ Point3d vec1pt = new Point3d(p1); vec1pt.sub(p2); Vector3d vec1 = new Vector3d(vec1pt); vec1.cross(vec1, norm); // Cross surface normal with vec1 to get orthogonal vector Vector3d vec2 = new Vector3d(); vec2.cross( norm, vec1); // Cross product of surface normal with new vector vec1 to get 2nd orthogonal vector /* Make unit vectors */ norm.normalize(); vec1.normalize(); vec2.normalize(); /* Set up the five different frustums, and stitch together using viewPort */ /* Viewport to set up the view of the scene */ /* ----- FRONT FACE ----- */ gl.glPushMatrix(); gl.glViewport(0, 0, drawable.getWidth(), drawable.getHeight() / 3); /* Set up frustums for this face */ gl.glMatrixMode(gl.GL_PROJECTION); gl.glLoadIdentity(); gl.glFrustum(-near, near, -near, near, near, far); /* Position camera at center of specified patch (which) */ gl.glMatrixMode(gl.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt( centerPoint.x, centerPoint.y, centerPoint.z, centerPoint.x + norm.x, centerPoint.y + norm.y, centerPoint.z + norm.z, centerPoint.x + vec1.x, centerPoint.y + vec1.y, centerPoint.z + vec1.z); /* Draw the frustum to screen */ draw(drawable, scene.drawStyle.IDENT); gl.glPopMatrix(); /* ----- BOTTOM FACE ----- */ gl.glPushMatrix(); gl.glViewport(0, drawable.getHeight() / 3, drawable.getWidth(), drawable.getHeight() / 6); gl.glMatrixMode(gl.GL_PROJECTION); gl.glLoadIdentity(); gl.glFrustum(-near, near, 0, near, near, far); /* Position camera at center of specified patch (which) */ gl.glMatrixMode(gl.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt( centerPoint.x, centerPoint.y, centerPoint.z, centerPoint.x + (-vec1.x), centerPoint.y + (-vec1.y), centerPoint.z + (-vec1.z), centerPoint.x + norm.x, centerPoint.y + norm.y, centerPoint.z + norm.z); /* Draw the frustum to screen */ draw(drawable, scene.drawStyle.IDENT); gl.glPopMatrix(); /* ----- TOP FACE ----- */ gl.glPushMatrix(); gl.glViewport( 0, (drawable.getHeight() / 3) + (drawable.getHeight() / 6), drawable.getWidth(), drawable.getHeight() / 6); gl.glMatrixMode(gl.GL_PROJECTION); gl.glLoadIdentity(); gl.glFrustum(-near, near, -near, 0, near, far); /* Position camera at center of specified patch (which) */ gl.glMatrixMode(gl.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt( centerPoint.x, centerPoint.y, centerPoint.z, centerPoint.x + vec1.x, centerPoint.y + vec1.y, centerPoint.z + vec1.z, centerPoint.x - norm.x, centerPoint.y - norm.y, centerPoint.z - norm.z); /* Draw the frustum to screen */ draw(drawable, scene.drawStyle.IDENT); gl.glPopMatrix(); /* ----- LEFT FACE ----- */ gl.glPushMatrix(); gl.glViewport( 0, (drawable.getHeight() / 3) + 2 * (drawable.getHeight() / 6), drawable.getWidth(), drawable.getHeight() / 6); gl.glMatrixMode(gl.GL_PROJECTION); gl.glLoadIdentity(); gl.glFrustum(0, near, -near, near, near, far); /* Position camera at center of specified patch (which) */ gl.glMatrixMode(gl.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt( centerPoint.x, centerPoint.y, centerPoint.z, centerPoint.x + vec2.x, centerPoint.y + vec2.y, centerPoint.z + vec2.z, centerPoint.x + vec1.x, centerPoint.y + vec1.y, centerPoint.z + vec1.z); /* Draw the frustum to screen */ draw(drawable, scene.drawStyle.IDENT); gl.glPopMatrix(); /* ----- RIGHT FACE ----- */ gl.glPushMatrix(); gl.glViewport( 0, (drawable.getHeight() / 3) + 3 * (drawable.getHeight() / 6), drawable.getWidth(), drawable.getHeight() / 6); gl.glMatrixMode(gl.GL_PROJECTION); gl.glLoadIdentity(); gl.glFrustum(near, 0, -near, near, near, far); /* Position camera at center of specified patch (which) */ gl.glMatrixMode(gl.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt( centerPoint.x, centerPoint.y, centerPoint.z, centerPoint.x + (-vec2.x), centerPoint.y + (-vec2.y), centerPoint.z + (-vec2.z), centerPoint.x + vec1.x, centerPoint.y + vec1.y, centerPoint.z + vec1.z); /* Draw the frustum to screen */ draw(drawable, scene.drawStyle.IDENT); gl.glPopMatrix(); /* ---- End Frustums ---- */ // if collecting the form factors, then read back and process the data if (bCollect) { gl.glFlush(); gl.glFinish(); gl.glReadPixels( 0, 0, divisions * 2, divisions * 6, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixelDataBuffer); collectData(which); } }