/* FUNCTION positive_boundingbox 
This function will translate the mesh using the 3D translation function in order to have a bounding box in the positive part of the axis (x,y,z)
*/
void positive_boundingbox( pMesh mesh , pPoint point)
{
	double xmin , ymin, zmin ;
	int i ;
	/* First of all we have to determine the length of the translation */
	/* so we determine the bounding box */
	xmin = point_min ( mesh , 'x');
	ymin = point_min ( mesh , 'y');
	zmin = point_min ( mesh , 'z');
	
	if ( xmin < 0 || ymin < 0 || zmin < 0 ) 
	{
		
		/* now we translate */
		translation3D(mesh, fabs(xmin), fabs(ymin), fabs(zmin));
		
	
		/* and the point */
		point->c[0] = (point->c[0] + fabs(xmin))/10 ;
		point->c[1] = (point->c[1] + fabs(ymin))/10 ;
		point->c[2] = (point->c[2] + fabs(zmin))/10 ;
		
		
		for ( i = 1; i <=  mesh->np ; i++ )
		{
	
			mesh->point[i].c[0] = mesh->point[i].c[0] /10 ;
			mesh->point[i].c[1] = mesh->point[i].c[1] /10 ;
			mesh->point[i].c[2] = mesh->point[i].c[2] /10 ;
		} 
	}
}
Beispiel #2
0
void RaceScene::DrawObjects(GeometryShader * curShade) {
	//Track/City
	sweep->renderWithDisplayList(*curShade,50, true, 0.3,20);

	//Vehicle Location
	vec3 vehLoc = vehicle->worldSpacePos();

	//Put matrices together for smaller stack size
	mat4 transformation = vehicle->orientationBasis() *
		translation3D(vehLoc).transpose();

	pushMat4(transformation);
	vehicle->draw(curShade); 
	popTransform();
}
Beispiel #3
0
void Scene::parsefile (FILE *fp) {
  char line[1000], command[1000] ; // Very bad to prefix array size :-)
  vec3** verts = NULL;
  int curvert = 0;
  int maxverts;

  vertnorm* vertnorms = NULL;
  int curvertnorm = 0;
  int maxvertnorms;

  Color curDiffuse = Color(vec3(0, 0, 0));
  Color curSpecular = Color(vec3(0, 0, 0));
  Color curEmission = Color(vec3(0, 0, 0));
  double curShininess = 0.0;
  Color black = Color(0, 0, 0);

  //  int sizeset = 0 ;

  //  initdefaults() ;
  
  while (!feof(fp)) {
    fgets(line,sizeof(line),fp) ;
    if (feof(fp)) break ;
    if (line[0] == '#') continue ; // Comment lines
    
    int num = sscanf(line, "%s", command) ;
    if (num != 1) continue ; // Blank line etc.

    // Now, we simply parse the file by looking at the first line for the 
    // various commands
    
    /**************        CAMERA LOCATION **********/
  
    if (!strcmp(command, "camera")) {
      double lookfrom[3], lookat[3], up[3], _fov ;
      int num = sscanf(line, "%s %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", 
					   command, lookfrom, lookfrom+1, lookfrom+2, 
					   lookat, lookat+1, lookat+2, up, up+1, up+2, &_fov) ;
      if (num != 11) {
		fprintf(stderr, "camera from[3] at[3] up[3] fov\n") ;
		exit(1) ;
      }

      assert(!strcmp(command,"camera")) ;

	  Scene::cameraPos = vec3(lookfrom[0], lookfrom[1], lookfrom[2]);
	  Scene::cameraUp = vec3(up[0], up[1], up[2]);
	  Scene::cameraLookAt = vec3(lookat[0], lookat[1], lookat[2]);
	  Scene::fov = _fov;
    }

    else if (!strcmp(command, "lenssize")) {
      double temp;
	  int num = sscanf(line, "%s %lf", command, &temp) ;
	  assert(num == 2) ;
	  assert(!strcmp(command,"lenssize")) ;
      
      lensSize = temp;
	}

    /****************************************/

    /***********  GEOMETRY *******************/

    else if (!strcmp(command, "sphere")) {
	  double radius ; // Syntax is sphere x y z radius 
	  double pos[3] ;
	  double index;
	  int num = sscanf(line, "%s %lf %lf %lf %lf %lf", command, pos, pos+1, pos+2, &radius, &index) ;
	  if (num != 6) {
		fprintf(stderr, "sphere x y z radius\n") ;
		exit(1) ;
	  }

	  shapes->push_back(new Sphere(vec3(pos[0], pos[1], pos[2]), radius,
								   curDiffuse, curSpecular, curEmission,
								   curShininess, index, transformations.top()));

	}

	else if (!strcmp(command, "maxverts")) {
	  int num = sscanf(line, "%s %d", command, &maxverts) ;
	  assert(num == 2) ; assert(maxverts > 0) ;
	  assert(!strcmp(command,"maxverts")) ;
	  assert(verts = new vec3 *[maxverts]) ;
	}
  
	else if (!strcmp(command, "maxvertnorms")) {
	  int num = sscanf(line, "%s %d", command, &maxvertnorms) ;
	  assert(num == 2) ; assert(maxvertnorms > 0) ;
	  assert(!strcmp(command,"maxvertnorms")) ;
	  assert(vertnorms = new vertnorm [maxvertnorms]) ;
	}
  
  
	else if (!strcmp(command, "vertex")) {  // Add a vertex to the stack
	  assert(maxverts) ; assert(curvert < maxverts) ;
    double x,y,z;
	  int num = sscanf(line, "%s %lf %lf %lf", command, &x, &y, &z) ;
	  assert(num == 4) ; assert(!strcmp(command,"vertex")) ;
	  verts[curvert] = new vec3(x,y,z) ;
	  ++curvert ;
	}
  
  
	else if (!strcmp(command, "vertexnormal")) {  
	  // Add a vertex to the stack with a normal
	  assert(maxvertnorms) ; assert(curvertnorm < maxvertnorms) ;
	  vertnorm vn ;
          double x,y,z,nx,ny,nz;

	  int num = sscanf(line, "%s %lf %lf %lf %lf %lf %lf", 
		  command, &x, &y, &z, &nx, &ny, &nz); 

	  assert(num == 7) ; assert(!strcmp(command,"vertexnormal")) ;
          vn.vert = new vec3(x,y,z);
          vn.norm = new vec3(nx,ny,nz);
	  vertnorms[curvertnorm] = vn ;
	  ++curvertnorm ;
	}


	else if (!strcmp(command, "tri")) { // Triangle from 3 vertices
	 int pts[3] ; 
	 int num = sscanf(line, "%s %d %d %d", command, pts, pts+1, pts+2) ;
	 assert(num == 4) ; assert(!strcmp(command,"tri")) ;
	 int i ;
	 for (i = 0 ; i < 3 ; i++) {
	   assert(pts[i] >= 0 && pts[i] < maxverts) ;
	 }
	 vec4 temp0, temp1, temp2;
	 temp0 = vec4(*verts[pts[0]]);
	 temp1 = vec4(*verts[pts[1]]);
	 temp2 = vec4(*verts[pts[2]]);
	 vec3 vert0 = vec3(transformations.top() * temp0);
	 vec3 vert1 = vec3(transformations.top() * temp1);
	 vec3 vert2 = vec3(transformations.top() * temp2);

	 shapes->push_back(new Triangle(vert0, vert1, vert2, curDiffuse, curSpecular, curEmission, curShininess));

  }
 	else if (!strcmp(command, "trirefractive")) { // Triangle from 3 vertices
	 int pts[3] ; 
	 float index;
	 int num = sscanf(line, "%s %d %d %d %f", command, pts, pts+1, pts+2, &index) ;
	 assert(num == 5) ; assert(!strcmp(command,"trirefractive")) ;
	 int i ;
	 for (i = 0 ; i < 3 ; i++) {
	   assert(pts[i] >= 0 && pts[i] < maxverts) ;
	 }
	 vec4 temp0, temp1, temp2;
	 temp0 = vec4(*verts[pts[0]]);
	 temp1 = vec4(*verts[pts[1]]);
	 temp2 = vec4(*verts[pts[2]]);
	 vec3 vert0 = vec3(transformations.top() * temp0);
	 vec3 vert1 = vec3(transformations.top() * temp1);
	 vec3 vert2 = vec3(transformations.top() * temp2);

	 shapes->push_back(new Triangle(vert0, vert1, vert2, curDiffuse, curSpecular, curEmission, curShininess, index));

  } 
        else if (!strcmp(command, "trinormal")) {
	  int pts[3] ;
	  int num = sscanf(line, "%s %d %d %d", command, pts, pts+1, pts+2) ;
	  assert(num == 4) ; assert(!strcmp(command,"trinormal")) ;
	  int i;
	  for (i = 0 ; i < 3 ; i++) {
	    assert(pts[i] >= 0 && pts[i] < maxvertnorms) ;
	  }

	 vec4 temp0, temp1, temp2;
	 vertnorm v0 = vertnorms[pts[0]];
	 vertnorm v1 = vertnorms[pts[1]];
	 vertnorm v2 = vertnorms[pts[2]];
	 temp0 = vec4(*(v0.vert));
	 temp1 = vec4(*(v1.vert));
	 temp2 = vec4(*(v2.vert));
	 vec3 vert0 = vec3(transformations.top() * temp0);
	 vec3 vert1 = vec3(transformations.top() * temp1);
	 vec3 vert2 = vec3(transformations.top() * temp2);

	shapes->push_back(new TriNormal(vert0,vert1,vert2, *(v0.norm), *(v1.norm), *(v2.norm), curDiffuse, curSpecular, curEmission, curShininess)); 
	}

    /******************************************/

    /**************** TRANSFORMATIONS *********/


	else if (!strcmp(command, "translate")) {
	  double x,y,z ; // Translate by x y z as in standard OpenGL

	  int num = sscanf(line, "%s %lf %lf %lf",command, &x, &y, &z) ;
	  if (num != 4) {
		fprintf(stderr, "translate x y z\n") ;
		exit(1) ;
	  }
	  vec3 t = vec3(x, y, z);
	  mat4 m = transformations.top() * translation3D(t);
	  transformations.pop();
	  transformations.push(m);
	}

	else if (!strcmp(command, "rotate")) {
	  double ang, x,y,z ; // Rotate by an angle about axis x y z as in standard OpenGL

	  int num = sscanf(line, "%s %lf %lf %lf %lf",command, &x, &y, &z, &ang) ;
	  if (num != 5) {
		fprintf(stderr, "rotate angle x y z\n") ;
		exit(1) ;
	  }
	  vec3 r = vec3(x, y, z);
	  mat4 m = transformations.top() * rotation3D(r, ang);
	  transformations.pop();
	  transformations.push(m);
	}

	else if (!strcmp(command, "scale")) {
	  double x,y,z ; // Scale by x y z as in standard OpenGL

	  int num = sscanf(line, "%s %lf %lf %lf",command, &x, &y, &z) ;
	  if (num != 4) {
		fprintf(stderr, "scale x y z\n") ;
		exit(1) ;
	  }
	  vec3 s = vec3(x, y, z);
	  mat4 m = transformations.top() * scaling3D(s);
	  transformations.pop();
	  transformations.push(m);
	}

	else if (!strcmp(command, "pushTransform")) {
	  // Push the current matrix on the stack as in OpenGL
	  transformations.push(transformations.top());
	}

	else if (!strcmp(command, "popTransform")) {
	  // Pop the current matrix as in OpenGL
	  if (transformations.size() == 1) {
		cerr << "Cannot pop anymore." << endl;
	  } else {
		transformations.pop();
	  }
	}

    /************************************************************/

    /********* MISCELLANEOUS IGNORED FOR OPENGL *******************/

	else if (!strcmp(command, "maxdepth")) {
	  int maxdepth;
	  int num = sscanf(line, "%s %d", command, &maxdepth) ;
	  assert(num == 2) ;
	  assert(!strcmp(command, "maxdepth")) ;

	  maxDepth = maxdepth;
	}

	else if (!strcmp(command, "output")) {
	   char out[300] ;
	   int num = sscanf(line, "%s %s", command, out) ;
	   assert(num == 2) ;
	   assert(!strcmp(command, "output")) ;

	   outputPath = string(out);

	}

	else if (!strcmp(command, "samples")) {
	  int samples;
	  int num = sscanf(line, "%s %d", command, &samples) ;
	  assert(num == 2) ;
	  assert(!strcmp(command, "samples")) ;

	  numSamples = samples;
	}


    /*************************************************/

    /***************  LIGHTS *******************/
       else if (!strcmp(command, "directional")) {
	 double x,y,z,r,g,b;
	 int num = sscanf(line, "%s %lf %lf %lf %lf %lf %lf", command, &x, &y, &z, &r, &g, &b) ;
	 assert(num == 7) ;

	 vec3 dir = vec3(x,y,z);
	 dir = vec3(transformations.top() * vec4(dir, 0), 3);

	 lights->push_back(new DirectionalLight(dir, Color(r,g,b)));

       }

      else if (!strcmp(command, "point")) {
	 double x,y,z,r,g,b;
	 int num = sscanf(line, "%s %lf %lf %lf %lf %lf %lf", command, &x, &y, &z, &r, &g, &b) ;
	 assert(num == 7) ;

	 vec3 pos = vec3(x,y,z);
	 pos = vec3(transformations.top() * vec4(pos, 1));

	 lights->push_back(new PointLight(pos, Color(r,g,b), attenuation));

       }

      else if (!strcmp(command, "area")) {
        double x,y,z,i,j,r,g,b;
        int up;
        int num = sscanf(line, "%s %lf %lf %lf %lf %lf %d %lf %lf %lf", command, &x, &y, &z, &i, &j, &up, &r, &g, &b) ;
	 assert(num == 10) ;

	 vec3 pos = vec3(x,y,z);
	 pos = vec3(transformations.top() * vec4(pos, 1));
     Color c = Color(r, g, b);
     vec3 tri_pos[4];
     tri_pos[0] = pos;
     if (up == 0) {
       tri_pos[1] = pos + vec3(0, i, 0);
       tri_pos[2] = pos + vec3(0, 0, j);
       tri_pos[3] = pos + vec3(0, i, j);
     } else if (up == 1) {
       tri_pos[1] = pos + vec3(i, 0, 0);
       tri_pos[2] = pos + vec3(0, 0, j);
       tri_pos[3] = pos + vec3(i, 0, j);
     } else {
       tri_pos[1] = pos + vec3(i, 0, 0);
       tri_pos[2] = pos + vec3(0, j, 0);
       tri_pos[3] = pos + vec3(i, j, 0);
     }

     Triangle *one, *two;
     one = new Triangle(tri_pos[0], tri_pos[1], tri_pos[2],
                        black, black, c, 0);
     two = new Triangle(tri_pos[1], tri_pos[3], tri_pos[2],
                        black, black, c, 0);

	 lights->push_back(new AreaLight(pos, i, j, up, c, attenuation));
     shapes->push_back(one);
     shapes->push_back(two);

       }

     else if (!strcmp(command, "attenuation")) {
       double c, l, q;
       int num = sscanf(line, "%s %lf %lf %lf", command, &c, &l, &q );
       assert(num == 4) ;
       assert(!strcmp(command, "attenuation")) ;
       attenuation[0] = c;
	   attenuation[1] = l;
	   attenuation[2] = q;
     }

     else if (!strcmp(command, "ambient")) {
       double r,g,b; 
       int num = sscanf(line, "%s %lf %lf %lf", command, &r,&g,&b) ;
       assert(num == 4) ;
       assert(!strcmp(command, "ambient")) ;
       ambient = Color(r,g,b);
     }
    /*******************************************************/

    /****************** MATERIALS ************************/

     else if (!strcmp(command, "diffuse")) {
       float diffuse[4] ; diffuse[3] = 1.0 ;
       int num = sscanf(line, "%s %f %f %f", command, diffuse, diffuse+1, diffuse+2) ;
       assert(num == 4) ; assert (!strcmp(command, "diffuse")) ;

	   curDiffuse = Color(vec3(diffuse[0], diffuse[1], diffuse[2]));
     }

     else if (!strcmp(command, "specular")) {
       float specular[4] ; specular[3] = 1.0 ;
       int num = sscanf(line, "%s %f %f %f", command, specular, specular+1, specular+2) ;
       assert(num == 4) ; assert (!strcmp(command, "specular")) ;
      
	   curSpecular = Color(vec3(specular[0], specular[1], specular[2]));
     }

     else if (!strcmp(command, "shininess")) {
       float shininess ;
       int num = sscanf(line, "%s %f", command, &shininess) ;
       assert(num == 2) ; assert (!strcmp(command, "shininess")) ;

	   curShininess = shininess;
     }

     else if (!strcmp(command, "emission")) {
       float emission[4] ; emission[3] = 1.0 ;
       int num = sscanf(line, "%s %f %f %f", command, emission, emission+1, emission+2) ;
       assert(num == 4) ; assert (!strcmp(command, "emission")) ;

	   curEmission = Color(vec3(emission[0], emission[1], emission[2]));
     }

    /*****************************************************/

    else {
      fprintf(stderr, "Unimplemented command: %s\n", command) ;
      exit(1) ;
    }
  }
}
Beispiel #4
0
int main(int argc, char *argv[]) {
  // Start stopwatch
  double start = clock();
  
  // Parsing command line for input file name:
  std::string file = std::string(argv[1]);
  
  // Initialize/Declare everything!
  float windowW = 0;
  float windowH = 0;
  unsigned int maxDepth = 0;
  Camera c;
  unsigned int shapeNum = 0;
  BRDF brdf;
  float a1 = 1.0f;
  float a2 = 0.0f;
  float a3 = 0.0f;

  // Initialize Containers
  std::vector< std::vector<float> > vertices;
  std::vector< std::vector<float> > trinormvertices;
  std::vector< std::vector<float> > trinormnormals; 
  std::vector<Shape *> shapes0;
  std::vector<Shape> shapes1;
  std::vector<Sphere> spheres1;
  std::vector<Triangle> triangles1;
  std::vector<TriNormal> trinormals1;
  std::vector<DirectionalLight> DLs1;
  std::vector<PointLight> PLs1;
  std::vector<DirectionalLight *> DLs0;
  std::vector<PointLight *> PLs0;

  //stack of 4x4 matrix transformations
  std::stack<mat4> transforms; //transf
  //push the idendity 4x4 matrix
  transforms.push(identity3D()); //transf






  
  std::string fname = "output.bmp";

  std::ifstream inpfile(file.c_str());
  if(!inpfile.is_open()) {
    std::cout << "Unable to open file" << std::endl;
  } else {
    std::string line;
    // MatrixStack mst;

    while(inpfile.good()) {
      std::vector<std::string> splitline;
      std::string buf;

      std::getline(inpfile,line);
      std::stringstream ss(line);

      while (ss >> buf) {
        splitline.push_back(buf);
      }
      // Ignore blank lines
      if(splitline.size() == 0) {
        continue;
      }

      // Ignore comments
      if(splitline[0][0] == '#') {
        continue;
      }

      // Valid commands:
      // size width height
      //  must be first command of file, controls image size
      else if(!splitline[0].compare("size")) {
        windowW = atoi(splitline[1].c_str());
	c.w = windowW;
        c.h = windowH = atoi(splitline[2].c_str());
      }
      // maxdepth depth
      //  max # of bounces for ray (default 5)
      else if(!splitline[0].compare("maxdepth")) {
        maxDepth = atoi(splitline[1].c_str());
      }
      // output filename
      //  output file to write image to 
      else if(!splitline[0].compare("output")) {
        fname = splitline[1];
      }

      // camera lookfromx lookfromy lookfromz lookatx lookaty lookatz upx upy upz fov
      //  specifies the camera in the standard way, as in homework 2.
      else if (!splitline[0].compare("camera")) {
        c.lookFrom.at(0) = atof(splitline[1].c_str());
      	c.lookFrom.at(1) = atof(splitline[2].c_str());
      	c.lookFrom.at(2) = atof(splitline[3].c_str());
      	c.lookAt.at(0) = atof(splitline[4].c_str());
      	c.lookAt.at(1) = atof(splitline[5].c_str());
      	c.lookAt.at(2) = atof(splitline[6].c_str());
              c.upDir.at(0) = atof(splitline[7].c_str());
      	c.upDir.at(1) = atof(splitline[8].c_str());
      	c.upDir.at(2) = atof(splitline[9].c_str());
      	c.fov = atof(splitline[10].c_str());
      }

      // sphere x y z radius
      //  Defines a sphere with a given position and radius.
      else if(!splitline[0].compare("sphere")) {
      	Shape shape(shapeNum);
      	Sphere s(atof(splitline[1].c_str()),
            		 atof(splitline[2].c_str()),
            		 atof(splitline[3].c_str()),
            		 atof(splitline[4].c_str()),
            		 brdf, shapeNum++, transforms.top());
      	spheres1.push_back(s);
      	shape.brdf = brdf;
      	shapes1.push_back(shape);
        //   STORE CURRENT TOP OF MATRIX STACK
      }

      // Ignore these, unused
      else if(!splitline[0].compare("maxverts")) {
        continue;
      }
      else if(!splitline[0].compare("maxvertsnorms")) {
        continue;
      }
      
      //vertex x y z
      //  Defines a vertex at the given location.
      //  The vertex is put into a pile, starting to be numbered at 0.
      else if(!splitline[0].compare("vertex")) {
      	std::vector<float> p(3, 0.0f);
      	p.at(0) = atof(splitline[1].c_str());
      	p.at(1) = atof(splitline[2].c_str());
      	p.at(2) = atof(splitline[3].c_str());
      	vertices.push_back(p);
	
        // Create a new vertex with these 3 values, store in some array
      }
      //vertexnormal x y z nx ny nz
      //  Similar to the above, but define a surface normal with each vertex.
      //  The vertex and vertexnormal set of vertices are completely independent
      //  (as are maxverts and maxvertnorms).
      else if(!splitline[0].compare("vertexnormal")) {
      	std::vector<float> p(6, 0.0f);
      	std::vector<float> n(6, 0.0f);
      	p.at(0) = atof(splitline[1].c_str());
      	p.at(1) = atof(splitline[2].c_str());
      	p.at(2) = atof(splitline[3].c_str());
      	n.at(3) = atof(splitline[4].c_str());
      	n.at(4) = atof(splitline[5].c_str());
      	n.at(5) = atof(splitline[6].c_str());
      	trinormvertices.push_back(p);
      	trinormnormals.push_back(n);
      }
      //tri v1 v2 v3
      //  Create a triangle out of the vertices involved (which have previously 
      //  been specified with the vertex command). The vertices are assumed to 
      //  be specified in counter-clockwise order. Your code should internally 
      //  compute a face normal for this triangle.
      else if(!splitline[0].compare("tri")) {
      	Shape shape(shapeNum);
      	// std::vector<float> *v1 = &vertices.at(atoi(splitline[1].c_str()));
      	// std::vector<float> *v2 = &vertices.at(atoi(splitline[2].c_str()));
      	// std::vector<float> *v3 = &vertices.at(atoi(splitline[3].c_str()));

        //original code:
        //std::vector<float> *v1 = &vertices.at(atoi(splitline[1].c_str()));
        //std::vector<float> *v2 = &vertices.at(atoi(splitline[2].c_str()));
        //std::vector<float> *v3 = &vertices.at(atoi(splitline[3].c_str()));

        //casting each of the three 3D vertice vectors into 4D vectors:
        std::vector<float> *v1 = &vertices.at(atoi(splitline[1].c_str()));
        std::vector<float> *v2 = &vertices.at(atoi(splitline[2].c_str()));
        std::vector<float> *v3 = &vertices.at(atoi(splitline[3].c_str()));

        //new component is set by default to 1.0
        //e.g., casted 4D vector of v1 looks like: v1(v1.x, v1.y, v1.z, 1.0)
        //vec4 v1_4D = vec4((*v1)[0], *&(v1->at(1)), v1->at(2));
        vec3 v1_3d = vec3((float) v1->at(0), (float) v1->at(1), (float) v1->at(2));
        vec3 v2_3d = vec3((float) v2->at(0), (float) v2->at(1), (float) v2->at(2));
        vec3 v3_3d = vec3((float) v3->at(0), (float) v3->at(1), (float) v3->at(2));

        vec4 v1_4D = vec4(v1_3d);
        vec4 v2_4D = vec4(v2_3d);
        vec4 v3_4D = vec4(v3_3d);

        //transforming the vertices by multiplying the transformation
        //matrix by the 4D vertex vector:
        //algebra3 notes about casting down from 4D to 3D: When casting to a lower dimension,
        //the vector is homogenized in the lower dimension. E.g., if a 4d {X,Y,Z,W}
        //is cast to 3d, the resulting vector is {X/W, Y/W, Z/W}.
        vec3 v1_3D = vec3(transforms.top() * v1_4D);
        vec3 v2_3D = vec3(transforms.top() * v2_4D);
        vec3 v3_3D = vec3(transforms.top() * v3_4D);

        //converting each vec3 into a vector<float>:
	std::vector<float> *vv1 = new std::vector<float>(3, 0.0f);
	std::vector<float> *vv2 = new std::vector<float>(3, 0.0f);
	std::vector<float> *vv3 = new std::vector<float>(3, 0.0f);
	
        vv1->at(0) = v1_3D[0];
        vv1->at(1) = v1_3D[1];
        vv1->at(2) = v1_3D[2];

        vv2->at(0) = v2_3D[0];
        vv2->at(1) = v2_3D[1];
        vv2->at(2) = v2_3D[2];

        vv3->at(0) = v3_3D[0];
        vv3->at(1) = v3_3D[1];
        vv3->at(2) = v3_3D[2];

	
        
        //Finally, pushing the transformed vertices into the triangles container:
      	Triangle t(vv1, vv2, vv3, brdf, shapeNum++);
      	triangles1.push_back(t);
      	shape.brdf = brdf;
      	shapes1.push_back(shape);
        //   STORE CURRENT TOP OF MATRIX
      }
      //trinormal v1 v2 v3
      //  Same as above but for vertices specified with normals.
      //  In this case, each vertex has an associated normal, 
      //  and when doing shading, you should interpolate the normals 
      //  for intermediate points on the triangle.
      else if(!splitline[0].compare("trinormal")) {
      	Shape shape(shapeNum);
      	std::vector<float> *v1 = &trinormvertices.at(atoi(splitline[1].c_str()));
      	std::vector<float> *v2 = &trinormvertices.at(atoi(splitline[2].c_str()));
      	std::vector<float> *v3 = &trinormvertices.at(atoi(splitline[3].c_str()));
      	std::vector<float> *n1 = &trinormnormals.at(atoi(splitline[1].c_str()));
      	std::vector<float> *n2 = &trinormnormals.at(atoi(splitline[2].c_str()));
      	std::vector<float> *n3 = &trinormnormals.at(atoi(splitline[3].c_str()));
      	TriNormal t(v1, v2, v3, n1, n2, n3, brdf, shapeNum++);
      	trinormals1.push_back(t);
      	shape.brdf = brdf;
      	shapes1.push_back(shape);
        //   STORE CURRENT TOP OF MATRIX STACK
      }

      //Translate x y z
      //  A translation 3-vector
      else if(!splitline[0].compare("translate")) {
        float x, y, z;
        x = atof(splitline[1].c_str());
        y = atof(splitline[2].c_str());
        z = atof(splitline[3].c_str());

        //creating translation vector, v:
        vec3 v = vec3(x, y, z);

        //getting the top (i.e. latest) matrix on the stack, and doing a translation3D transform:
        mat4 vTranslated = translation3D(v);
        mat4 transMat = transforms.top() * vTranslated;

        //updating the top of the matrix stack:
        transforms.pop();
        transforms.push(transMat);
      }
      //rotate x y z angle
      //  Rotate by angle (in degrees) about the given axis as in OpenGL.
      else if(!splitline[0].compare("rotate")) {
        float x, y, z, angle;
        x = atof(splitline[1].c_str());
        y = atof(splitline[2].c_str());
        z = atof(splitline[3].c_str());

        //angle of rotation IN DEGREES
        angle = atof(splitline[4].c_str());

        //creating the axis of rotation vector, axis:
        vec3 axis = vec3(x, y, z);

        //getting the top (i.e.latest) matrix on the stack, and doing a rotation3D transform using DEGREES:
        mat4 rotatedV = rotation3D(axis, angle);
        mat4 rotMat = transforms.top() * rotatedV;

        //updating the top of the matrix stack:
        transforms.pop();
        transforms.push(rotMat);
      }
      //scale x y z
      //  Scale by the corresponding amount in each axis (a non-uniform scaling).
      else if(!splitline[0].compare("scale")) {
        float x, y, z;
        x = atof(splitline[1].c_str());
        y = atof(splitline[2].c_str());
        z = atof(splitline[3].c_str());

        //creating the scaling vector, scaleV
        vec3 scaleV = vec3(x, y, z);

        //getting the top (i.e.latest) matrix on the stack, and doing a scaling3D transform
        mat4 scaledV = scaling3D(scaleV);
        mat4 scaleMat = transforms.top() * scaledV;

        //updating the top of the matrix stack:
        transforms.pop();
        transforms.push(scaleMat);
      }
      //pushTransform
      //  Push the current modeling transform on the stack as in OpenGL. 
      //  You might want to do pushTransform immediately after setting 
      //   the camera to preserve the “identity” transformation.
      else if(!splitline[0].compare("pushTransform")) {
        transforms.push(transforms.top());
      }
      //popTransform
      //  Pop the current transform from the stack as in OpenGL. 
      //  The sequence of popTransform and pushTransform can be used if 
      //  desired before every primitive to reset the transformation 
      //  (assuming the initial camera transformation is on the stack as 
      //  discussed above).
      else if(!splitline[0].compare("popTransform")) {
        if (transforms.size() == 1) {
          std::cout << "No more matrices." << std::endl;
        } else {
          transforms.pop();
        }
      }

      //directional x y z r g b
      //  The direction to the light source, and the color, as in OpenGL.
      else if(!splitline[0].compare("directional")) {
        //original DO NOT DELETE
	      // DLs1.push_back(*new DirectionalLight (atof(splitline[1].c_str()),
					  //    atof(splitline[2].c_str()),
					  //    atof(splitline[3].c_str()),
					  //    atof(splitline[4].c_str()),
					  //    atof(splitline[5].c_str()),
					  //    atof(splitline[6].c_str())));

        vec3 dir = vec3(atof(splitline[1].c_str()), atof(splitline[2].c_str()), atof(splitline[3].c_str()));
        vec3 rgb = vec3(atof(splitline[4].c_str()), atof(splitline[5].c_str()), atof(splitline[6].c_str()));

        //lizzie comment: vec3(const vec4& v, int dropAxis); <- casts v4 to v3
        dir = vec3(transforms.top() * vec4(dir, 0), 3);

        DLs1.push_back(*new DirectionalLight(dir[0], dir[1], dir[2], rgb[0], rgb[1], rgb[2]));

      }
      //point x y z r g b
      //  The location of a point source and the color, as in OpenGL.
      else if(!splitline[0].compare("point")) {
        //original code DO NOT DELETE
	     // PLs1.push_back(*new PointLight (atof(splitline[1].c_str()),
				  //      atof(splitline[2].c_str()),
				  //      atof(splitline[3].c_str()),
				  //      atof(splitline[4].c_str()),
				  //      atof(splitline[5].c_str()),
				  //      atof(splitline[6].c_str()), a1, a2, a3));
        vec3 loc = vec3(atof(splitline[1].c_str()), atof(splitline[2].c_str()), atof(splitline[3].c_str()));
        vec3 rgb = vec3(atof(splitline[4].c_str()), atof(splitline[5].c_str()), atof(splitline[6].c_str()));

        //lizzie comment: vec3(const vec4& v, int dropAxis); <- casts v4 to v3
        loc = vec3(transforms.top() * vec4(loc, 1));

        PLs1.push_back(*new PointLight(loc[0], loc[1], loc[2], rgb[0], rgb[1], rgb[2], a1, a2, a3));
      }
      //attenuation const linear quadratic
      //  Sets the constant, linear and quadratic attenuations 
      //  (default 1,0,0) as in OpenGL.
      else if(!splitline[0].compare("attenuation")) {
        a1 = atof(splitline[1].c_str());
        a2 = atof(splitline[2].c_str());
        a3 = atof(splitline[3].c_str());
      }
      //ambient r g b
      //  The global ambient color to be added for each object 
      //  (default is .2,.2,.2), set in BRDF constructor
      else if(!splitline[0].compare("ambient")) {
        brdf.ka.at(0) = atof(splitline[1].c_str());
        brdf.ka.at(1) = atof(splitline[2].c_str());
        brdf.ka.at(2) = atof(splitline[3].c_str());
      }
      //diffuse r g b
      //  specifies the diffuse color of the surface.
      else if(!splitline[0].compare("diffuse")) {
        brdf.kd.at(0) = atof(splitline[1].c_str());
        brdf.kd.at(1) = atof(splitline[2].c_str());
        brdf.kd.at(2) = atof(splitline[3].c_str());
      }
      //specular r g b 
      //  specifies the specular color of the surface.
      else if(!splitline[0].compare("specular")) {
        brdf.ks.at(0) = atof(splitline[1].c_str());
        brdf.ks.at(1) = atof(splitline[2].c_str());
        brdf.ks.at(2) = atof(splitline[3].c_str());
      }
      //shininess s
      //  specifies the shininess of the surface.
      else if(!splitline[0].compare("shininess")) {
	brdf.s = atof(splitline[1].c_str());
      }
      //emission r g b
      //  gives the emissive color of the surface.
      else if(!splitline[0].compare("emission")) {
        brdf.ke.at(0) = atof(splitline[1].c_str());
        brdf.ke.at(1) = atof(splitline[2].c_str());
        brdf.ke.at(2) = atof(splitline[3].c_str());
      } else {
        std::cerr << "Unknown command: " << splitline[0] << std::endl;
      }
    }

    inpfile.close();
  }

  // BEGIN SHIT
  c.setD();			// set camera d
  c.setULRD();			// set camera ULRD
  Film f(windowW, windowH);
  RayTracer rt(&c);
  Sampler s(&c, &rt, &f);
  // Create iterators for containers
  unsigned int sphCount = 0;
  unsigned int triCount = 0;
  unsigned int tnCount = 0;
  // Set up shapes0, the finalized container
  for (unsigned int i = 0; i < shapes1.size(); i++) {
    if (sphCount < spheres1.size() && spheres1[sphCount].num == i) {
      shapes1[i].sph = &spheres1[sphCount++];
      shapes0.push_back(&shapes1[i]);
    } else if (triCount < triangles1.size() && triangles1[triCount].num == i) {
      shapes1[i].tri = &triangles1[triCount++];
      shapes0.push_back(&shapes1[i]);
    } else if (tnCount < trinormals1.size() && trinormals1[tnCount].num == i) {
      shapes1[i].tn = &trinormals1[tnCount++];
      shapes0.push_back(&shapes1[i]);
    } else {
      printf("container maker not working");
      std::exit(1);
    }
  }
  for (unsigned int i = 0; i < PLs1.size(); i++) {
    PLs0.push_back(&PLs1[i]);
  }
  for (unsigned int i = 0; i < DLs1.size(); i++) {
    DLs0.push_back(&DLs1[i]);
  }
  
  rt.shapes = &shapes0;
  rt.DLs = &DLs0;
  rt.PLs = &PLs0;
  
  // GOOOOOOOOOOOOOOO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  render(windowW, windowH, maxDepth, fname, &s);
  double total = (clock() - start) / 1000000;
  if (total > 3599) {
    std::cout<<"Time taken: " << total / 3600 << " hours\n";
  } else if (total > 59) {
    std::cout<<"Time taken: " << total/60 << " minutes\n";
  } else {
    std::cout<<"Time taken: " << total << " seconds\n";
  }
}