public boolean load(String filepath) throws FileNotFoundException {
    fileType = "OBJ"; // Set the file type to OBJ in case we ever want to later identify its source
    filePath =
        Utils.dirFromPath(
            filepath); // The fileName is the ENTIRE path to the file (including the filename)
    objName = Utils.fileFromPath(filepath); // The objName is strictly the filename to begin with
    readVerts(filepath); // Read all of the vertices from the file
    // readTexVerts(filepath);	// Read all of the texture vertices (if any) from the file)

    // Read any materials from the file
    // If no materials are loaded, a default one will be assigned
    if (readMaterials(filepath) == -1) {
      System.out.println("Not all materials could be loaded for: " + filepath);
      System.out.println("Surfaces with no materials will be assigned a default material");
    } // end if

    readSurfaces(filepath); // Read all surface information
    countPolyVerts(); // Calculates how many vertices are in each polygon
    calcPolyNorms(); // Calculate all polygon normals (never rely on the file itself)
    calcVertNorms(); // Calculate all vertex normals based on polygon normals
    boundingSphere = calcBoundingSphere(); // Calculate the bounding sphere for raytracing

    active = true; // We've just created an object...so make it active!
    next = null; // Next object in the linked list is null

    // This simply loads the modelMat with an identity matrix.
    modelMat = MatrixOps.newIdentity();

    // System.out.println("\nObject loaded!\n");
    loadBuffers();
    return true;
  } // end method load
  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);
    }
  }