public RayTracer(Scene theScene, GL2 _gl, GLU _glu) {
    System.out.println("Init RayTracer");
    gl = _gl;
    glu = _glu;
    scene = theScene;
    lights = scene.lights;

    xMin = scene.camera.viewportLeft + 0.5;
    xMax = scene.camera.viewportRight;
    yMin = scene.camera.viewportBottom + 0.5;
    yMax = scene.camera.viewportTop;

    // Transform into camera coords
    vpWidth = xMax - xMin;
    vpHeight = yMax - yMin;
    widthRatio = (scene.camera.windowRight - scene.camera.windowLeft) / vpWidth;
    heightRatio = (scene.camera.windowTop - scene.camera.windowBottom) / vpHeight;

    // Init the buffer
    viewPort = new DoubleColor[(int) vpWidth + 1][(int) vpHeight + 1];
    for (int i = 0; i < vpWidth; i++)
      for (int j = 0; j < vpHeight; j++) viewPort[i][j] = new DoubleColor(0.0, 0.0, 0.0, 1.0);

    numObjects = scene.objects.size();
    shapes = new PMesh[numObjects];
    spheres = new Sphere[numObjects];

    // Loop through all objects in the scene and store them in the object so we don't need to access
    // it from generic objects
    for (int objNum = 0; objNum < numObjects; objNum++) {
      shapes[objNum] = (PMesh) scene.objects.elementAt(objNum);
      // Fill viewCoords of vertices
      for (PMesh.SurfCell s = shapes[objNum].surfHead; s != null; s = s.next)
        for (PMesh.PolyCell poly = s.polyHead; poly != null; poly = poly.next) {
          Double3D v[] = new Double3D[3];
          int j = 0;

          try {
            poly.viewNorm =
                poly.normal.preMultiplyMatrix(
                    MatrixOps.inverseTranspose(
                        MatrixOps.multMat(scene.camera.viewMat, shapes[objNum].modelMat)));
          } catch (Exception e) {
            System.out.println("Matrix cannot be inverted");
          }

          for (PMesh.VertListCell vert = poly.vert; vert != null; vert = vert.next) {
            // v[j] = shapes[objNum].vertArray.get(vert.vert).viewPos;
            // Short circuit if possible
            // if(calcViewCoords || (v[j].x == v[j].y && v[j].y == v[j].z && v[j].z == 0))
            v[j] =
                shapes[objNum]
                    .vertArray
                    .get(vert.vert)
                    .worldPos
                    .preMultiplyMatrix(shapes[objNum].modelMat);
            v[j] = v[j].preMultiplyMatrix(scene.camera.viewMat);
            shapes[objNum].vertArray.get(vert.vert).viewPos = v[j];
            j++;
          }
        }

      spheres[objNum] = new Sphere(shapes[objNum].boundingSphere);
      // Apply the camera transform the point
      spheres[objNum].center = spheres[objNum].center.preMultiplyMatrix(scene.camera.viewMat);
    }
  }