if (b[' ']) {  canvas.repaint(); }
    public void display(GLDrawable drawable) {      if (quit) {        return;      }      GL gl = drawable.getGL();      GLU glu = drawable.getGLU();      gl.glMatrixMode(GL.GL_PROJECTION);      gl.glLoadIdentity();      if (doViewAll) {        viewer.viewAll(gl);        doViewAll = false;      }      objectManipXform = objectManip.getTransform();      lightManipXform  = lightManip.getTransform();      if (toggleDepthClampNV) {        if (enableDepthClampNV) {          gl.glEnable(GL.GL_DEPTH_CLAMP_NV);        } else {          gl.glDisable(GL.GL_DEPTH_CLAMP_NV);        }        toggleDepthClampNV = false;      }      if (b[' ']) {        animateForward = true;      }      if (animateForward) {        Model mm = m[curr_model];        mm.frame_num += mm.frame_incr;        if (mm.frame_num >= mm.mod.f.length)          mm.frame_num = 0;        interpolate_frame();        animateForward = false;      }      if (animateBackward) {        Model mm = m[curr_model];        mm.frame_num -= mm.frame_incr;        if (mm.frame_num < 0)          mm.frame_num += mm.mod.f.length;        interpolate_frame();        animateBackward = false;      }      if (hideCurrentModel) {        gl.glNewList(faceDisplayList, GL.GL_COMPILE);        drawMesh(gl, 20, 40);        gl.glEndList();        hideCurrentModel = false;      }      if (toggleWireframe) {        if(b['w'])          gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);        else          gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);      }      if(b['I']) {        // push far plane to infinity        switch (curr_view) {          case CAMERA_VIEW:            viewer.update(gl);            // Undo perspective effects of ExaminerViewer            gl.glMatrixMode(GL.GL_PROJECTION);            gl.glLoadIdentity();            applyInfinitePerspective(gl, viewer);            break;          case SCENE_VIEW:            applyInfinitePerspective(gl, viewer);            // FIXME: do we need more primitives in the ExaminerViewer class?            //            scenecam.apply_inverse_transform();            break;          case CLIP_VIEW:            applyInfinitePerspective(gl, viewer);            // FIXME            //            clipcam.apply_inverse_transform();            gl.glScalef(10,10,-10);            applyInfinitePerspective(gl, viewer);            break;          default:            break;        }      } else {        switch (curr_view) {          case CAMERA_VIEW:            viewer.update(gl);            break;          case SCENE_VIEW:            applyInfinitePerspective(gl, viewer);            // FIXME            //            scenecam.apply_inverse_transform();            break;          case CLIP_VIEW:            applyInfinitePerspective(gl, viewer);            // FIXME            //            clipcam.apply_inverse_transform();            gl.glScalef(10,10,-10);            // FIXME            //            reshaper.apply_projection();            break;          default:            break;        }      }      gl.glMatrixMode(GL.GL_MODELVIEW);      // FIXME      if (b['X']) {        gl.glLoadIdentity();        if(b['I']) {          // FIXME          applyInfinitePerspectiveInverse(gl, viewer);        } else {          // FIXME          //          reshaper.apply_projection_inverse();        }        double[] pos_x = new double[] {-1, 0, 0, 1};        double[] neg_x = new double[] { 1, 0, 0, 1};        double[] pos_y = new double[] { 0,-1, 0, 1};        double[] neg_y = new double[] { 0, 1, 0, 1};        double[] pos_z = new double[] { 0, 0,-1, 1};        double[] neg_z = new double[] { 0, 0, 1, 1};        gl.glClipPlane(GL.GL_CLIP_PLANE0, pos_x);        gl.glClipPlane(GL.GL_CLIP_PLANE1, neg_x);        gl.glClipPlane(GL.GL_CLIP_PLANE2, pos_y);        gl.glClipPlane(GL.GL_CLIP_PLANE3, neg_y);        gl.glClipPlane(GL.GL_CLIP_PLANE4, pos_z);        gl.glClipPlane(GL.GL_CLIP_PLANE5, neg_z);        gl.glEnable(GL.GL_CLIP_PLANE0);        gl.glEnable(GL.GL_CLIP_PLANE1);        gl.glEnable(GL.GL_CLIP_PLANE2);        gl.glEnable(GL.GL_CLIP_PLANE3);        gl.glEnable(GL.GL_CLIP_PLANE4);        gl.glEnable(GL.GL_CLIP_PLANE5);        gl.glLoadIdentity();      }      gl.glPushMatrix();      // FIXME      //      camera.apply_inverse_transform();      //      light.apply_transform();      gl.glMultMatrixf(getData(lightManipXform));      gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, getData(light_position));      gl.glPopMatrix();      gl.glEnable(GL.GL_LIGHT0);      // FIXME      gl.glPushMatrix();      //      gl.glLoadIdentity();      //      camera.apply_inverse_transform();      gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT);      ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters());      ManipManager.getManipManager().render(drawable, gl);      if (!b['R']) {        drawRoom(gl, false);      }      if (!b['m']) {        for (int i = 0; i < num_models; i++)          if (m[i].draw)            drawModel(gl, i, false);      }      if (b['X']) {        gl.glDisable(GL.GL_CLIP_PLANE0);        gl.glDisable(GL.GL_CLIP_PLANE1);        gl.glDisable(GL.GL_CLIP_PLANE2);        gl.glDisable(GL.GL_CLIP_PLANE3);        gl.glDisable(GL.GL_CLIP_PLANE4);        gl.glDisable(GL.GL_CLIP_PLANE5);      }      if (!b['s']) {        for (int i = 0; i < num_models; i++)          if (m[i].draw)            drawShadowVolumeToStencil(gl, i);      }      // Be aware that this can cause some multipass artifacts      // due to invariance issues.      if (b['X']) {        gl.glEnable(GL.GL_CLIP_PLANE0);        gl.glEnable(GL.GL_CLIP_PLANE1);        gl.glEnable(GL.GL_CLIP_PLANE2);        gl.glEnable(GL.GL_CLIP_PLANE3);        gl.glEnable(GL.GL_CLIP_PLANE4);        gl.glEnable(GL.GL_CLIP_PLANE5);      }      if (!b['d']) {        if (!b['R'])          drawRoom(gl, true);        if (!b['m'])          for (int i = 0; i < num_models; i++)            if (m[i].draw)              drawModel(gl, i, true);      }      if(!b['S']) {        for (int i = 0; i < num_models; i++)          if (m[i].draw)            drawPossibleSilhouette(gl, i);      }      if (!b['v']) {        for (int i = 0; i < num_models; i++)          if (m[i].draw)            drawShadowVolumeToColor(gl, i);      }      // Be aware that this can cause some multipass artifacts      // due to invariance issues.      if (b['X']) {        gl.glDisable(GL.GL_CLIP_PLANE0);        gl.glDisable(GL.GL_CLIP_PLANE1);        gl.glDisable(GL.GL_CLIP_PLANE2);        gl.glDisable(GL.GL_CLIP_PLANE3);        gl.glDisable(GL.GL_CLIP_PLANE4);        gl.glDisable(GL.GL_CLIP_PLANE5);      }      drawLight(gl, glu);      gl.glPopMatrix();      // In an "external" viewing mode, show the camera's view volume      // as a yellow wireframe cube or frustum.      if (curr_view != CAMERA_VIEW) {        gl.glPushMatrix();        if (b['I']) {          // FIXME          applyInfinitePerspectiveInverse(gl, viewer);        } else {          // FIXME          //          reshaper.apply_projection_inverse();        }        gl.glColor3f(.75f,.75f,0);        gl.glLineWidth(3);        glut.glutWireCube(gl, 2);        gl.glLineWidth(1);        gl.glPopMatrix();      }    }